UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

118 lines 25.1 kB
import { Component } from '@angular/core'; import { AlertService, gettext, ModalService, PX_ACTIONS, Status } from '@c8y/ngx-components'; import { DeviceProvisionedCertificatesService } from './device-provisioned-certificates.service'; import { ActivatedRoute } from '@angular/router'; import { CrlService } from '@c8y/client'; import { BehaviorSubject } from 'rxjs'; import { switchMap, map, tap, finalize, shareReplay } from 'rxjs/operators'; import { TranslateService } from '@ngx-translate/core'; import * as i0 from "@angular/core"; import * as i1 from "@c8y/ngx-components"; import * as i2 from "./device-provisioned-certificates.service"; import * as i3 from "@c8y/client"; import * as i4 from "@angular/router"; import * as i5 from "@ngx-translate/core"; import * as i6 from "@angular/common"; export class DeviceTabProvisionedCertificatesComponent { constructor(alertService, modalService, deviceSerialsService, crlService, route, translateService) { this.alertService = alertService; this.modalService = modalService; this.deviceSerialsService = deviceSerialsService; this.crlService = crlService; this.route = route; this.translateService = translateService; this.reloading = false; this.reload$ = new BehaviorSubject(null); this.tableTitle = gettext('Provisioned certificates'); this.columns = [ { name: 'serialNumber', path: 'serialNumber', header: gettext('Serial number') }, { name: 'validTill', path: 'validTill', header: gettext('Expiration date') } ]; this.rows$ = this.reload$.pipe(tap(() => { this.reloading = true; }), map(() => this.route.snapshot.parent.data.contextData), switchMap(device => this.deviceSerialsService.getDeviceProvisionedCertificates(device)), map(provisionedCertificates => provisionedCertificates.map(cert => ({ ...cert, id: cert.serialNumber }))), tap(() => { this.reloading = false; }), shareReplay(1), finalize(() => { this.reloading = false; })); this.pagination = { pageSize: 20, currentPage: 1 }; this.actionControls = [ { type: 'REVOKE', text: gettext('Revoke'), icon: 'trash', iconClasses: 'text-danger', showOnHover: false, callback: (item) => this.revokeProvisionedCertificate(item) } ]; this.displayOptions = { filter: false, striped: true, hover: true, bordered: false, gridHeader: true }; this.PX_ACTIONS = PX_ACTIONS; } ngOnInit() { this.reload(); } reload() { this.reload$.next(); } highlightDependingOnExpirationStatus(item) { const warningOffset = 24 * 60 * 60 * 1000 * 90; // 90 days const todayTimestamp = new Date().getTime(); const warningTimestamp = new Date().getTime() + warningOffset; const notAfterTimestamp = new Date(item.validTill).getTime(); const expired = notAfterTimestamp < todayTimestamp; const expiresInLessThan90Days = notAfterTimestamp < warningTimestamp; if (expired) { return 'text-danger'; } if (expiresInLessThan90Days) { return 'text-warning'; } return ''; } async revokeProvisionedCertificate(provisionedCertificate) { if (provisionedCertificate) { try { const serialNumberInHex = provisionedCertificate.serialNumber; await this.confirmRevocation(serialNumberInHex); await this.crlService.uploadCrls([{ serialNumberInHex }]); } catch (error) { this.alertService.addServerFailure(error); } finally { this.reload(); } } } async confirmRevocation(serialNumber) { return await this.modalService.confirm(gettext('Revoke provisioned certificate'), this.translateService.instant(gettext(`You are about to revoke provisioned certificate {{ serialNumber }}. Do you want to proceed?`), { serialNumber }), Status.DANGER, { ok: gettext('Revoke'), cancel: gettext('Cancel') }); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DeviceTabProvisionedCertificatesComponent, deps: [{ token: i1.AlertService }, { token: i1.ModalService }, { token: i2.DeviceProvisionedCertificatesService }, { token: i3.CrlService }, { token: i4.ActivatedRoute }, { token: i5.TranslateService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DeviceTabProvisionedCertificatesComponent, selector: "device-tab-serials-component", ngImport: i0, template: "<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n title=\"{{ 'Reload' | translate }}\"\n type=\"button\"\n (click)=\"reload()\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': reloading }\"\n ></i>\n {{ 'Reload' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<c8y-data-grid\n [title]=\"tableTitle | translate\"\n [columns]=\"columns\"\n [rows]=\"rows$ | async\"\n [pagination]=\"pagination\"\n [actionControls]=\"actionControls\"\n [displayOptions]=\"displayOptions\"\n [hideReload]=\"true\"\n>\n <c8y-ui-empty-state\n [icon]=\"'certificate'\"\n [title]=\"'No provisioned certificates to display.' | translate\"\n *ngIf=\"(rows$ | async)?.length === 0\"\n ></c8y-ui-empty-state>\n\n <c8y-column name=\"serialNumber\">\n <ng-container *c8yCellRendererDef=\"let context\">\n <span\n class=\"text-truncate\"\n title=\"{{ context.property.header | translate }}: {{ context.value }}\"\n >\n {{ context.value }}\n </span>\n </ng-container>\n </c8y-column>\n\n <c8y-column name=\"validTill\">\n <ng-container *c8yCellRendererDef=\"let context\">\n <span\n class=\"text-truncate\"\n title=\"{{ context.property.header | translate }}: {{ context.value | c8yDate }}\"\n >\n <span\n *ngIf=\"context.value\"\n [ngClass]=\"highlightDependingOnExpirationStatus(context.item)\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"calendar\"\n *ngIf=\"!highlightDependingOnExpirationStatus(context.item)\"\n ></i>\n <i\n class=\"m-r-4\"\n c8yIcon=\"warning\"\n *ngIf=\"highlightDependingOnExpirationStatus(context.item)\"\n ></i>\n <span>{{ context.value | c8yDate }}</span>\n </span>\n </span>\n </ng-container>\n </c8y-column>\n</c8y-data-grid>\n", dependencies: [{ kind: "component", type: i1.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "component", type: i1.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i1.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.CellRendererDefDirective, selector: "[c8yCellRendererDef]" }, { kind: "directive", type: i1.ColumnDirective, selector: "c8y-column", inputs: ["name"] }, { kind: "component", type: i1.DataGridComponent, selector: "c8y-data-grid", inputs: ["title", "loadMoreItemsLabel", "loadingItemsLabel", "showSearch", "refresh", "columns", "rows", "pagination", "infiniteScroll", "serverSideDataCallback", "selectable", "singleSelection", "selectionPrimaryKey", "displayOptions", "actionControls", "bulkActionControls", "headerActionControls", "searchText", "configureColumnsEnabled", "showCounterWarning", "activeClassName", "expandableRows", "hideReload"], outputs: ["rowMouseOver", "rowMouseLeave", "rowClick", "onConfigChange", "onBeforeFilter", "onBeforeSearch", "onFilter", "itemsSelect", "onReload", "onAddCustomColumn", "onRemoveCustomColumn", "onColumnFilterReset", "onSort", "onPageSizeChange", "onColumnReordered", "onColumnVisibilityChange"] }, { kind: "pipe", type: i1.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i1.DatePipe, name: "c8yDate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DeviceTabProvisionedCertificatesComponent, decorators: [{ type: Component, args: [{ selector: 'device-tab-serials-component', template: "<c8y-action-bar-item [placement]=\"'right'\">\n <button\n class=\"btn btn-link\"\n title=\"{{ 'Reload' | translate }}\"\n type=\"button\"\n (click)=\"reload()\"\n >\n <i\n c8yIcon=\"refresh\"\n [ngClass]=\"{ 'icon-spin': reloading }\"\n ></i>\n {{ 'Reload' | translate }}\n </button>\n</c8y-action-bar-item>\n\n<c8y-data-grid\n [title]=\"tableTitle | translate\"\n [columns]=\"columns\"\n [rows]=\"rows$ | async\"\n [pagination]=\"pagination\"\n [actionControls]=\"actionControls\"\n [displayOptions]=\"displayOptions\"\n [hideReload]=\"true\"\n>\n <c8y-ui-empty-state\n [icon]=\"'certificate'\"\n [title]=\"'No provisioned certificates to display.' | translate\"\n *ngIf=\"(rows$ | async)?.length === 0\"\n ></c8y-ui-empty-state>\n\n <c8y-column name=\"serialNumber\">\n <ng-container *c8yCellRendererDef=\"let context\">\n <span\n class=\"text-truncate\"\n title=\"{{ context.property.header | translate }}: {{ context.value }}\"\n >\n {{ context.value }}\n </span>\n </ng-container>\n </c8y-column>\n\n <c8y-column name=\"validTill\">\n <ng-container *c8yCellRendererDef=\"let context\">\n <span\n class=\"text-truncate\"\n title=\"{{ context.property.header | translate }}: {{ context.value | c8yDate }}\"\n >\n <span\n *ngIf=\"context.value\"\n [ngClass]=\"highlightDependingOnExpirationStatus(context.item)\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"calendar\"\n *ngIf=\"!highlightDependingOnExpirationStatus(context.item)\"\n ></i>\n <i\n class=\"m-r-4\"\n c8yIcon=\"warning\"\n *ngIf=\"highlightDependingOnExpirationStatus(context.item)\"\n ></i>\n <span>{{ context.value | c8yDate }}</span>\n </span>\n </span>\n </ng-container>\n </c8y-column>\n</c8y-data-grid>\n" }] }], ctorParameters: () => [{ type: i1.AlertService }, { type: i1.ModalService }, { type: i2.DeviceProvisionedCertificatesService }, { type: i3.CrlService }, { type: i4.ActivatedRoute }, { type: i5.TranslateService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGV2aWNlLXRhYi1wcm92aXNpb25lZC1jZXJ0aWZpY2F0ZXMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vZGV2aWNlLXByb3Zpc2lvbmVkLWNlcnRpZmljYXRlcy9kZXZpY2UtdGFiLXByb3Zpc2lvbmVkLWNlcnRpZmljYXRlcy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi9kZXZpY2UtcHJvdmlzaW9uZWQtY2VydGlmaWNhdGVzL2RldmljZS10YWItcHJvdmlzaW9uZWQtY2VydGlmaWNhdGVzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFDbEQsT0FBTyxFQUVMLFlBQVksRUFHWixPQUFPLEVBQ1AsWUFBWSxFQUVaLFVBQVUsRUFFVixNQUFNLEVBQ1AsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQUUsb0NBQW9DLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUNqRyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDakQsT0FBTyxFQUFFLFVBQVUsRUFBa0IsTUFBTSxhQUFhLENBQUM7QUFDekQsT0FBTyxFQUFFLGVBQWUsRUFBYyxNQUFNLE1BQU0sQ0FBQztBQUNuRCxPQUFPLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzVFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7Ozs7OztBQVF2RCxNQUFNLE9BQU8seUNBQXlDO0lBNkRwRCxZQUNVLFlBQTBCLEVBQzFCLFlBQTBCLEVBQzFCLG9CQUEwRCxFQUMxRCxVQUFzQixFQUN0QixLQUFxQixFQUNyQixnQkFBa0M7UUFMbEMsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIs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LE9BQU8sQ0FBQyxnQ0FBZ0MsQ0FBQyxFQUN6QyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUMzQixPQUFPLENBQ0wsNkZBQTZGLENBQzlGLEVBQ0QsRUFBRSxZQUFZLEVBQUUsQ0FDakIsRUFDRCxNQUFNLENBQUMsTUFBTSxFQUNiLEVBQUUsRUFBRSxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQ3JELENBQUM7SUFDSixDQUFDOytHQXhIVSx5Q0FBeUM7bUdBQXpDLHlDQUF5QyxvRUMxQnRELG82REFtRUE7OzRGRHpDYSx5Q0FBeUM7a0JBSnJELFNBQVM7K0JBQ0UsOEJBQThCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7XG4gIEFjdGlvbkNvbnRyb2wsXG4gIEFsZXJ0U2VydmljZSxcbiAgQ29sdW1uLFxuICBEaXNwbGF5T3B0aW9ucyxcbiAgZ2V0dGV4dCxcbiAgTW9kYWxTZXJ2aWNlLFxuICBQYWdpbmF0aW9uLFxuICBQWF9BQ1RJT05TLFxuICBSb3csXG4gIFN0YXR1c1xufSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7IERldmljZVByb3Zpc2lvbmVkQ2VydGlmaWNhdGVzU2VydmljZSB9IGZyb20gJy4vZGV2aWNlLXByb3Zpc2lvbmVkLWNlcnRpZmljYXRlcy5zZXJ2aWNlJztcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7IENybFNlcnZpY2UsIElNYW5hZ2VkT2JqZWN0IH0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBzd2l0Y2hNYXAsIG1hcCwgdGFwLCBmaW5hbGl6ZSwgc2hhcmVSZXBsYXkgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5cbmV4cG9ydCB0eXBlIFByb3Zpc2lvbmVkQ2VydGlmaWNhdGUgPSB7IHNlcmlhbE51bWJlcjogc3RyaW5nOyB2YWxpZFRpbGw6IHN0cmluZyB9O1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdkZXZpY2UtdGFiLXNlcmlhbHMtY29tcG9uZW50JyxcbiAgdGVtcGxhdGVVcmw6ICcuL2RldmljZS10YWItcHJvdmlzaW9uZWQtY2VydGlmaWNhdGVzLmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBEZXZpY2VUYWJQcm92aXNpb25lZENlcnRpZmljYXRlc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIHJlbG9hZGluZyA9IGZhbHNlO1xuICByZWxvYWQkOiBCZWhhdmlvclN1YmplY3Q8dm9pZD4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KG51bGwpO1xuXG4gIHRhYmxlVGl0bGUgPSBnZXR0ZXh0KCdQcm92aXNpb25lZCBjZXJ0aWZpY2F0ZXMnKTtcbiAgY29sdW1uczogQ29sdW1uW10gPSBbXG4gICAge1xuICAgICAgbmFtZTogJ3NlcmlhbE51bWJlcicsXG4gICAgICBwYXRoOiAnc2VyaWFsTnVtYmVyJyxcbiAgICAgIGhlYWRlcjogZ2V0dGV4dCgnU2VyaWFsIG51bWJlcicpXG4gICAgfSxcbiAgICB7XG4gICAgICBuYW1lOiAndmFsaWRUaWxsJyxcbiAgICAgIHBhdGg6ICd2YWxpZFRpbGwnLFxuICAgICAgaGVhZGVyOiBnZXR0ZXh0KCdFeHBpcmF0aW9uIGRhdGUnKVxuICAgIH1cbiAgXTtcbiAgcm93cyQ6IE9ic2VydmFibGU8QXJyYXk8Um93ICYgUHJvdmlzaW9uZWRDZXJ0aWZpY2F0ZT4+ID0gdGhpcy5yZWxvYWQkLnBpcGUoXG4gICAgdGFwKCgpID0+IHtcbiAgICAgIHRoaXMucmVsb2FkaW5nID0gdHJ1ZTtcbiAgICB9KSxcbiAgICBtYXAoKCkgPT4gdGhpcy5yb3V0ZS5zbmFwc2hvdC5wYXJlbnQuZGF0YS5jb250ZXh0RGF0YSBhcyBJTWFuYWdlZE9iamVjdCksXG4gICAgc3dpdGNoTWFwKGRldmljZSA9PiB0aGlzLmRldmljZVNlcmlhbHNTZXJ2aWNlLmdldERldmljZVByb3Zpc2lvbmVkQ2VydGlmaWNhdGVzKGRldmljZSkpLFxuICAgIG1hcChwcm92aXNpb25lZENlcnRpZmljYXRlcyA9PlxuICAgICAgcHJvdmlzaW9uZWRDZXJ0aWZpY2F0ZXMubWFwKGNlcnQgPT4gKHtcbiAgICAgICAgLi4uY2VydCxcbiAgICAgICAgaWQ6IGNlcnQuc2VyaWFsTnVtYmVyXG4gICAgICB9KSlcbiAgICApLFxuICAgIHRhcCgoKSA9PiB7XG4gICAgICB0aGlzLnJlbG9hZGluZyA9IGZhbHNlO1xuICAgIH0pLFxuICAgIHNoYXJlUmVwbGF5KDEpLFxuICAgIGZpbmFsaXplKCgpID0+IHtcbiAgICAgIHRoaXMucmVsb2FkaW5nID0gZmFsc2U7XG4gICAgfSlcbiAgKTtcbiAgcGFnaW5hdGlvbjogUGFnaW5hdGlvbiA9IHtcbiAgICBwYWdlU2l6ZTogMjAsXG4gICAgY3VycmVudFBhZ2U6IDFcbiAgfTtcbiAgYWN0aW9uQ29udHJvbHM6IEFjdGlvbkNvbnRyb2xbXSA9IFtcbiAgICB7XG4gICAgICB0eXBlOiAnUkVWT0tFJyxcbiAgICAgIHRleHQ6IGdldHRleHQoJ1Jldm9rZScpLFxuICAgICAgaWNvbjogJ3RyYXNoJyxcbiAgICAgIGljb25DbGFzc2VzOiAndGV4dC1kYW5nZXInLFxuICAgICAgc2hvd09uSG92ZXI6IGZhbHNlLFxuICAgICAgY2FsbGJhY2s6IChpdGVtOiBSb3cgJiBQcm92aXNpb25lZENlcnRpZmljYXRlKSA9PiB0aGlzLnJldm9rZVByb3Zpc2lvbmVkQ2VydGlmaWNhdGUoaXRlbSlcbiAgICB9XG4gIF07XG4gIGRpc3BsYXlPcHRpb25zOiBEaXNwbGF5T3B0aW9ucyA9IHtcbiAgICBmaWx0ZXI6IGZhbHNlLFxuICAgIHN0cmlwZWQ6IHRydWUsXG4gICAgaG92ZXI6IHRydWUsXG4gICAgYm9yZGVyZWQ6IGZhbHNlLFxuICAgIGdyaWRIZWFkZXI6IHRydWVcbiAgfTtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgUFhfQUNUSU9OUyA9IFBYX0FDVElPTlM7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBhbGVydFNlcnZpY2U6IEFsZXJ0U2VydmljZSxcbiAgICBwcml2YXRlIG1vZGFsU2VydmljZTogTW9kYWxTZXJ2aWNlLFxuICAgIHByaXZhdGUgZGV2aWNlU2VyaWFsc1NlcnZpY2U6IERldmljZVByb3Zpc2lvbmVkQ2VydGlmaWNhdGVzU2VydmljZSxcbiAgICBwcml2YXRlIGNybFNlcnZpY2U6IENybFNlcnZpY2UsXG4gICAgcHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGVTZXJ2aWNlOiBUcmFuc2xhdGVTZXJ2aWNlXG4gICkge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnJlbG9hZCgpO1xuICB9XG5cbiAgcmVsb2FkKCkge1xuICAgIHRoaXMucmVsb2FkJC5uZXh0KCk7XG4gIH1cblxuICBoaWdobGlnaHREZXBlbmRpbmdPbkV4cGlyYXRpb25TdGF0dXMoaXRlbTogUHJvdmlzaW9uZWRDZXJ0aWZpY2F0ZSkge1xuICAgIGNvbnN0IHdhcm5pbmdPZmZzZXQgPSAyNCAqIDYwICogNjAgKiAxMDAwICogOTA7IC8vIDkwIGRheXNcbiAgICBjb25zdCB0b2RheVRpbWVzdGFtcCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuICAgIGNvbnN0IHdhcm5pbmdUaW1lc3RhbXAgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSArIHdhcm5pbmdPZmZzZXQ7XG4gICAgY29uc3Qgbm90QWZ0ZXJUaW1lc3RhbXAgPSBuZXcgRGF0ZShpdGVtLnZhbGlkVGlsbCkuZ2V0VGltZSgpO1xuICAgIGNvbnN0IGV4cGlyZWQgPSBub3RBZnRlclRpbWVzdGFtcCA8IHRvZGF5VGltZXN0YW1wO1xuICAgIGNvbnN0IGV4cGlyZXNJbkxlc3NUaGFuOTBEYXlzID0gbm90QWZ0ZXJUaW1lc3RhbXAgPCB3YXJuaW5nVGltZXN0YW1wO1xuICAgIGlmIChleHBpcmVkKSB7XG4gICAgICByZXR1cm4gJ3RleHQtZGFuZ2VyJztcbiAgICB9XG4gICAgaWYgKGV4cGlyZXNJbkxlc3NUaGFuOTBEYXlzKSB7XG4gICAgICByZXR1cm4gJ3RleHQtd2FybmluZyc7XG4gICAgfVxuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIGFzeW5jIHJldm9rZVByb3Zpc2lvbmVkQ2VydGlmaWNhdGUocHJvdmlzaW9uZWRDZXJ0aWZpY2F0ZTogUHJvdmlzaW9uZWRDZXJ0aWZpY2F0ZSkge1xuICAgIGlmIChwcm92aXNpb25lZENlcnRpZmljYXRlKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBzZXJpYWxOdW1iZXJJbkhleCA9IHByb3Zpc2lvbmVkQ2VydGlmaWNhdGUuc2VyaWFsTnVtYmVyO1xuICAgICAgICBhd2FpdCB0aGlzLmNvbmZpcm1SZXZvY2F0aW9uKHNlcmlhbE51bWJlckluSGV4KTtcbiAgICAgICAgYXdhaXQgdGhpcy5jcmxTZXJ2aWNlLnVwbG9hZENybHMoW3sgc2VyaWFsTnVtYmVySW5IZXggfV0pO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdGhpcy5hbGVydFNlcnZpY2UuYWRkU2VydmVyRmFpbHVyZShlcnJvcik7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICB0aGlzLnJlbG9hZCgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY29uZmlybVJldm9jYXRpb24oc2VyaWFsTnVtYmVyOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gYXdhaXQgdGhpcy5tb2RhbFNlcnZpY2UuY29uZmlybShcbiAgICAgIGdldHRleHQoJ1Jldm9rZSBwcm92aXNpb25lZCBjZXJ0aWZpY2F0ZScpLFxuICAgICAgdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQoXG4gICAgICAgIGdldHRleHQoXG4gICAgICAgICAgYFlvdSBhcmUgYWJvdXQgdG8gcmV2b2tlIHByb3Zpc2lvbmVkIGNlcnRpZmljYXRlIHt7IHNlcmlhbE51bWJlciB9fS4gRG8geW91IHdhbnQgdG8gcHJvY2VlZD9gXG4gICAgICAgICksXG4gICAgICAgIHsgc2VyaWFsTnVtYmVyIH1cbiAgICAgICksXG4gICAgICBTdGF0dXMuREFOR0VSLFxuICAgICAgeyBvazogZ2V0dGV4dCgnUmV2b2tlJyksIGNhbmNlbDogZ2V0dGV4dCgnQ2FuY2VsJykgfVxuICAgICk7XG4gIH1cbn1cbiIsIjxjOHktYWN0aW9uLWJhci1pdGVtIFtwbGFjZW1lbnRdPVwiJ3JpZ2h0J1wiPlxuICA8YnV0dG9uXG4gICAgY2xhc3M9XCJidG4gYnRuLWxpbmtcIlxuICAgIHRpdGxlPVwie3sgJ1JlbG9hZCcgfCB0cmFuc2xhdGUgfX1cIlxuICAgIHR5cGU9XCJidXR0b25cIlxuICAgIChjbGljayk9XCJyZWxvYWQoKVwiXG4gID5cbiAgICA8aVxuICAgICAgYzh5SWNvbj1cInJlZnJlc2hcIlxuICAgICAgW25nQ2xhc3NdPVwieyAnaWNvbi1zcGluJzogcmVsb2FkaW5nIH1cIlxuICAgID48L2k+XG4gICAge3sgJ1JlbG9hZCcgfCB0cmFuc2xhdGUgfX1cbiAgPC9idXR0b24+XG48L2M4eS1hY3Rpb24tYmFyLWl0ZW0+XG5cbjxjOHktZGF0YS1ncmlkXG4gIFt0aXRsZV09XCJ0YWJsZVRpdGxlIHwgdHJhbnNsYXRlXCJcbiAgW2NvbHVtbnNdPVwiY29sdW1uc1wiXG4gIFtyb3dzXT1cInJvd3MkIHwgYXN5bmNcIlxuICBbcGFnaW5hdGlvbl09XCJwYWdpbmF0aW9uXCJcbiAgW2FjdGlvbkNvbnRyb2xzXT1cImFjdGlvbkNvbnRyb2xzXCJcbiAgW2Rpc3BsYXlPcHRpb25zXT1cImRpc3BsYXlPcHRpb25zXCJcbiAgW2hpZGVSZWxvYWRdPVwidHJ1ZVwiXG4+XG4gIDxjOHktdWktZW1wdHktc3RhdGVcbiAgICBbaWNvbl09XCInY2VydGlmaWNhdGUnXCJcbiAgICBbdGl0bGVdPVwiJ05vIHByb3Zpc2lvbmVkIGNlcnRpZmljYXRlcyB0byBkaXNwbGF5LicgfCB0cmFuc2xhdGVcIlxuICAgICpuZ0lmPVwiKHJvd3MkIHwgYXN5bmMpPy5sZW5ndGggPT09IDBcIlxuICA+PC9jOHktdWktZW1wdHktc3RhdGU+XG5cbiAgPGM4eS1jb2x1bW4gbmFtZT1cInNlcmlhbE51bWJlclwiPlxuICAgIDxuZy1jb250YWluZXIgKmM4eUNlbGxSZW5kZXJlckRlZj1cImxldCBjb250ZXh0XCI+XG4gICAgICA8c3BhblxuICAgICAgICBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIlxuICAgICAgICB0aXRsZT1cInt7IGNvbnRleHQucHJvcGVydHkuaGVhZGVyIHwgdHJhbnNsYXRlIH19OiB7eyBjb250ZXh0LnZhbHVlIH19XCJcbiAgICAgID5cbiAgICAgICAge3sgY29udGV4dC52YWx1ZSB9fVxuICAgICAgPC9zcGFuPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L2M4eS1jb2x1bW4+XG5cbiAgPGM4eS1jb2x1bW4gbmFtZT1cInZhbGlkVGlsbFwiPlxuICAgIDxuZy1jb250YWluZXIgKmM4eUNlbGxSZW5kZXJlckRlZj1cImxldCBjb250ZXh0XCI+XG4gICAgICA8c3BhblxuICAgICAgICBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIlxuICAgICAgICB0aXRsZT1cInt7IGNvbnRleHQucHJvcGVydHkuaGVhZGVyIHwgdHJhbnNsYXRlIH19OiB7eyBjb250ZXh0LnZhbHVlIHwgYzh5RGF0ZSB9fVwiXG4gICAgICA+XG4gICAgICAgIDxzcGFuXG4gICAgICAgICAgKm5nSWY9XCJjb250ZXh0LnZhbHVlXCJcbiAgICAgICAgICBbbmdDbGFzc109XCJoaWdobGlnaHREZXBlbmRpbmdPbkV4cGlyYXRpb25TdGF0dXMoY29udGV4dC5pdGVtKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8aVxuICAgICAgICAgICAgY2xhc3M9XCJtLXItNFwiXG4gICAgICAgICAgICBjOHlJY29uPVwiY2FsZW5kYXJcIlxuICAgICAgICAgICAgKm5nSWY9XCIhaGlnaGxpZ2h0RGVwZW5kaW5nT25FeHBpcmF0aW9uU3RhdHVzKGNvbnRleHQuaXRlbSlcIlxuICAgICAgICAgID48L2k+XG4gICAgICAgICAgPGlcbiAgICAgICAgICAgIGNsYXNzPVwibS1yLTRcIlxuICAgICAgICAgICAgYzh5SWNvbj1cIndhcm5pbmdcIlxuICAgICAgICAgICAgKm5nSWY9XCJoaWdobGlnaHREZXBlbmRpbmdPbkV4cGlyYXRpb25TdGF0dXMoY29udGV4dC5pdGVtKVwiXG4gICAgICAgICAgPjwvaT5cbiAgICAgICAgICA8c3Bhbj57eyBjb250ZXh0LnZhbHVlIHwgYzh5RGF0ZSB9fTwvc3Bhbj5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC9zcGFuPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L2M4eS1jb2x1bW4+XG48L2M4eS1kYXRhLWdyaWQ+XG4iXX0=