@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
120 lines • 47.7 kB
JavaScript
import { Component } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { FetchClient } from '@c8y/client';
import { AppStateService, ContextRouteService, GainsightService, PackageType, PluginsService, WizardModalService } from '@c8y/ngx-components';
import { BehaviorSubject } from 'rxjs';
import { EcosystemService, EcosystemWizards, packageProperties, PACKAGE_TYPE_LABELS, PackageAvailabilityService, PRODUCT_EXPERIENCE_ECOSYSTEM } from '@c8y/ngx-components/ecosystem/shared';
import * as i0 from "@angular/core";
import * as i1 from "@angular/router";
import * as i2 from "@c8y/client";
import * as i3 from "@c8y/ngx-components";
import * as i4 from "@c8y/ngx-components/ecosystem/shared";
import * as i5 from "@angular/common";
import * as i6 from "@angular/forms";
import * as i7 from "ngx-bootstrap/tooltip";
import * as i8 from "../../application-plugins/plugin-list.component";
export class PackageDetailsComponent {
constructor(activatedRoute, client, wizardModalService, ecosystemService, contextRouteService, pluginsService, packageAvailabilityService, ui, pluginService, gainsightService) {
this.activatedRoute = activatedRoute;
this.client = client;
this.wizardModalService = wizardModalService;
this.ecosystemService = ecosystemService;
this.contextRouteService = contextRouteService;
this.pluginsService = pluginsService;
this.packageAvailabilityService = packageAvailabilityService;
this.ui = ui;
this.pluginService = pluginService;
this.gainsightService = gainsightService;
this.package = {};
this.exportedPlugins$ = new BehaviorSubject([]);
this.isChangingAvailability = false;
this.isOwnedByCurrentTenant = false;
this.isAllowedToCreateSubtenants = false;
this.packageTypeLabels = PACKAGE_TYPE_LABELS;
this.PACKAGE_TYPE = PackageType;
this.packageProperties = packageProperties;
this.headers = { 'Content-Type': 'text/markdown', responseType: 'blob' };
this.NOT_FOUND_ERROR_CODE = 404;
}
async ngOnInit() {
this.isAllowedToCreateSubtenants = !!this.ui.currentTenant.value?.allowCreateTenants;
await this.loadData();
}
deploy() {
this.gainsightService.triggerEvent(PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.EVENTS.PACKAGE_PLUGINS, {
component: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.COMPONENTS.PACKAGE_DETAILS,
action: PRODUCT_EXPERIENCE_ECOSYSTEM.APPLICATIONS.ACTIONS.DEPLOY_APPLICATION_INITIATED
});
const initialState = {
wizardConfig: {},
id: EcosystemWizards.BLUEPRINT_DEPLOYMENT,
package: this.package
};
const modalOptions = { initialState };
this.wizardModalService.show(modalOptions);
}
async togglePackageAvailability(pckg, newAvailability) {
this.isChangingAvailability = true;
pckg = await this.packageAvailabilityService.askIfAvailabilityShouldBeSetTo(pckg, newAvailability);
const availabilityHasChanged = pckg.availability === newAvailability;
if (availabilityHasChanged) {
await this.loadData(pckg);
this.contextRouteService.setContext(this.activatedRoute, pckg);
}
else {
this.packageAvailability = this.package.availability;
}
this.isChangingAvailability = false;
}
async loadData(pckg) {
this.package = pckg
? pckg
: this.contextRouteService.getContextData(this.activatedRoute)?.contextData;
this.packageAvailability = this.package.availability;
this.packageContentState = this.ecosystemService.getPackageContentState(this.package);
this.packageType = this.pluginService.getPackageType(this.package);
this.name = this.package?.name;
this.description = this.package?.manifest?.description;
this.markdown = await this.getReadmeFileContent();
this.baseUrl = this.getBaseUrl();
this.appState = this.ecosystemService.getAppState(this.package);
this.isPackageBlueprint = this.ecosystemService.isPackageBlueprint(this.package);
this.isOwnedByCurrentTenant =
this.package?.owner?.tenant?.id === this.ui.currentTenant.value?.name;
this.extractPackageMFExports();
}
extractPackageMFExports() {
const exports = this.pluginsService.getMFExports(this.package);
this.exportedPlugins$.next(exports);
}
async getReadmeFileContent() {
const readmeFile = await this.getReadmeFile();
if (readmeFile.status === 200) {
return await readmeFile.text();
}
return '';
}
async getReadmeFile() {
const baseUrl = this.getBaseUrl();
let result;
const options = {
method: 'GET',
headers: this.headers
};
result = await this.client.fetch(`${baseUrl}README.md`, options);
if (result && result.status === this.NOT_FOUND_ERROR_CODE) {
result = await this.client.fetch(`${baseUrl}readme.md`, options);
}
return result;
}
getBaseUrl() {
return `/apps/${this.package.contextPath}/`;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PackageDetailsComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.FetchClient }, { token: i3.WizardModalService }, { token: i4.EcosystemService }, { token: i3.ContextRouteService }, { token: i3.PluginsService }, { token: i4.PackageAvailabilityService }, { token: i3.AppStateService }, { token: i3.PluginsService }, { token: i3.GainsightService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: PackageDetailsComponent, selector: "c8y-package-details", ngImport: i0, template: "<c8y-title>{{ name | humanizeAppName | async }}</c8y-title>\n\n<c8y-breadcrumb>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-atom'\"\n [label]=\"'Ecosystem' | translate\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [icon]=\"'big-parcel'\"\n [label]=\"'Extensions' | translate\"\n [path]=\"'ecosystem/extension/extensions'\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item [label]=\"name | humanizeAppName | async\"></c8y-breadcrumb-item>\n <c8y-breadcrumb-item [label]=\"'Extension package' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item\n placement=\"right\"\n itemClass=\"navbar-form\"\n *ngIf=\"isOwnedByCurrentTenant && isAllowedToCreateSubtenants\"\n>\n <div class=\"form-horizontal\">\n <div class=\"form-group\">\n <label\n for=\"availability\"\n translate\n >\n Availability`of package based on app state`\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n id=\"availability\"\n [(ngModel)]=\"packageAvailability\"\n [disabled]=\"isChangingAvailability\"\n (ngModelChange)=\"togglePackageAvailability(package, $event)\"\n >\n <option\n *ngFor=\"let availability of packageAvailabilityService.availabilities\"\n [ngValue]=\"availability.value\"\n >\n {{ availability.label | translate }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n </div>\n</c8y-action-bar-item>\n\n<div class=\"card content-fullpage d-grid grid__col--8-4--md grid__row--fit-auto\">\n <div class=\"bg-level-1 grid__col--fullspan separator-bottom\">\n <div class=\"card-block p-t-24 p-b-24 large-padding\">\n <button\n class=\"card__ribbon btn-clean\"\n [attr.aria-label]=\"\n (package.label || package.manifest.label | translatePackageLabel) +\n ': ' +\n (packageTypeLabels[packageType].tooltip | translate)\n \"\n tooltip=\"{{ packageTypeLabels[packageType].tooltip | translate }}\"\n placement=\"bottom\"\n type=\"button\"\n *ngIf=\"packageType !== PACKAGE_TYPE.CUSTOM\"\n [delay]=\"500\"\n >\n <span\n [ngClass]=\"{\n 'bg-info': packageType === PACKAGE_TYPE.COMMUNITY,\n 'bg-primary': packageType === PACKAGE_TYPE.OFFICIAL,\n 'bg-warning': packageType === PACKAGE_TYPE.ARCHIVED\n }\"\n >\n {{ package.label || package.manifest.label | translatePackageLabel }}\n </span>\n </button>\n <div class=\"content-flex-70\">\n <div class=\"text-center\">\n <i\n class=\"c8y-icon-duocolor icon-48\"\n c8yIcon=\"big-parcel\"\n ></i>\n <button\n class=\"btn-clean\"\n [attr.aria-label]=\"\n (appState?.label | translate) + ': ' + (appState?.tooltip | translate)\n \"\n [tooltip]=\"appState?.tooltip | translate\"\n placement=\"top\"\n type=\"button\"\n [delay]=\"500\"\n >\n <span\n class=\"label\"\n [ngClass]=\"appState?.class\"\n >\n {{ appState?.label | translate }}\n </span>\n </button>\n <button\n class=\"btn-clean\"\n [attr.aria-label]=\"\n (packageContentState?.label | translate) +\n ': ' +\n (packageContentState?.tooltip | translate)\n \"\n [tooltip]=\"packageContentState?.tooltip | translate\"\n placement=\"bottom\"\n type=\"button\"\n [delay]=\"500\"\n >\n <span\n class=\"label\"\n [ngClass]=\"packageContentState?.class\"\n >\n {{ packageContentState?.label | translate }}\n </span>\n </button>\n </div>\n\n <div class=\"flex-grow col-10\">\n <div class=\"content-flex-80\">\n <div class=\"col-5\">\n <div class=\"card-title text-bold m-b-8\">{{ name | humanizeAppName | async }}</div>\n <p *ngIf=\"description\">{{ description }}</p>\n <p\n class=\"text-muted\"\n *ngIf=\"!description\"\n >\n <em>{{ 'No description available.' | translate }}</em>\n </p>\n </div>\n <div\n class=\"col-3 text-right-md p-r-md-40\"\n *ngIf=\"isPackageBlueprint\"\n >\n <button\n class=\"btn btn-primary btn-sm\"\n (click)=\"deploy()\"\n data-cy=\"c8y-package-details--deploy-application-button\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"output\"\n ></i>\n {{ 'Deploy application' | translate }}\n </button>\n </div>\n <div class=\"flex-grow\">\n <c8y-properties-list\n [data]=\"package.manifest\"\n [properties]=\"packageProperties\"\n ></c8y-properties-list>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"inner-scroll\">\n <div class=\"card-header separator sticky-top\">\n <div class=\"card-title\">{{ 'Extension package overview' | translate }}</div>\n </div>\n <div class=\"card-block p-l-16 p-r-16\">\n <div\n class=\"alert alert-warning m-b-16\"\n style=\"margin: auto\"\n *ngIf=\"packageType === PACKAGE_TYPE.ARCHIVED\"\n translate\n >\n The package was archived by the owner marking it as out of maintenance. It is not\n recommended to install the package.\n </div>\n <c8y-ui-empty-state\n [icon]=\"'user-manual'\"\n [title]=\"'No README.md found' | translate\"\n [subtitle]=\"\n 'To view the contents of "README", add the file "README.md" to the package.'\n | translate\n \"\n *ngIf=\"!markdown\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n <div\n class=\"markdown-content\"\n [innerHTML]=\"markdown | markdownToHtml: { baseUrl } | async\"\n ></div>\n </div>\n <div class=\"separator-bottom visible-sm visible-xs\"></div>\n </div>\n\n <div class=\"inner-scroll d-flex d-col\">\n <div class=\"card-header separator sticky-top\">\n <div class=\"card-title\">{{ 'Package plugins' | translate }}</div>\n </div>\n <div class=\"border-left flex-grow\">\n <!-- empty state -->\n <div\n class=\"p-16\"\n *ngIf=\"(exportedPlugins$ | async).length === 0\"\n >\n <c8y-ui-empty-state\n [icon]=\"'plugin'\"\n [title]=\"'No plugins to display.' | translate\"\n [subtitle]=\"'This package doesn\\'t contain plugins.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n <c8y-plugin-list\n [plugins$]=\"exportedPlugins$\"\n [selectable]=\"false\"\n [installable]=\"true\"\n [package]=\"package\"\n ></c8y-plugin-list>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "component", type: i3.ActionBarItemComponent, selector: "c8y-action-bar-item", inputs: ["placement", "priority", "itemClass", "injector", "groupId", "inGroupPriority"] }, { kind: "component", type: i3.BreadcrumbComponent, selector: "c8y-breadcrumb" }, { kind: "component", type: i3.BreadcrumbItemComponent, selector: "c8y-breadcrumb-item", inputs: ["icon", "translate", "label", "path", "injector"] }, { kind: "component", type: i3.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.TitleComponent, selector: "c8y-title", inputs: ["pageTitleUpdate"] }, { kind: "directive", type: i6.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i3.PropertiesListComponent, selector: "c8y-properties-list", inputs: ["properties", "title", "icon", "data", "groups", "noParse", "emptyLabel"] }, { kind: "directive", type: i7.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "component", type: i8.PluginListComponent, selector: "c8y-plugin-list", inputs: ["plugins$", "emptyListText", "selectable", "hideSource", "installable", "package"], outputs: ["selectedItems"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i5.AsyncPipe, name: "async" }, { kind: "pipe", type: i3.HumanizeAppNamePipe, name: "humanizeAppName" }, { kind: "pipe", type: i3.MarkdownToHtmlPipe, name: "markdownToHtml" }, { kind: "pipe", type: i4.TranslatePackageLabelPipe, name: "translatePackageLabel" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PackageDetailsComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-package-details', template: "<c8y-title>{{ name | humanizeAppName | async }}</c8y-title>\n\n<c8y-breadcrumb>\n <c8y-breadcrumb-item\n [icon]=\"'c8y-atom'\"\n [label]=\"'Ecosystem' | translate\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item\n [icon]=\"'big-parcel'\"\n [label]=\"'Extensions' | translate\"\n [path]=\"'ecosystem/extension/extensions'\"\n ></c8y-breadcrumb-item>\n <c8y-breadcrumb-item [label]=\"name | humanizeAppName | async\"></c8y-breadcrumb-item>\n <c8y-breadcrumb-item [label]=\"'Extension package' | translate\"></c8y-breadcrumb-item>\n</c8y-breadcrumb>\n\n<c8y-action-bar-item\n placement=\"right\"\n itemClass=\"navbar-form\"\n *ngIf=\"isOwnedByCurrentTenant && isAllowedToCreateSubtenants\"\n>\n <div class=\"form-horizontal\">\n <div class=\"form-group\">\n <label\n for=\"availability\"\n translate\n >\n Availability`of package based on app state`\n </label>\n <div class=\"c8y-select-wrapper\">\n <select\n class=\"form-control\"\n id=\"availability\"\n [(ngModel)]=\"packageAvailability\"\n [disabled]=\"isChangingAvailability\"\n (ngModelChange)=\"togglePackageAvailability(package, $event)\"\n >\n <option\n *ngFor=\"let availability of packageAvailabilityService.availabilities\"\n [ngValue]=\"availability.value\"\n >\n {{ availability.label | translate }}\n </option>\n </select>\n <span></span>\n </div>\n </div>\n </div>\n</c8y-action-bar-item>\n\n<div class=\"card content-fullpage d-grid grid__col--8-4--md grid__row--fit-auto\">\n <div class=\"bg-level-1 grid__col--fullspan separator-bottom\">\n <div class=\"card-block p-t-24 p-b-24 large-padding\">\n <button\n class=\"card__ribbon btn-clean\"\n [attr.aria-label]=\"\n (package.label || package.manifest.label | translatePackageLabel) +\n ': ' +\n (packageTypeLabels[packageType].tooltip | translate)\n \"\n tooltip=\"{{ packageTypeLabels[packageType].tooltip | translate }}\"\n placement=\"bottom\"\n type=\"button\"\n *ngIf=\"packageType !== PACKAGE_TYPE.CUSTOM\"\n [delay]=\"500\"\n >\n <span\n [ngClass]=\"{\n 'bg-info': packageType === PACKAGE_TYPE.COMMUNITY,\n 'bg-primary': packageType === PACKAGE_TYPE.OFFICIAL,\n 'bg-warning': packageType === PACKAGE_TYPE.ARCHIVED\n }\"\n >\n {{ package.label || package.manifest.label | translatePackageLabel }}\n </span>\n </button>\n <div class=\"content-flex-70\">\n <div class=\"text-center\">\n <i\n class=\"c8y-icon-duocolor icon-48\"\n c8yIcon=\"big-parcel\"\n ></i>\n <button\n class=\"btn-clean\"\n [attr.aria-label]=\"\n (appState?.label | translate) + ': ' + (appState?.tooltip | translate)\n \"\n [tooltip]=\"appState?.tooltip | translate\"\n placement=\"top\"\n type=\"button\"\n [delay]=\"500\"\n >\n <span\n class=\"label\"\n [ngClass]=\"appState?.class\"\n >\n {{ appState?.label | translate }}\n </span>\n </button>\n <button\n class=\"btn-clean\"\n [attr.aria-label]=\"\n (packageContentState?.label | translate) +\n ': ' +\n (packageContentState?.tooltip | translate)\n \"\n [tooltip]=\"packageContentState?.tooltip | translate\"\n placement=\"bottom\"\n type=\"button\"\n [delay]=\"500\"\n >\n <span\n class=\"label\"\n [ngClass]=\"packageContentState?.class\"\n >\n {{ packageContentState?.label | translate }}\n </span>\n </button>\n </div>\n\n <div class=\"flex-grow col-10\">\n <div class=\"content-flex-80\">\n <div class=\"col-5\">\n <div class=\"card-title text-bold m-b-8\">{{ name | humanizeAppName | async }}</div>\n <p *ngIf=\"description\">{{ description }}</p>\n <p\n class=\"text-muted\"\n *ngIf=\"!description\"\n >\n <em>{{ 'No description available.' | translate }}</em>\n </p>\n </div>\n <div\n class=\"col-3 text-right-md p-r-md-40\"\n *ngIf=\"isPackageBlueprint\"\n >\n <button\n class=\"btn btn-primary btn-sm\"\n (click)=\"deploy()\"\n data-cy=\"c8y-package-details--deploy-application-button\"\n >\n <i\n class=\"m-r-4\"\n c8yIcon=\"output\"\n ></i>\n {{ 'Deploy application' | translate }}\n </button>\n </div>\n <div class=\"flex-grow\">\n <c8y-properties-list\n [data]=\"package.manifest\"\n [properties]=\"packageProperties\"\n ></c8y-properties-list>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"inner-scroll\">\n <div class=\"card-header separator sticky-top\">\n <div class=\"card-title\">{{ 'Extension package overview' | translate }}</div>\n </div>\n <div class=\"card-block p-l-16 p-r-16\">\n <div\n class=\"alert alert-warning m-b-16\"\n style=\"margin: auto\"\n *ngIf=\"packageType === PACKAGE_TYPE.ARCHIVED\"\n translate\n >\n The package was archived by the owner marking it as out of maintenance. It is not\n recommended to install the package.\n </div>\n <c8y-ui-empty-state\n [icon]=\"'user-manual'\"\n [title]=\"'No README.md found' | translate\"\n [subtitle]=\"\n 'To view the contents of "README", add the file "README.md" to the package.'\n | translate\n \"\n *ngIf=\"!markdown\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n <div\n class=\"markdown-content\"\n [innerHTML]=\"markdown | markdownToHtml: { baseUrl } | async\"\n ></div>\n </div>\n <div class=\"separator-bottom visible-sm visible-xs\"></div>\n </div>\n\n <div class=\"inner-scroll d-flex d-col\">\n <div class=\"card-header separator sticky-top\">\n <div class=\"card-title\">{{ 'Package plugins' | translate }}</div>\n </div>\n <div class=\"border-left flex-grow\">\n <!-- empty state -->\n <div\n class=\"p-16\"\n *ngIf=\"(exportedPlugins$ | async).length === 0\"\n >\n <c8y-ui-empty-state\n [icon]=\"'plugin'\"\n [title]=\"'No plugins to display.' | translate\"\n [subtitle]=\"'This package doesn\\'t contain plugins.' | translate\"\n [horizontal]=\"true\"\n ></c8y-ui-empty-state>\n </div>\n <c8y-plugin-list\n [plugins$]=\"exportedPlugins$\"\n [selectable]=\"false\"\n [installable]=\"true\"\n [package]=\"package\"\n ></c8y-plugin-list>\n </div>\n </div>\n</div>\n" }]
}], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i2.FetchClient }, { type: i3.WizardModalService }, { type: i4.EcosystemService }, { type: i3.ContextRouteService }, { type: i3.PluginsService }, { type: i4.PackageAvailabilityService }, { type: i3.AppStateService }, { type: i3.PluginsService }, { type: i3.GainsightService }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFja2FnZS1kZXRhaWxzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2Vjb3N5c3RlbS9wYWNrYWdlcy9wYWNrYWdlLWRldGFpbHMvcGFja2FnZS1kZXRhaWxzLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL2Vjb3N5c3RlbS9wYWNrYWdlcy9wYWNrYWdlLWRldGFpbHMvcGFja2FnZS1kZXRhaWxzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFDbEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2pELE9BQU8sRUFFTCxXQUFXLEVBSVosTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUVMLGVBQWUsRUFDZixtQkFBbUIsRUFDbkIsZ0JBQWdCLEVBQ2hCLFdBQVcsRUFDWCxjQUFjLEVBRWQsa0JBQWtCLEVBQ25CLE1BQU0scUJBQXFCLENBQUM7QUFFN0IsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN2QyxPQUFPLEVBRUwsZ0JBQWdCLEVBQ2hCLGdCQUFnQixFQUNoQixpQkFBaUIsRUFDakIsbUJBQW1CLEVBQ25CLDBCQUEwQixFQUMxQiw0QkFBNEIsRUFDN0IsTUFBTSxzQ0FBc0MsQ0FBQzs7Ozs7Ozs7OztBQU05QyxNQUFNLE9BQU8sdUJBQXVCO0lBc0JsQyxZQUNVLGNBQThCLEVBQzlCLE1BQW1CLEVBQ25CLGtCQUFzQyxFQUN0QyxnQkFBa0MsRUFDbEMsbUJBQXdDLEVBQ3hDLGNBQThCLEVBQzlCLDBCQUFzRCxFQUN0RCxFQUFtQixFQUNuQixhQUE2QixFQUM3QixnQkFBa0M7UUFUbEMsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLFdBQU0sR0FBTixNQUFNLENBQWE7UUFDbkIsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFvQjtRQUN0Qyxx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cG9ydCB7IENvbXBvbmVudCwgT25Jbml0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQge1xuICBBcHBsaWNhdGlvbkF2YWlsYWJpbGl0eSxcbiAgRmV0Y2hDbGllbnQsXG4gIElBcHBsaWNhdGlvbixcbiAgSUZldGNoT3B0aW9ucyxcbiAgSUZldGNoUmVzcG9uc2Vcbn0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHtcbiAgQXBwbGljYXRpb25QbHVnaW4sXG4gIEFwcFN0YXRlU2VydmljZSxcbiAgQ29udGV4dFJvdXRlU2VydmljZSxcbiAgR2FpbnNpZ2h0U2VydmljZSxcbiAgUGFja2FnZVR5cGUsXG4gIFBsdWdpbnNTZXJ2aWNlLFxuICBQcm9wZXJ0aWVzTGlzdEl0ZW0sXG4gIFdpemFyZE1vZGFsU2VydmljZVxufSBmcm9tICdAYzh5L25neC1jb21wb25lbnRzJztcbmltcG9ydCB7IE1vZGFsT3B0aW9ucyB9IGZyb20gJ25neC1ib290c3RyYXAvbW9kYWwnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1xuICBBcHBsaWNhdGlvblN0YXRlLFxuICBFY29zeXN0ZW1TZXJ2aWNlLFxuICBFY29zeXN0ZW1XaXphcmRzLFxuICBwYWNrYWdlUHJvcGVydGllcyxcbiAgUEFDS0FHRV9UWVBFX0xBQkVMUyxcbiAgUGFja2FnZUF2YWlsYWJpbGl0eVNlcnZpY2UsXG4gIFBST0RVQ1RfRVhQRVJJRU5DRV9FQ09TWVNURU1cbn0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9lY29zeXN0ZW0vc2hhcmVkJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnYzh5LXBhY2thZ2UtZGV0YWlscycsXG4gIHRlbXBsYXRlVXJsOiAnLi9wYWNrYWdlLWRldGFpbHMuY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIFBhY2thZ2VEZXRhaWxzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgbWFya2Rvd246IHN0cmluZztcbiAgYmFzZVVybDogc3RyaW5nO1xuICBwYWNrYWdlOiBJQXBwbGljYXRpb24gPSB7fTtcbiAgbmFtZTogc3RyaW5nO1xuICBkZXNjcmlwdGlvbjogc3RyaW5nO1xuICBhcHBTdGF0ZTogQXBwbGljYXRpb25TdGF0ZTtcbiAgaXNQYWNrYWdlQmx1ZXByaW50OiBib29sZWFuO1xuICBleHBvcnRlZFBsdWdpbnMkOiBCZWhhdmlvclN1YmplY3Q8QXBwbGljYXRpb25QbHVnaW5bXT4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0KFtdKTtcbiAgaXNDaGFuZ2luZ0F2YWlsYWJpbGl0eSA9IGZhbHNlO1xuICBpc093bmVkQnlDdXJyZW50VGVuYW50ID0gZmFsc2U7XG4gIGlzQWxsb3dlZFRvQ3JlYXRlU3VidGVuYW50cyA9IGZhbHNlO1xuICBwYWNrYWdlQ29udGVudFN0YXRlOiBBcHBsaWNhdGlvblN0YXRlO1xuICBwYWNrYWdlVHlwZTogUGFja2FnZVR5cGU7XG4gIHBhY2thZ2VBdmFpbGFiaWxpdHk6IEFwcGxpY2F0aW9uQXZhaWxhYmlsaXR5O1xuXG4gIHJlYWRvbmx5IHBhY2thZ2VUeXBlTGFiZWxzID0gUEFDS0FHRV9UWVBFX0xBQkVMUztcbiAgcmVhZG9ubHkgUEFDS0FHRV9UWVBFID0gUGFja2FnZVR5cGU7XG4gIHJlYWRvbmx5IHBhY2thZ2VQcm9wZXJ0aWVzOiBQcm9wZXJ0aWVzTGlzdEl0ZW1bXSA9IHBhY2thZ2VQcm9wZXJ0aWVzO1xuICBwcml2YXRlIHJlYWRvbmx5IGhlYWRlcnM6IGFueSA9IHsgJ0NvbnRlbnQtVHlwZSc6ICd0ZXh0L21hcmtkb3duJywgcmVzcG9uc2VUeXBlOiAnYmxvYicgfTtcbiAgcHJpdmF0ZSBOT1RfRk9VTkRfRVJST1JfQ09ERSA9IDQwNDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGFjdGl2YXRlZFJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSxcbiAgICBwcml2YXRlIGNsaWVudDogRmV0Y2hDbGllbnQsXG4gICAgcHJpdmF0ZSB3aXphcmRNb2RhbFNlcnZpY2U6IFdpemFyZE1vZGFsU2VydmljZSxcbiAgICBwcml2YXRlIGVjb3N5c3RlbVNlcnZpY2U6IEVjb3N5c3RlbVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBjb250ZXh0Um91dGVTZXJ2aWNlOiBDb250ZXh0Um91dGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgcGx1Z2luc1NlcnZpY2U6IFBsdWdpbnNTZXJ2aWNlLFxuICAgIHByaXZhdGUgcGFja2FnZUF2YWlsYWJpbGl0eVNlcnZpY2U6IFBhY2thZ2VBdmFpbGFiaWxpdHlTZXJ2aWNlLFxuICAgIHByaXZhdGUgdWk6IEFwcFN0YXRlU2VydmljZSxcbiAgICBwcml2YXRlIHBsdWdpblNlcnZpY2U6IFBsdWdpbnNTZXJ2aWNlLFxuICAgIHByaXZhdGUgZ2FpbnNpZ2h0U2VydmljZTogR2FpbnNpZ2h0U2VydmljZVxuICApIHt9XG5cbiAgYXN5bmMgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5pc0FsbG93ZWRUb0NyZWF0ZVN1YnRlbmFudHMgPSAhIXRoaXMudWkuY3VycmVudFRlbmFudC52YWx1ZT8uYWxsb3dDcmVhdGVUZW5hbnRzO1xuICAgIGF3YWl0IHRoaXMubG9hZERhdGEoKTtcbiAgfVxuXG4gIGRlcGxveSgpIHtcbiAgICB0aGlzLmdhaW5zaWdodFNlcnZpY2UudHJpZ2dlckV2ZW50KFxuICAgICAgUFJPRFVDVF9FWFBFUklFTkNFX0VDT1NZU1RFTS5BUFBMSUNBVElPTlMuRVZFTlRTLlBBQ0tBR0VfUExVR0lOUyxcbiAgICAgIHtcbiAgICAgICAgY29tcG9uZW50OiBQUk9EVUNUX0VYUEVSSUVOQ0VfRUNPU1lTVEVNLkFQUExJQ0FUSU9OUy5DT01QT05FTlRTLlBBQ0tBR0VfREVUQUlMUyxcbiAgICAgICAgYWN0aW9uOiBQUk9EVUNUX0VYUEVSSUVOQ0VfRUNPU1lTVEVNLkFQUExJQ0FUSU9OUy5BQ1RJT05TLkRFUExPWV9BUFBMSUNBVElPTl9JTklUSUFURURcbiAgICAgIH1cbiAgICApO1xuXG4gICAgY29uc3QgaW5pdGlhbFN0YXRlOiBhbnkgPSB7XG4gICAgICB3aXphcmRDb25maWc6IHt9LFxuICAgICAgaWQ6IEVjb3N5c3RlbVdpemFyZHMuQkxVRVBSSU5UX0RFUExPWU1FTlQsXG4gICAgICBwYWNrYWdlOiB0aGlzLnBhY2thZ2VcbiAgICB9O1xuICAgIGNvbnN0IG1vZGFsT3B0aW9uczogTW9kYWxPcHRpb25zID0geyBpbml0aWFsU3RhdGUgfTtcbiAgICB0aGlzLndpemFyZE1vZGFsU2VydmljZS5zaG93KG1vZGFsT3B0aW9ucyk7XG4gIH1cblxuICBhc3luYyB0b2dnbGVQYWNrYWdlQXZhaWxhYmlsaXR5KHBja2c6IElBcHBsaWNhdGlvbiwgbmV3QXZhaWxhYmlsaXR5OiBBcHBsaWNhdGlvbkF2YWlsYWJpbGl0eSkge1xuICAgIHRoaXMuaXNDaGFuZ2luZ0F2YWlsYWJpbGl0eSA9IHRydWU7XG4gICAgcGNrZyA9IGF3YWl0IHRoaXMucGFja2FnZUF2YWlsYWJpbGl0eVNlcnZpY2UuYXNrSWZBdmFpbGFiaWxpdHlTaG91bGRCZVNldFRvKFxuICAgICAgcGNrZyxcbiAgICAgIG5ld0F2YWlsYWJpbGl0eVxuICAgICk7XG4gICAgY29uc3QgYXZhaWxhYmlsaXR5SGFzQ2hhbmdlZCA9IHBja2cuYXZhaWxhYmlsaXR5ID09PSBuZXdBdmFpbGFiaWxpdHk7XG4gICAgaWYgKGF2YWlsYWJpbGl0eUhhc0NoYW5nZWQpIHtcbiAgICAgIGF3YWl0IHRoaXMubG9hZERhdGEocGNrZyk7XG4gICAgICB0aGlzLmNvbnRleHRSb3V0ZVNlcnZpY2Uuc2V0Q29udGV4dCh0aGlzLmFjdGl2YXRlZFJvdXRlLCBwY2tnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wYWNrYWdlQXZhaWxhYmlsaXR5ID0gdGhpcy5wYWNrYWdlLmF2YWlsYWJpbGl0eTtcbiAgICB9XG4gICAgdGhpcy5pc0NoYW5naW5nQXZhaWxhYmlsaXR5ID0gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGxvYWREYXRhKHBja2c/OiBJQXBwbGljYXRpb24pIHtcbiAgICB0aGlzLnBhY2thZ2UgPSBwY2tnXG4gICAgICA/IHBja2dcbiAgICAgIDogdGhpcy5jb250ZXh0Um91dGVTZXJ2aWNlLmdldENvbnRleHREYXRhKHRoaXMuYWN0aXZhdGVkUm91dGUpPy5jb250ZXh0RGF0YTtcbiAgICB0aGlzLnBhY2thZ2VBdmFpbGFiaWxpdHkgPSB0aGlzLnBhY2thZ2UuYXZhaWxhYmlsaXR5O1xuICAgIHRoaXMucGFja2FnZUNvbnRlbnRTdGF0ZSA9IHRoaXMuZWNvc3lzdGVtU2VydmljZS5nZXRQYWNrYWdlQ29udGVudFN0YXRlKHRoaXMucGFja2FnZSk7XG4gICAgdGhpcy5wYWNrYWdlVHlwZSA9IHRoaXMucGx1Z2luU2VydmljZS5nZXRQYWNrYWdlVHlwZSh0aGlzLnBhY2thZ2UpO1xuICAgIHRoaXMubmFtZSA9IHRoaXMucGFja2FnZT8ubmFtZTtcbiAgICB0aGlzLmRlc2NyaXB0aW9uID0gdGhpcy5wYWNrYWdlPy5tYW5pZmVzdD8uZGVzY3JpcHRpb247XG4gICAgdGhpcy5tYXJrZG93biA9IGF3YWl0IHRoaXMuZ2V0UmVhZG1lRmlsZUNvbnRlbnQoKTtcbiAgICB0aGlzLmJhc2VVcmwgPSB0aGlzLmdldEJhc2VVcmwoKTtcbiAgICB0aGlzLmFwcFN0YXRlID0gdGhpcy5lY29zeXN0ZW1TZXJ2aWNlLmdldEFwcFN0YXRlKHRoaXMucGFja2FnZSk7XG4gICAgdGhpcy5pc1BhY2thZ2VCbHVlcHJpbnQgPSB0aGlzLmVjb3N5c3RlbVNlcnZpY2UuaXNQYWNrYWdlQmx1ZXByaW50KHRoaXMucGFja2FnZSk7XG4gICAgdGhpcy5pc093bmVkQnlDdXJyZW50VGVuYW50ID1cbiAgICAgIHRoaXMucGFja2FnZT8ub3duZXI/LnRlbmFudD8uaWQgPT09IHRoaXMudWkuY3VycmVudFRlbmFudC52YWx1ZT8ubmFtZTtcbiAgICB0aGlzLmV4dHJhY3RQYWNrYWdlTUZFeHBvcnRzKCk7XG4gIH1cblxuICBwcml2YXRlIGV4dHJhY3RQYWNrYWdlTUZFeHBvcnRzKCkge1xuICAgIGNvbnN0IGV4cG9ydHMgPSB0aGlzLnBsdWdpbnNTZXJ2aWNlLmdldE1GRXhwb3J0cyh0aGlzLnBhY2thZ2UpO1xuICAgIHRoaXMuZXhwb3J0ZWRQbHVnaW5zJC5uZXh0KGV4cG9ydHMpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBnZXRSZWFkbWVGaWxlQ29udGVudCgpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIGNvbnN0IHJlYWRtZUZpbGUgPSBhd2FpdCB0aGlzLmdldFJlYWRtZUZpbGUoKTtcblxuICAgIGlmIChyZWFkbWVGaWxlLnN0YXR1cyA9PT0gMjAwKSB7XG4gICAgICByZXR1cm4gYXdhaXQgcmVhZG1lRmlsZS50ZXh0KCk7XG4gICAgfVxuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0UmVhZG1lRmlsZSgpOiBQcm9taXNlPElGZXRjaFJlc3BvbnNlPiB7XG4gICAgY29uc3QgYmFzZVVybCA9IHRoaXMuZ2V0QmFzZVVybCgpO1xuICAgIGxldCByZXN1bHQ6IElGZXRjaFJlc3BvbnNlO1xuICAgIGNvbnN0IG9wdGlvbnM6IElGZXRjaE9wdGlvbnMgPSB7XG4gICAgICBtZXRob2Q6ICdHRVQnLFxuICAgICAgaGVhZGVyczogdGhpcy5oZWFkZXJzXG4gICAgfTtcbiAgICByZXN1bHQgPSBhd2FpdCB0aGlzLmNsaWVudC5mZXRjaChgJHtiYXNlVXJsfVJFQURNRS5tZGAsIG9wdGlvbnMpO1xuXG4gICAgaWYgKHJlc3VsdCAmJiByZXN1bHQuc3RhdHVzID09PSB0aGlzLk5PVF9GT1VORF9FUlJPUl9DT0RFKSB7XG4gICAgICByZXN1bHQgPSBhd2FpdCB0aGlzLmNsaWVudC5mZXRjaChgJHtiYXNlVXJsfXJlYWRtZS5tZGAsIG9wdGlvbnMpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRCYXNlVXJsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGAvYXBwcy8ke3RoaXMucGFja2FnZS5jb250ZXh0UGF0aH0vYDtcbiAgfVxufVxuIiwiPGM4eS10aXRsZT57eyBuYW1lIHwgaHVtYW5pemVBcHBOYW1lIHwgYXN5bmMgfX08L2M4eS10aXRsZT5cblxuPGM4eS1icmVhZGNydW1iPlxuICA8Yzh5LWJyZWFkY3J1bWItaXRlbVxuICAgIFtpY29uXT1cIidjOHktYXRvbSdcIlxuICAgIFtsYWJlbF09XCInRWNvc3lzdGVtJyB8IHRyYW5zbGF0ZVwiXG4gID48L2M4eS1icmVhZGNydW1iLWl0ZW0+XG4gIDxjOHktYnJlYWRjcnVtYi1pdGVtXG4gICAgW2ljb25dPVwiJ2JpZy1wYXJjZWwnXCJcbiAgICBbbGFiZWxdPVwiJ0V4dGVuc2lvbnMnIHwgdHJhbnNsYXRlXCJcbiAgICBbcGF0aF09XCInZWNvc3lzdGVtL2V4dGVuc2lvbi9leHRlbnNpb25zJ1wiXG4gID48L2M4eS1icmVhZGNydW1iLWl0ZW0+XG4gIDxjOHktYnJlYWRjcnVtYi1pdGVtIFtsYWJlbF09XCJuYW1lIHwgaHVtYW5pemVBcHBOYW1lIHwgYXN5bmNcIj48L2M4eS1icmVhZGNydW1iLWl0ZW0+XG4gIDxjOHktYnJlYWRjcnVtYi1pdGVtIFtsYWJlbF09XCInRXh0ZW5zaW9uIHBhY2thZ2UnIHwgdHJhbnNsYXRlXCI+PC9jOHktYnJlYWRjcnVtYi1pdGVtPlxuPC9jOHktYnJlYWRjcnVtYj5cblxuPGM4eS1hY3Rpb24tYmFyLWl0ZW1cbiAgcGxhY2VtZW50PVwicmlnaHRcIlxuICBpdGVtQ2xhc3M9XCJuYXZiYXItZm9ybVwiXG4gICpuZ0lmPVwiaXNPd25lZEJ5Q3VycmVudFRlbmFudCAmJiBpc0FsbG93ZWRUb0NyZWF0ZVN1YnRlbmFudHNcIlxuPlxuICA8ZGl2IGNsYXNzPVwiZm9ybS1ob3Jpem9udGFsXCI+XG4gICAgPGRpdiBjbGFzcz1cImZvcm0tZ3JvdXBcIj5cbiAgICAgIDxsYWJlbFxuICAgICAgICBmb3I9XCJhdmFpbGFiaWxpdHlcIlxuICAgICAgICB0cmFuc2xhdGVcbiAgICAgID5cbiAgICAgICAgQXZhaWxhYmlsaXR5YG9mIHBhY2thZ2UgYmFzZWQgb24gYXBwIHN0YXRlYFxuICAgICAgPC9sYWJlbD5cbiAgICAgIDxkaXYgY2xhc3M9XCJjOHktc2VsZWN0LXdyYXBwZXJcIj5cbiAgICAgICAgPHNlbGVjdFxuICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcbiAgICAgICAgICBpZD1cImF2YWlsYWJpbGl0eVwiXG4gICAgICAgICAgWyhuZ01vZGVsKV09XCJwYWNrYWdlQXZhaWxhYmlsaXR5XCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiaXNDaGFuZ2luZ0F2YWlsYWJpbGl0eVwiXG4gICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwidG9nZ2xlUGFja2FnZUF2YWlsYWJpbGl0eShwYWNrYWdlLCAkZXZlbnQpXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxvcHRpb25cbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBhdmFpbGFiaWxpdHkgb2YgcGFja2FnZUF2YWlsYWJpbGl0eVNlcnZpY2UuYXZhaWxhYmlsaXRpZXNcIlxuICAgICAgICAgICAgW25nVmFsdWVdPVwiYXZhaWxhYmlsaXR5LnZhbHVlXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICB7eyBhdmFpbGFiaWxpdHkubGFiZWwgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgIDxzcGFuPjwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvYzh5LWFjdGlvbi1iYXItaXRlbT5cblxuPGRpdiBjbGFzcz1cImNhcmQgY29udGVudC1mdWxscGFnZSBkLWdyaWQgZ3JpZF9fY29sLS04LTQtLW1kIGdyaWRfX3Jvdy0tZml0LWF1dG9cIj5cbiAgPGRpdiBjbGFzcz1cImJnLWxldmVsLTEgZ3JpZF9fY29sLS1mdWxsc3BhbiBzZXBhcmF0b3ItYm90dG9tXCI+XG4gICAgPGRpdiBjbGFzcz1cImNhcmQtYmxvY2sgcC10LTI0IHAtYi0yNCBsYXJnZS1wYWRkaW5nXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIGNsYXNzPVwiY2FyZF9fcmliYm9uIGJ0bi1jbGVhblwiXG4gICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiXG4gICAgICAgICAgKHBhY2thZ2UubGFiZWwgfHwgcGFja2FnZS5tYW5pZmVzdC5sYWJlbCB8IHRyYW5zbGF0ZVBhY2thZ2VMYWJlbCkgK1xuICAgICAgICAgICc6ICcgK1xuICAgICAgICAgIChwYWNrYWdlVHlwZUxhYmVsc1twYWNrYWdlVHlwZV0udG9vbHRpcCB8IHRyYW5zbGF0ZSlcbiAgICAgICAgXCJcbiAgICAgICAgdG9vbHRpcD1cInt7IHBhY2thZ2VUeXBlTGFiZWxzW3BhY2thZ2VUeXBlXS50b29sdGlwIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgcGxhY2VtZW50PVwiYm90dG9tXCJcbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICpuZ0lmPVwicGFja2FnZVR5cGUgIT09IFBBQ0tBR0VfVFlQRS5DVVNUT01cIlxuICAgICAgICBbZGVsYXldPVwiNTAwXCJcbiAgICAgID5cbiAgICAgICAgPHNwYW5cbiAgICAgICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICAgICAnYmctaW5mbyc6IHBhY2thZ2VUeXBlID09PSBQQUNLQUdFX1RZUEUuQ09NTVVOSVRZLFxuICAgICAgICAgICAgJ2JnLXByaW1hcnknOiBwYWNrYWdlVHlwZSA9PT0gUEFDS0FHRV9UWVBFLk9GRklDSUFMLFxuICAgICAgICAgICAgJ2JnLXdhcm5pbmcnOiBwYWNrYWdlVHlwZSA9PT0gUEFDS0FHRV9UWVBFLkFSQ0hJVkVEXG4gICAgICAgICAgfVwiXG4gICAgICAgID5cbiAgICAgICAgICB7eyBwYWNrYWdlLmxhYmVsIHx8IHBhY2thZ2UubWFuaWZlc3QubGFiZWwgfCB0cmFuc2xhdGVQYWNrYWdlTGFiZWwgfX1cbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29udGVudC1mbGV4LTcwXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPlxuICAgICAgICAgIDxpXG4gICAgICAgICAgICBjbGFzcz1cImM4eS1pY29uLWR1b2NvbG9yIGljb24tNDhcIlxuICAgICAgICAgICAgYzh5SWNvbj1cImJpZy1wYXJjZWxcIlxuICAgICAgICAgID48L2k+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgY2xhc3M9XCJidG4tY2xlYW5cIlxuICAgICAgICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCJcbiAgICAgICAgICAgICAgKGFwcFN0YXRlPy5sYWJlbCB8IHRyYW5zbGF0ZSkgKyAnOiAnICsgKGFwcFN0YXRlPy50b29sdGlwIHwgdHJhbnNsYXRlKVxuICAgICAgICAgICAgXCJcbiAgICAgICAgICAgIFt0b29sdGlwXT1cImFwcFN0YXRlPy50b29sdGlwIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICAgIHBsYWNlbWVudD1cInRvcFwiXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIFtkZWxheV09XCI1MDBcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgIGNsYXNzPVwibGFiZWxcIlxuICAgICAgICAgICAgICBbbmdDbGFzc109XCJhcHBTdGF0ZT8uY2xhc3NcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICB7eyBhcHBTdGF0ZT8ubGFiZWwgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBjbGFzcz1cImJ0bi1jbGVhblwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIlxuICAgICAgICAgICAgICAocGFja2FnZUNvbnRlbnRTdGF0ZT8ubGFiZWwgfCB0cmFuc2xhdGUpICtcbiAgICAgICAgICAgICAgJzogJyArXG4gICAgICAgICAgICAgIChwYWNrYWdlQ29udGVudFN0YXRlPy50b29sdGlwIHwgdHJhbnNsYXRlKVxuICAgICAgICAgICAgXCJcbiAgICAgICAgICAgIFt0b29sdGlwXT1cInBhY2thZ2VDb250ZW50U3RhdGU/LnRvb2x0aXAgfCB0cmFuc2xhdGVcIlxuICAgICAgICAgICAgcGxhY2VtZW50PVwiYm90dG9tXCJcbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgW2RlbGF5XT1cIjUwMFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgY2xhc3M9XCJsYWJlbFwiXG4gICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInBhY2thZ2VDb250ZW50U3RhdGU/LmNsYXNzXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge3sgcGFja2FnZUNvbnRlbnRTdGF0ZT8ubGFiZWwgfCB0cmFuc2xhdGUgfX1cbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImZsZXgtZ3JvdyBjb2wtMTBcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29udGVudC1mbGV4LTgwXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29sLTVcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtdGl0bGUgdGV4dC1ib2xkIG0tYi04XCI+e3sgbmFtZSB8IGh1bWFuaXplQXBwTmFtZSB8IGFzeW5jIH19PC9kaXY+XG4gICAgICAgICAgICAgIDxwICpuZ0lmPVwiZGVzY3JpcHRpb25cIj57eyBkZXNjcmlwdGlvbiB9fTwvcD5cbiAgICAgICAgICAgICAgPHBcbiAgICAgICAgICAgICAgICBjbGFzcz1cInRleHQtbXV0ZWRcIlxuICAgICAgICAgICAgICAgICpuZ0lmPVwiIWRlc2NyaXB0aW9uXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxlbT57eyAnTm8gZGVzY3JpcHRpb24gYXZhaWxhYmxlLicgfCB0cmFuc2xhdGUgfX08L2VtPlxuICAgICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgY2xhc3M9XCJjb2wtMyB0ZXh0LXJpZ2h0LW1kIHAtci1tZC00MFwiXG4gICAgICAgICAgICAgICpuZ0lmPVwiaXNQYWNrYWdlQmx1ZXByaW50XCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IGJ0bi1zbVwiXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImRlcGxveSgpXCJcbiAgICAgICAgICAgICAgICBkYXRhLWN5PVwiYzh5LXBhY2thZ2UtZGV0YWlscy0tZGVwbG95LWFwcGxpY2F0aW9uLWJ1dHRvblwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8aVxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtLXItNFwiXG4gICAgICAgICAgICAgICAgICBjOHlJY29uPVwib3V0cHV0XCJcbiAgICAgICAgICAgICAgICA+PC9pPlxuICAgICAgICAgICAgICAgIHt7ICdEZXBsb3kgYXBwbGljYXRpb24nIHwgdHJhbnNsYXRlIH19XG4gICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleC1ncm93XCI+XG4gICAgICAgICAgICAgIDxjOHktcHJvcGVydGllcy1saXN0XG4gICAgICAgICAgICAgICAgW2RhdGFdPVwicGFja2FnZS5tYW5pZmVzdFwiXG4gICAgICAgICAgICAgICAgW3Byb3BlcnRpZXNdPVwicGFja2FnZVByb3BlcnRpZXNcIlxuICAgICAgICAgICAgICA+PC9jOHktcHJvcGVydGllcy1saXN0PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuICA8ZGl2IGNsYXNzPVwiaW5uZXItc2Nyb2xsXCI+XG4gICAgPGRpdiBjbGFzcz1cImNhcmQtaGVhZGVyIHNlcGFyYXRvciBzdGlja3ktdG9wXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY2FyZC10aXRsZVwiPnt7ICdFeHRlbnNpb24gcGFja2FnZSBvdmVydmlldycgfCB0cmFuc2xhdGUgfX08L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiY2FyZC1ibG9jayBwLWwtMTYgcC1yLTE2XCI+XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwiYWxlcnQgYWxlcnQtd2FybmluZyBtLWItMTZcIlxuICAgICAgICBzdHlsZT1cIm1hcmdpbjogYXV0b1wiXG4gICAgICAgICpuZ0lmPVwicGFja2FnZVR5cGUgPT09IFBBQ0tBR0VfVFlQRS5BUkNISVZFRFwiXG4gICAgICAgIHRyYW5zbGF0ZVxuICAgICAgPlxuICAgICAgICBUaGUgcGFja2FnZSB3YXMgYXJjaGl2ZWQgYnkgdGhlIG93bmVyIG1hcmtpbmcgaXQgYXMgb3V0IG9mIG1haW50ZW5hbmNlLiBJdCBpcyBub3RcbiAgICAgICAgcmVjb21tZW5kZWQgdG8gaW5zdGFsbCB0aGUgcGFja2FnZS5cbiAgICAgIDwvZGl2PlxuICAgICAgPGM4eS11aS1lbXB0eS1zdGF0ZVxuICAgICAgICBbaWNvbl09XCIndXNlci1tYW51YWwnXCJcbiAgICAgICAgW3RpdGxlXT1cIidObyBSRUFETUUubWQgZm91bmQnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgW3N1YnRpdGxlXT1cIlxuICAgICAgICAgICdUbyB2aWV3IHRoZSBjb250ZW50cyBvZiAmcXVvdDtSRUFETUUmcXVvdDssIGFkZCB0aGUgZmlsZSAmcXVvdDtSRUFETUUubWQmcXVvdDsgdG8gdGhlIHBhY2thZ2UuJ1xuICAgICAgICAgICAgfCB0cmFuc2xhdGVcbiAgICAgICAgXCJcbiAgICAgICAgKm5nSWY9XCIhbWFya2Rvd25cIlxuICAgICAgICBbaG9yaXpvbnRhbF09XCJ0cnVlXCJcbiAgICAgID48L2M4eS11aS1lbXB0eS1zdGF0ZT5cbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJtYXJrZG93bi1jb250ZW50XCJcbiAgICAgICAgW2lubmVySFRNTF09XCJtYXJrZG93biB8IG1hcmtkb3duVG9IdG1sOiB7IGJhc2VVcmwgfSB8IGFzeW5jXCJcbiAgICAgID48L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwic2VwYXJhdG9yLWJvdHRvbSB2aXNpYmxlLXNtIHZpc2libGUteHNcIj48L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cImlubmVyLXNjcm9sbCBkLWZsZXggZC1jb2xcIj5cbiAgICA8ZGl2IGNsYXNzPVwiY2FyZC1oZWFkZXIgc2VwYXJhdG9yIHN0aWNreS10b3BcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLXRpdGxlXCI+e3sgJ1BhY2thZ2UgcGx1Z2lucycgfCB0cmFuc2xhdGUgfX08L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiYm9yZGVyLWxlZnQgZmxleC1ncm93XCI+XG4gICAgICA8IS0tIGVtcHR5IHN0YXRlIC0tPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cInAtMTZcIlxuICAgICAgICAqbmdJZj1cIihleHBvcnRlZFBsdWdpbnMkIHwgYXN5bmMpLmxlbmd0aCA9PT0gMFwiXG4gICAgICA+XG4gICAgICAgIDxjOHktdWktZW1wdHktc3RhdGVcbiAgICAgICAgICBbaWNvbl09XCIncGx1Z2luJ1wiXG4gICAgICAgICAgW3RpdGxlXT1cIidObyBwbHVnaW5zIHRvIGRpc3BsYXkuJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICAgW3N1YnRpdGxlXT1cIidUaGlzIHBhY2thZ2UgZG9lc25cXCd0IGNvbnRhaW4gcGx1Z2lucy4nIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgICBbaG9yaXpvbnRhbF09XCJ0cnVlXCJcbiAgICAgICAgPjwvYzh5LXVpLWVtcHR5LXN0YXRlPlxuICAgICAgPC9kaXY+XG4gICAgICA8Yzh5LXBsdWdpbi1saXN0XG4gICAgICAgIFtwbHVnaW5zJF09XCJleHBvcnRlZFBsdWdpbnMkXCJcbiAgICAgICAgW3NlbGVjdGFibGVdPVwiZmFsc2VcIlxuICAgICAgICBbaW5zdGFsbGFibGVdPVwidHJ1ZVwiXG4gICAgICAgIFtwYWNrYWdlXT1cInBhY2thZ2VcIlxuICAgICAgPjwvYzh5LXBsdWdpbi1saXN0PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19