@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
115 lines • 30.7 kB
JavaScript
import { Component, Input, ViewChild } from '@angular/core';
import { ApplicationService, ApplicationAvailability } from '@c8y/client';
import { AlertService, DropAreaComponent, WizardComponent, gettext } from '@c8y/ngx-components';
import { EcosystemService } from './ecosystem.service';
import { ERROR_MESSAGES } from './ecosystem.constants';
import { TranslateService } from '@ngx-translate/core';
import { PackageAvailabilityService } from './package-availability.service';
import * as i0 from "@angular/core";
import * as i1 from "./ecosystem.service";
import * as i2 from "@c8y/ngx-components";
import * as i3 from "@c8y/client";
import * as i4 from "@ngx-translate/core";
import * as i5 from "./package-availability.service";
import * as i6 from "@angular/common";
import * as i7 from "@angular/forms";
import * as i8 from "ngx-bootstrap/popover";
export class AddApplicationComponent {
constructor(ecosystemService, alertService, applicationService, wizardComponent, translateService, packageAvailability) {
this.ecosystemService = ecosystemService;
this.alertService = alertService;
this.applicationService = applicationService;
this.wizardComponent = wizardComponent;
this.translateService = translateService;
this.packageAvailability = packageAvailability;
this.canGoBack = false;
this.applicationType = 'application';
this.canOpenInBrowser = false;
this.selectedAvailability = ApplicationAvailability.PRIVATE;
this.availabilityHelpPopoverText = gettext(`
<p class="m-b-8"><b>Shared</b> availability will make the package available to all subtenants without explicitly subscribing the package.</p>
<p class="m-b-8"><b>Market</b> availability will make the package available to your own tenant and needs to be subscribed to subtenants individually.</p>
<p class="m-b-8"><b>Private</b> availability will make the package only available to your own tenant.</p>
`);
this.uploadCanceled = false;
}
get progress() {
return this.ecosystemService.progress;
}
onFileDroppedEvent(event) {
if (event && event.length > 0) {
const file = event[0].file;
this.onFile(file);
}
}
async onFile(file) {
this.isLoading = true;
this.errorMessage = null;
this.progress.next(0);
try {
this.createdApp = await this.createApplicationHandler(file);
if (this.applicationType === 'package') {
this.createdApp = await this.packageAvailability.setAvailability(this.createdApp, this.selectedAvailability);
}
await this.uploadApplicationHandler(file, this.createdApp);
this.canOpenInBrowser = this.ecosystemService.canOpenAppInBrowser(this.createdApp);
this.isAppCreated = true;
}
catch (ex) {
this.ecosystemService.cancelAppCreation(this.createdApp);
this.createdApp = null;
this.dropAreaComponent.onDelete();
// prepare translation of static message if it exists
const staticErrorMessage = ERROR_MESSAGES[ex.message] && this.translateService.instant(ERROR_MESSAGES[ex.message]);
// if there is no static message, use dynamic one from the exception
this.errorMessage = staticErrorMessage ?? ex.message;
if (!this.errorMessage && !this.uploadCanceled) {
this.alertService.addServerFailure(ex);
}
}
this.progress.next(100);
this.isLoading = false;
}
getHref(app) {
return this.applicationService.getHref(app);
}
cancel() {
this.cancelFileUpload();
this.wizardComponent.close();
}
done() {
this.wizardComponent.close();
}
back() {
this.wizardComponent.reset();
}
cancelFileUpload() {
this.uploadCanceled = true;
this.ecosystemService.cancelAppCreation(this.createdApp);
this.createdApp = null;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AddApplicationComponent, deps: [{ token: i1.EcosystemService }, { token: i2.AlertService }, { token: i3.ApplicationService }, { token: i2.WizardComponent }, { token: i4.TranslateService }, { token: i5.PackageAvailabilityService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AddApplicationComponent, selector: "c8y-add-application", inputs: { headerText: "headerText", headerIcon: "headerIcon", successText: "successText", createApplicationHandler: "createApplicationHandler", uploadApplicationHandler: "uploadApplicationHandler", canGoBack: "canGoBack", applicationType: "applicationType" }, viewQueries: [{ propertyName: "dropAreaComponent", first: true, predicate: DropAreaComponent, descendants: true }], ngImport: i0, template: "<c8y-wizard-header>\n <i [c8yIcon]=\"headerIcon\"></i>\n <h4 id=\"modal-title\">{{ headerText | translate }}</h4>\n</c8y-wizard-header>\n\n<c8y-wizard-body>\n <p class=\"p-16 text-center text-medium separator-bottom sticky-top bg-component\">\n {{ 'Upload a *.zip file' | translate }}\n </p>\n <c8y-form-group\n class=\"m-t-16 m-l-auto m-r-auto\"\n style=\"max-width: 265px\"\n id=\"modal-body\"\n *ngIf=\"!isAppCreated; else appCreated\"\n [hasError]=\"!!errorMessage\"\n >\n <c8y-drop-area\n class=\"drop-area\"\n (dropped)=\"onFileDroppedEvent($event)\"\n [accept]=\"'.zip'\"\n [loading]=\"isLoading\"\n [maxAllowedFiles]=\"1\"\n [progress]=\"progress | async\"\n ></c8y-drop-area>\n <c8y-messages>\n <c8y-message *ngIf=\"errorMessage\">\n {{ errorMessage | translate }}\n </c8y-message>\n </c8y-messages>\n </c8y-form-group>\n <div class=\"card-block\" *ngIf=\"applicationType === 'package'\">\n <c8y-form-group>\n <label\n class=\"m-r-8 d-inline-block\"\n id=\"availabilitySelectorLabel\"\n for=\"availabilitySelector\"\n >\n {{ 'Select extension availability' | translate }}\n </label>\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"availabilityHelpPopover\"\n placement=\"top\"\n triggers=\"focus\"\n type=\"button\"\n ></button>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n id=\"availabilitySelector\"\n name=\"availabilitySelector\"\n [(ngModel)]=\"selectedAvailability\"\n >\n <option\n *ngFor=\"let availability of packageAvailability.availabilities\"\n [ngValue]=\"availability.value\"\n >\n {{ availability.label | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n <ng-template #appCreated>\n <div\n class=\"d-flex a-i-center j-c-center\"\n style=\"min-height: 285px\"\n >\n <c8y-operation-result\n class=\"lead\"\n type=\"success\"\n text=\"{{ successText | translate }}\"\n [vertical]=\"true\"\n [size]=\"84\"\n ></c8y-operation-result>\n </div>\n </ng-template>\n <ng-template #availabilityHelpPopover>\n <div [innerHtml]=\"availabilityHelpPopoverText | translate\"></div>\n </ng-template>\n</c8y-wizard-body>\n\n<c8y-wizard-footer>\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Back' | translate }}\"\n type=\"button\"\n (click)=\"back()\"\n *ngIf=\"!isAppCreated && canGoBack\"\n translate\n >\n Back\n </button>\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n *ngIf=\"!isAppCreated\"\n translate\n >\n Cancel\n </button>\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Done' | translate }}\"\n type=\"button\"\n (click)=\"done()\"\n *ngIf=\"isAppCreated\"\n translate\n >\n Done\n </button>\n <a\n class=\"btn btn-primary\"\n title=\"{{ 'Open' | translate }}\"\n target=\"_blank\"\n (click)=\"$event.stopPropagation()\"\n *ngIf=\"isAppCreated && canOpenInBrowser\"\n [href]=\"getHref(createdApp)\"\n rel=\"noopener noreferrer\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"external-link\"\n ></i>\n {{ 'Open' | translate }}\n </a>\n</c8y-wizard-footer>\n", dependencies: [{ kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.OperationResultComponent, selector: "c8y-operation-result", inputs: ["text", "vertical", "size", "type"] }, { kind: "component", type: i2.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: i7.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i7.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i2.FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: i2.MessageDirective, selector: "c8y-message", inputs: ["name", "text"] }, { kind: "component", type: i2.MessagesComponent, selector: "c8y-messages", inputs: ["show", "defaults", "helpMessage"] }, { kind: "component", type: i2.WizardHeaderComponent, selector: "c8y-wizard-header" }, { kind: "component", type: i2.WizardBodyComponent, selector: "c8y-wizard-body" }, { kind: "component", type: i2.WizardFooterComponent, selector: "c8y-wizard-footer" }, { kind: "directive", type: i8.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: i2.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AddApplicationComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-add-application', template: "<c8y-wizard-header>\n <i [c8yIcon]=\"headerIcon\"></i>\n <h4 id=\"modal-title\">{{ headerText | translate }}</h4>\n</c8y-wizard-header>\n\n<c8y-wizard-body>\n <p class=\"p-16 text-center text-medium separator-bottom sticky-top bg-component\">\n {{ 'Upload a *.zip file' | translate }}\n </p>\n <c8y-form-group\n class=\"m-t-16 m-l-auto m-r-auto\"\n style=\"max-width: 265px\"\n id=\"modal-body\"\n *ngIf=\"!isAppCreated; else appCreated\"\n [hasError]=\"!!errorMessage\"\n >\n <c8y-drop-area\n class=\"drop-area\"\n (dropped)=\"onFileDroppedEvent($event)\"\n [accept]=\"'.zip'\"\n [loading]=\"isLoading\"\n [maxAllowedFiles]=\"1\"\n [progress]=\"progress | async\"\n ></c8y-drop-area>\n <c8y-messages>\n <c8y-message *ngIf=\"errorMessage\">\n {{ errorMessage | translate }}\n </c8y-message>\n </c8y-messages>\n </c8y-form-group>\n <div class=\"card-block\" *ngIf=\"applicationType === 'package'\">\n <c8y-form-group>\n <label\n class=\"m-r-8 d-inline-block\"\n id=\"availabilitySelectorLabel\"\n for=\"availabilitySelector\"\n >\n {{ 'Select extension availability' | translate }}\n </label>\n <button\n class=\"btn-help btn-help--sm\"\n [attr.aria-label]=\"'Help' | translate\"\n [popover]=\"availabilityHelpPopover\"\n placement=\"top\"\n triggers=\"focus\"\n type=\"button\"\n ></button>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n id=\"availabilitySelector\"\n name=\"availabilitySelector\"\n [(ngModel)]=\"selectedAvailability\"\n >\n <option\n *ngFor=\"let availability of packageAvailability.availabilities\"\n [ngValue]=\"availability.value\"\n >\n {{ availability.label | translate }}\n </option>\n </select>\n </div>\n </c8y-form-group>\n </div>\n <ng-template #appCreated>\n <div\n class=\"d-flex a-i-center j-c-center\"\n style=\"min-height: 285px\"\n >\n <c8y-operation-result\n class=\"lead\"\n type=\"success\"\n text=\"{{ successText | translate }}\"\n [vertical]=\"true\"\n [size]=\"84\"\n ></c8y-operation-result>\n </div>\n </ng-template>\n <ng-template #availabilityHelpPopover>\n <div [innerHtml]=\"availabilityHelpPopoverText | translate\"></div>\n </ng-template>\n</c8y-wizard-body>\n\n<c8y-wizard-footer>\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Back' | translate }}\"\n type=\"button\"\n (click)=\"back()\"\n *ngIf=\"!isAppCreated && canGoBack\"\n translate\n >\n Back\n </button>\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Cancel' | translate }}\"\n type=\"button\"\n (click)=\"cancel()\"\n *ngIf=\"!isAppCreated\"\n translate\n >\n Cancel\n </button>\n <button\n class=\"btn btn-default\"\n title=\"{{ 'Done' | translate }}\"\n type=\"button\"\n (click)=\"done()\"\n *ngIf=\"isAppCreated\"\n translate\n >\n Done\n </button>\n <a\n class=\"btn btn-primary\"\n title=\"{{ 'Open' | translate }}\"\n target=\"_blank\"\n (click)=\"$event.stopPropagation()\"\n *ngIf=\"isAppCreated && canOpenInBrowser\"\n [href]=\"getHref(createdApp)\"\n rel=\"noopener noreferrer\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"external-link\"\n ></i>\n {{ 'Open' | translate }}\n </a>\n</c8y-wizard-footer>\n" }]
}], ctorParameters: () => [{ type: i1.EcosystemService }, { type: i2.AlertService }, { type: i3.ApplicationService }, { type: i2.WizardComponent }, { type: i4.TranslateService }, { type: i5.PackageAvailabilityService }], propDecorators: { headerText: [{
type: Input
}], headerIcon: [{
type: Input
}], successText: [{
type: Input
}], createApplicationHandler: [{
type: Input
}], uploadApplicationHandler: [{
type: Input
}], canGoBack: [{
type: Input
}], applicationType: [{
type: Input
}], dropAreaComponent: [{
type: ViewChild,
args: [DropAreaComponent]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkLWFwcGxpY2F0aW9uLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2Vjb3N5c3RlbS9zaGFyZWQvYWRkLWFwcGxpY2F0aW9uLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL2Vjb3N5c3RlbS9zaGFyZWQvYWRkLWFwcGxpY2F0aW9uLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM1RCxPQUFPLEVBQUUsa0JBQWtCLEVBQWdCLHVCQUF1QixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3hGLE9BQU8sRUFBRSxZQUFZLEVBQUUsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRWhHLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQzs7Ozs7Ozs7OztBQU81RSxNQUFNLE9BQU8sdUJBQXVCO0lBd0JsQyxZQUNVLGdCQUFrQyxFQUNsQyxZQUEwQixFQUMxQixrQkFBc0MsRUFDdEMsZUFBZ0MsRUFDaEMsZ0JBQWtDLEVBQ2xDLG1CQUErQztRQUwvQyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ2xDLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFDdEMsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUE0QjtRQXhCaEQsY0FB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QUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQy9CLENBQUM7SUFFRCxJQUFJO1FBQ0YsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUMvQixDQUFDO0lBRUQsSUFBSTtRQUNGLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDL0IsQ0FBQztJQUVPLGdCQUFnQjtRQUN0QixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztRQUMzQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3pELElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO0lBQ3pCLENBQUM7K0dBbEdVLHVCQUF1QjttR0FBdkIsdUJBQXVCLGtYQVN2QixpQkFBaUIsZ0RDdkI5Qix5K0dBa0lBOzs0RkRwSGEsdUJBQXVCO2tCQUpuQyxTQUFTOytCQUNFLHFCQUFxQjt1UEFJdEIsVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csd0JBQXdCO3NCQUFoQyxLQUFLO2dCQUNHLHdCQUF3QjtzQkFBaEMsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLGVBQWU7c0JBQXZCLEtBQUs7Z0JBRXdCLGlCQUFpQjtzQkFBOUMsU0FBUzt1QkFBQyxpQkFBaUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEFwcGxpY2F0aW9uU2VydmljZSwgSUFwcGxpY2F0aW9uLCBBcHBsaWNhdGlvbkF2YWlsYWJpbGl0eSB9IGZyb20gJ0BjOHkvY2xpZW50JztcbmltcG9ydCB7IEFsZXJ0U2VydmljZSwgRHJvcEFyZWFDb21wb25lbnQsIFdpemFyZENvbXBvbmVudCwgZ2V0dGV4dCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBFY29zeXN0ZW1TZXJ2aWNlIH0gZnJvbSAnLi9lY29zeXN0ZW0uc2VydmljZSc7XG5pbXBvcnQgeyBFUlJPUl9NRVNTQUdFUyB9IGZyb20gJy4vZWNvc3lzdGVtLmNvbnN0YW50cyc7XG5pbXBvcnQgeyBUcmFuc2xhdGVTZXJ2aWNlIH0gZnJvbSAnQG5neC10cmFuc2xhdGUvY29yZSc7XG5pbXBvcnQgeyBQYWNrYWdlQXZhaWxhYmlsaXR5U2VydmljZSB9IGZyb20gJy4vcGFja2FnZS1hdmFpbGFiaWxpdHkuc2VydmljZSc7XG5pbXBvcnQgeyBTdXBwb3J0ZWRJY29uc1N1Z2dlc3Rpb25zIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9pY29uLXNlbGVjdG9yL2ljb25zJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYzh5LWFkZC1hcHBsaWNhdGlvbicsXG4gIHRlbXBsYXRlVXJsOiAnLi9hZGQtYXBwbGljYXRpb24uY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIEFkZEFwcGxpY2F0aW9uQ29tcG9uZW50IHtcbiAgQElucHV0KCkgaGVhZGVyVGV4dDogc3RyaW5nO1xuICBASW5wdXQoKSBoZWFkZXJJY29uOiBTdXBwb3J0ZWRJY29uc1N1Z2dlc3Rpb25zO1xuICBASW5wdXQoKSBzdWNjZXNzVGV4dDogc3RyaW5nO1xuICBASW5wdXQoKSBjcmVhdGVBcHBsaWNhdGlvbkhhbmRsZXI6IGFueTtcbiAgQElucHV0KCkgdXBsb2FkQXBwbGljYXRpb25IYW5kbGVyOiBhbnk7XG4gIEBJbnB1dCgpIGNhbkdvQmFjayA9IGZhbHNlO1xuICBASW5wdXQoKSBhcHBsaWNhdGlvblR5cGU6ICdhcHBsaWNhdGlvbicgfCAncGFja2FnZScgPSAnYXBwbGljYXRpb24nO1xuXG4gIEBWaWV3Q2hpbGQoRHJvcEFyZWFDb21wb25lbnQpIGRyb3BBcmVhQ29tcG9uZW50O1xuXG4gIGlzTG9hZGluZzogYm9vbGVhbjtcbiAgaXNBcHBDcmVhdGVkOiBib29sZWFuO1xuICBjcmVhdGVkQXBwOiBJQXBwbGljYXRpb247XG4gIGNhbk9wZW5JbkJyb3dzZXIgPSBmYWxzZTtcbiAgZXJyb3JNZXNzYWdlOiBzdHJpbmc7XG4gIHNlbGVjdGVkQXZhaWxhYmlsaXR5ID0gQXBwbGljYXRpb25BdmFpbGFiaWxpdHkuUFJJVkFURTtcbiAgYXZhaWxhYmlsaXR5SGVscFBvcG92ZXJUZXh0ID0gZ2V0dGV4dChgXG4gICAgICA8cCBjbGFzcz1cIm0tYi04XCI+PGI+U2hhcmVkPC9iPiBhdmFpbGFiaWxpdHkgd2lsbCBtYWtlIHRoZSBwYWNrYWdlIGF2YWlsYWJsZSB0byBhbGwgc3VidGVuYW50cyB3aXRob3V0IGV4cGxpY2l0bHkgc3Vic2NyaWJpbmcgdGhlIHBhY2thZ2UuPC9wPlxuICAgICAgPHAgY2xhc3M9XCJtLWItOFwiPjxiPk1hcmtldDwvYj4gYXZhaWxhYmlsaXR5IHdpbGwgbWFrZSB0aGUgcGFja2FnZSBhdmFpbGFibGUgdG8geW91ciBvd24gdGVuYW50IGFuZCBuZWVkcyB0byBiZSBzdWJzY3JpYmVkIHRvIHN1YnRlbmFudHMgaW5kaXZpZHVhbGx5LjwvcD5cbiAgICAgIDxwIGNsYXNzPVwibS1iLThcIj48Yj5Qcml2YXRlPC9iPiBhdmFpbGFiaWxpdHkgd2lsbCBtYWtlIHRoZSBwYWNrYWdlIG9ubHkgYXZhaWxhYmxlIHRvIHlvdXIgb3duIHRlbmFudC48L3A+XG4gIGApO1xuICBwcml2YXRlIHVwbG9hZENhbmNlbGVkID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBlY29zeXN0ZW1TZXJ2aWNlOiBFY29zeXN0ZW1TZXJ2aWNlLFxuICAgIHByaXZhdGUgYWxlcnRTZXJ2aWNlOiBBbGVydFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBhcHBsaWNhdGlvblNlcnZpY2U6IEFwcGxpY2F0aW9uU2VydmljZSxcbiAgICBwcml2YXRlIHdpemFyZENvbXBvbmVudDogV2l6YXJkQ29tcG9uZW50LFxuICAgIHByaXZhdGUgdHJhbnNsYXRlU2VydmljZTogVHJhbnNsYXRlU2VydmljZSxcbiAgICBwcml2YXRlIHBhY2thZ2VBdmFpbGFiaWxpdHk6IFBhY2thZ2VBdmFpbGFiaWxpdHlTZXJ2aWNlXG4gICkge31cblxuICBnZXQgcHJvZ3Jlc3MoKTogQmVoYXZpb3JTdWJqZWN0PG51bWJlcj4ge1xuICAgIHJldHVybiB0aGlzLmVjb3N5c3RlbVNlcnZpY2UucHJvZ3Jlc3M7XG4gIH1cblxuICBvbkZpbGVEcm9wcGVkRXZlbnQoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQgJiYgZXZlbnQubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3QgZmlsZSA9IGV2ZW50WzBdLmZpbGU7XG4gICAgICB0aGlzLm9uRmlsZShmaWxlKTtcbiAgICB9XG4gIH1cblxuICBhc3luYyBvbkZpbGUoZmlsZTogRmlsZSkge1xuICAgIHRoaXMuaXNMb2FkaW5nID0gdHJ1ZTtcbiAgICB0aGlzLmVycm9yTWVzc2FnZSA9IG51bGw7XG4gICAgdGhpcy5wcm9ncmVzcy5uZXh0KDApO1xuXG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuY3JlYXRlZEFwcCA9IGF3YWl0IHRoaXMuY3JlYXRlQXBwbGljYXRpb25IYW5kbGVyKGZpbGUpO1xuICAgICAgaWYgKHRoaXMuYXBwbGljYXRpb25UeXBlID09PSAncGFja2FnZScpIHtcbiAgICAgICAgdGhpcy5jcmVhdGVkQXBwID0gYXdhaXQgdGhpcy5wYWNrYWdlQXZhaWxhYmlsaXR5LnNldEF2YWlsYWJpbGl0eShcbiAgICAgICAgICB0aGlzLmNyZWF0ZWRBcHAsXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZEF2YWlsYWJpbGl0eVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgYXdhaXQgdGhpcy51cGxvYWRBcHBsaWNhdGlvbkhhbmRsZXIoZmlsZSwgdGhpcy5jcmVhdGVkQXBwKTtcbiAgICAgIHRoaXMuY2FuT3BlbkluQnJvd3NlciA9IHRoaXMuZWNvc3lzdGVtU2VydmljZS5jYW5PcGVuQXBwSW5Ccm93c2VyKHRoaXMuY3JlYXRlZEFwcCk7XG4gICAgICB0aGlzLmlzQXBwQ3JlYXRlZCA9IHRydWU7XG4gICAgfSBjYXRjaCAoZXgpIHtcbiAgICAgIHRoaXMuZWNvc3lzdGVtU2VydmljZS5jYW5jZWxBcHBDcmVhdGlvbih0aGlzLmNyZWF0ZWRBcHApO1xuICAgICAgdGhpcy5jcmVhdGVkQXBwID0gbnVsbDtcbiAgICAgIHRoaXMuZHJvcEFyZWFDb21wb25lbnQub25EZWxldGUoKTtcbiAgICAgIC8vIHByZXBhcmUgdHJhbnNsYXRpb24gb2Ygc3RhdGljIG1lc3NhZ2UgaWYgaXQgZXhpc3RzXG4gICAgICBjb25zdCBzdGF0aWNFcnJvck1lc3NhZ2UgPVxuICAgICAgICBFUlJPUl9NRVNTQUdFU1tleC5tZXNzYWdlXSAmJiB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChFUlJPUl9NRVNTQUdFU1tleC5tZXNzYWdlXSk7XG4gICAgICAvLyBpZiB0aGVyZSBpcyBubyBzdGF0aWMgbWVzc2FnZSwgdXNlIGR5bmFtaWMgb25lIGZyb20gdGhlIGV4Y2VwdGlvblxuICAgICAgdGhpcy5lcnJvck1lc3NhZ2UgPSBzdGF0aWNFcnJvck1lc3NhZ2UgPz8gZXgubWVzc2FnZTtcbiAgICAgIGlmICghdGhpcy5lcnJvck1lc3NhZ2UgJiYgIXRoaXMudXBsb2FkQ2FuY2VsZWQpIHtcbiAgICAgICAgdGhpcy5hbGVydFNlcnZpY2UuYWRkU2VydmVyRmFpbHVyZShleCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucHJvZ3Jlc3MubmV4dCgxMDApO1xuICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XG4gIH1cblxuICBnZXRIcmVmKGFwcDogSUFwcGxpY2F0aW9uKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5hcHBsaWNhdGlvblNlcnZpY2UuZ2V0SHJlZihhcHApO1xuICB9XG5cbiAgY2FuY2VsKCkge1xuICAgIHRoaXMuY2FuY2VsRmlsZVVwbG9hZCgpO1xuICAgIHRoaXMud2l6YXJkQ29tcG9uZW50LmNsb3NlKCk7XG4gIH1cblxuICBkb25lKCkge1xuICAgIHRoaXMud2l6YXJkQ29tcG9uZW50LmNsb3NlKCk7XG4gIH1cblxuICBiYWNrKCkge1xuICAgIHRoaXMud2l6YXJkQ29tcG9uZW50LnJlc2V0KCk7XG4gIH1cblxuICBwcml2YXRlIGNhbmNlbEZpbGVVcGxvYWQoKSB7XG4gICAgdGhpcy51cGxvYWRDYW5jZWxlZCA9IHRydWU7XG4gICAgdGhpcy5lY29zeXN0ZW1TZXJ2aWNlLmNhbmNlbEFwcENyZWF0aW9uKHRoaXMuY3JlYXRlZEFwcCk7XG4gICAgdGhpcy5jcmVhdGVkQXBwID0gbnVsbDtcbiAgfVxufVxuIiwiPGM4eS13aXphcmQtaGVhZGVyPlxuICA8aSBbYzh5SWNvbl09XCJoZWFkZXJJY29uXCI+PC9pPlxuICA8aDQgaWQ9XCJtb2RhbC10aXRsZVwiPnt7IGhlYWRlclRleHQgfCB0cmFuc2xhdGUgfX08L2g0PlxuPC9jOHktd2l6YXJkLWhlYWRlcj5cblxuPGM4eS13aXphcmQtYm9keT5cbiAgPHAgY2xhc3M9XCJwLTE2IHRleHQtY2VudGVyIHRleHQtbWVkaXVtIHNlcGFyYXRvci1ib3R0b20gc3RpY2t5LXRvcCBiZy1jb21wb25lbnRcIj5cbiAgICB7eyAnVXBsb2FkIGEgKi56aXAgZmlsZScgfCB0cmFuc2xhdGUgfX1cbiAgPC9wPlxuICA8Yzh5LWZvcm0tZ3JvdXBcbiAgICBjbGFzcz1cIm0tdC0xNiBtLWwtYXV0byBtLXItYXV0b1wiXG4gICAgc3R5bGU9XCJtYXgtd2lkdGg6IDI2NXB4XCJcbiAgICBpZD1cIm1vZGFsLWJvZHlcIlxuICAgICpuZ0lmPVwiIWlzQXBwQ3JlYXRlZDsgZWxzZSBhcHBDcmVhdGVkXCJcbiAgICBbaGFzRXJyb3JdPVwiISFlcnJvck1lc3NhZ2VcIlxuICA+XG4gICAgPGM4eS1kcm9wLWFyZWFcbiAgICAgIGNsYXNzPVwiZHJvcC1hcmVhXCJcbiAgICAgIChkcm9wcGVkKT1cIm9uRmlsZURyb3BwZWRFdmVudCgkZXZlbnQpXCJcbiAgICAgIFthY2NlcHRdPVwiJy56aXAnXCJcbiAgICAgIFtsb2FkaW5nXT1cImlzTG9hZGluZ1wiXG4gICAgICBbbWF4QWxsb3dlZEZpbGVzXT1cIjFcIlxuICAgICAgW3Byb2dyZXNzXT1cInByb2dyZXNzIHwgYXN5bmNcIlxuICAgID48L2M4eS1kcm9wLWFyZWE+XG4gICAgPGM4eS1tZXNzYWdlcz5cbiAgICAgIDxjOHktbWVzc2FnZSAqbmdJZj1cImVycm9yTWVzc2FnZVwiPlxuICAgICAgICB7eyBlcnJvck1lc3NhZ2UgfCB0cmFuc2xhdGUgfX1cbiAgICAgIDwvYzh5LW1lc3NhZ2U+XG4gICAgPC9jOHktbWVzc2FnZXM+XG4gIDwvYzh5LWZvcm0tZ3JvdXA+XG4gIDxkaXYgY2xhc3M9XCJjYXJkLWJsb2NrXCIgKm5nSWY9XCJhcHBsaWNhdGlvblR5cGUgPT09ICdwYWNrYWdlJ1wiPlxuICAgIDxjOHktZm9ybS1ncm91cD5cbiAgICAgIDxsYWJlbFxuICAgICAgICBjbGFzcz1cIm0tci04IGQtaW5saW5lLWJsb2NrXCJcbiAgICAgICAgaWQ9XCJhdmFpbGFiaWxpdHlTZWxlY3RvckxhYmVsXCJcbiAgICAgICAgZm9yPVwiYXZhaWxhYmlsaXR5U2VsZWN0b3JcIlxuICAgICAgPlxuICAgICAgICB7eyAnU2VsZWN0IGV4dGVuc2lvbiBhdmFpbGFiaWxpdHknIHwgdHJhbnNsYXRlIH19XG4gICAgICA8L2xhYmVsPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBjbGFzcz1cImJ0bi1oZWxwIGJ0bi1oZWxwLS1zbVwiXG4gICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ0hlbHAnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgW3BvcG92ZXJdPVwiYXZhaWxhYmlsaXR5SGVscFBvcG92ZXJcIlxuICAgICAgICBwbGFjZW1lbnQ9XCJ0b3BcIlxuICAgICAgICB0cmlnZ2Vycz1cImZvY3VzXCJcbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICA+PC9idXR0b24+XG4gICAgICA8ZGl2IGNsYXNzPVwiYzh5LXNlbGVjdC13cmFwcGVyXCI+XG4gICAgICAgIDxzZWxlY3RcbiAgICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbFwiXG4gICAgICAgICAgaWQ9XCJhdmFpbGFiaWxpdHlTZWxlY3RvclwiXG4gICAgICAgICAgbmFtZT1cImF2YWlsYWJpbGl0eVNlbGVjdG9yXCJcbiAgICAgICAgICBbKG5nTW9kZWwpXT1cInNlbGVjdGVkQXZhaWxhYmlsaXR5XCJcbiAgICAgICAgPlxuICAgICAgICAgIDxvcHRpb25cbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBhdmFpbGFiaWxpdHkgb2YgcGFja2FnZUF2YWlsYWJpbGl0eS5hdmFpbGFiaWxpdGllc1wiXG4gICAgICAgICAgICBbbmdWYWx1ZV09XCJhdmFpbGFiaWxpdHkudmFsdWVcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIHt7IGF2YWlsYWJpbGl0eS5sYWJlbCB8IHRyYW5zbGF0ZSB9fVxuICAgICAgICAgIDwvb3B0aW9uPlxuICAgICAgICA8L3NlbGVjdD5cbiAgICAgIDwvZGl2PlxuICAgIDwvYzh5LWZvcm0tZ3JvdXA+XG4gIDwvZGl2PlxuICA8bmctdGVtcGxhdGUgI2FwcENyZWF0ZWQ+XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJkLWZsZXggYS1pLWNlbnRlciBqLWMtY2VudGVyXCJcbiAgICAgIHN0eWxlPVwibWluLWhlaWdodDogMjg1cHhcIlxuICAgID5cbiAgICAgIDxjOHktb3BlcmF0aW9uLXJlc3VsdFxuICAgICAgICBjbGFzcz1cImxlYWRcIlxuICAgICAgICB0eXBlPVwic3VjY2Vzc1wiXG4gICAgICAgIHRleHQ9XCJ7eyBzdWNjZXNzVGV4dCB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgIFt2ZXJ0aWNhbF09XCJ0cnVlXCJcbiAgICAgICAgW3NpemVdPVwiODRcIlxuICAgICAgPjwvYzh5LW9wZXJhdGlvbi1yZXN1bHQ+XG4gICAgPC9kaXY+XG4gIDwvbmctdGVtcGxhdGU+XG4gIDxuZy10ZW1wbGF0ZSAjYXZhaWxhYmlsaXR5SGVscFBvcG92ZXI+XG4gICAgPGRpdiBbaW5uZXJIdG1sXT1cImF2YWlsYWJpbGl0eUhlbHBQb3BvdmVyVGV4dCB8IHRyYW5zbGF0ZVwiPjwvZGl2PlxuICA8L25nLXRlbXBsYXRlPlxuPC9jOHktd2l6YXJkLWJvZHk+XG5cbjxjOHktd2l6YXJkLWZvb3Rlcj5cbiAgPGJ1dHRvblxuICAgIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0XCJcbiAgICB0aXRsZT1cInt7ICdCYWNrJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgdHlwZT1cImJ1dHRvblwiXG4gICAgKGNsaWNrKT1cImJhY2soKVwiXG4gICAgKm5nSWY9XCIhaXNBcHBDcmVhdGVkICYmIGNhbkdvQmFja1wiXG4gICAgdHJhbnNsYXRlXG4gID5cbiAgICBCYWNrXG4gIDwvYnV0dG9uPlxuICA8YnV0dG9uXG4gICAgY2xhc3M9XCJidG4gYnRuLWRlZmF1bHRcIlxuICAgIHRpdGxlPVwie3sgJ0NhbmNlbCcgfCB0cmFuc2xhdGUgfX1cIlxuICAgIHR5cGU9XCJidXR0b25cIlxuICAgIChjbGljayk9XCJjYW5jZWwoKVwiXG4gICAgKm5nSWY9XCIhaXNBcHBDcmVhdGVkXCJcbiAgICB0cmFuc2xhdGVcbiAgPlxuICAgIENhbmNlbFxuICA8L2J1dHRvbj5cbiAgPGJ1dHRvblxuICAgIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0XCJcbiAgICB0aXRsZT1cInt7ICdEb25lJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgdHlwZT1cImJ1dHRvblwiXG4gICAgKGNsaWNrKT1cImRvbmUoKVwiXG4gICAgKm5nSWY9XCJpc0FwcENyZWF0ZWRcIlxuICAgIHRyYW5zbGF0ZVxuICA+XG4gICAgRG9uZVxuICA8L2J1dHRvbj5cbiAgPGFcbiAgICBjbGFzcz1cImJ0biBidG4tcHJpbWFyeVwiXG4gICAgdGl0bGU9XCJ7eyAnT3BlbicgfCB0cmFuc2xhdGUgfX1cIlxuICAgIHRhcmdldD1cIl9ibGFua1wiXG4gICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgKm5nSWY9XCJpc0FwcENyZWF0ZWQgJiYgY2FuT3BlbkluQnJvd3NlclwiXG4gICAgW2hyZWZdPVwiZ2V0SHJlZihjcmVhdGVkQXBwKVwiXG4gICAgcmVsPVwibm9vcGVuZXIgbm9yZWZlcnJlclwiXG4gID5cbiAgICA8aVxuICAgICAgY2xhc3M9XCJtLXItNFwiXG4gICAgICBjOHlJY29uPVwiZXh0ZXJuYWwtbGlua1wiXG4gICAgPjwvaT5cbiAgICB7eyAnT3BlbicgfCB0cmFuc2xhdGUgfX1cbiAgPC9hPlxuPC9jOHktd2l6YXJkLWZvb3Rlcj5cbiJdfQ==