@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
66 lines • 19.6 kB
JavaScript
import { Component, EventEmitter, Input, Output } from '@angular/core';
import { Observable } from 'rxjs';
import { PluginListService } from './plugin-list.service';
import * as i0 from "@angular/core";
import * as i1 from "./plugin-list.service";
import * as i2 from "@c8y/ngx-components";
import * as i3 from "@angular/common";
import * as i4 from "./plugin-list-item.component";
export class PluginListComponent {
constructor(pluginListService) {
this.pluginListService = pluginListService;
this.CURRENT_LOCATION = location.href;
this.emptyListText = '';
this.hideSource = false;
/**
* Shows the install button for each plugin separately. Currently used in package-details view.
*/
this.installable = false;
this.selectedItems = new EventEmitter();
this.showOverview = new EventEmitter();
this.selectedPlugins = {};
this.updatingPluginId = this.pluginListService.updatingPluginId;
}
updateSelectedItems(selected, plugin) {
this.selectedPlugins[plugin.id] = selected ? plugin : undefined;
const onlyInstalledPlugins = Object.values(this.selectedPlugins).filter(Boolean);
this.selectedItems.emit(onlyInstalledPlugins);
}
showPluginOverview(plugin) {
if (plugin?.id === this.selectedPlugin?.id) {
return;
}
this.showOverview.emit(plugin);
}
async installPlugin(plugin) {
await this.pluginListService.updateAppRemotes(plugin, 'install', this.package);
}
async uninstallPlugin(plugin) {
await this.pluginListService.updateAppRemotes(plugin, 'uninstall', this.package);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PluginListComponent, deps: [{ token: i1.PluginListService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: PluginListComponent, selector: "c8y-plugin-list", inputs: { plugins$: "plugins$", emptyListText: "emptyListText", selectable: "selectable", hideSource: "hideSource", installable: "installable", package: "package", selectedPlugin: "selectedPlugin" }, outputs: { selectedItems: "selectedItems", showOverview: "showOverview" }, ngImport: i0, template: "<c8y-list-group class=\"bg-inherit\">\n <ng-container *ngIf=\"(plugins$ | async)?.length !== 0; else emptyList\">\n <ng-container *ngFor=\"let plugin of plugins$ | async\">\n <c8y-li\n [ngClass]=\"{\n disabled: plugin.installed,\n selected: selectedPlugin?.id === plugin?.id\n }\"\n >\n <div class=\"d-flex fit-w\">\n <ng-container *ngIf=\"plugin.readmePath\">\n <button\n class=\"c8y-list__item__btn d-flex fit-w gap-4\"\n title=\"{{ 'Details' | translate }}\"\n (click)=\"showPluginOverview(plugin)\"\n >\n <c8y-plugin-list-item\n class=\"d-contents\"\n (isItemSelected)=\"updateSelectedItems($event, plugin)\"\n [plugin]=\"plugin\"\n [selectable]=\"selectable\"\n [hideSource]=\"hideSource\"\n ></c8y-plugin-list-item>\n <i\n class=\"icon-24 m-l-auto a-s-center\"\n c8yIcon=\"forward\"\n ></i>\n </button>\n </ng-container>\n <ng-container *ngIf=\"!plugin.readmePath\">\n <c8y-plugin-list-item\n class=\"d-contents\"\n (isItemSelected)=\"updateSelectedItems($event, plugin)\"\n [plugin]=\"plugin\"\n [selectable]=\"selectable\"\n [hideSource]=\"hideSource\"\n ></c8y-plugin-list-item>\n </ng-container>\n </div>\n <div class=\"p-l-40 m-t-4 d-flex flex-wrap gap-8\">\n <button\n class=\"btn btn-danger btn-sm\"\n title=\"{{ 'Uninstall plugin' | translate }}\"\n *ngIf=\"installable\"\n (click)=\"uninstallPlugin(plugin)\"\n [ngClass]=\"{ 'btn-pending': plugin.id === updatingPluginId.uninstall }\"\n [disabled]=\"updatingPluginId.uninstall && plugin.id === updatingPluginId.uninstall\"\n data-cy=\"plugin-list--uninstall-plugin-button\"\n translate\n >\n Uninstall plugin\n </button>\n <button\n class=\"btn btn-default btn-sm m-0\"\n title=\"{{ 'Install plugin' | translate }}\"\n *ngIf=\"installable\"\n (click)=\"installPlugin(plugin)\"\n [ngClass]=\"{ 'btn-pending': plugin.id === updatingPluginId.install }\"\n [disabled]=\"updatingPluginId.install && plugin.id === updatingPluginId.install\"\n data-cy=\"plugin-list--install-plugin-button\"\n translate\n >\n Install plugin\n </button>\n </div>\n </c8y-li>\n </ng-container>\n </ng-container>\n</c8y-list-group>\n<ng-template #emptyList>\n <c8y-ui-empty-state\n [icon]=\"'plugin'\"\n [title]=\"emptyListText | translate\"\n [horizontal]=\"true\"\n *ngIf=\"emptyListText\"\n ></c8y-ui-empty-state>\n</ng-template>\n", dependencies: [{ kind: "component", type: i2.EmptyStateComponent, selector: "c8y-ui-empty-state", inputs: ["icon", "title", "subtitle", "horizontal"] }, { kind: "directive", type: i2.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i2.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i2.ListGroupComponent, selector: "c8y-list-group" }, { kind: "component", type: i2.ListItemComponent, selector: "c8y-list-item, c8y-li", inputs: ["active", "highlighted", "emptyActions", "dense", "collapsed", "selectable"], outputs: ["collapsedChange"] }, { kind: "component", type: i4.PluginListItemComponent, selector: "c8y-plugin-list-item", inputs: ["plugin", "selectable", "hideSource"], outputs: ["isItemSelected"] }, { kind: "pipe", type: i2.C8yTranslatePipe, name: "translate" }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PluginListComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-plugin-list', template: "<c8y-list-group class=\"bg-inherit\">\n <ng-container *ngIf=\"(plugins$ | async)?.length !== 0; else emptyList\">\n <ng-container *ngFor=\"let plugin of plugins$ | async\">\n <c8y-li\n [ngClass]=\"{\n disabled: plugin.installed,\n selected: selectedPlugin?.id === plugin?.id\n }\"\n >\n <div class=\"d-flex fit-w\">\n <ng-container *ngIf=\"plugin.readmePath\">\n <button\n class=\"c8y-list__item__btn d-flex fit-w gap-4\"\n title=\"{{ 'Details' | translate }}\"\n (click)=\"showPluginOverview(plugin)\"\n >\n <c8y-plugin-list-item\n class=\"d-contents\"\n (isItemSelected)=\"updateSelectedItems($event, plugin)\"\n [plugin]=\"plugin\"\n [selectable]=\"selectable\"\n [hideSource]=\"hideSource\"\n ></c8y-plugin-list-item>\n <i\n class=\"icon-24 m-l-auto a-s-center\"\n c8yIcon=\"forward\"\n ></i>\n </button>\n </ng-container>\n <ng-container *ngIf=\"!plugin.readmePath\">\n <c8y-plugin-list-item\n class=\"d-contents\"\n (isItemSelected)=\"updateSelectedItems($event, plugin)\"\n [plugin]=\"plugin\"\n [selectable]=\"selectable\"\n [hideSource]=\"hideSource\"\n ></c8y-plugin-list-item>\n </ng-container>\n </div>\n <div class=\"p-l-40 m-t-4 d-flex flex-wrap gap-8\">\n <button\n class=\"btn btn-danger btn-sm\"\n title=\"{{ 'Uninstall plugin' | translate }}\"\n *ngIf=\"installable\"\n (click)=\"uninstallPlugin(plugin)\"\n [ngClass]=\"{ 'btn-pending': plugin.id === updatingPluginId.uninstall }\"\n [disabled]=\"updatingPluginId.uninstall && plugin.id === updatingPluginId.uninstall\"\n data-cy=\"plugin-list--uninstall-plugin-button\"\n translate\n >\n Uninstall plugin\n </button>\n <button\n class=\"btn btn-default btn-sm m-0\"\n title=\"{{ 'Install plugin' | translate }}\"\n *ngIf=\"installable\"\n (click)=\"installPlugin(plugin)\"\n [ngClass]=\"{ 'btn-pending': plugin.id === updatingPluginId.install }\"\n [disabled]=\"updatingPluginId.install && plugin.id === updatingPluginId.install\"\n data-cy=\"plugin-list--install-plugin-button\"\n translate\n >\n Install plugin\n </button>\n </div>\n </c8y-li>\n </ng-container>\n </ng-container>\n</c8y-list-group>\n<ng-template #emptyList>\n <c8y-ui-empty-state\n [icon]=\"'plugin'\"\n [title]=\"emptyListText | translate\"\n [horizontal]=\"true\"\n *ngIf=\"emptyListText\"\n ></c8y-ui-empty-state>\n</ng-template>\n" }]
}], ctorParameters: () => [{ type: i1.PluginListService }], propDecorators: { plugins$: [{
type: Input
}], emptyListText: [{
type: Input
}], selectable: [{
type: Input
}], hideSource: [{
type: Input
}], installable: [{
type: Input
}], package: [{
type: Input
}], selectedPlugin: [{
type: Input
}], selectedItems: [{
type: Output
}], showOverview: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2luLWxpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vZWNvc3lzdGVtL2FwcGxpY2F0aW9uLXBsdWdpbnMvcGx1Z2luLWxpc3QuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vZWNvc3lzdGVtL2FwcGxpY2F0aW9uLXBsdWdpbnMvcGx1Z2luLWxpc3QuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUl2RSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRWxDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDOzs7Ozs7QUFPMUQsTUFBTSxPQUFPLG1CQUFtQjtJQWtCOUIsWUFBb0IsaUJBQW9DO1FBQXBDLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBbUI7UUFqQnhELHFCQUFnQixHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUM7UUFHeEIsa0JBQWEsR0FBRyxFQUFFLENBQUM7UUFFbkIsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUM1Qjs7V0FFRztRQUNNLGdCQUFXLEdBQUcsS0FBSyxDQUFDO1FBR25CLGtCQUFhLEdBQXNDLElBQUksWUFBWSxFQUFFLENBQUM7UUFDdEUsaUJBQVksR0FBRyxJQUFJLFlBQVksRUFBcUIsQ0FBQztRQUMvRCxvQkFBZSxHQUF5QyxFQUFFLENBQUM7UUFJekQsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxnQkFBZ0IsQ0FBQztJQUNsRSxDQUFDO0lBRUQsbUJBQW1CLENBQUMsUUFBaUIsRUFBRSxNQUF5QjtRQUM5RCxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBQ2hFLE1BQU0sb0JBQW9CLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2pGLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVELGtCQUFrQixDQUFDLE1BQXlCO1FBQzFDLElBQUksTUFBTSxFQUFFLEVBQUUsS0FBSyxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUUsRUFBRSxDQUFDO1lBQzNDLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVELEtBQUssQ0FBQyxhQUFhLENBQUMsTUFBeUI7UUFDM0MsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDakYsQ0FBQztJQUVELEtBQUssQ0FBQyxlQUFlLENBQUMsTUFBeUI7UUFDN0MsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDbkYsQ0FBQzsrR0F6Q1UsbUJBQW1CO21HQUFuQixtQkFBbUIsMFVDYmhDLCs1RkE2RUE7OzRGRGhFYSxtQkFBbUI7a0JBSi9CLFNBQVM7K0JBQ0UsaUJBQWlCO3NGQU1sQixRQUFRO3NCQUFoQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUlHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0ksYUFBYTtzQkFBdEIsTUFBTTtnQkFDRyxZQUFZO3NCQUFyQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IElBcHBsaWNhdGlvbiB9IGZyb20gJ0BjOHkvY2xpZW50JztcbmltcG9ydCB7IEFwcGxpY2F0aW9uUGx1Z2luIH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cyc7XG5cbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgUGx1Z2luTGlzdFNlcnZpY2UgfSBmcm9tICcuL3BsdWdpbi1saXN0LnNlcnZpY2UnO1xuaW1wb3J0IHsgVXBkYXRlVHlwZSB9IGZyb20gJy4vYXBwcy10by11cGRhdGUtcmVtb3Rlcy1zZWxlY3QubW9kZWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktcGx1Z2luLWxpc3QnLFxuICB0ZW1wbGF0ZVVybDogJy4vcGx1Z2luLWxpc3QuY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIFBsdWdpbkxpc3RDb21wb25lbnQge1xuICBDVVJSRU5UX0xPQ0FUSU9OID0gbG9jYXRpb24uaHJlZjtcblxuICBASW5wdXQoKSBwbHVnaW5zJDogT2JzZXJ2YWJsZTxBcHBsaWNhdGlvblBsdWdpbltdPjtcbiAgQElucHV0KCkgZW1wdHlMaXN0VGV4dCA9ICcnO1xuICBASW5wdXQoKSBzZWxlY3RhYmxlOiBib29sZWFuO1xuICBASW5wdXQoKSBoaWRlU291cmNlID0gZmFsc2U7XG4gIC8qKlxuICAgKiBTaG93cyB0aGUgaW5zdGFsbCBidXR0b24gZm9yIGVhY2ggcGx1Z2luIHNlcGFyYXRlbHkuIEN1cnJlbnRseSB1c2VkIGluIHBhY2thZ2UtZGV0YWlscyB2aWV3LlxuICAgKi9cbiAgQElucHV0KCkgaW5zdGFsbGFibGUgPSBmYWxzZTtcbiAgQElucHV0KCkgcGFja2FnZTogSUFwcGxpY2F0aW9uO1xuICBASW5wdXQoKSBzZWxlY3RlZFBsdWdpbjogQXBwbGljYXRpb25QbHVnaW47XG4gIEBPdXRwdXQoKSBzZWxlY3RlZEl0ZW1zOiBFdmVudEVtaXR0ZXI8QXBwbGljYXRpb25QbHVnaW5bXT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBzaG93T3ZlcnZpZXcgPSBuZXcgRXZlbnRFbWl0dGVyPEFwcGxpY2F0aW9uUGx1Z2luPigpO1xuICBzZWxlY3RlZFBsdWdpbnM6IHsgW2tleTogc3RyaW5nXTogQXBwbGljYXRpb25QbHVnaW4gfSA9IHt9O1xuICB1cGRhdGluZ1BsdWdpbklkOiBSZWNvcmQ8VXBkYXRlVHlwZSwgc3RyaW5nPjtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHBsdWdpbkxpc3RTZXJ2aWNlOiBQbHVnaW5MaXN0U2VydmljZSkge1xuICAgIHRoaXMudXBkYXRpbmdQbHVnaW5JZCA9IHRoaXMucGx1Z2luTGlzdFNlcnZpY2UudXBkYXRpbmdQbHVnaW5JZDtcbiAgfVxuXG4gIHVwZGF0ZVNlbGVjdGVkSXRlbXMoc2VsZWN0ZWQ6IGJvb2xlYW4sIHBsdWdpbjogQXBwbGljYXRpb25QbHVnaW4pIHtcbiAgICB0aGlzLnNlbGVjdGVkUGx1Z2luc1twbHVnaW4uaWRdID0gc2VsZWN0ZWQgPyBwbHVnaW4gOiB1bmRlZmluZWQ7XG4gICAgY29uc3Qgb25seUluc3RhbGxlZFBsdWdpbnMgPSBPYmplY3QudmFsdWVzKHRoaXMuc2VsZWN0ZWRQbHVnaW5zKS5maWx0ZXIoQm9vbGVhbik7XG4gICAgdGhpcy5zZWxlY3RlZEl0ZW1zLmVtaXQob25seUluc3RhbGxlZFBsdWdpbnMpO1xuICB9XG5cbiAgc2hvd1BsdWdpbk92ZXJ2aWV3KHBsdWdpbjogQXBwbGljYXRpb25QbHVnaW4pOiB2b2lkIHtcbiAgICBpZiAocGx1Z2luPy5pZCA9PT0gdGhpcy5zZWxlY3RlZFBsdWdpbj8uaWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5zaG93T3ZlcnZpZXcuZW1pdChwbHVnaW4pO1xuICB9XG5cbiAgYXN5bmMgaW5zdGFsbFBsdWdpbihwbHVnaW46IEFwcGxpY2F0aW9uUGx1Z2luKSB7XG4gICAgYXdhaXQgdGhpcy5wbHVnaW5MaXN0U2VydmljZS51cGRhdGVBcHBSZW1vdGVzKHBsdWdpbiwgJ2luc3RhbGwnLCB0aGlzLnBhY2thZ2UpO1xuICB9XG5cbiAgYXN5bmMgdW5pbnN0YWxsUGx1Z2luKHBsdWdpbjogQXBwbGljYXRpb25QbHVnaW4pIHtcbiAgICBhd2FpdCB0aGlzLnBsdWdpbkxpc3RTZXJ2aWNlLnVwZGF0ZUFwcFJlbW90ZXMocGx1Z2luLCAndW5pbnN0YWxsJywgdGhpcy5wYWNrYWdlKTtcbiAgfVxufVxuIiwiPGM4eS1saXN0LWdyb3VwIGNsYXNzPVwiYmctaW5oZXJpdFwiPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwiKHBsdWdpbnMkIHwgYXN5bmMpPy5sZW5ndGggIT09IDA7IGVsc2UgZW1wdHlMaXN0XCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgcGx1Z2luIG9mIHBsdWdpbnMkIHwgYXN5bmNcIj5cbiAgICAgIDxjOHktbGlcbiAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgIGRpc2FibGVkOiBwbHVnaW4uaW5zdGFsbGVkLFxuICAgICAgICAgIHNlbGVjdGVkOiBzZWxlY3RlZFBsdWdpbj8uaWQgPT09IHBsdWdpbj8uaWRcbiAgICAgICAgfVwiXG4gICAgICA+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZml0LXdcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwicGx1Z2luLnJlYWRtZVBhdGhcIj5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgY2xhc3M9XCJjOHktbGlzdF9faXRlbV9fYnRuIGQtZmxleCBmaXQtdyBnYXAtNFwiXG4gICAgICAgICAgICAgIHRpdGxlPVwie3sgJ0RldGFpbHMnIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInNob3dQbHVnaW5PdmVydmlldyhwbHVnaW4pXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPGM4eS1wbHVnaW4tbGlzdC1pdGVtXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJkLWNvbnRlbnRzXCJcbiAgICAgICAgICAgICAgICAoaXNJdGVtU2VsZWN0ZWQpPVwidXBkYXRlU2VsZWN0ZWRJdGVtcygkZXZlbnQsIHBsdWdpbilcIlxuICAgICAgICAgICAgICAgIFtwbHVnaW5dPVwicGx1Z2luXCJcbiAgICAgICAgICAgICAgICBbc2VsZWN0YWJsZV09XCJzZWxlY3RhYmxlXCJcbiAgICAgICAgICAgICAgICBbaGlkZVNvdXJjZV09XCJoaWRlU291cmNlXCJcbiAgICAgICAgICAgICAgPjwvYzh5LXBsdWdpbi1saXN0LWl0ZW0+XG4gICAgICAgICAgICAgIDxpXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJpY29uLTI0IG0tbC1hdXRvIGEtcy1jZW50ZXJcIlxuICAgICAgICAgICAgICAgIGM4eUljb249XCJmb3J3YXJkXCJcbiAgICAgICAgICAgICAgPjwvaT5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhcGx1Z2luLnJlYWRtZVBhdGhcIj5cbiAgICAgICAgICAgIDxjOHktcGx1Z2luLWxpc3QtaXRlbVxuICAgICAgICAgICAgICBjbGFzcz1cImQtY29udGVudHNcIlxuICAgICAgICAgICAgICAoaXNJdGVtU2VsZWN0ZWQpPVwidXBkYXRlU2VsZWN0ZWRJdGVtcygkZXZlbnQsIHBsdWdpbilcIlxuICAgICAgICAgICAgICBbcGx1Z2luXT1cInBsdWdpblwiXG4gICAgICAgICAgICAgIFtzZWxlY3RhYmxlXT1cInNlbGVjdGFibGVcIlxuICAgICAgICAgICAgICBbaGlkZVNvdXJjZV09XCJoaWRlU291cmNlXCJcbiAgICAgICAgICAgID48L2M4eS1wbHVnaW4tbGlzdC1pdGVtPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInAtbC00MCBtLXQtNCBkLWZsZXggZmxleC13cmFwIGdhcC04XCI+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLWRhbmdlciBidG4tc21cIlxuICAgICAgICAgICAgdGl0bGU9XCJ7eyAnVW5pbnN0YWxsIHBsdWdpbicgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgICAgKm5nSWY9XCJpbnN0YWxsYWJsZVwiXG4gICAgICAgICAgICAoY2xpY2spPVwidW5pbnN0YWxsUGx1Z2luKHBsdWdpbilcIlxuICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAnYnRuLXBlbmRpbmcnOiBwbHVnaW4uaWQgPT09IHVwZGF0aW5nUGx1Z2luSWQudW5pbnN0YWxsIH1cIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cInVwZGF0aW5nUGx1Z2luSWQudW5pbnN0YWxsICYmIHBsdWdpbi5pZCA9PT0gdXBkYXRpbmdQbHVnaW5JZC51bmluc3RhbGxcIlxuICAgICAgICAgICAgZGF0YS1jeT1cInBsdWdpbi1saXN0LS11bmluc3RhbGwtcGx1Z2luLWJ1dHRvblwiXG4gICAgICAgICAgICB0cmFuc2xhdGVcbiAgICAgICAgICA+XG4gICAgICAgICAgICBVbmluc3RhbGwgcGx1Z2luXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgY2xhc3M9XCJidG4gYnRuLWRlZmF1bHQgYnRuLXNtIG0tMFwiXG4gICAgICAgICAgICB0aXRsZT1cInt7ICdJbnN0YWxsIHBsdWdpbicgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgICAgKm5nSWY9XCJpbnN0YWxsYWJsZVwiXG4gICAgICAgICAgICAoY2xpY2spPVwiaW5zdGFsbFBsdWdpbihwbHVnaW4pXCJcbiAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgJ2J0bi1wZW5kaW5nJzogcGx1Z2luLmlkID09PSB1cGRhdGluZ1BsdWdpbklkLmluc3RhbGwgfVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwidXBkYXRpbmdQbHVnaW5JZC5pbnN0YWxsICYmIHBsdWdpbi5pZCA9PT0gdXBkYXRpbmdQbHVnaW5JZC5pbnN0YWxsXCJcbiAgICAgICAgICAgIGRhdGEtY3k9XCJwbHVnaW4tbGlzdC0taW5zdGFsbC1wbHVnaW4tYnV0dG9uXCJcbiAgICAgICAgICAgIHRyYW5zbGF0ZVxuICAgICAgICAgID5cbiAgICAgICAgICAgIEluc3RhbGwgcGx1Z2luXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9jOHktbGk+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvbmctY29udGFpbmVyPlxuPC9jOHktbGlzdC1ncm91cD5cbjxuZy10ZW1wbGF0ZSAjZW1wdHlMaXN0PlxuICA8Yzh5LXVpLWVtcHR5LXN0YXRlXG4gICAgW2ljb25dPVwiJ3BsdWdpbidcIlxuICAgIFt0aXRsZV09XCJlbXB0eUxpc3RUZXh0IHwgdHJhbnNsYXRlXCJcbiAgICBbaG9yaXpvbnRhbF09XCJ0cnVlXCJcbiAgICAqbmdJZj1cImVtcHR5TGlzdFRleHRcIlxuICA+PC9jOHktdWktZW1wdHktc3RhdGU+XG48L25nLXRlbXBsYXRlPlxuIl19