UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

69 lines 25.9 kB
import { Component } from '@angular/core'; import { BsModalRef } from 'ngx-bootstrap/modal'; import { GainsightService } from '@c8y/ngx-components'; import { TrustedCertificateService } from '@c8y/client'; import { AlertService, gettext } from '@c8y/ngx-components'; import { PRODUCT_EXPERIENCE_TRUSTED_CERTIFICATES } from './trusted-certificate.model'; import * as i0 from "@angular/core"; import * as i1 from "ngx-bootstrap/modal"; import * as i2 from "@c8y/client"; import * as i3 from "@c8y/ngx-components"; import * as i4 from "@angular/forms"; import * as i5 from "ngx-bootstrap/buttons"; import * as i6 from "ngx-bootstrap/popover"; export class AddTrustedCertificateComponent { constructor(modal, trustedCertificateService, alertService, gainsightService) { this.modal = modal; this.trustedCertificateService = trustedCertificateService; this.alertService = alertService; this.gainsightService = gainsightService; this.maxAllowedFiles = 1; this.AUTO_REGISTRATION_POPOVER = gettext('Devices using the MQTT protocol with credentials signed by this certificate will be able to communicate with the platform without prior registration. The option does not support devices using the LWM2M protocol.'); this.trustedCertificate = { status: 'DISABLED' }; this.fileIsUploaded = false; this.result = new Promise((resolve, reject) => { this._save = resolve; this._cancel = reject; }); this.PRODUCT_EXPERIENCE = PRODUCT_EXPERIENCE_TRUSTED_CERTIFICATES; } uploadFile(dropped) { this.fileIsUploaded = false; if (dropped) { const reader = new FileReader(); reader.onload = () => { this.fileIsUploaded = true; this.trustedCertificate.certInPemFormat = reader.result; }; reader.readAsText(dropped[0].file); } } async save() { try { await this.trustedCertificateService.create(this.trustedCertificate); this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_TRUSTED_CERTIFICATES.EVENT, { component: PRODUCT_EXPERIENCE_TRUSTED_CERTIFICATES.CERTIFICATES.COMPONENTS.TRUSTED_CERTIFICATE, result: PRODUCT_EXPERIENCE_TRUSTED_CERTIFICATES.CERTIFICATES.RESULTS.ADD_SUCCESS, action: PRODUCT_EXPERIENCE_TRUSTED_CERTIFICATES.CERTIFICATES.ACTIONS.ADD }); this.alertService.success(gettext('Certificate saved.')); this._save(); } catch (ex) { this.alertService.addServerFailure(ex); } } close() { this._cancel(); this.modal.hide(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AddTrustedCertificateComponent, deps: [{ token: i1.BsModalRef }, { token: i2.TrustedCertificateService }, { token: i3.AlertService }, { token: i3.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AddTrustedCertificateComponent, selector: "c8y-add-trusted-certificate", ngImport: i0, template: "<div class=\"viewport-modal\">\n <div class=\"modal-header dialog-header\">\n <i c8yIcon=\"certificate\"></i>\n <div\n class=\"modal-title\"\n id=\"addCertificateModalTitle\"\n translate\n >\n Add trusted certificate\n </div>\n </div>\n <form\n #addTrustedCertificateForm=\"ngForm\"\n (ngSubmit)=\"addTrustedCertificateForm.form.valid && fileIsUploaded && save()\"\n >\n <div class=\"modal-inner-scroll\">\n <div\n class=\"modal-body\"\n id=\"addCertificateModalDescription\"\n >\n <c8y-form-group>\n <label\n for=\"certificateName\"\n translate\n >\n Certificate name\n </label>\n <input\n class=\"form-control\"\n id=\"certificateName\"\n placeholder=\"{{ 'e.g. My certificate' | translate }}\"\n name=\"certificateName\"\n type=\"text\"\n autocomplete=\"off\"\n required\n [(ngModel)]=\"trustedCertificate.name\"\n />\n </c8y-form-group>\n <c8y-form-group>\n <label\n for=\"certificate\"\n translate\n >\n Certificate\n </label>\n <c8y-drop-area\n class=\"drop-area-sm\"\n [title]=\"'Paste the certificate in PEM format.' | translate\"\n (dropped)=\"uploadFile($event)\"\n [loadingMessage]=\"'Importing, please wait.' | translate\"\n [maxAllowedFiles]=\"maxAllowedFiles\"\n ></c8y-drop-area>\n </c8y-form-group>\n <c8y-form-group>\n <label\n class=\"c8y-checkbox\"\n title=\"{{ 'Auto registration' | translate }}\"\n >\n <input\n id=\"autoRegistration\"\n name=\"autoRegistration\"\n type=\"checkbox\"\n [(ngModel)]=\"trustedCertificate.autoRegistrationEnabled\"\n />\n <span></span>\n <span>{{ 'Auto registration' | translate }}</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ AUTO_REGISTRATION_POPOVER | translate }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </label>\n </c8y-form-group>\n <button\n class=\"btn\"\n name=\"certificateStatus\"\n type=\"button\"\n [(ngModel)]=\"trustedCertificate.status\"\n btnCheckbox\n btnCheckboxTrue=\"ENABLED\"\n btnCheckboxFalse=\"DISABLED\"\n >\n <span\n title=\"{{ 'Disabled`trusted certificate status`' | translate }}\"\n [hidden]=\"trustedCertificate.status !== 'DISABLED'\"\n >\n {{ 'Disabled`trusted certificate status`' | translate }}\n </span>\n <span\n title=\"{{ 'Enabled`trusted certificate status`' | translate }}\"\n [hidden]=\"trustedCertificate.status !== 'ENABLED'\"\n >\n {{ 'Enabled`trusted certificate status`' | translate }}\n </span>\n </button>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"close()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Add certificate' | translate }}\"\n type=\"submit\"\n [disabled]=\"\n addTrustedCertificateForm.form.invalid ||\n addTrustedCertificateForm.form.pristine ||\n !fileIsUploaded\n \"\n >\n {{ 'Add certificate' | translate }}\n </button>\n </div>\n </form>\n</div>\n", dependencies: [{ kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: i3.DropAreaComponent, selector: "c8y-drop-area", inputs: ["formControl", "title", "message", "icon", "loadingMessage", "forceHideList", "alwaysShow", "clickToOpen", "loading", "progress", "maxAllowedFiles", "files", "maxFileSizeInMegaBytes", "accept"], outputs: ["dropped"] }, { 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.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { 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: i3.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i3.RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "directive", type: i5.ButtonCheckboxDirective, selector: "[btnCheckbox]", inputs: ["btnCheckboxTrue", "btnCheckboxFalse"] }, { kind: "directive", type: i6.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AddTrustedCertificateComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-add-trusted-certificate', template: "<div class=\"viewport-modal\">\n <div class=\"modal-header dialog-header\">\n <i c8yIcon=\"certificate\"></i>\n <div\n class=\"modal-title\"\n id=\"addCertificateModalTitle\"\n translate\n >\n Add trusted certificate\n </div>\n </div>\n <form\n #addTrustedCertificateForm=\"ngForm\"\n (ngSubmit)=\"addTrustedCertificateForm.form.valid && fileIsUploaded && save()\"\n >\n <div class=\"modal-inner-scroll\">\n <div\n class=\"modal-body\"\n id=\"addCertificateModalDescription\"\n >\n <c8y-form-group>\n <label\n for=\"certificateName\"\n translate\n >\n Certificate name\n </label>\n <input\n class=\"form-control\"\n id=\"certificateName\"\n placeholder=\"{{ 'e.g. My certificate' | translate }}\"\n name=\"certificateName\"\n type=\"text\"\n autocomplete=\"off\"\n required\n [(ngModel)]=\"trustedCertificate.name\"\n />\n </c8y-form-group>\n <c8y-form-group>\n <label\n for=\"certificate\"\n translate\n >\n Certificate\n </label>\n <c8y-drop-area\n class=\"drop-area-sm\"\n [title]=\"'Paste the certificate in PEM format.' | translate\"\n (dropped)=\"uploadFile($event)\"\n [loadingMessage]=\"'Importing, please wait.' | translate\"\n [maxAllowedFiles]=\"maxAllowedFiles\"\n ></c8y-drop-area>\n </c8y-form-group>\n <c8y-form-group>\n <label\n class=\"c8y-checkbox\"\n title=\"{{ 'Auto registration' | translate }}\"\n >\n <input\n id=\"autoRegistration\"\n name=\"autoRegistration\"\n type=\"checkbox\"\n [(ngModel)]=\"trustedCertificate.autoRegistrationEnabled\"\n />\n <span></span>\n <span>{{ 'Auto registration' | translate }}</span>\n <button\n class=\"btn-help\"\n [attr.aria-label]=\"'Help' | translate\"\n popover=\"{{ AUTO_REGISTRATION_POPOVER | translate }}\"\n placement=\"right\"\n triggers=\"focus\"\n container=\"body\"\n type=\"button\"\n ></button>\n </label>\n </c8y-form-group>\n <button\n class=\"btn\"\n name=\"certificateStatus\"\n type=\"button\"\n [(ngModel)]=\"trustedCertificate.status\"\n btnCheckbox\n btnCheckboxTrue=\"ENABLED\"\n btnCheckboxFalse=\"DISABLED\"\n >\n <span\n title=\"{{ 'Disabled`trusted certificate status`' | translate }}\"\n [hidden]=\"trustedCertificate.status !== 'DISABLED'\"\n >\n {{ 'Disabled`trusted certificate status`' | translate }}\n </span>\n <span\n title=\"{{ 'Enabled`trusted certificate status`' | translate }}\"\n [hidden]=\"trustedCertificate.status !== 'ENABLED'\"\n >\n {{ 'Enabled`trusted certificate status`' | translate }}\n </span>\n </button>\n </div>\n </div>\n <div class=\"modal-footer\">\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"close()\"\n >\n {{ 'Cancel' | translate }}\n </button>\n\n <button\n class=\"btn btn-primary\"\n title=\"{{ 'Add certificate' | translate }}\"\n type=\"submit\"\n [disabled]=\"\n addTrustedCertificateForm.form.invalid ||\n addTrustedCertificateForm.form.pristine ||\n !fileIsUploaded\n \"\n >\n {{ 'Add certificate' | translate }}\n </button>\n </div>\n </form>\n</div>\n" }] }], ctorParameters: () => [{ type: i1.BsModalRef }, { type: i2.TrustedCertificateService }, { type: i3.AlertService }, { type: i3.GainsightService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkLXRydXN0ZWQtY2VydGlmaWNhdGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdHJ1c3RlZC1jZXJ0aWZpY2F0ZXMvbGlzdC9hZGQtdHJ1c3RlZC1jZXJ0aWZpY2F0ZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi90cnVzdGVkLWNlcnRpZmljYXRlcy9saXN0L2FkZC10cnVzdGVkLWNlcnRpZmljYXRlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDMUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2pELE9BQU8sRUFBZSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3BFLE9BQU8sRUFBdUIseUJBQXlCLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDN0UsT0FBTyxFQUFFLFlBQVksRUFBRSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM1RCxPQUFPLEVBQUUsdUNBQXVDLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQzs7Ozs7Ozs7QUFNdEYsTUFBTSxPQUFPLDhCQUE4QjtJQWtCekMsWUFDVSxLQUFpQixFQUNqQix5QkFBb0QsRUFDcEQsWUFBMEIsRUFDMUIsZ0JBQWtDO1FBSGxDLFVBQUssR0FBTCxLQUFLLENBQVk7UUFDakIsOEJBQXlCLEdBQXpCLHlCQUF5QixDQUEyQjtRQUNwRCxpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUMxQixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBckI1QyxvQkFBZSxHQUFHLENBQUMsQ0FBQztRQUNwQiw4QkFBeUIsR0FBRyxPQUFPLENBQ2pDLHFOQUFxTixDQUN0TixDQUFDO1FBQ0YsdUJBQWtCLEdBQWlDO1lBQ2pELE1BQU0sRUFBRSxVQUFVO1NBQ25CLENBQUM7UUFDRixtQkFBYyxHQUFHLEtBQUssQ0FBQztRQUV2QixXQUFNLEdBQWlCLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JELElBQUksQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDO1lBQ3JCLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO1FBQ3hCLENBQUMsQ0FBQyxDQUFDO1FBR0gsdUJBQWtCLEdBQUcsdUNBQXVDLENBQUM7SUFPMUQsQ0FBQztJQUVKLFVBQVUsQ0FBQyxPQUFzQjtRQUMvQixJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQztRQUM1QixJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ1osTUFBTSxNQUFNLEdBQUcsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNoQyxNQUFNLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFBRTtnQkFDbkIsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7Z0JBQzNCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxlQUFlLEdBQUcsTUFBTSxDQUFDLE1BQWdCLENBQUM7WUFDcEUsQ0FBQyxDQUFDO1lBQ0YsTUFBTSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckMsQ0FBQztJQUNILENBQUM7SUFFRCxLQUFLLENBQUMsSUFBSTtRQUNSLElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxDQUFDLHlCQUF5QixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztZQUNyRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLHVDQUF1QyxDQUFDLEtBQUssRUFBRTtnQkFDaEYsU0FBUyxFQUNQLHVDQUF1QyxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsbUJBQW1CO2dCQUNyRixNQUFNLEVBQUUsdUNBQXVDLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxXQUFXO2dCQUNoRixNQUFNLEVBQUUsdUNBQXVDLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxHQUFHO2FBQ3pFLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUM7WUFDekQsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2YsQ0FBQztRQUFDLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDWixJQUFJLENBQUMsWUFBWSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3pDLENBQUM7SUFDSCxDQUFDO0lBRUQsS0FBSztRQUNILElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNmLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDcEIsQ0FBQzsrR0F4RFUsOEJBQThCO21HQUE5Qiw4QkFBOEIsbUVDWDNDLDgzSEE4SEE7OzRGRG5IYSw4QkFBOEI7a0JBSjFDLFNBQVM7K0JBQ0UsNkJBQTZCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCc01vZGFsUmVmIH0gZnJvbSAnbmd4LWJvb3RzdHJhcC9tb2RhbCc7XG5pbXBvcnQgeyBEcm9wcGVkRmlsZSwgR2FpbnNpZ2h0U2VydmljZSB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgSVRydXN0ZWRDZXJ0aWZpY2F0ZSwgVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZSB9IGZyb20gJ0BjOHkvY2xpZW50JztcbmltcG9ydCB7IEFsZXJ0U2VydmljZSwgZ2V0dGV4dCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgUFJPRFVDVF9FWFBFUklFTkNFX1RSVVNURURfQ0VSVElGSUNBVEVTIH0gZnJvbSAnLi90cnVzdGVkLWNlcnRpZmljYXRlLm1vZGVsJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYzh5LWFkZC10cnVzdGVkLWNlcnRpZmljYXRlJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2FkZC10cnVzdGVkLWNlcnRpZmljYXRlLmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBBZGRUcnVzdGVkQ2VydGlmaWNhdGVDb21wb25lbnQge1xuICBtYXhBbGxvd2VkRmlsZXMgPSAxO1xuICBBVVRPX1JFR0lTVFJBVElPTl9QT1BPVkVSID0gZ2V0dGV4dChcbiAgICAnRGV2aWNlcyB1c2luZyB0aGUgTVFUVCBwcm90b2NvbCB3aXRoIGNyZWRlbnRpYWxzIHNpZ25lZCBieSB0aGlzIGNlcnRpZmljYXRlIHdpbGwgYmUgYWJsZSB0byBjb21tdW5pY2F0ZSB3aXRoIHRoZSBwbGF0Zm9ybSB3aXRob3V0IHByaW9yIHJlZ2lzdHJhdGlvbi4gVGhlIG9wdGlvbiBkb2VzIG5vdCBzdXBwb3J0IGRldmljZXMgdXNpbmcgdGhlIExXTTJNIHByb3RvY29sLidcbiAgKTtcbiAgdHJ1c3RlZENlcnRpZmljYXRlOiBQYXJ0aWFsPElUcnVzdGVkQ2VydGlmaWNhdGU+ID0ge1xuICAgIHN0YXR1czogJ0RJU0FCTEVEJ1xuICB9O1xuICBmaWxlSXNVcGxvYWRlZCA9IGZhbHNlO1xuXG4gIHJlc3VsdDogUHJvbWlzZTxhbnk+ID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgIHRoaXMuX3NhdmUgPSByZXNvbHZlO1xuICAgIHRoaXMuX2NhbmNlbCA9IHJlamVjdDtcbiAgfSk7XG4gIHByaXZhdGUgX3NhdmU7XG4gIHByaXZhdGUgX2NhbmNlbDtcbiAgUFJPRFVDVF9FWFBFUklFTkNFID0gUFJPRFVDVF9FWFBFUklFTkNFX1RSVVNURURfQ0VSVElGSUNBVEVTO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgbW9kYWw6IEJzTW9kYWxSZWYsXG4gICAgcHJpdmF0ZSB0cnVzdGVkQ2VydGlmaWNhdGVTZXJ2aWNlOiBUcnVzdGVkQ2VydGlmaWNhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgYWxlcnRTZXJ2aWNlOiBBbGVydFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBnYWluc2lnaHRTZXJ2aWNlOiBHYWluc2lnaHRTZXJ2aWNlXG4gICkge31cblxuICB1cGxvYWRGaWxlKGRyb3BwZWQ6IERyb3BwZWRGaWxlW10pIHtcbiAgICB0aGlzLmZpbGVJc1VwbG9hZGVkID0gZmFsc2U7XG4gICAgaWYgKGRyb3BwZWQpIHtcbiAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICByZWFkZXIub25sb2FkID0gKCkgPT4ge1xuICAgICAgICB0aGlzLmZpbGVJc1VwbG9hZGVkID0gdHJ1ZTtcbiAgICAgICAgdGhpcy50cnVzdGVkQ2VydGlmaWNhdGUuY2VydEluUGVtRm9ybWF0ID0gcmVhZGVyLnJlc3VsdCBhcyBzdHJpbmc7XG4gICAgICB9O1xuICAgICAgcmVhZGVyLnJlYWRBc1RleHQoZHJvcHBlZFswXS5maWxlKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBzYXZlKCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLnRydXN0ZWRDZXJ0aWZpY2F0ZVNlcnZpY2UuY3JlYXRlKHRoaXMudHJ1c3RlZENlcnRpZmljYXRlKTtcbiAgICAgIHRoaXMuZ2FpbnNpZ2h0U2VydmljZS50cmlnZ2VyRXZlbnQoUFJPRFVDVF9FWFBFUklFTkNFX1RSVVNURURfQ0VSVElGSUNBVEVTLkVWRU5ULCB7XG4gICAgICAgIGNvbXBvbmVudDpcbiAgICAgICAgICBQUk9EVUNUX0VYUEVSSUVOQ0VfVFJVU1RFRF9DRVJUSUZJQ0FURVMuQ0VSVElGSUNBVEVTLkNPTVBPTkVOVFMuVFJVU1RFRF9DRVJUSUZJQ0FURSxcbiAgICAgICAgcmVzdWx0OiBQUk9EVUNUX0VYUEVSSUVOQ0VfVFJVU1RFRF9DRVJUSUZJQ0FURVMuQ0VSVElGSUNBVEVTLlJFU1VMVFMuQUREX1NVQ0NFU1MsXG4gICAgICAgIGFjdGlvbjogUFJPRFVDVF9FWFBFUklFTkNFX1RSVVNURURfQ0VSVElGSUNBVEVTLkNFUlRJRklDQVRFUy5BQ1RJT05TLkFERFxuICAgICAgfSk7XG4gICAgICB0aGlzLmFsZXJ0U2VydmljZS5zdWNjZXNzKGdldHRleHQoJ0NlcnRpZmljYXRlIHNhdmVkLicpKTtcbiAgICAgIHRoaXMuX3NhdmUoKTtcbiAgICB9IGNhdGNoIChleCkge1xuICAgICAgdGhpcy5hbGVydFNlcnZpY2UuYWRkU2VydmVyRmFpbHVyZShleCk7XG4gICAgfVxuICB9XG5cbiAgY2xvc2UoKSB7XG4gICAgdGhpcy5fY2FuY2VsKCk7XG4gICAgdGhpcy5tb2RhbC5oaWRlKCk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJ2aWV3cG9ydC1tb2RhbFwiPlxuICA8ZGl2IGNsYXNzPVwibW9kYWwtaGVhZGVyIGRpYWxvZy1oZWFkZXJcIj5cbiAgICA8aSBjOHlJY29uPVwiY2VydGlmaWNhdGVcIj48L2k+XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJtb2RhbC10aXRsZVwiXG4gICAgICBpZD1cImFkZENlcnRpZmljYXRlTW9kYWxUaXRsZVwiXG4gICAgICB0cmFuc2xhdGVcbiAgICA+XG4gICAgICBBZGQgdHJ1c3RlZCBjZXJ0aWZpY2F0ZVxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPGZvcm1cbiAgICAjYWRkVHJ1c3RlZENlcnRpZmljYXRlRm9ybT1cIm5nRm9ybVwiXG4gICAgKG5nU3VibWl0KT1cImFkZFRydXN0ZWRDZXJ0aWZpY2F0ZUZvcm0uZm9ybS52YWxpZCAmJiBmaWxlSXNVcGxvYWRlZCAmJiBzYXZlKClcIlxuICA+XG4gICAgPGRpdiBjbGFzcz1cIm1vZGFsLWlubmVyLXNjcm9sbFwiPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cIm1vZGFsLWJvZHlcIlxuICAgICAgICBpZD1cImFkZENlcnRpZmljYXRlTW9kYWxEZXNjcmlwdGlvblwiXG4gICAgICA+XG4gICAgICAgIDxjOHktZm9ybS1ncm91cD5cbiAgICAgICAgICA8bGFiZWxcbiAgICAgICAgICAgIGZvcj1cImNlcnRpZmljYXRlTmFtZVwiXG4gICAgICAgICAgICB0cmFuc2xhdGVcbiAgICAgICAgICA+XG4gICAgICAgICAgICBDZXJ0aWZpY2F0ZSBuYW1lXG4gICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICAgIGlkPVwiY2VydGlmaWNhdGVOYW1lXCJcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwie3sgJ2UuZy4gTXkgY2VydGlmaWNhdGUnIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgICAgIG5hbWU9XCJjZXJ0aWZpY2F0ZU5hbWVcIlxuICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgYXV0b2NvbXBsZXRlPVwib2ZmXCJcbiAgICAgICAgICAgIHJlcXVpcmVkXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cInRydXN0ZWRDZXJ0aWZpY2F0ZS5uYW1lXCJcbiAgICAgICAgICAvPlxuICAgICAgICA8L2M4eS1mb3JtLWdyb3VwPlxuICAgICAgICA8Yzh5LWZvcm0tZ3JvdXA+XG4gICAgICAgICAgPGxhYmVsXG4gICAgICAgICAgICBmb3I9XCJjZXJ0aWZpY2F0ZVwiXG4gICAgICAgICAgICB0cmFuc2xhdGVcbiAgICAgICAgICA+XG4gICAgICAgICAgICBDZXJ0aWZpY2F0ZVxuICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgPGM4eS1kcm9wLWFyZWFcbiAgICAgICAgICAgIGNsYXNzPVwiZHJvcC1hcmVhLXNtXCJcbiAgICAgICAgICAgIFt0aXRsZV09XCInUGFzdGUgdGhlIGNlcnRpZmljYXRlIGluIFBFTSBmb3JtYXQuJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAoZHJvcHBlZCk9XCJ1cGxvYWRGaWxlKCRldmVudClcIlxuICAgICAgICAgICAgW2xvYWRpbmdNZXNzYWdlXT1cIidJbXBvcnRpbmcsIHBsZWFzZSB3YWl0LicgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgW21heEFsbG93ZWRGaWxlc109XCJtYXhBbGxvd2VkRmlsZXNcIlxuICAgICAgICAgID48L2M4eS1kcm9wLWFyZWE+XG4gICAgICAgIDwvYzh5LWZvcm0tZ3JvdXA+XG4gICAgICAgIDxjOHktZm9ybS1ncm91cD5cbiAgICAgICAgICA8bGFiZWxcbiAgICAgICAgICAgIGNsYXNzPVwiYzh5LWNoZWNrYm94XCJcbiAgICAgICAgICAgIHRpdGxlPVwie3sgJ0F1dG8gcmVnaXN0cmF0aW9uJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgIGlkPVwiYXV0b1JlZ2lzdHJhdGlvblwiXG4gICAgICAgICAgICAgIG5hbWU9XCJhdXRvUmVnaXN0cmF0aW9uXCJcbiAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJ0cnVzdGVkQ2VydGlmaWNhdGUuYXV0b1JlZ2lzdHJhdGlvbkVuYWJsZWRcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgICAgIDxzcGFuPjwvc3Bhbj5cbiAgICAgICAgICAgIDxzcGFuPnt7ICdBdXRvIHJlZ2lzdHJhdGlvbicgfCB0cmFuc2xhdGUgfX08L3NwYW4+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIGNsYXNzPVwiYnRuLWhlbHBcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidIZWxwJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgICAgIHBvcG92ZXI9XCJ7eyBBVVRPX1JFR0lTVFJBVElPTl9QT1BPVkVSIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgICAgICAgcGxhY2VtZW50PVwicmlnaHRcIlxuICAgICAgICAgICAgICB0cmlnZ2Vycz1cImZvY3VzXCJcbiAgICAgICAgICAgICAgY29udGFpbmVyPVwiYm9keVwiXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgPjwvYnV0dG9uPlxuICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgIDwvYzh5LWZvcm0tZ3JvdXA+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICBjbGFzcz1cImJ0blwiXG4gICAgICAgICAgbmFtZT1cImNlcnRpZmljYXRlU3RhdHVzXCJcbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBbKG5nTW9kZWwpXT1cInRydXN0ZWRDZXJ0aWZpY2F0ZS5zdGF0dXNcIlxuICAgICAgICAgIGJ0bkNoZWNrYm94XG4gICAgICAgICAgYnRuQ2hlY2tib3hUcnVlPVwiRU5BQkxFRFwiXG4gICAgICAgICAgYnRuQ2hlY2tib3hGYWxzZT1cIkRJU0FCTEVEXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICB0aXRsZT1cInt7ICdEaXNhYmxlZGB0cnVzdGVkIGNlcnRpZmljYXRlIHN0YXR1c2AnIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgICAgIFtoaWRkZW5dPVwidHJ1c3RlZENlcnRpZmljYXRlLnN0YXR1cyAhPT0gJ0RJU0FCTEVEJ1wiXG4gICAgICAgICAgPlxuICAgICAgICAgICAge3sgJ0Rpc2FibGVkYHRydXN0ZWQgY2VydGlmaWNhdGUgc3RhdHVzYCcgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgIHRpdGxlPVwie3sgJ0VuYWJsZWRgdHJ1c3RlZCBjZXJ0aWZpY2F0ZSBzdGF0dXNgJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgICBbaGlkZGVuXT1cInRydXN0ZWRDZXJ0aWZpY2F0ZS5zdGF0dXMgIT09ICdFTkFCTEVEJ1wiXG4gICAgICAgICAgPlxuICAgICAgICAgICAge3sgJ0VuYWJsZWRgdHJ1c3RlZCBjZXJ0aWZpY2F0ZSBzdGF0dXNgJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwibW9kYWwtZm9vdGVyXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0XCJcbiAgICAgICAgdGl0bGU9XCJ7eyAnQ2FuY2VsJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAoY2xpY2spPVwiY2xvc2UoKVwiXG4gICAgICA+XG4gICAgICAgIHt7ICdDYW5jZWwnIHwgdHJhbnNsYXRlIH19XG4gICAgICA8L2J1dHRvbj5cblxuICAgICAgPGJ1dHRvblxuICAgICAgICBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiXG4gICAgICAgIHRpdGxlPVwie3sgJ0FkZCBjZXJ0aWZpY2F0ZScgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICB0eXBlPVwic3VibWl0XCJcbiAgICAgICAgW2Rpc2FibGVkXT1cIlxuICAgICAgICAgIGFkZFRydXN0ZWRDZXJ0aWZpY2F0ZUZvcm0uZm9ybS5pbnZhbGlkIHx8XG4gICAgICAgICAgYWRkVHJ1c3RlZENlcnRpZmljYXRlRm9ybS5mb3JtLnByaXN0aW5lIHx8XG4gICAgICAgICAgIWZpbGVJc1VwbG9hZGVkXG4gICAgICAgIFwiXG4gICAgICA+XG4gICAgICAgIHt7ICdBZGQgY2VydGlmaWNhdGUnIHwgdHJhbnNsYXRlIH19XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9mb3JtPlxuPC9kaXY+XG4iXX0=