UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

81 lines 16.6 kB
import { Component, Output, EventEmitter, Input, ViewChild } from '@angular/core'; import { ControlContainer, NgForm } from '@angular/forms'; import { LoginService } from '../login/login.service'; import { UserService } from '@c8y/client'; import { AlertService } from '../alert/alert.service'; import { ModalComponent } from '../modal/modal.component'; import * as i0 from "@angular/core"; import * as i1 from "../login/login.service"; import * as i2 from "@c8y/client"; import * as i3 from "../alert/alert.service"; import * as i4 from "@angular/forms"; import * as i5 from "../forms/form-group.component"; import * as i6 from "../forms/required-input-placeholder.directive"; import * as i7 from "../i18n/c8y-translate.directive"; import * as i8 from "@angular/common"; import * as i9 from "../i18n/c8y-translate.pipe"; export class TotpChallengeComponent { constructor(loginService, users, alert) { this.loginService = loginService; this.users = users; this.alert = alert; /** * Calls the verify endpoint if set to true (default true) */ this.verify = true; /** * Emits the token on success. */ this.onSuccess = new EventEmitter(); /** * Emits if set up two-factor authentication is canceled. */ this.totpUnconfirmedEmitter = new EventEmitter(); this.loading = false; this.hasError = false; this.isModal = false; this.model = { token: '' }; } async verifyCode() { try { this.loading = true; this.hasError = false; if (this.verify) { await this.users.verifyTotpCode(this.model.token); } this.onSuccess.emit(this.model.token); } catch (e) { this.hasError = true; this.alert.removeLastDanger(); this.loading = false; } } cancel() { this.totpUnconfirmedEmitter.emit(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TotpChallengeComponent, deps: [{ token: i1.LoginService }, { token: i2.UserService }, { token: i3.AlertService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TotpChallengeComponent, selector: "c8y-totp-challenge", inputs: { verify: "verify", loading: "loading", hasError: "hasError", isModal: "isModal" }, outputs: { onSuccess: "onSuccess", totpUnconfirmedEmitter: "totpUnconfirmedEmitter" }, viewQueries: [{ propertyName: "modal", first: true, predicate: ["modal"], descendants: true }], ngImport: i0, template: "<form #totpForm=\"ngForm\" class=\"loginForm\" (ngSubmit)=\"verifyCode()\" novalidate>\n <div class=\"d-block p-b-0\" [ngClass]=\"isModal ? 'p-24' : 'p-t-24'\">\n <c8y-form-group\n [hasError]=\"hasError\"\n [novalidation]=\"true\"\n [ngClass]=\"{ 'p-b-24': hasError }\"\n >\n <label translate for=\"totpToken\">Verification code</label>\n\n <input\n id=\"totpToken\"\n [(ngModel)]=\"model.token\"\n name=\"totpToken\"\n type=\"text\"\n autofocus\n autocapitalize=\"off\"\n autocorrect=\"off\"\n autocomplete=\"off\"\n class=\"form-control\"\n placeholder=\"{{ 'e.g.' | translate }} 624327\"\n required\n />\n\n <p id=\"helpinput\" *ngIf=\"!hasError\" class=\"help-block\" translate>\n In case of key loss, please contact your platform administrator.\n </p>\n </c8y-form-group>\n </div>\n <div [ngClass]=\"isModal ? 'modal-footer separator-top bg-level-0 sticky-bottom' : 'text-center'\">\n <button\n class=\"btn btn-default\"\n [ngClass]=\"{ 'btn-lg': !isModal }\"\n type=\"button\"\n title=\"{{ 'Cancel' | translate }}\"\n (click)=\"cancel()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n [ngClass]=\"{ 'btn-lg': !isModal }\"\n type=\"submit\"\n title=\"{{ 'Verify' | translate }}\"\n *ngIf=\"!loading\"\n [disabled]=\"!totpForm.form.valid\"\n >\n {{ 'Verify' | translate }}\n </button>\n\n <button\n class=\"btn btn-primary btn-pending\"\n [ngClass]=\"{ 'btn-lg': !isModal }\"\n type=\"submit\"\n title=\"{{ 'Verifying\u2026' | translate }}\"\n *ngIf=\"loading\"\n >\n {{ 'Verifying\u2026' | translate }}\n </button>\n </div>\n</form>\n", dependencies: [{ kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i4.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i5.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i6.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i7.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i8.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i8.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i9.C8yTranslatePipe, name: "translate" }], viewProviders: [{ provide: ControlContainer, useExisting: NgForm }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TotpChallengeComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-totp-challenge', viewProviders: [{ provide: ControlContainer, useExisting: NgForm }], template: "<form #totpForm=\"ngForm\" class=\"loginForm\" (ngSubmit)=\"verifyCode()\" novalidate>\n <div class=\"d-block p-b-0\" [ngClass]=\"isModal ? 'p-24' : 'p-t-24'\">\n <c8y-form-group\n [hasError]=\"hasError\"\n [novalidation]=\"true\"\n [ngClass]=\"{ 'p-b-24': hasError }\"\n >\n <label translate for=\"totpToken\">Verification code</label>\n\n <input\n id=\"totpToken\"\n [(ngModel)]=\"model.token\"\n name=\"totpToken\"\n type=\"text\"\n autofocus\n autocapitalize=\"off\"\n autocorrect=\"off\"\n autocomplete=\"off\"\n class=\"form-control\"\n placeholder=\"{{ 'e.g.' | translate }} 624327\"\n required\n />\n\n <p id=\"helpinput\" *ngIf=\"!hasError\" class=\"help-block\" translate>\n In case of key loss, please contact your platform administrator.\n </p>\n </c8y-form-group>\n </div>\n <div [ngClass]=\"isModal ? 'modal-footer separator-top bg-level-0 sticky-bottom' : 'text-center'\">\n <button\n class=\"btn btn-default\"\n [ngClass]=\"{ 'btn-lg': !isModal }\"\n type=\"button\"\n title=\"{{ 'Cancel' | translate }}\"\n (click)=\"cancel()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n <button\n class=\"btn btn-primary\"\n [ngClass]=\"{ 'btn-lg': !isModal }\"\n type=\"submit\"\n title=\"{{ 'Verify' | translate }}\"\n *ngIf=\"!loading\"\n [disabled]=\"!totpForm.form.valid\"\n >\n {{ 'Verify' | translate }}\n </button>\n\n <button\n class=\"btn btn-primary btn-pending\"\n [ngClass]=\"{ 'btn-lg': !isModal }\"\n type=\"submit\"\n title=\"{{ 'Verifying\u2026' | translate }}\"\n *ngIf=\"loading\"\n >\n {{ 'Verifying\u2026' | translate }}\n </button>\n </div>\n</form>\n" }] }], ctorParameters: () => [{ type: i1.LoginService }, { type: i2.UserService }, { type: i3.AlertService }], propDecorators: { verify: [{ type: Input }], onSuccess: [{ type: Output }], totpUnconfirmedEmitter: [{ type: Output }], loading: [{ type: Input }], hasError: [{ type: Input }], isModal: [{ type: Input }], modal: [{ type: ViewChild, args: ['modal', { static: false }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG90cC1jaGFsbGVuZ2UuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vY29yZS9hdXRoZW50aWNhdGlvbi90b3RwLWNoYWxsZW5nZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9jb3JlL2F1dGhlbnRpY2F0aW9uL3RvdHAtY2hhbGxlbmdlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2xGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUMxQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFDOzs7Ozs7Ozs7OztBQU8xRCxNQUFNLE9BQU8sc0JBQXNCO0lBcUJqQyxZQUNTLFlBQTBCLEVBQ3pCLEtBQWtCLEVBQ2xCLEtBQW1CO1FBRnBCLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQ3pCLFVBQUssR0FBTCxLQUFLLENBQWE7UUFDbEIsVUFBSyxHQUFMLEtBQUssQ0FBYztRQXZCN0I7O1dBRUc7UUFDTSxXQUFNLEdBQUcsSUFBSSxDQUFDO1FBQ3ZCOztXQUVHO1FBQ08sY0FBUyxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDekM7O1dBRUc7UUFDTywyQkFBc0IsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQzdDLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDaEIsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixZQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ3pCLFVBQUssR0FBRztZQUNOLEtBQUssRUFBRSxFQUFFO1NBQ1YsQ0FBQztJQU9DLENBQUM7SUFFSixLQUFLLENBQUMsVUFBVTtRQUNkLElBQUksQ0FBQztZQUNILElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1lBQ3RCLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO2dCQUNoQixNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDcEQsQ0FBQztZQUNELElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDeEMsQ0FBQztRQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDWCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztZQUNyQixJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUFFLENBQUM7WUFDOUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDdkIsQ0FBQztJQUNILENBQUM7SUFFRCxNQUFNO1FBQ0osSUFBSSxDQUFDLHNCQUFzQixDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3JDLENBQUM7K0dBNUNVLHNCQUFzQjttR0FBdEIsc0JBQXNCLDZVQ1puQywreURBNERBLDYzRERsRGlCLENBQUMsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsV0FBVyxFQUFFLE1BQU0sRUFBRSxDQUFDOzs0RkFFeEQsc0JBQXNCO2tCQUxsQyxTQUFTOytCQUNFLG9CQUFvQixpQkFFZixDQUFDLEVBQUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsQ0FBQztzSUFNMUQsTUFBTTtzQkFBZCxLQUFLO2dCQUlJLFNBQVM7c0JBQWxCLE1BQU07Z0JBSUcsc0JBQXNCO3NCQUEvQixNQUFNO2dCQUNFLE9BQU87c0JBQWYsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFJeUMsS0FBSztzQkFBbkQsU0FBUzt1QkFBQyxPQUFPLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29udHJvbENvbnRhaW5lciwgTmdGb3JtIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTG9naW5TZXJ2aWNlIH0gZnJvbSAnLi4vbG9naW4vbG9naW4uc2VydmljZSc7XG5pbXBvcnQgeyBVc2VyU2VydmljZSB9IGZyb20gJ0BjOHkvY2xpZW50JztcbmltcG9ydCB7IEFsZXJ0U2VydmljZSB9IGZyb20gJy4uL2FsZXJ0L2FsZXJ0LnNlcnZpY2UnO1xuaW1wb3J0IHsgTW9kYWxDb21wb25lbnQgfSBmcm9tICcuLi9tb2RhbC9tb2RhbC5jb21wb25lbnQnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktdG90cC1jaGFsbGVuZ2UnLFxuICB0ZW1wbGF0ZVVybDogJy4vdG90cC1jaGFsbGVuZ2UuY29tcG9uZW50Lmh0bWwnLFxuICB2aWV3UHJvdmlkZXJzOiBbeyBwcm92aWRlOiBDb250cm9sQ29udGFpbmVyLCB1c2VFeGlzdGluZzogTmdGb3JtIH1dXG59KVxuZXhwb3J0IGNsYXNzIFRvdHBDaGFsbGVuZ2VDb21wb25lbnQge1xuICAvKipcbiAgICogQ2FsbHMgdGhlIHZlcmlmeSBlbmRwb2ludCBpZiBzZXQgdG8gdHJ1ZSAoZGVmYXVsdCB0cnVlKVxuICAgKi9cbiAgQElucHV0KCkgdmVyaWZ5ID0gdHJ1ZTtcbiAgLyoqXG4gICAqIEVtaXRzIHRoZSB0b2tlbiBvbiBzdWNjZXNzLlxuICAgKi9cbiAgQE91dHB1dCgpIG9uU3VjY2VzcyA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgLyoqXG4gICAqIEVtaXRzIGlmIHNldCB1cCB0d28tZmFjdG9yIGF1dGhlbnRpY2F0aW9uIGlzIGNhbmNlbGVkLlxuICAgKi9cbiAgQE91dHB1dCgpIHRvdHBVbmNvbmZpcm1lZEVtaXR0ZXIgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBJbnB1dCgpIGxvYWRpbmcgPSBmYWxzZTtcbiAgQElucHV0KCkgaGFzRXJyb3IgPSBmYWxzZTtcbiAgQElucHV0KCkgaXNNb2RhbCA9IGZhbHNlO1xuICBtb2RlbCA9IHtcbiAgICB0b2tlbjogJydcbiAgfTtcbiAgQFZpZXdDaGlsZCgnbW9kYWwnLCB7IHN0YXRpYzogZmFsc2UgfSkgcHJpdmF0ZSBtb2RhbDogTW9kYWxDb21wb25lbnQ7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGxvZ2luU2VydmljZTogTG9naW5TZXJ2aWNlLFxuICAgIHByaXZhdGUgdXNlcnM6IFVzZXJTZXJ2aWNlLFxuICAgIHByaXZhdGUgYWxlcnQ6IEFsZXJ0U2VydmljZVxuICApIHt9XG5cbiAgYXN5bmMgdmVyaWZ5Q29kZSgpIHtcbiAgICB0cnkge1xuICAgICAgdGhpcy5sb2FkaW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuaGFzRXJyb3IgPSBmYWxzZTtcbiAgICAgIGlmICh0aGlzLnZlcmlmeSkge1xuICAgICAgICBhd2FpdCB0aGlzLnVzZXJzLnZlcmlmeVRvdHBDb2RlKHRoaXMubW9kZWwudG9rZW4pO1xuICAgICAgfVxuICAgICAgdGhpcy5vblN1Y2Nlc3MuZW1pdCh0aGlzLm1vZGVsLnRva2VuKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICB0aGlzLmhhc0Vycm9yID0gdHJ1ZTtcbiAgICAgIHRoaXMuYWxlcnQucmVtb3ZlTGFzdERhbmdlcigpO1xuICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgY2FuY2VsKCkge1xuICAgIHRoaXMudG90cFVuY29uZmlybWVkRW1pdHRlci5lbWl0KCk7XG4gIH1cbn1cbiIsIjxmb3JtICN0b3RwRm9ybT1cIm5nRm9ybVwiIGNsYXNzPVwibG9naW5Gb3JtXCIgKG5nU3VibWl0KT1cInZlcmlmeUNvZGUoKVwiIG5vdmFsaWRhdGU+XG4gIDxkaXYgY2xhc3M9XCJkLWJsb2NrIHAtYi0wXCIgW25nQ2xhc3NdPVwiaXNNb2RhbCA/ICdwLTI0JyA6ICdwLXQtMjQnXCI+XG4gICAgPGM4eS1mb3JtLWdyb3VwXG4gICAgICBbaGFzRXJyb3JdPVwiaGFzRXJyb3JcIlxuICAgICAgW25vdmFsaWRhdGlvbl09XCJ0cnVlXCJcbiAgICAgIFtuZ0NsYXNzXT1cInsgJ3AtYi0yNCc6IGhhc0Vycm9yIH1cIlxuICAgID5cbiAgICAgIDxsYWJlbCB0cmFuc2xhdGUgZm9yPVwidG90cFRva2VuXCI+VmVyaWZpY2F0aW9uIGNvZGU8L2xhYmVsPlxuXG4gICAgICA8aW5wdXRcbiAgICAgICAgaWQ9XCJ0b3RwVG9rZW5cIlxuICAgICAgICBbKG5nTW9kZWwpXT1cIm1vZGVsLnRva2VuXCJcbiAgICAgICAgbmFtZT1cInRvdHBUb2tlblwiXG4gICAgICAgIHR5cGU9XCJ0ZXh0XCJcbiAgICAgICAgYXV0b2ZvY3VzXG4gICAgICAgIGF1dG9jYXBpdGFsaXplPVwib2ZmXCJcbiAgICAgICAgYXV0b2NvcnJlY3Q9XCJvZmZcIlxuICAgICAgICBhdXRvY29tcGxldGU9XCJvZmZcIlxuICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgIHBsYWNlaG9sZGVyPVwie3sgJ2UuZy4nIHwgdHJhbnNsYXRlIH19IDYyNDMyN1wiXG4gICAgICAgIHJlcXVpcmVkXG4gICAgICAvPlxuXG4gICAgICA8cCBpZD1cImhlbHBpbnB1dFwiICpuZ0lmPVwiIWhhc0Vycm9yXCIgY2xhc3M9XCJoZWxwLWJsb2NrXCIgdHJhbnNsYXRlPlxuICAgICAgICBJbiBjYXNlIG9mIGtleSBsb3NzLCBwbGVhc2UgY29udGFjdCB5b3VyIHBsYXRmb3JtIGFkbWluaXN0cmF0b3IuXG4gICAgICA8L3A+XG4gICAgPC9jOHktZm9ybS1ncm91cD5cbiAgPC9kaXY+XG4gIDxkaXYgW25nQ2xhc3NdPVwiaXNNb2RhbCA/ICdtb2RhbC1mb290ZXIgc2VwYXJhdG9yLXRvcCBiZy1sZXZlbC0wIHN0aWNreS1ib3R0b20nIDogJ3RleHQtY2VudGVyJ1wiPlxuICAgIDxidXR0b25cbiAgICAgIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0XCJcbiAgICAgIFtuZ0NsYXNzXT1cInsgJ2J0bi1sZyc6ICFpc01vZGFsIH1cIlxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICB0aXRsZT1cInt7ICdDYW5jZWwnIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgIChjbGljayk9XCJjYW5jZWwoKVwiXG4gICAgPlxuICAgICAge3sgJ0NhbmNlbCcgfCB0cmFuc2xhdGUgfX1cbiAgICA8L2J1dHRvbj5cbiAgICA8YnV0dG9uXG4gICAgICBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiXG4gICAgICBbbmdDbGFzc109XCJ7ICdidG4tbGcnOiAhaXNNb2RhbCB9XCJcbiAgICAgIHR5cGU9XCJzdWJtaXRcIlxuICAgICAgdGl0bGU9XCJ7eyAnVmVyaWZ5JyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAqbmdJZj1cIiFsb2FkaW5nXCJcbiAgICAgIFtkaXNhYmxlZF09XCIhdG90cEZvcm0uZm9ybS52YWxpZFwiXG4gICAgPlxuICAgICAge3sgJ1ZlcmlmeScgfCB0cmFuc2xhdGUgfX1cbiAgICA8L2J1dHRvbj5cblxuICAgIDxidXR0b25cbiAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IGJ0bi1wZW5kaW5nXCJcbiAgICAgIFtuZ0NsYXNzXT1cInsgJ2J0bi1sZyc6ICFpc01vZGFsIH1cIlxuICAgICAgdHlwZT1cInN1Ym1pdFwiXG4gICAgICB0aXRsZT1cInt7ICdWZXJpZnlpbmfigKYnIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICpuZ0lmPVwibG9hZGluZ1wiXG4gICAgPlxuICAgICAge3sgJ1ZlcmlmeWluZ+KApicgfCB0cmFuc2xhdGUgfX1cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG48L2Zvcm0+XG4iXX0=