@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
96 lines • 20.3 kB
JavaScript
import { ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import { ControlContainer, NgForm, NgModel } from '@angular/forms';
import { LoginService } from '../login/login.service';
import * as i0 from "@angular/core";
import * as i1 from "../login/login.service";
import * as i2 from "../forms/default-validation.directive";
import * as i3 from "@angular/forms";
import * as i4 from "../forms/form-group.component";
import * as i5 from "../i18n/c8y-translate.directive";
import * as i6 from "@angular/common";
import * as i7 from "./password-confirm.directive";
import * as i8 from "./password-check-list.component";
import * as i9 from "./password-input.component";
import * as i10 from "../i18n/c8y-translate.pipe";
export class NewPasswordComponent {
set _newPasswordModel(ngModel) {
if (ngModel) {
this.newPasswordModel = ngModel;
ngModel.control.addValidators(this.passwordChecklistValidator);
}
}
constructor(loginService, cdRef) {
this.loginService = loginService;
this.cdRef = cdRef;
this.password = new EventEmitter();
this.showChangePasswordButton = true;
this.model = {};
this.changePassword = false;
this.passwordEnforced = false;
this.passwordChecklistValidator = () => this.requirementsFulfilled ? null : { passwordStrengthChecklist: true };
}
ngOnInit() {
this.loadPasswordStrengthSettings();
this.loginService.getGreenMinLength().then(value => {
this.minlength = value;
});
}
async ngOnChanges(changes) {
if (changes.showChangePasswordButton) {
this.changePassword = !this.showChangePasswordButton;
}
if (changes.requireStrongPassword?.previousValue !== changes.requireStrongPassword?.currentValue) {
await this.loadPasswordStrengthSettings();
}
}
newPasswordChanged() {
this.password.emit({
password: this.model.newPassword,
passwordStrength: this.model.strength
});
}
updateValidity(requirementsFulfilled) {
this.requirementsFulfilled = requirementsFulfilled;
this.cdRef.detectChanges();
this.newPasswordModel.control.updateValueAndValidity();
// There are two validators checking password validity, but we only want to show one of these errors at a time,
// where checklist validator takes priority.
if (!this.requirementsFulfilled) {
delete this.newPasswordModel.control.errors['password'];
}
}
async loadPasswordStrengthSettings() {
if (this.requireStrongPassword) {
this.passwordEnforced = this.requireStrongPassword;
}
else {
const passwordStrengthSettings = await this.loginService.getPasswordStrengthEnforced({
refresh: true
});
this.passwordEnforced = passwordStrengthSettings;
}
}
toggleChangePassword() {
this.changePassword = !this.changePassword;
if (!this.changePassword) {
this.password.emit({});
this.model = {};
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NewPasswordComponent, deps: [{ token: i1.LoginService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: NewPasswordComponent, selector: "c8y-new-password", inputs: { showChangePasswordButton: "showChangePasswordButton", requireStrongPassword: "requireStrongPassword" }, outputs: { password: "password" }, viewQueries: [{ propertyName: "_newPasswordModel", first: true, predicate: ["newPassword"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"showChangePasswordButton\" class=\"form-group\">\n <button\n class=\"btn btn-default\"\n type=\"button\"\n (click)=\"toggleChangePassword()\"\n data-cy=\"c8y-new-password--change-button\"\n >\n <ng-container *ngIf=\"!changePassword\">\n {{ 'Change password' | translate }}\n </ng-container>\n <ng-container *ngIf=\"changePassword\">\n {{ 'Cancel password change' | translate }}\n </ng-container>\n </button>\n</div>\n\n<div\n class=\"row content-flex-50\"\n *ngIf=\"changePassword\"\n>\n <div class=\"col-6\">\n <c8y-form-group>\n <label\n for=\"newPassword\"\n translate\n >\n Password\n </label>\n <c8y-password-input\n name=\"newPassword\"\n required\n [id]=\"'newPassword'\"\n #newPassword=\"ngModel\"\n [(ngModel)]=\"model.newPassword\"\n (change)=\"newPasswordChanged()\"\n (input)=\"newPasswordConfirm.control.updateValueAndValidity()\"\n c8yDefaultValidation=\"password\"\n [autocomplete]=\"'new-password'\"\n ></c8y-password-input>\n </c8y-form-group>\n\n <c8y-form-group>\n <label\n for=\"newConfirmPassword\"\n translate\n >\n Confirm password\n </label>\n <c8y-password-input\n name=\"newPasswordConfirm\"\n required\n [id]=\"'newConfirmPassword'\"\n #newPasswordConfirm=\"ngModel\"\n [(ngModel)]=\"model.newPasswordConfirm\"\n passwordConfirm=\"newPassword\"\n [autocomplete]=\"'new-password'\"\n ></c8y-password-input>\n </c8y-form-group>\n </div>\n <div class=\"col-6\">\n <c8y-password-check-list\n [password]=\"model.newPassword\"\n [strengthEnforced]=\"passwordEnforced\"\n (onRequirementsFulfilled)=\"updateValidity($event)\"\n ></c8y-password-check-list>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i2.DefaultValidationDirective, selector: "[c8yDefaultValidation]", inputs: ["c8yDefaultValidation"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i5.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.PasswordConfirm, selector: "[passwordConfirm]" }, { kind: "component", type: i8.PasswordCheckListComponent, selector: "c8y-password-check-list", inputs: ["strengthEnforced", "password"], outputs: ["onRequirementsFulfilled"] }, { kind: "component", type: i9.PasswordInputComponent, selector: "c8y-password-input", inputs: ["id", "autocomplete"] }, { kind: "pipe", type: i10.C8yTranslatePipe, name: "translate" }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: NewPasswordComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-new-password', viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], template: "<div *ngIf=\"showChangePasswordButton\" class=\"form-group\">\n <button\n class=\"btn btn-default\"\n type=\"button\"\n (click)=\"toggleChangePassword()\"\n data-cy=\"c8y-new-password--change-button\"\n >\n <ng-container *ngIf=\"!changePassword\">\n {{ 'Change password' | translate }}\n </ng-container>\n <ng-container *ngIf=\"changePassword\">\n {{ 'Cancel password change' | translate }}\n </ng-container>\n </button>\n</div>\n\n<div\n class=\"row content-flex-50\"\n *ngIf=\"changePassword\"\n>\n <div class=\"col-6\">\n <c8y-form-group>\n <label\n for=\"newPassword\"\n translate\n >\n Password\n </label>\n <c8y-password-input\n name=\"newPassword\"\n required\n [id]=\"'newPassword'\"\n #newPassword=\"ngModel\"\n [(ngModel)]=\"model.newPassword\"\n (change)=\"newPasswordChanged()\"\n (input)=\"newPasswordConfirm.control.updateValueAndValidity()\"\n c8yDefaultValidation=\"password\"\n [autocomplete]=\"'new-password'\"\n ></c8y-password-input>\n </c8y-form-group>\n\n <c8y-form-group>\n <label\n for=\"newConfirmPassword\"\n translate\n >\n Confirm password\n </label>\n <c8y-password-input\n name=\"newPasswordConfirm\"\n required\n [id]=\"'newConfirmPassword'\"\n #newPasswordConfirm=\"ngModel\"\n [(ngModel)]=\"model.newPasswordConfirm\"\n passwordConfirm=\"newPassword\"\n [autocomplete]=\"'new-password'\"\n ></c8y-password-input>\n </c8y-form-group>\n </div>\n <div class=\"col-6\">\n <c8y-password-check-list\n [password]=\"model.newPassword\"\n [strengthEnforced]=\"passwordEnforced\"\n (onRequirementsFulfilled)=\"updateValidity($event)\"\n ></c8y-password-check-list>\n </div>\n</div>\n" }]
}], ctorParameters: () => [{ type: i1.LoginService }, { type: i0.ChangeDetectorRef }], propDecorators: { password: [{
type: Output
}], showChangePasswordButton: [{
type: Input
}], requireStrongPassword: [{
type: Input
}], _newPasswordModel: [{
type: ViewChild,
args: ['newPassword']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmV3LXBhc3N3b3JkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2NvcmUvYXV0aGVudGljYXRpb24vbmV3LXBhc3N3b3JkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL2NvcmUvYXV0aGVudGljYXRpb24vbmV3LXBhc3N3b3JkLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxpQkFBaUIsRUFDakIsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUNOLFNBQVMsRUFFVixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBZSxNQUFNLGdCQUFnQixDQUFDO0FBQ2hGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7Ozs7Ozs7Ozs7O0FBT3RELE1BQU0sT0FBTyxvQkFBb0I7SUFXL0IsSUFDSSxpQkFBaUIsQ0FBQyxPQUFnQjtRQUNwQyxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ1osSUFBSSxDQUFDLGdCQUFnQixHQUFHLE9BQU8sQ0FBQztZQUNoQyxPQUFPLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsQ0FBQztRQUNqRSxDQUFDO0lBQ0gsQ0FBQztJQUVELFlBQ1UsWUFBMEIsRUFDMUIsS0FBd0I7UUFEeEIsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsVUFBSyxHQUFMLEtBQUssQ0FBbUI7UUFwQnhCLGFBQVEsR0FBRyxJQUFJLFlBQVksRUFBd0IsQ0FBQztRQUNyRCw2QkFBd0IsR0FBRyxJQUFJLENBQUM7UUFFekMsVUFBSyxHQUFRLEVBQUUsQ0FBQztRQUNoQixtQkFBYyxHQUFHLEtBQUssQ0FBQztRQUN2QixxQkFBZ0IsR0FBRyxLQUFLLENBQUM7UUFrQnpCLCtCQUEwQixHQUFnQixHQUFHLEVBQUUsQ0FDN0MsSUFB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Z0JBU0YsaUJBQWlCO3NCQURwQixTQUFTO3VCQUFDLGFBQWEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkluaXQsXG4gIE9uQ2hhbmdlcyxcbiAgT3V0cHV0LFxuICBWaWV3Q2hpbGQsXG4gIFNpbXBsZUNoYW5nZXNcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOZXdQYXNzd29yZCB9IGZyb20gJy4vcGFzc3dvcmQubW9kZWwnO1xuaW1wb3J0IHsgQ29udHJvbENvbnRhaW5lciwgTmdGb3JtLCBOZ01vZGVsLCBWYWxpZGF0b3JGbiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IExvZ2luU2VydmljZSB9IGZyb20gJy4uL2xvZ2luL2xvZ2luLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktbmV3LXBhc3N3b3JkJyxcbiAgdGVtcGxhdGVVcmw6ICcuL25ldy1wYXNzd29yZC5jb21wb25lbnQuaHRtbCcsXG4gIHZpZXdQcm92aWRlcnM6IFt7IHByb3ZpZGU6IENvbnRyb2xDb250YWluZXIsIHVzZUV4aXN0aW5nOiBOZ0Zvcm0gfV1cbn0pXG5leHBvcnQgY2xhc3MgTmV3UGFzc3dvcmRDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMsIE9uSW5pdCB7XG4gIEBPdXRwdXQoKSBwYXNzd29yZCA9IG5ldyBFdmVudEVtaXR0ZXI8TmV3UGFzc3dvcmQgfCBvYmplY3Q+KCk7XG4gIEBJbnB1dCgpIHNob3dDaGFuZ2VQYXNzd29yZEJ1dHRvbiA9IHRydWU7XG4gIEBJbnB1dCgpIHJlcXVpcmVTdHJvbmdQYXNzd29yZDogYm9vbGVhbjtcbiAgbW9kZWw6IGFueSA9IHt9O1xuICBjaGFuZ2VQYXNzd29yZCA9IGZhbHNlO1xuICBwYXNzd29yZEVuZm9yY2VkID0gZmFsc2U7XG4gIG1pbmxlbmd0aDogbnVtYmVyO1xuICByZXF1aXJlbWVudHNGdWxmaWxsZWQ6IGJvb2xlYW47XG4gIG5ld1Bhc3N3b3JkTW9kZWw6IE5nTW9kZWw7XG5cbiAgQFZpZXdDaGlsZCgnbmV3UGFzc3dvcmQnKVxuICBzZXQgX25ld1Bhc3N3b3JkTW9kZWwobmdNb2RlbDogTmdNb2RlbCkge1xuICAgIGlmIChuZ01vZGVsKSB7XG4gICAgICB0aGlzLm5ld1Bhc3N3b3JkTW9kZWwgPSBuZ01vZGVsO1xuICAgICAgbmdNb2RlbC5jb250cm9sLmFkZFZhbGlkYXRvcnModGhpcy5wYXNzd29yZENoZWNrbGlzdFZhbGlkYXRvcik7XG4gICAgfVxuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBsb2dpblNlcnZpY2U6IExvZ2luU2VydmljZSxcbiAgICBwcml2YXRlIGNkUmVmOiBDaGFuZ2VEZXRlY3RvclJlZlxuICApIHt9XG5cbiAgcGFzc3dvcmRDaGVja2xpc3RWYWxpZGF0b3I6IFZhbGlkYXRvckZuID0gKCkgPT5cbiAgICB0aGlzLnJlcXVpcmVtZW50c0Z1bGZpbGxlZCA/IG51bGwgOiB7IHBhc3N3b3JkU3RyZW5ndGhDaGVja2xpc3Q6IHRydWUgfTtcblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmxvYWRQYXNzd29yZFN0cmVuZ3RoU2V0dGluZ3MoKTtcbiAgICB0aGlzLmxvZ2luU2VydmljZS5nZXRHcmVlbk1pbkxlbmd0aCgpLnRoZW4odmFsdWUgPT4ge1xuICAgICAgdGhpcy5taW5sZW5ndGggPSB2YWx1ZTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBpZiAoY2hhbmdlcy5zaG93Q2hhbmdlUGFzc3dvcmRCdXR0b24pIHtcbiAgICAgIHRoaXMuY2hhbmdlUGFzc3dvcmQgPSAhdGhpcy5zaG93Q2hhbmdlUGFzc3dvcmRCdXR0b247XG4gICAgfVxuICAgIGlmIChcbiAgICAgIGNoYW5nZXMucmVxdWlyZVN0cm9uZ1Bhc3N3b3JkPy5wcmV2aW91c1ZhbHVlICE9PSBjaGFuZ2VzLnJlcXVpcmVTdHJvbmdQYXNzd29yZD8uY3VycmVudFZhbHVlXG4gICAgKSB7XG4gICAgICBhd2FpdCB0aGlzLmxvYWRQYXNzd29yZFN0cmVuZ3RoU2V0dGluZ3MoKTtcbiAgICB9XG4gIH1cblxuICBuZXdQYXNzd29yZENoYW5nZWQoKSB7XG4gICAgdGhpcy5wYXNzd29yZC5lbWl0KHtcbiAgICAgIHBhc3N3b3JkOiB0aGlzLm1vZGVsLm5ld1Bhc3N3b3JkLFxuICAgICAgcGFzc3dvcmRTdHJlbmd0aDogdGhpcy5tb2RlbC5zdHJlbmd0aFxuICAgIH0pO1xuICB9XG5cbiAgdXBkYXRlVmFsaWRpdHkocmVxdWlyZW1lbnRzRnVsZmlsbGVkOiBib29sZWFuKSB7XG4gICAgdGhpcy5yZXF1aXJlbWVudHNGdWxmaWxsZWQgPSByZXF1aXJlbWVudHNGdWxmaWxsZWQ7XG4gICAgdGhpcy5jZFJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgdGhpcy5uZXdQYXNzd29yZE1vZGVsLmNvbnRyb2wudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xuICAgIC8vIFRoZXJlIGFyZSB0d28gdmFsaWRhdG9ycyBjaGVja2luZyBwYXNzd29yZCB2YWxpZGl0eSwgYnV0IHdlIG9ubHkgd2FudCB0byBzaG93IG9uZSBvZiB0aGVzZSBlcnJvcnMgYXQgYSB0aW1lLFxuICAgIC8vIHdoZXJlIGNoZWNrbGlzdCB2YWxpZGF0b3IgdGFrZXMgcHJpb3JpdHkuXG4gICAgaWYgKCF0aGlzLnJlcXVpcmVtZW50c0Z1bGZpbGxlZCkge1xuICAgICAgZGVsZXRlIHRoaXMubmV3UGFzc3dvcmRNb2RlbC5jb250cm9sLmVycm9yc1sncGFzc3dvcmQnXTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBsb2FkUGFzc3dvcmRTdHJlbmd0aFNldHRpbmdzKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLnJlcXVpcmVTdHJvbmdQYXNzd29yZCkge1xuICAgICAgdGhpcy5wYXNzd29yZEVuZm9yY2VkID0gdGhpcy5yZXF1aXJlU3Ryb25nUGFzc3dvcmQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHBhc3N3b3JkU3RyZW5ndGhTZXR0aW5ncyA9IGF3YWl0IHRoaXMubG9naW5TZXJ2aWNlLmdldFBhc3N3b3JkU3RyZW5ndGhFbmZvcmNlZCh7XG4gICAgICAgIHJlZnJlc2g6IHRydWVcbiAgICAgIH0pO1xuICAgICAgdGhpcy5wYXNzd29yZEVuZm9yY2VkID0gcGFzc3dvcmRTdHJlbmd0aFNldHRpbmdzO1xuICAgIH1cbiAgfVxuXG4gIHRvZ2dsZUNoYW5nZVBhc3N3b3JkKCkge1xuICAgIHRoaXMuY2hhbmdlUGFzc3dvcmQgPSAhdGhpcy5jaGFuZ2VQYXNzd29yZDtcbiAgICBpZiAoIXRoaXMuY2hhbmdlUGFzc3dvcmQpIHtcbiAgICAgIHRoaXMucGFzc3dvcmQuZW1pdCh7fSk7XG4gICAgICB0aGlzLm1vZGVsID0ge307XG4gICAgfVxuICB9XG59XG4iLCI8ZGl2ICpuZ0lmPVwic2hvd0NoYW5nZVBhc3N3b3JkQnV0dG9uXCIgY2xhc3M9XCJmb3JtLWdyb3VwXCI+XG4gIDxidXR0b25cbiAgICBjbGFzcz1cImJ0biBidG4tZGVmYXVsdFwiXG4gICAgdHlwZT1cImJ1dHRvblwiXG4gICAgKGNsaWNrKT1cInRvZ2dsZUNoYW5nZVBhc3N3b3JkKClcIlxuICAgIGRhdGEtY3k9XCJjOHktbmV3LXBhc3N3b3JkLS1jaGFuZ2UtYnV0dG9uXCJcbiAgPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhY2hhbmdlUGFzc3dvcmRcIj5cbiAgICAgIHt7ICdDaGFuZ2UgcGFzc3dvcmQnIHwgdHJhbnNsYXRlIH19XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNoYW5nZVBhc3N3b3JkXCI+XG4gICAgICB7eyAnQ2FuY2VsIHBhc3N3b3JkIGNoYW5nZScgfCB0cmFuc2xhdGUgfX1cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9idXR0b24+XG48L2Rpdj5cblxuPGRpdlxuICBjbGFzcz1cInJvdyBjb250ZW50LWZsZXgtNTBcIlxuICAqbmdJZj1cImNoYW5nZVBhc3N3b3JkXCJcbj5cbiAgPGRpdiBjbGFzcz1cImNvbC02XCI+XG4gICAgPGM4eS1mb3JtLWdyb3VwPlxuICAgICAgPGxhYmVsXG4gICAgICAgIGZvcj1cIm5ld1Bhc3N3b3JkXCJcbiAgICAgICAgdHJhbnNsYXRlXG4gICAgICA+XG4gICAgICAgIFBhc3N3b3JkXG4gICAgICA8L2xhYmVsPlxuICAgICAgPGM4eS1wYXNzd29yZC1pbnB1dFxuICAgICAgICBuYW1lPVwibmV3UGFzc3dvcmRcIlxuICAgICAgICByZXF1aXJlZFxuICAgICAgICBbaWRdPVwiJ25ld1Bhc3N3b3JkJ1wiXG4gICAgICAgICNuZXdQYXNzd29yZD1cIm5nTW9kZWxcIlxuICAgICAgICBbKG5nTW9kZWwpXT1cIm1vZGVsLm5ld1Bhc3N3b3JkXCJcbiAgICAgICAgKGNoYW5nZSk9XCJuZXdQYXNzd29yZENoYW5nZWQoKVwiXG4gICAgICAgIChpbnB1dCk9XCJuZXdQYXNzd29yZENvbmZpcm0uY29udHJvbC51cGRhdGVWYWx1ZUFuZFZhbGlkaXR5KClcIlxuICAgICAgICBjOHlEZWZhdWx0VmFsaWRhdGlvbj1cInBhc3N3b3JkXCJcbiAgICAgICAgW2F1dG9jb21wbGV0ZV09XCInbmV3LXBhc3N3b3JkJ1wiXG4gICAgICA+PC9jOHktcGFzc3dvcmQtaW5wdXQ+XG4gICAgPC9jOHktZm9ybS1ncm91cD5cblxuICAgIDxjOHktZm9ybS1ncm91cD5cbiAgICAgIDxsYWJlbFxuICAgICAgICBmb3I9XCJuZXdDb25maXJtUGFzc3dvcmRcIlxuICAgICAgICB0cmFuc2xhdGVcbiAgICAgID5cbiAgICAgICAgQ29uZmlybSBwYXNzd29yZFxuICAgICAgPC9sYWJlbD5cbiAgICAgIDxjOHktcGFzc3dvcmQtaW5wdXRcbiAgICAgICAgbmFtZT1cIm5ld1Bhc3N3b3JkQ29uZmlybVwiXG4gICAgICAgIHJlcXVpcmVkXG4gICAgICAgIFtpZF09XCInbmV3Q29uZmlybVBhc3N3b3JkJ1wiXG4gICAgICAgICNuZXdQYXNzd29yZENvbmZpcm09XCJuZ01vZGVsXCJcbiAgICAgICAgWyhuZ01vZGVsKV09XCJtb2RlbC5uZXdQYXNzd29yZENvbmZpcm1cIlxuICAgICAgICBwYXNzd29yZENvbmZpcm09XCJuZXdQYXNzd29yZFwiXG4gICAgICAgIFthdXRvY29tcGxldGVdPVwiJ25ldy1wYXNzd29yZCdcIlxuICAgICAgPjwvYzh5LXBhc3N3b3JkLWlucHV0PlxuICAgIDwvYzh5LWZvcm0tZ3JvdXA+XG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiY29sLTZcIj5cbiAgICA8Yzh5LXBhc3N3b3JkLWNoZWNrLWxpc3RcbiAgICAgIFtwYXNzd29yZF09XCJtb2RlbC5uZXdQYXNzd29yZFwiXG4gICAgICBbc3RyZW5ndGhFbmZvcmNlZF09XCJwYXNzd29yZEVuZm9yY2VkXCJcbiAgICAgIChvblJlcXVpcmVtZW50c0Z1bGZpbGxlZCk9XCJ1cGRhdGVWYWxpZGl0eSgkZXZlbnQpXCJcbiAgICA+PC9jOHktcGFzc3dvcmQtY2hlY2stbGlzdD5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==