@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
110 lines • 27.3 kB
JavaScript
import { Component } from '@angular/core';
import { FormGroup, ReactiveFormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
import { TenantService } from '@c8y/client';
import { ActivatedRoute, RouterLink } from '@angular/router';
import { AlertService, CoreModule, FormsModule, gettext, GainsightService } from '@c8y/ngx-components';
import { CustomPropertiesService } from '../custom-properties/custom-properties.service';
import { CustomPropertyFieldComponent } from '../custom-properties/custom-property-field/custom-property-field.component';
import { PRODUCT_EXPERIENCE_TENANT_MANAGEMENT } from '../tenants.model';
import { take } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "@c8y/client";
import * as i2 from "@c8y/ngx-components";
import * as i3 from "@angular/router";
import * as i4 from "../custom-properties/custom-properties.service";
import * as i5 from "@angular/common";
import * as i6 from "@angular/forms";
const { ACTIONS, EVENTS, COMPONENTS, RESULTS } = PRODUCT_EXPERIENCE_TENANT_MANAGEMENT;
export class CustomPropertiesComponent {
constructor(tenantService, alertService, activatedRoute, customPropertiesService, gainsightService) {
this.tenantService = tenantService;
this.alertService = alertService;
this.activatedRoute = activatedRoute;
this.customPropertiesService = customPropertiesService;
this.gainsightService = gainsightService;
this.customPropsForm = new FormGroup({});
this.tenant = null;
this.initialized = false;
}
async ngOnInit() {
await this.loadTenantDetails();
const { form, fields } = await this.customPropertiesService.getFormAndFieldList();
this.customPropsForm = form;
this.fieldDefinitions = fields;
this.applyValuesFromTenant();
this.initialized = true;
this.sendGainsightEvent(ACTIONS.TENANT_CUSTOM_PROPERTIES_OPENED);
this.customPropsForm.valueChanges.pipe(take(1)).subscribe(() => {
this.sendGainsightEvent(ACTIONS.TENANT_CUSTOM_PROPERTIES_STARTED_CHANGING);
});
}
async onSubmit() {
if (this.customPropsForm.invalid || !this.tenant) {
return;
}
const updatedTenant = {
...this.tenant,
customProperties: {
...this.tenant.customProperties,
...this.getDirtyValues()
}
};
try {
await this.tenantService.update(updatedTenant);
this.alertService.success(gettext('Custom properties values saved.'));
this.sendGainsightEvent(ACTIONS.TENANT_CUSTOM_PROPERTIES_SAVED, { result: RESULTS.SUCCESS });
}
catch (error) {
this.alertService.addServerFailure(error);
this.sendGainsightEvent(ACTIONS.TENANT_CUSTOM_PROPERTIES_SAVED, {
result: RESULTS.FAILURE,
error
});
}
}
async loadTenantDetails() {
try {
const result = await this.tenantService.detail(this.activatedRoute.snapshot.parent.data.contextData.id);
this.tenant = result.data;
}
catch (error) {
this.alertService.addServerFailure(error);
}
}
applyValuesFromTenant() {
const customProps = this.tenant?.customProperties || {};
this.customPropsForm.patchValue(customProps);
}
getDirtyValues() {
const dirtyValues = {};
Object.keys(this.customPropsForm.controls).forEach(key => {
const control = this.customPropsForm.controls[key];
if (control && control.dirty && control.value !== null) {
dirtyValues[key] = control.value;
}
});
return dirtyValues;
}
sendGainsightEvent(action, props = {}) {
this.gainsightService.triggerEvent(EVENTS.TENANT_MANAGEMENT, {
component: COMPONENTS.TENANT_CUSTOM_PROPERTIES,
action,
...props
});
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CustomPropertiesComponent, deps: [{ token: i1.TenantService }, { token: i2.AlertService }, { token: i3.ActivatedRoute }, { token: i4.CustomPropertiesService }, { token: i2.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: CustomPropertiesComponent, isStandalone: true, selector: "c8y-custom-properties", ngImport: i0, template: "<c8y-title *ngIf=\"tenant\">\n {{ tenant.company }}\n</c8y-title>\n\n<c8y-breadcrumb>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-layers'\"\n [label]=\"'Tenants' | translate\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-layers'\"\n [label]=\"'Subtenants' | translate\"\n [path]=\"'/tenants'\"\n ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<ng-container>\n <form\n [formGroup]=\"customPropsForm\"\n (ngSubmit)=\"onSubmit()\"\n >\n <div class=\"card card--fullpage m-b-0\">\n <div class=\"card-header separator\">\n <div\n class=\"card-title\"\n translate\n >\n Custom properties\n </div>\n </div>\n\n <div class=\"inner-scroll\">\n <div\n class=\"card-block\"\n *ngIf=\"!initialized\"\n >\n <c8y-loading></c8y-loading>\n </div>\n\n <c8y-help src=\"/docs/enterprise-tenant/managing-tenants/#custom-properties\"></c8y-help>\n\n <!-- empty state -->\n <c8y-ui-empty-state\n [icon]=\"'property-script'\"\n [title]=\"'No custom properties to display.' | translate\"\n [subtitle]=\"'Add a new tenant property in Properties library.' | translate\"\n *ngIf=\"fieldDefinitions?.length === 0 && initialized\"\n >\n <p c8y-guide-docs>\n <small translate>\n Find out more in the\n <a c8y-guide-href=\"/docs/enterprise-tenant/managing-tenants/#custom-properties\">\n User guide\n </a>\n .\n </small>\n </p>\n </c8y-ui-empty-state>\n\n <div\n class=\"card-block\"\n *ngIf=\"initialized\"\n >\n <ng-container *ngFor=\"let field of fieldDefinitions\">\n <c8y-custom-property-field\n [fieldDefinition]=\"field\"\n [form]=\"customPropsForm\"\n ></c8y-custom-property-field>\n </ng-container>\n </div>\n </div>\n\n <div\n class=\"card-footer separator\"\n *ngIf=\"initialized\"\n >\n <button\n class=\"btn btn-default\"\n type=\"button\"\n [routerLink]=\"['/tenants']\"\n translate\n data-cy=\"custom-properties--cancel-button\"\n >\n Cancel\n </button>\n <button\n class=\"btn btn-primary\"\n type=\"submit\"\n [disabled]=\"!(!customPropsForm.invalid && customPropsForm.dirty)\"\n translate\n data-cy=\"custom-properties--save-button\"\n >\n Save\n </button>\n </div>\n </div>\n </form>\n</ng-container>\n", dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: CoreModule }, { kind: "component", type: i2.BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: i2.BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "component", type: i2.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "component", type: i2.LoadingComponent, selector: "c8y-loading", inputs: ["layout", "progress", "message"] }, { kind: "component", type: i2.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: i2.GuideHrefDirective, selector: "[c8y-guide-href]", inputs: ["c8y-guide-href"] }, { kind: "component", type: i2.GuideDocsComponent, selector: "[c8y-guide-docs]" }, { kind: "component", type: i2.HelpComponent, selector: "c8y-help", inputs: ["src", "isCollapsed", "priority", "icon"] }, { kind: "directive", type: RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "component", type: CustomPropertyFieldComponent, selector: "c8y-custom-property-field", inputs: ["fieldDefinition", "form"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: CustomPropertiesComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-custom-properties', standalone: true, imports: [
CommonModule,
ReactiveFormsModule,
FormsModule,
CoreModule,
RouterLink,
CustomPropertyFieldComponent
], template: "<c8y-title *ngIf=\"tenant\">\n {{ tenant.company }}\n</c8y-title>\n\n<c8y-breadcrumb>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-layers'\"\n [label]=\"'Tenants' | translate\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-layers'\"\n [label]=\"'Subtenants' | translate\"\n [path]=\"'/tenants'\"\n ></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<ng-container>\n <form\n [formGroup]=\"customPropsForm\"\n (ngSubmit)=\"onSubmit()\"\n >\n <div class=\"card card--fullpage m-b-0\">\n <div class=\"card-header separator\">\n <div\n class=\"card-title\"\n translate\n >\n Custom properties\n </div>\n </div>\n\n <div class=\"inner-scroll\">\n <div\n class=\"card-block\"\n *ngIf=\"!initialized\"\n >\n <c8y-loading></c8y-loading>\n </div>\n\n <c8y-help src=\"/docs/enterprise-tenant/managing-tenants/#custom-properties\"></c8y-help>\n\n <!-- empty state -->\n <c8y-ui-empty-state\n [icon]=\"'property-script'\"\n [title]=\"'No custom properties to display.' | translate\"\n [subtitle]=\"'Add a new tenant property in Properties library.' | translate\"\n *ngIf=\"fieldDefinitions?.length === 0 && initialized\"\n >\n <p c8y-guide-docs>\n <small translate>\n Find out more in the\n <a c8y-guide-href=\"/docs/enterprise-tenant/managing-tenants/#custom-properties\">\n User guide\n </a>\n .\n </small>\n </p>\n </c8y-ui-empty-state>\n\n <div\n class=\"card-block\"\n *ngIf=\"initialized\"\n >\n <ng-container *ngFor=\"let field of fieldDefinitions\">\n <c8y-custom-property-field\n [fieldDefinition]=\"field\"\n [form]=\"customPropsForm\"\n ></c8y-custom-property-field>\n </ng-container>\n </div>\n </div>\n\n <div\n class=\"card-footer separator\"\n *ngIf=\"initialized\"\n >\n <button\n class=\"btn btn-default\"\n type=\"button\"\n [routerLink]=\"['/tenants']\"\n translate\n data-cy=\"custom-properties--cancel-button\"\n >\n Cancel\n </button>\n <button\n class=\"btn btn-primary\"\n type=\"submit\"\n [disabled]=\"!(!customPropsForm.invalid && customPropsForm.dirty)\"\n translate\n data-cy=\"custom-properties--save-button\"\n >\n Save\n </button>\n </div>\n </div>\n </form>\n</ng-container>\n" }]
}], ctorParameters: () => [{ type: i1.TenantService }, { type: i2.AlertService }, { type: i3.ActivatedRoute }, { type: i4.CustomPropertiesService }, { type: i2.GainsightService }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tLXByb3BlcnRpZXMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdGVuYW50cy9jdXN0b20tcHJvcGVydGllcy9jdXN0b20tcHJvcGVydGllcy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi90ZW5hbnRzL2N1c3RvbS1wcm9wZXJ0aWVzL2N1c3RvbS1wcm9wZXJ0aWVzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFDbEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQW9CLGFBQWEsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM5RCxPQUFPLEVBQUUsY0FBYyxFQUFFLFVBQVUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzdELE9BQU8sRUFDTCxZQUFZLEVBQ1osVUFBVSxFQUNWLFdBQVcsRUFDWCxPQUFPLEVBQ1AsZ0JBQWdCLEVBQ2pCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUNMLHVCQUF1QixFQUV4QixNQUFNLGdEQUFnRCxDQUFDO0FBQ3hELE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLDRFQUE0RSxDQUFDO0FBQzFILE9BQU8sRUFFTCxvQ0FBb0MsRUFFckMsTUFBTSxrQkFBa0IsQ0FBQztBQUMxQixPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7Ozs7O0FBRXRDLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxPQUFPLEVBQUUsR0FBRyxvQ0FBb0MsQ0FBQztBQWV0RixNQUFNLE9BQU8seUJBQXlCO0lBTXBDLFlBQ1UsYUFBNEIsRUFDNUIsWUFBMEIsRUFDMUIsY0FBOEIsRUFDOUIsdUJB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QixJQUFJLFdBQ1A7d0JBQ1AsWUFBWTt3QkFDWixtQkFBbUI7d0JBQ25CLFdBQVc7d0JBQ1gsVUFBVTt3QkFDVixVQUFVO3dCQUNWLDRCQUE0QjtxQkFDN0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUdyb3VwLCBSZWFjdGl2ZUZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IElSZXN1bHQsIElUZW5hbnQsIFRlbmFudFNlcnZpY2UgfSBmcm9tICdAYzh5L2NsaWVudCc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSwgUm91dGVyTGluayB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQge1xuICBBbGVydFNlcnZpY2UsXG4gIENvcmVNb2R1bGUsXG4gIEZvcm1zTW9kdWxlLFxuICBnZXR0ZXh0LFxuICBHYWluc2lnaHRTZXJ2aWNlXG59IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHtcbiAgQ3VzdG9tUHJvcGVydGllc1NlcnZpY2UsXG4gIFRlbmFudEN1c3RvbVByb3BlcnR5RmllbGRcbn0gZnJvbSAnLi4vY3VzdG9tLXByb3BlcnRpZXMvY3VzdG9tLXByb3BlcnRpZXMuc2VydmljZSc7XG5pbXBvcnQgeyBDdXN0b21Qcm9wZXJ0eUZpZWxkQ29tcG9uZW50IH0gZnJvbSAnLi4vY3VzdG9tLXByb3BlcnRpZXMvY3VzdG9tLXByb3BlcnR5LWZpZWxkL2N1c3RvbS1wcm9wZXJ0eS1maWVsZC5jb21wb25lbnQnO1xuaW1wb3J0IHtcbiAgVGVuYW50TWFuYWdlbWVudEFjdGlvblR5cGUsXG4gIFBST0RVQ1RfRVhQRVJJRU5DRV9URU5BTlRfTUFOQUdFTUVOVCxcbiAgVGVuYW50TWFuYWdlbWVudFJlc3VsdFR5cGVcbn0gZnJvbSAnLi4vdGVuYW50cy5tb2RlbCc7XG5pbXBvcnQgeyB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5jb25zdCB7IEFDVElPTlMsIEVWRU5UUywgQ09NUE9ORU5UUywgUkVTVUxUUyB9ID0gUFJPRFVDVF9FWFBFUklFTkNFX1RFTkFOVF9NQU5BR0VNRU5UO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktY3VzdG9tLXByb3BlcnRpZXMnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIFJlYWN0aXZlRm9ybXNNb2R1bGUsXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgQ29yZU1vZHVsZSxcbiAgICBSb3V0ZXJMaW5rLFxuICAgIEN1c3RvbVByb3BlcnR5RmllbGRDb21wb25lbnRcbiAgXSxcbiAgdGVtcGxhdGVVcmw6ICcuL2N1c3RvbS1wcm9wZXJ0aWVzLmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBDdXN0b21Qcm9wZXJ0aWVzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgZmllbGREZWZpbml0aW9uczogVGVuYW50Q3VzdG9tUHJvcGVydHlGaWVsZFtdO1xuICBjdXN0b21Qcm9wc0Zvcm06IEZvcm1Hcm91cCA9IG5ldyBGb3JtR3JvdXAoe30pO1xuICB0ZW5hbnQ6IElUZW5hbnQgfCBudWxsID0gbnVsbDtcbiAgaW5pdGlhbGl6ZWQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHRlbmFudFNlcnZpY2U6IFRlbmFudFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBhbGVydFNlcnZpY2U6IEFsZXJ0U2VydmljZSxcbiAgICBwcml2YXRlIGFjdGl2YXRlZFJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSxcbiAgICBwcml2YXRlIGN1c3RvbVByb3BlcnRpZXNTZXJ2aWNlOiBDdXN0b21Qcm9wZXJ0aWVzU2VydmljZSxcbiAgICBwcml2YXRlIGdhaW5zaWdodFNlcnZpY2U6IEdhaW5zaWdodFNlcnZpY2VcbiAgKSB7fVxuXG4gIGFzeW5jIG5nT25Jbml0KCkge1xuICAgIGF3YWl0IHRoaXMubG9hZFRlbmFudERldGFpbHMoKTtcbiAgICBjb25zdCB7IGZvcm0sIGZpZWxkcyB9ID0gYXdhaXQgdGhpcy5jdXN0b21Qcm9wZXJ0aWVzU2VydmljZS5nZXRGb3JtQW5kRmllbGRMaXN0KCk7XG4gICAgdGhpcy5jdXN0b21Qcm9wc0Zvcm0gPSBmb3JtO1xuICAgIHRoaXMuZmllbGREZWZpbml0aW9ucyA9IGZpZWxkcztcbiAgICB0aGlzLmFwcGx5VmFsdWVzRnJvbVRlbmFudCgpO1xuICAgIHRoaXMuaW5pdGlhbGl6ZWQgPSB0cnVlO1xuXG4gICAgdGhpcy5zZW5kR2FpbnNpZ2h0RXZlbnQoQUNUSU9OUy5URU5BTlRfQ1VTVE9NX1BST1BFUlRJRVNfT1BFTkVEKTtcblxuICAgIHRoaXMuY3VzdG9tUHJvcHNGb3JtLnZhbHVlQ2hhbmdlcy5waXBlKHRha2UoMSkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLnNlbmRHYWluc2lnaHRFdmVudChBQ1RJT05TLlRFTkFOVF9DVVNUT01fUFJPUEVSVElFU19TVEFSVEVEX0NIQU5HSU5HKTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIG9uU3VibWl0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLmN1c3RvbVByb3BzRm9ybS5pbnZhbGlkIHx8ICF0aGlzLnRlbmFudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHVwZGF0ZWRUZW5hbnQ6IElUZW5hbnQgPSB7XG4gICAgICAuLi50aGlzLnRlbmFudCxcbiAgICAgIGN1c3RvbVByb3BlcnRpZXM6IHtcbiAgICAgICAgLi4udGhpcy50ZW5hbnQuY3VzdG9tUHJvcGVydGllcyxcbiAgICAgICAgLi4udGhpcy5nZXREaXJ0eVZhbHVlcygpXG4gICAgICB9XG4gICAgfTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLnRlbmFudFNlcnZpY2UudXBkYXRlKHVwZGF0ZWRUZW5hbnQpO1xuICAgICAgdGhpcy5hbGVydFNlcnZpY2Uuc3VjY2VzcyhnZXR0ZXh0KCdDdXN0b20gcHJvcGVydGllcyB2YWx1ZXMgc2F2ZWQuJykpO1xuICAgICAgdGhpcy5zZW5kR2FpbnNpZ2h0RXZlbnQoQUNUSU9OUy5URU5BTlRfQ1VTVE9NX1BST1BFUlRJRVNfU0FWRUQsIHsgcmVzdWx0OiBSRVNVTFRTLlNVQ0NFU1MgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMuYWxlcnRTZXJ2aWNlLmFkZFNlcnZlckZhaWx1cmUoZXJyb3IpO1xuICAgICAgdGhpcy5zZW5kR2FpbnNpZ2h0RXZlbnQoQUNUSU9OUy5URU5BTlRfQ1VTVE9NX1BST1BFUlRJRVNfU0FWRUQsIHtcbiAgICAgICAgcmVzdWx0OiBSRVNVTFRTLkZBSUxVUkUsXG4gICAgICAgIGVycm9yXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxvYWRUZW5hbnREZXRhaWxzKCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXN1bHQ6IElSZXN1bHQ8SVRlbmFudD4gPSBhd2FpdCB0aGlzLnRlbmFudFNlcnZpY2UuZGV0YWlsKFxuICAgICAgICB0aGlzLmFjdGl2YXRlZFJvdXRlLnNuYXBzaG90LnBhcmVudC5kYXRhLmNvbnRleHREYXRhLmlkXG4gICAgICApO1xuICAgICAgdGhpcy50ZW5hbnQgPSByZXN1bHQuZGF0YTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhpcy5hbGVydFNlcnZpY2UuYWRkU2VydmVyRmFpbHVyZShlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhcHBseVZhbHVlc0Zyb21UZW5hbnQoKTogdm9pZCB7XG4gICAgY29uc3QgY3VzdG9tUHJvcHMgPSB0aGlzLnRlbmFudD8uY3VzdG9tUHJvcGVydGllcyB8fCB7fTtcbiAgICB0aGlzLmN1c3RvbVByb3BzRm9ybS5wYXRjaFZhbHVlKGN1c3RvbVByb3BzKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0RGlydHlWYWx1ZXMoKTogeyBba2V5OiBzdHJpbmddOiB1bmtub3duIH0ge1xuICAgIGNvbnN0IGRpcnR5VmFsdWVzOiB7IFtrZXk6IHN0cmluZ106IHVua25vd24gfSA9IHt9O1xuICAgIE9iamVjdC5rZXlzKHRoaXMuY3VzdG9tUHJvcHNGb3JtLmNvbnRyb2xzKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICBjb25zdCBjb250cm9sID0gdGhpcy5jdXN0b21Qcm9wc0Zvcm0uY29udHJvbHNba2V5XTtcbiAgICAgIGlmIChjb250cm9sICYmIGNvbnRyb2wuZGlydHkgJiYgY29udHJvbC52YWx1ZSAhPT0gbnVsbCkge1xuICAgICAgICBkaXJ0eVZhbHVlc1trZXldID0gY29udHJvbC52YWx1ZTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiBkaXJ0eVZhbHVlcztcbiAgfVxuXG4gIHByaXZhdGUgc2VuZEdhaW5zaWdodEV2ZW50KFxuICAgIGFjdGlvbjogVGVuYW50TWFuYWdlbWVudEFjdGlvblR5cGUsXG4gICAgcHJvcHM6IHsgcmVzdWx0PzogVGVuYW50TWFuYWdlbWVudFJlc3VsdFR5cGU7IGVycm9yPzogdW5rbm93biB9ID0ge31cbiAgKSB7XG4gICAgdGhpcy5nYWluc2lnaHRTZXJ2aWNlLnRyaWdnZXJFdmVudChFVkVOVFMuVEVOQU5UX01BTkFHRU1FTlQsIHtcbiAgICAgIGNvbXBvbmVudDogQ09NUE9ORU5UUy5URU5BTlRfQ1VTVE9NX1BST1BFUlRJRVMsXG4gICAgICBhY3Rpb24sXG4gICAgICAuLi5wcm9wc1xuICAgIH0pO1xuICB9XG59XG4iLCI8Yzh5LXRpdGxlICpuZ0lmPVwidGVuYW50XCI+XG4gIHt7IHRlbmFudC5jb21wYW55IH19XG48L2M4eS10aXRsZT5cblxuPGM4eS1icmVhZGNydW1iPlxuICA8Yzh5LWJyZWFkY3J1bWItaXRlbVxuICAgIFtpY29uXT1cIidjOHktbGF5ZXJzJ1wiXG4gICAgW2xhYmVsXT1cIidUZW5hbnRzJyB8IHRyYW5zbGF0ZVwiXG4gID48L2M4eS1icmVhZGNydW1iLWl0ZW0+XG4gIDxjOHktYnJlYWRjcnVtYi1pdGVtXG4gICAgW2ljb25dPVwiJ2M4eS1sYXllcnMnXCJcbiAgICBbbGFiZWxdPVwiJ1N1YnRlbmFudHMnIHwgdHJhbnNsYXRlXCJcbiAgICBbcGF0aF09XCInL3RlbmFudHMnXCJcbiAgPjwvYzh5LWJyZWFkY3J1bWItaXRlbT5cbjwvYzh5LWJyZWFkY3J1bWI+XG5cbjxuZy1jb250YWluZXI+XG4gIDxmb3JtXG4gICAgW2Zvcm1Hcm91cF09XCJjdXN0b21Qcm9wc0Zvcm1cIlxuICAgIChuZ1N1Ym1pdCk9XCJvblN1Ym1pdCgpXCJcbiAgPlxuICAgIDxkaXYgY2xhc3M9XCJjYXJkIGNhcmQtLWZ1bGxwYWdlIG0tYi0wXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1oZWFkZXIgc2VwYXJhdG9yXCI+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICBjbGFzcz1cImNhcmQtdGl0bGVcIlxuICAgICAgICAgIHRyYW5zbGF0ZVxuICAgICAgICA+XG4gICAgICAgICAgQ3VzdG9tIHByb3BlcnRpZXNcbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cImlubmVyLXNjcm9sbFwiPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3M9XCJjYXJkLWJsb2NrXCJcbiAgICAgICAgICAqbmdJZj1cIiFpbml0aWFsaXplZFwiXG4gICAgICAgID5cbiAgICAgICAgICA8Yzh5LWxvYWRpbmc+PC9jOHktbG9hZGluZz5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGM4eS1oZWxwIHNyYz1cIi9kb2NzL2VudGVycHJpc2UtdGVuYW50L21hbmFnaW5nLXRlbmFudHMvI2N1c3RvbS1wcm9wZXJ0aWVzXCI+PC9jOHktaGVscD5cblxuICAgICAgICA8IS0tIGVtcHR5IHN0YXRlIC0tPlxuICAgICAgICA8Yzh5LXVpLWVtcHR5LXN0YXRlXG4gICAgICAgICAgW2ljb25dPVwiJ3Byb3BlcnR5LXNjcmlwdCdcIlxuICAgICAgICAgIFt0aXRsZV09XCInTm8gY3VzdG9tIHByb3BlcnRpZXMgdG8gZGlzcGxheS4nIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICBbc3VidGl0bGVdPVwiJ0FkZCBhIG5ldyB0ZW5hbnQgcHJvcGVydHkgaW4gUHJvcGVydGllcyBsaWJyYXJ5LicgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICpuZ0lmPVwiZmllbGREZWZpbml0aW9ucz8ubGVuZ3RoID09PSAwICYmIGluaXRpYWxpemVkXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxwIGM4eS1ndWlkZS1kb2NzPlxuICAgICAgICAgICAgPHNtYWxsIHRyYW5zbGF0ZT5cbiAgICAgICAgICAgICAgRmluZCBvdXQgbW9yZSBpbiB0aGVcbiAgICAgICAgICAgICAgPGEgYzh5LWd1aWRlLWhyZWY9XCIvZG9jcy9lbnRlcnByaXNlLXRlbmFudC9tYW5hZ2luZy10ZW5hbnRzLyNjdXN0b20tcHJvcGVydGllc1wiPlxuICAgICAgICAgICAgICAgIFVzZXIgZ3VpZGVcbiAgICAgICAgICAgICAgPC9hPlxuICAgICAgICAgICAgICAuXG4gICAgICAgICAgICA8L3NtYWxsPlxuICAgICAgICAgIDwvcD5cbiAgICAgICAgPC9jOHktdWktZW1wdHktc3RhdGU+XG5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzPVwiY2FyZC1ibG9ja1wiXG4gICAgICAgICAgKm5nSWY9XCJpbml0aWFsaXplZFwiXG4gICAgICAgID5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBmaWVsZCBvZiBmaWVsZERlZmluaXRpb25zXCI+XG4gICAgICAgICAgICA8Yzh5LWN1c3RvbS1wcm9wZXJ0eS1maWVsZFxuICAgICAgICAgICAgICBbZmllbGREZWZpbml0aW9uXT1cImZpZWxkXCJcbiAgICAgICAgICAgICAgW2Zvcm1dPVwiY3VzdG9tUHJvcHNGb3JtXCJcbiAgICAgICAgICAgID48L2M4eS1jdXN0b20tcHJvcGVydHktZmllbGQ+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJjYXJkLWZvb3RlciBzZXBhcmF0b3JcIlxuICAgICAgICAqbmdJZj1cImluaXRpYWxpemVkXCJcbiAgICAgID5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0XCJcbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBbcm91dGVyTGlua109XCJbJy90ZW5hbnRzJ11cIlxuICAgICAgICAgIHRyYW5zbGF0ZVxuICAgICAgICAgIGRhdGEtY3k9XCJjdXN0b20tcHJvcGVydGllcy0tY2FuY2VsLWJ1dHRvblwiXG4gICAgICAgID5cbiAgICAgICAgICBDYW5jZWxcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiXG4gICAgICAgICAgdHlwZT1cInN1Ym1pdFwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cIiEoIWN1c3RvbVByb3BzRm9ybS5pbnZhbGlkICYmIGN1c3RvbVByb3BzRm9ybS5kaXJ0eSlcIlxuICAgICAgICAgIHRyYW5zbGF0ZVxuICAgICAgICAgIGRhdGEtY3k9XCJjdXN0b20tcHJvcGVydGllcy0tc2F2ZS1idXR0b25cIlxuICAgICAgICA+XG4gICAgICAgICAgU2F2ZVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Zvcm0+XG48L25nLWNvbnRhaW5lcj5cbiJdfQ==