UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

172 lines 20.3 kB
import { Component, Input, Optional, Output, EventEmitter, HostListener } from '@angular/core'; import { BsModalRef } from 'ngx-bootstrap/modal'; import { gettext } from '../i18n/gettext'; import { isEmpty } from 'lodash'; import * as i0 from "@angular/core"; import * as i1 from "ngx-bootstrap/modal"; import * as i2 from "@angular/common"; import * as i3 from "../i18n/c8y-translate.pipe"; /** * C8Y component for creating modals. * * Creating custom modal: * ```typescript * import { Component } from "@angular/core"; * import { Subject } from 'rxjs'; * * @Component({ * selector: "my-modal", * template: ` * <c8y-modal title="CustomTitle" * (onClose)="onClose($event)" * (onDismiss)="onDismiss($event)" * [labels]="labels" * [disabled]="true" <- will disable ok button * > * <span>I am body of modal</span> * <span>For simple string use body="string"</span> * </c8y-modal>` * }) * * export class MyModalComponent { * * closeSubject: Subject<boolean> = new Subject(); * labels : ModalLabels = {ok: "customOK", cancel: "customCancel"}; * * onDismiss(event){ * this.closeSubject.next(false); * } * * onClose(event) { * this.closeSubject.next(true); * } * } * ``` * * Showing modal: * ```typescript * import { BsModalService } from "ngx-bootstrap/modal"; * * constructor( * public bsModalService: BsModalService, * ) {} * * showModal() { * const modalRef = this.bsModalService.show(MyModalComponent); * modalRef.content.closeSubject.subscribe(result => { * console.log('results:', result); * }); * } * ``` */ export class ModalComponent { /** * Custom labels for 'cancel' and 'ok' buttons. */ set labels({ ok, cancel }) { this._labels = { ok, cancel }; } get labels() { return this._labels; } constructor(modal) { this.modal = modal; /** * Emits 'true' when 'cancel' button is clicked. */ this.onDismiss = new EventEmitter(); /** * Emits 'true' when 'ok' button is clicked. */ this.onClose = new EventEmitter(); /** * Indicates if the 'ok' (confirmation) button is disabled. */ this.disabled = false; /** * Indicates if modal should use custom footer provided with content projection (or no footer at all). * If false, default footer with 'cancel' and 'ok' buttons will be displayed. */ this.customFooter = false; /** * CSS classes for modal header. */ this.headerClasses = ''; this._labels = { ok: gettext('OK'), cancel: gettext('Cancel') }; } /** * Hides modal or calls 'dismiss' input callback, then emits 'onDismiss' output. * Method is called when 'cancel' button is clicked, but can be also triggered by accessing 'ModalComponent' instance. */ _dismiss() { let fn = this.dismiss; if (!fn && this.modal) { fn = () => this.modal.hide(); } if (fn) { fn(); } this.onDismiss.emit(true); } /** * Hides modal or calls 'close' input callback, then emits 'onClose' output. * Method is called when 'ok' button is clicked, but can be also triggered by accessing 'ModalComponent' instance. */ _close() { let fn = this.close; if (!fn && this.modal) { fn = () => this.modal.hide(); } if (fn) { fn(); } this.onClose.emit(true); } /** * 'Enter' keyboard button handler. Calls '_dismiss' or '_close' method when only one corresponding button exists. * @param _event Enter keydown event */ onEnterKeyDown(_event) { const hasOnlyOneButton = isEmpty(this.labels.ok) !== isEmpty(this.labels.cancel); const isCancelClickable = !this.customFooter && this.labels.cancel; const isOkClickable = !this.customFooter && !this.disabled && this.labels.ok; if (hasOnlyOneButton && isCancelClickable) { this._dismiss(); } if (hasOnlyOneButton && isOkClickable) { this._close(); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ModalComponent, deps: [{ token: i1.BsModalRef, optional: true }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: ModalComponent, selector: "c8y-modal", inputs: { disabled: "disabled", close: "close", dismiss: "dismiss", title: "title", body: "body", customFooter: "customFooter", headerClasses: "headerClasses", labels: "labels" }, outputs: { onDismiss: "onDismiss", onClose: "onClose" }, host: { listeners: { "document:keydown.enter": "onEnterKeyDown($event)" } }, ngImport: i0, template: "<div class=\"viewport-modal\">\n <div class=\"modal-header {{ headerClasses }}\" [ngClass]=\"{ separator: title }\">\n <ng-content select=\"[c8y-modal-title]\"></ng-content>\n <div [hidden]=\"!title\" id=\"modal-title\" class=\"modal-title\">\n {{ title | translate }}\n </div>\n </div>\n <div class=\"modal-inner-scroll\" id=\"modal-body\">\n <div [ngClass]=\"{ 'modal-body': !customFooter, 'd-contents': customFooter }\">\n <p *ngIf=\"title\" class=\"text-center text-break-word\">\n {{ body }}\n </p>\n <ng-content></ng-content>\n </div>\n </div>\n <ng-content select=\"[c8y-modal-footer-custom]\"></ng-content>\n <div class=\"modal-footer\" *ngIf=\"!customFooter\">\n <ng-content select=\"[c8y-modal-footer]\"></ng-content>\n <button\n type=\"button\"\n title=\"{{ labels.cancel | translate }}\"\n *ngIf=\"labels.cancel\"\n class=\"btn btn-default\"\n (click)=\"_dismiss()\"\n >\n {{ labels.cancel | translate }}\n </button>\n <button\n type=\"button\"\n title=\"{{ labels.ok | translate }}\"\n *ngIf=\"labels.ok\"\n class=\"btn btn-primary\"\n (click)=\"_close()\"\n [disabled]=\"disabled\"\n >\n {{ labels.ok | translate }}\n </button>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ModalComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-modal', template: "<div class=\"viewport-modal\">\n <div class=\"modal-header {{ headerClasses }}\" [ngClass]=\"{ separator: title }\">\n <ng-content select=\"[c8y-modal-title]\"></ng-content>\n <div [hidden]=\"!title\" id=\"modal-title\" class=\"modal-title\">\n {{ title | translate }}\n </div>\n </div>\n <div class=\"modal-inner-scroll\" id=\"modal-body\">\n <div [ngClass]=\"{ 'modal-body': !customFooter, 'd-contents': customFooter }\">\n <p *ngIf=\"title\" class=\"text-center text-break-word\">\n {{ body }}\n </p>\n <ng-content></ng-content>\n </div>\n </div>\n <ng-content select=\"[c8y-modal-footer-custom]\"></ng-content>\n <div class=\"modal-footer\" *ngIf=\"!customFooter\">\n <ng-content select=\"[c8y-modal-footer]\"></ng-content>\n <button\n type=\"button\"\n title=\"{{ labels.cancel | translate }}\"\n *ngIf=\"labels.cancel\"\n class=\"btn btn-default\"\n (click)=\"_dismiss()\"\n >\n {{ labels.cancel | translate }}\n </button>\n <button\n type=\"button\"\n title=\"{{ labels.ok | translate }}\"\n *ngIf=\"labels.ok\"\n class=\"btn btn-primary\"\n (click)=\"_close()\"\n [disabled]=\"disabled\"\n >\n {{ labels.ok | translate }}\n </button>\n </div>\n</div>\n" }] }], ctorParameters: () => [{ type: i1.BsModalRef, decorators: [{ type: Optional }] }], propDecorators: { onDismiss: [{ type: Output }], onClose: [{ type: Output }], disabled: [{ type: Input }], close: [{ type: Input }], dismiss: [{ type: Input }], title: [{ type: Input }], body: [{ type: Input }], customFooter: [{ type: Input }], headerClasses: [{ type: Input }], labels: [{ type: Input }], onEnterKeyDown: [{ type: HostListener, args: ['document:keydown.enter', ['$event']] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kYWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vY29yZS9tb2RhbC9tb2RhbC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9jb3JlL21vZGFsL21vZGFsLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMvRixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxRQUFRLENBQUM7Ozs7O0FBR2pDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0RHO0FBS0gsTUFBTSxPQUFPLGNBQWM7SUF1Q3pCOztPQUVHO0lBQ0gsSUFBYSxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFlO1FBQzdDLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxFQUFFLEVBQUUsTUFBTSxFQUFFLENBQUM7SUFDaEMsQ0FBQztJQUVELElBQUksTUFBTTtRQUNSLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN0QixDQUFDO0lBSUQsWUFBZ0MsS0FBaUI7UUFBakIsVUFBSyxHQUFMLEtBQUssQ0FBWTtRQW5EakQ7O1dBRUc7UUFDTyxjQUFTLEdBQTBCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDaEU7O1dBRUc7UUFDTyxZQUFPLEdBQTBCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDOUQ7O1dBRUc7UUFDTSxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBaUIxQjs7O1dBR0c7UUFDTSxpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUM5Qjs7V0FFRztRQUNNLGtCQUFhLEdBQUcsRUFBRSxDQUFDO1FBYXBCLFlBQU8sR0FBZ0IsRUFBRSxFQUFFLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztJQUU1QixDQUFDO0lBRXJEOzs7T0FHRztJQUNILFFBQVE7UUFDTixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDO1FBQ3RCLElBQUksQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3RCLEVBQUUsR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQy9CLENBQUM7UUFDRCxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQ1AsRUFBRSxFQUFFLENBQUM7UUFDUCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVEOzs7T0FHRztJQUNILE1BQU07UUFDSixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQ3BCLElBQUksQ0FBQyxFQUFFLElBQUksSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3RCLEVBQUUsR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQy9CLENBQUM7UUFDRCxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQ1AsRUFBRSxFQUFFLENBQUM7UUFDUCxDQUFDO1FBQ0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDMUIsQ0FBQztJQUVEOzs7T0FHRztJQUNpRCxjQUFjLENBQUMsTUFBcUI7UUFDdEYsTUFBTSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNqRixNQUFNLGlCQUFpQixHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUNuRSxNQUFNLGFBQWEsR0FBRyxDQUFDLElBQUksQ0FBQyxZQUFZLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQzdFLElBQUksZ0JBQWdCLElBQUksaUJBQWlCLEVBQUUsQ0FBQztZQUMxQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDbEIsQ0FBQztRQUNELElBQUksZ0JBQWdCLElBQUksYUFBYSxFQUFFLENBQUM7WUFDdEMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ2hCLENBQUM7SUFDSCxDQUFDOytHQWxHVSxjQUFjO21HQUFkLGNBQWMsMldDL0QzQixpeENBdUNBOzs0RkR3QmEsY0FBYztrQkFKMUIsU0FBUzsrQkFDRSxXQUFXOzswQkF1RFIsUUFBUTt5Q0FoRFgsU0FBUztzQkFBbEIsTUFBTTtnQkFJRyxPQUFPO3NCQUFoQixNQUFNO2dCQUlFLFFBQVE7c0JBQWhCLEtBQUs7Z0JBSUcsS0FBSztzQkFBYixLQUFLO2dCQUlHLE9BQU87c0JBQWYsS0FBSztnQkFJRyxLQUFLO3NCQUFiLEtBQUs7Z0JBSUcsSUFBSTtzQkFBWixLQUFLO2dCQUtHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBSUcsYUFBYTtzQkFBckIsS0FBSztnQkFLTyxNQUFNO3NCQUFsQixLQUFLO2dCQThDOEMsY0FBYztzQkFBakUsWUFBWTt1QkFBQyx3QkFBd0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE9wdGlvbmFsLCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCc01vZGFsUmVmIH0gZnJvbSAnbmd4LWJvb3RzdHJhcC9tb2RhbCc7XG5pbXBvcnQgeyBnZXR0ZXh0IH0gZnJvbSAnLi4vaTE4bi9nZXR0ZXh0JztcbmltcG9ydCB7IGlzRW1wdHkgfSBmcm9tICdsb2Rhc2gnO1xuaW1wb3J0IHsgTW9kYWxMYWJlbHMgfSBmcm9tICcuLi9zZWxlY3QtbW9kYWwvc2VsZWN0LW1vZGFsLm1vZGVsJztcblxuLyoqXG4gKiBDOFkgY29tcG9uZW50IGZvciBjcmVhdGluZyBtb2RhbHMuXG4gKlxuICogQ3JlYXRpbmcgY3VzdG9tIG1vZGFsOlxuICogYGBgdHlwZXNjcmlwdFxuICogIGltcG9ydCB7IENvbXBvbmVudCB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG4gKiAgaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuICpcbiAqIEBDb21wb25lbnQoe1xuICogIHNlbGVjdG9yOiBcIm15LW1vZGFsXCIsXG4gKiAgdGVtcGxhdGU6IGBcbiAqICAgIDxjOHktbW9kYWwgdGl0bGU9XCJDdXN0b21UaXRsZVwiXG4gKiAgICAgIChvbkNsb3NlKT1cIm9uQ2xvc2UoJGV2ZW50KVwiXG4gKiAgICAgIChvbkRpc21pc3MpPVwib25EaXNtaXNzKCRldmVudClcIlxuICogICAgICBbbGFiZWxzXT1cImxhYmVsc1wiXG4gKiAgICAgIFtkaXNhYmxlZF09XCJ0cnVlXCIgPC0gd2lsbCBkaXNhYmxlIG9rIGJ1dHRvblxuICogICAgICA+XG4gKiAgICAgICAgPHNwYW4+SSBhbSBib2R5IG9mIG1vZGFsPC9zcGFuPlxuICogICAgICAgIDxzcGFuPkZvciBzaW1wbGUgc3RyaW5nIHVzZSBib2R5PVwic3RyaW5nXCI8L3NwYW4+XG4gKiAgICA8L2M4eS1tb2RhbD5gXG4gKiB9KVxuICpcbiAqIGV4cG9ydCBjbGFzcyBNeU1vZGFsQ29tcG9uZW50IHtcbiAqXG4gKiAgY2xvc2VTdWJqZWN0OiBTdWJqZWN0PGJvb2xlYW4+ID0gbmV3IFN1YmplY3QoKTtcbiAqICBsYWJlbHMgOiBNb2RhbExhYmVscyA9IHtvazogXCJjdXN0b21PS1wiLCBjYW5jZWw6IFwiY3VzdG9tQ2FuY2VsXCJ9O1xuICpcbiAqICBvbkRpc21pc3MoZXZlbnQpe1xuICogICAgdGhpcy5jbG9zZVN1YmplY3QubmV4dChmYWxzZSk7XG4gKiAgfVxuICpcbiAqICBvbkNsb3NlKGV2ZW50KSB7XG4gKiAgICB0aGlzLmNsb3NlU3ViamVjdC5uZXh0KHRydWUpO1xuICogIH1cbiAqIH1cbiAqIGBgYFxuICpcbiAqIFNob3dpbmcgbW9kYWw6XG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpbXBvcnQgeyBCc01vZGFsU2VydmljZSB9IGZyb20gXCJuZ3gtYm9vdHN0cmFwL21vZGFsXCI7XG4gKlxuICogY29uc3RydWN0b3IoXG4gKiAgcHVibGljIGJzTW9kYWxTZXJ2aWNlOiBCc01vZGFsU2VydmljZSxcbiAqICkge31cbiAqXG4gKiBzaG93TW9kYWwoKSB7XG4gKiAgY29uc3QgbW9kYWxSZWYgPSB0aGlzLmJzTW9kYWxTZXJ2aWNlLnNob3coTXlNb2RhbENvbXBvbmVudCk7XG4gKiAgbW9kYWxSZWYuY29udGVudC5jbG9zZVN1YmplY3Quc3Vic2NyaWJlKHJlc3VsdCA9PiB7XG4gKiAgICBjb25zb2xlLmxvZygncmVzdWx0czonLCByZXN1bHQpO1xuICogIH0pO1xuICogfVxuICogYGBgXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2M4eS1tb2RhbCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9tb2RhbC5jb21wb25lbnQuaHRtbCdcbn0pXG5leHBvcnQgY2xhc3MgTW9kYWxDb21wb25lbnQge1xuICAvKipcbiAgICogRW1pdHMgJ3RydWUnIHdoZW4gJ2NhbmNlbCcgYnV0dG9uIGlzIGNsaWNrZWQuXG4gICAqL1xuICBAT3V0cHV0KCkgb25EaXNtaXNzOiBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIC8qKlxuICAgKiBFbWl0cyAndHJ1ZScgd2hlbiAnb2snIGJ1dHRvbiBpcyBjbGlja2VkLlxuICAgKi9cbiAgQE91dHB1dCgpIG9uQ2xvc2U6IEV2ZW50RW1pdHRlcjxib29sZWFuPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgLyoqXG4gICAqIEluZGljYXRlcyBpZiB0aGUgJ29rJyAoY29uZmlybWF0aW9uKSBidXR0b24gaXMgZGlzYWJsZWQuXG4gICAqL1xuICBASW5wdXQoKSBkaXNhYmxlZCA9IGZhbHNlO1xuICAvKipcbiAgICogQ2FsbGJhY2sgZnVuY3Rpb24gd2hpY2ggaXMgY2FsbGVkIHJpZ2h0IGFmdGVyICdvaycgYnV0dG9uIGlzIGNsaWNrZWQsIGJlZm9yZSAnb25DbG9zZScgZW1pdHMuXG4gICAqL1xuICBASW5wdXQoKSBjbG9zZTogKCkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIENhbGxiYWNrIGZ1bmN0aW9uIHdoaWNoIGlzIGNhbGxlZCByaWdodCBhZnRlciAnY2FuY2VsJyBidXR0b24gaXMgY2xpY2tlZCwgYmVmb3JlICdvbkRpc21pc3MnIGVtaXRzLlxuICAgKi9cbiAgQElucHV0KCkgZGlzbWlzczogKCkgPT4gdm9pZDtcbiAgLyoqXG4gICAqIFRpdGxlIG9mIG1vZGFsLlxuICAgKi9cbiAgQElucHV0KCkgdGl0bGU6IHN0cmluZztcbiAgLyoqXG4gICAqIE1vZGFsIGJvZHkuXG4gICAqL1xuICBASW5wdXQoKSBib2R5OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgaWYgbW9kYWwgc2hvdWxkIHVzZSBjdXN0b20gZm9vdGVyIHByb3ZpZGVkIHdpdGggY29udGVudCBwcm9qZWN0aW9uIChvciBubyBmb290ZXIgYXQgYWxsKS5cbiAgICogSWYgZmFsc2UsIGRlZmF1bHQgZm9vdGVyIHdpdGggJ2NhbmNlbCcgYW5kICdvaycgYnV0dG9ucyB3aWxsIGJlIGRpc3BsYXllZC5cbiAgICovXG4gIEBJbnB1dCgpIGN1c3RvbUZvb3RlciA9IGZhbHNlO1xuICAvKipcbiAgICogQ1NTIGNsYXNzZXMgZm9yIG1vZGFsIGhlYWRlci5cbiAgICovXG4gIEBJbnB1dCgpIGhlYWRlckNsYXNzZXMgPSAnJztcblxuICAvKipcbiAgICogQ3VzdG9tIGxhYmVscyBmb3IgJ2NhbmNlbCcgYW5kICdvaycgYnV0dG9ucy5cbiAgICovXG4gIEBJbnB1dCgpIHNldCBsYWJlbHMoeyBvaywgY2FuY2VsIH06IE1vZGFsTGFiZWxzKSB7XG4gICAgdGhpcy5fbGFiZWxzID0geyBvaywgY2FuY2VsIH07XG4gIH1cblxuICBnZXQgbGFiZWxzKCk6IE1vZGFsTGFiZWxzIHtcbiAgICByZXR1cm4gdGhpcy5fbGFiZWxzO1xuICB9XG5cbiAgcHJpdmF0ZSBfbGFiZWxzOiBNb2RhbExhYmVscyA9IHsgb2s6IGdldHRleHQoJ09LJyksIGNhbmNlbDogZ2V0dGV4dCgnQ2FuY2VsJykgfTtcblxuICBjb25zdHJ1Y3RvcihAT3B0aW9uYWwoKSBwcml2YXRlIG1vZGFsOiBCc01vZGFsUmVmKSB7fVxuXG4gIC8qKlxuICAgKiBIaWRlcyBtb2RhbCBvciBjYWxscyAnZGlzbWlzcycgaW5wdXQgY2FsbGJhY2ssIHRoZW4gZW1pdHMgJ29uRGlzbWlzcycgb3V0cHV0LlxuICAgKiBNZXRob2QgaXMgY2FsbGVkIHdoZW4gJ2NhbmNlbCcgYnV0dG9uIGlzIGNsaWNrZWQsIGJ1dCBjYW4gYmUgYWxzbyB0cmlnZ2VyZWQgYnkgYWNjZXNzaW5nICdNb2RhbENvbXBvbmVudCcgaW5zdGFuY2UuXG4gICAqL1xuICBfZGlzbWlzcygpIHtcbiAgICBsZXQgZm4gPSB0aGlzLmRpc21pc3M7XG4gICAgaWYgKCFmbiAmJiB0aGlzLm1vZGFsKSB7XG4gICAgICBmbiA9ICgpID0+IHRoaXMubW9kYWwuaGlkZSgpO1xuICAgIH1cbiAgICBpZiAoZm4pIHtcbiAgICAgIGZuKCk7XG4gICAgfVxuICAgIHRoaXMub25EaXNtaXNzLmVtaXQodHJ1ZSk7XG4gIH1cblxuICAvKipcbiAgICogSGlkZXMgbW9kYWwgb3IgY2FsbHMgJ2Nsb3NlJyBpbnB1dCBjYWxsYmFjaywgdGhlbiBlbWl0cyAnb25DbG9zZScgb3V0cHV0LlxuICAgKiBNZXRob2QgaXMgY2FsbGVkIHdoZW4gJ29rJyBidXR0b24gaXMgY2xpY2tlZCwgYnV0IGNhbiBiZSBhbHNvIHRyaWdnZXJlZCBieSBhY2Nlc3NpbmcgJ01vZGFsQ29tcG9uZW50JyBpbnN0YW5jZS5cbiAgICovXG4gIF9jbG9zZSgpIHtcbiAgICBsZXQgZm4gPSB0aGlzLmNsb3NlO1xuICAgIGlmICghZm4gJiYgdGhpcy5tb2RhbCkge1xuICAgICAgZm4gPSAoKSA9PiB0aGlzLm1vZGFsLmhpZGUoKTtcbiAgICB9XG4gICAgaWYgKGZuKSB7XG4gICAgICBmbigpO1xuICAgIH1cbiAgICB0aGlzLm9uQ2xvc2UuZW1pdCh0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiAnRW50ZXInIGtleWJvYXJkIGJ1dHRvbiBoYW5kbGVyLiBDYWxscyAnX2Rpc21pc3MnIG9yICdfY2xvc2UnIG1ldGhvZCB3aGVuIG9ubHkgb25lIGNvcnJlc3BvbmRpbmcgYnV0dG9uIGV4aXN0cy5cbiAgICogQHBhcmFtIF9ldmVudCBFbnRlciBrZXlkb3duIGV2ZW50XG4gICAqL1xuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDprZXlkb3duLmVudGVyJywgWyckZXZlbnQnXSkgb25FbnRlcktleURvd24oX2V2ZW50OiBLZXlib2FyZEV2ZW50KSB7XG4gICAgY29uc3QgaGFzT25seU9uZUJ1dHRvbiA9IGlzRW1wdHkodGhpcy5sYWJlbHMub2spICE9PSBpc0VtcHR5KHRoaXMubGFiZWxzLmNhbmNlbCk7XG4gICAgY29uc3QgaXNDYW5jZWxDbGlja2FibGUgPSAhdGhpcy5jdXN0b21Gb290ZXIgJiYgdGhpcy5sYWJlbHMuY2FuY2VsO1xuICAgIGNvbnN0IGlzT2tDbGlja2FibGUgPSAhdGhpcy5jdXN0b21Gb290ZXIgJiYgIXRoaXMuZGlzYWJsZWQgJiYgdGhpcy5sYWJlbHMub2s7XG4gICAgaWYgKGhhc09ubHlPbmVCdXR0b24gJiYgaXNDYW5jZWxDbGlja2FibGUpIHtcbiAgICAgIHRoaXMuX2Rpc21pc3MoKTtcbiAgICB9XG4gICAgaWYgKGhhc09ubHlPbmVCdXR0b24gJiYgaXNPa0NsaWNrYWJsZSkge1xuICAgICAgdGhpcy5fY2xvc2UoKTtcbiAgICB9XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJ2aWV3cG9ydC1tb2RhbFwiPlxuICA8ZGl2IGNsYXNzPVwibW9kYWwtaGVhZGVyIHt7IGhlYWRlckNsYXNzZXMgfX1cIiBbbmdDbGFzc109XCJ7IHNlcGFyYXRvcjogdGl0bGUgfVwiPlxuICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIltjOHktbW9kYWwtdGl0bGVdXCI+PC9uZy1jb250ZW50PlxuICAgIDxkaXYgW2hpZGRlbl09XCIhdGl0bGVcIiBpZD1cIm1vZGFsLXRpdGxlXCIgY2xhc3M9XCJtb2RhbC10aXRsZVwiPlxuICAgICAge3sgdGl0bGUgfCB0cmFuc2xhdGUgfX1cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJtb2RhbC1pbm5lci1zY3JvbGxcIiBpZD1cIm1vZGFsLWJvZHlcIj5cbiAgICA8ZGl2IFtuZ0NsYXNzXT1cInsgJ21vZGFsLWJvZHknOiAhY3VzdG9tRm9vdGVyLCAnZC1jb250ZW50cyc6IGN1c3RvbUZvb3RlciB9XCI+XG4gICAgICA8cCAqbmdJZj1cInRpdGxlXCIgY2xhc3M9XCJ0ZXh0LWNlbnRlciB0ZXh0LWJyZWFrLXdvcmRcIj5cbiAgICAgICAge3sgYm9keSB9fVxuICAgICAgPC9wPlxuICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPG5nLWNvbnRlbnQgc2VsZWN0PVwiW2M4eS1tb2RhbC1mb290ZXItY3VzdG9tXVwiPjwvbmctY29udGVudD5cbiAgPGRpdiBjbGFzcz1cIm1vZGFsLWZvb3RlclwiICpuZ0lmPVwiIWN1c3RvbUZvb3RlclwiPlxuICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIltjOHktbW9kYWwtZm9vdGVyXVwiPjwvbmctY29udGVudD5cbiAgICA8YnV0dG9uXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIHRpdGxlPVwie3sgbGFiZWxzLmNhbmNlbCB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAqbmdJZj1cImxhYmVscy5jYW5jZWxcIlxuICAgICAgY2xhc3M9XCJidG4gYnRuLWRlZmF1bHRcIlxuICAgICAgKGNsaWNrKT1cIl9kaXNtaXNzKClcIlxuICAgID5cbiAgICAgIHt7IGxhYmVscy5jYW5jZWwgfCB0cmFuc2xhdGUgfX1cbiAgICA8L2J1dHRvbj5cbiAgICA8YnV0dG9uXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIHRpdGxlPVwie3sgbGFiZWxzLm9rIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICpuZ0lmPVwibGFiZWxzLm9rXCJcbiAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCJcbiAgICAgIChjbGljayk9XCJfY2xvc2UoKVwiXG4gICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgID5cbiAgICAgIHt7IGxhYmVscy5vayB8IHRyYW5zbGF0ZSB9fVxuICAgIDwvYnV0dG9uPlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19