UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

201 lines 48.3 kB
import { ChangeDetectorRef, Component, EventEmitter, Input, Output } from '@angular/core'; import { gettext } from '@c8y/ngx-components'; import { TranslateService } from '@ngx-translate/core'; import { Subject } from 'rxjs'; import { filter, takeUntil } from 'rxjs/operators'; import { AssetsNavigatorAction } from '../action.enum'; import { AssetSelectorService } from './asset-selector.service'; import { GroupNode } from './group-node'; import * as i0 from "@angular/core"; import * as i1 from "@ngx-translate/core"; import * as i2 from "./asset-selector.service"; import * as i3 from "@c8y/ngx-components"; import * as i4 from "@angular/common"; import * as i5 from "ngx-bootstrap/collapse"; export class AssetSelectorNodeComponent { /** * @ignore */ get expandTitle() { return !this.node.open ? gettext('Expand') : gettext('Collapse'); } /** * @ignore only di */ constructor(translateService, cd, assetSelectorService) { this.translateService = translateService; this.cd = cd; this.assetSelectorService = assetSelectorService; /** * All preselected items. */ this.preselected = []; /** * Should the path be shown. */ this.showPath = false; /** * Can the user select multiple assets. */ this.multi = false; /** * The current path to the node. */ this.view = 'tree'; this.disabled = false; /** * Event, which indicates whether the loading of the node has completed. */ this.isLoadingState = new EventEmitter(); /** * Event that emits when a node is selected. */ this.onSelect = new EventEmitter(); /** * Event that emits when a node is deselected. */ this.onDeselect = new EventEmitter(); /** * @ignore */ this.level = 0; /** * @ignore */ this.unsubscribe$ = new Subject(); this.isNodeSelectable = true; /** sets the `btn-pending` class in the load more button */ this.isLoading = false; } /** * @ignore */ async ngOnInit() { this.isNodeSelectable = this.assetSelectorService.isNodeSelectable(this.node); this.breadcrumb = this.node.label; this.setupBreadcrumbsAndLevel(this.node); if (this.node instanceof GroupNode) { this.node.hookEvents(); } // open on startup if (this.node.root) { this.click(); } // used for loading and to trigger change detection when the node is no longer loading. if (this.node.events) { this.node.events .pipe(takeUntil(this.unsubscribe$), filter((a) => a === AssetsNavigatorAction.LOADING_DONE)) .subscribe(() => { this.isLoadingState.emit(false); this.cd.markForCheck(); }); } } /** * Opens a node. */ click() { this.node.open = !this.node.open; this.node.click({ open: this.node.open }); } setupBreadcrumbsAndLevel(node) { if (node.parents && node.parents.length) { const parent = node.parents[0]; this.breadcrumb = this.translateService.instant(parent.label) + ' > ' + this.translateService.instant(this.breadcrumb); this.level++; this.setupBreadcrumbsAndLevel(parent); } } /** * Selects the node and emits a change on the parent component. * @param node The node to select. */ selected(node) { if (node.mo) { this.updateSelection(node.mo); return; } this.click(); } /** * Handles clicks on a item in Miller View. * @param node The node that was clicked. */ millerViewClick(node) { node.breadcrumb = this.breadcrumb; if (!this.handleNextMillerViewColumn) { return; } const shouldHandleDefault = this.handleNextMillerViewColumn(node, this.index); if (shouldHandleDefault) { this.selected(node); } } /** * @ignore */ ngOnDestroy() { this.unsubscribe$.next(); this.unsubscribe$.complete(); } isSelected() { if (!this.node.mo) { return false; } return this.assetSelectorService.getIndexOfSelected(this.preselected, this.node.mo) > -1; } isActive() { if (this.active && this.node.mo) { return this.active.mo?.id === this.node.mo.id; } return false; } updateSelection(selectedMo) { if (!this.multi) { this.onDeselect.emit({ deselectMode: 'all', mo: selectedMo }); return; } if (this.isSelected()) { this.onDeselect.emit({ deselectMode: 'single', mo: selectedMo }); return; } this.onSelect.emit(selectedMo); this.cd.markForCheck(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AssetSelectorNodeComponent, deps: [{ token: i1.TranslateService }, { token: i0.ChangeDetectorRef }, { token: i2.AssetSelectorService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: AssetSelectorNodeComponent, selector: "c8y-asset-selector-node", inputs: { node: "node", rootNode: "rootNode", preselected: "preselected", showPath: "showPath", multi: "multi", view: "view", index: "index", active: "active", handleNextMillerViewColumn: "handleNextMillerViewColumn", disabled: "disabled" }, outputs: { isLoadingState: "isLoadingState", onSelect: "onSelect", onDeselect: "onDeselect" }, ngImport: i0, template: "<!-- Hierarchy tree -->\n<div\n class=\"c8y-asset-selector__item\"\n [ngStyle]=\"{\n 'margin-left': level > 1 ? 16 + 'px' : '0'\n }\"\n *ngIf=\"view === 'tree'\"\n [attr.role]=\"view === 'tree' ? 'tree' : 'list'\"\n [ngClass]=\"{\n 'c8y-asset-selector__item--more': node?.icon === 'plus',\n 'c8y-asset-selector__item--start': level === 0\n }\"\n>\n <div\n class=\"c8y-asset-selector__node\"\n title=\"{{ breadcrumb | translate }}\"\n *ngIf=\"node && !node.root && !node.hidden\"\n [attr.role]=\"view === 'tree' ? 'treeitem' : 'listitem'\"\n [ngClass]=\"{ 'c8y-asset-selector__node--open': node?.open }\"\n >\n <!-- expand button -->\n <div class=\"c8y-asset-selector__node__btn-spacer\">\n <button\n class=\"collapse-btn btn-dot\"\n [title]=\"expandTitle | translate\"\n [attr.aria-expanded]=\"node.open\"\n (click)=\"click()\"\n *ngIf=\"node.isGroup() || node.hasChildDevices()\"\n >\n <i c8yIcon=\"angle-right\"></i>\n </button>\n </div>\n <div\n class=\"d-flex a-i-center p-t-4 p-b-4\"\n *ngIf=\"node.toString() !== 'LoadMoreNode' && isNodeSelectable\"\n >\n <label [ngClass]=\"{ 'c8y-checkbox': multi, 'c8y-radio': !multi }\">\n <input\n id=\"nodeLabel\"\n [type]=\"multi ? 'checkbox' : 'radio'\"\n (change)=\"selected(node)\"\n [checked]=\"isSelected()\"\n [disabled]=\"disabled || !node.groupsSelectable && node.isGroup()\"\n />\n <span></span>\n <span\n class=\"sr-only\"\n for=\"nodeLabel\"\n translate\n >\n Node label\n </span>\n </label>\n </div>\n\n <!-- group button -->\n <button\n class=\"c8y-asset-selector__btn text-truncate\"\n [attr.aria-expanded]=\"!node.open\"\n *ngIf=\"node.isGroup() || node.hasChildDevices()\"\n (click)=\"click()\"\n >\n <i\n class=\"c8y-icon c8y-icon-duocolor m-r-4 text-16\"\n [c8yIcon]=\"node.icon\"\n [title]=\"'Smart group' | translate\"\n *ngIf=\"node.icon === 'c8y-group-smart'\"\n ></i>\n <i\n class=\"c8y-icon c8y-icon-duocolor m-r-4 text-16\"\n [c8yIcon]=\"node.icon\"\n [title]=\"'Group' | translate\"\n *ngIf=\"node.icon !== 'c8y-group-smart'\"\n ></i>\n <span title=\"{{ breadcrumb }}\">\n {{ node.translateLabel ? (node.label | translate) : node.label }}\n <!-- use just for search results to display the path -->\n <p\n class=\"text-truncate\"\n *ngIf=\"showPath\"\n >\n <small\n class=\"text-muted\"\n title=\"{{ breadcrumb }}\"\n >\n <em>{{ breadcrumb }}</em>\n </small>\n </p>\n <!-- up to here -->\n </span>\n </button>\n <!-- not a group button -->\n <button\n class=\"flex-grow\"\n title=\"{{ breadcrumb }}\"\n type=\"button\"\n *ngIf=\"!node.isGroup() && !node.hasChildDevices()\"\n [ngClass]=\"{\n 'btn btn-default btn-sm m-b-8 m-r-8 d-flex j-c-center': node.icon === 'plus',\n 'c8y-asset-selector__btn text-truncate': node.icon != 'plus'\n }\"\n (click)=\"selected(node)\"\n >\n <i\n class=\"c8y-icon c8y-icon-duocolor m-r-4 text-16\"\n [c8yIcon]=\"node.icon\"\n [title]=\"'Smart group' | translate\"\n *ngIf=\"node.icon === 'c8y-group-smart'\"\n ></i>\n <i\n class=\"c8y-icon m-r-4\"\n [c8yIcon]=\"node.icon\"\n [title]=\"'Group' | translate\"\n *ngIf=\"node.icon !== 'c8y-group-smart'\"\n [ngClass]=\"{ 'c8y-icon-duocolor text-16 ': node.icon != 'plus' }\"\n ></i>\n <span title=\"{{ breadcrumb }}\">\n {{ node.translateLabel ? (node.label | translate) : node.label }}\n <!-- use just for search results to display the path -->\n <p\n class=\"text-truncate text-muted small\"\n *ngIf=\"showPath\"\n >\n <em>{{ breadcrumb }}</em>\n </p>\n <!-- up to here -->\n </span>\n </button>\n </div>\n <div\n class=\"collapse\"\n *ngIf=\"node.countChildren()\"\n [collapse]=\"!node.open\"\n [isAnimated]=\"true\"\n [attr.role]=\"'group'\"\n >\n <c8y-asset-selector-node\n *ngFor=\"let childNode of node.children\"\n [node]=\"childNode\"\n [preselected]=\"preselected || []\"\n [disabled]=\"disabled\"\n [multi]=\"multi\"\n [active]=\"active\"\n [attr.role]=\"view === 'tree' ? 'treeitem' : 'listitem'\"\n (onSelect)=\"onSelect.emit($event)\"\n (onDeselect)=\"onDeselect.emit($event)\"\n ></c8y-asset-selector-node>\n </div>\n</div>\n\n<!-- Miller columns -->\n<div *ngIf=\"view === 'miller'\">\n <div\n class=\"miller-column__item bg-inherit\"\n title=\"{{ breadcrumb | translate }}\"\n *ngIf=\"node && !node.root && !node.hidden && node !== rootNode\"\n [ngClass]=\"{\n active: isActive(),\n 'miller-column__item--more': node.toString() === 'LoadMoreNode'\n }\"\n >\n <div\n class=\"m-l-4 m-r-4 miller-column__item__checkbox\"\n *ngIf=\"node.toString() !== 'LoadMoreNode'\"\n >\n <label [ngClass]=\"{ 'c8y-radio': !multi, 'c8y-checkbox': multi }\">\n <input\n id=\"nodeLabel2\"\n [type]=\"multi ? 'checkbox' : 'radio'\"\n (change)=\"selected(node)\"\n [checked]=\"isSelected()\"\n [disabled]=\"disabled || !node.groupsSelectable && node.isGroup()\"\n />\n <span></span>\n <span\n class=\"sr-only\"\n for=\"nodeLabel2\"\n translate\n >\n Node label\n </span>\n </label>\n </div>\n\n <button\n title=\"{{ breadcrumb | translate }}\"\n type=\"button\"\n [ngClass]=\"{\n 'btn btn-default btn-sm d-flex flex-grow j-c-center m-l-16 m-r-16 m-b-4 m-t-4':\n node.toString() === 'LoadMoreNode',\n 'miller-column__item__btn': node.toString() !== 'LoadMoreNode',\n 'btn-pending': node.loading && node.toString() === 'LoadMoreNode'\n }\"\n (click)=\"millerViewClick(node)\"\n >\n <i\n class=\"c8y-icon m-r-4\"\n [c8yIcon]=\"node.icon\"\n [ngClass]=\"{ 'c8y-icon-duocolor text-16': node.toString() !== 'LoadMoreNode' }\"\n ></i>\n <div class=\"text-left text-truncate\">\n <p\n class=\"text-truncate\"\n title=\"{{ node.translateLabel ? (node.label | translate) : node.label }}\"\n >\n {{ node.translateLabel ? (node.label | translate) : node.label }}\n </p>\n <!-- use just for search results to display the path -->\n <small\n class=\"text-muted text-truncate\"\n title=\"{{ breadcrumb }}\"\n *ngIf=\"showPath\"\n >\n <em>{{ breadcrumb }}</em>\n </small>\n <!-- up to here -->\n </div>\n <span\n class=\"p-l-4 m-l-auto\"\n *ngIf=\"node.isGroup() || node.hasChildDevices()\"\n >\n <i c8yIcon=\"angle-right\"></i>\n </span>\n </button>\n </div>\n\n <div\n role=\"list\"\n *ngIf=\"node\"\n [ngClass]=\"{ hidden: node !== rootNode }\"\n >\n <c8y-asset-selector-node\n role=\"listitem\"\n *ngFor=\"let childNode of node.children\"\n [node]=\"childNode\"\n [rootNode]=\"rootNode\"\n [preselected]=\"preselected || []\"\n [multi]=\"multi\"\n [view]=\"view\"\n [index]=\"index\"\n [active]=\"active\"\n [disabled]=\"disabled\"\n [handleNextMillerViewColumn]=\"handleNextMillerViewColumn\"\n (onSelect)=\"onSelect.emit($event)\"\n (onDeselect)=\"onDeselect.emit($event)\"\n ></c8y-asset-selector-node>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i3.IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: i3.C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i5.CollapseDirective, selector: "[collapse]", inputs: ["display", "isAnimated", "collapse"], outputs: ["collapsed", "collapses", "expanded", "expands"], exportAs: ["bs-collapse"] }, { kind: "component", type: AssetSelectorNodeComponent, selector: "c8y-asset-selector-node", inputs: ["node", "rootNode", "preselected", "showPath", "multi", "view", "index", "active", "handleNextMillerViewColumn", "disabled"], outputs: ["isLoadingState", "onSelect", "onDeselect"] }, { kind: "pipe", type: i3.C8yTranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: AssetSelectorNodeComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-asset-selector-node', template: "<!-- Hierarchy tree -->\n<div\n class=\"c8y-asset-selector__item\"\n [ngStyle]=\"{\n 'margin-left': level > 1 ? 16 + 'px' : '0'\n }\"\n *ngIf=\"view === 'tree'\"\n [attr.role]=\"view === 'tree' ? 'tree' : 'list'\"\n [ngClass]=\"{\n 'c8y-asset-selector__item--more': node?.icon === 'plus',\n 'c8y-asset-selector__item--start': level === 0\n }\"\n>\n <div\n class=\"c8y-asset-selector__node\"\n title=\"{{ breadcrumb | translate }}\"\n *ngIf=\"node && !node.root && !node.hidden\"\n [attr.role]=\"view === 'tree' ? 'treeitem' : 'listitem'\"\n [ngClass]=\"{ 'c8y-asset-selector__node--open': node?.open }\"\n >\n <!-- expand button -->\n <div class=\"c8y-asset-selector__node__btn-spacer\">\n <button\n class=\"collapse-btn btn-dot\"\n [title]=\"expandTitle | translate\"\n [attr.aria-expanded]=\"node.open\"\n (click)=\"click()\"\n *ngIf=\"node.isGroup() || node.hasChildDevices()\"\n >\n <i c8yIcon=\"angle-right\"></i>\n </button>\n </div>\n <div\n class=\"d-flex a-i-center p-t-4 p-b-4\"\n *ngIf=\"node.toString() !== 'LoadMoreNode' && isNodeSelectable\"\n >\n <label [ngClass]=\"{ 'c8y-checkbox': multi, 'c8y-radio': !multi }\">\n <input\n id=\"nodeLabel\"\n [type]=\"multi ? 'checkbox' : 'radio'\"\n (change)=\"selected(node)\"\n [checked]=\"isSelected()\"\n [disabled]=\"disabled || !node.groupsSelectable && node.isGroup()\"\n />\n <span></span>\n <span\n class=\"sr-only\"\n for=\"nodeLabel\"\n translate\n >\n Node label\n </span>\n </label>\n </div>\n\n <!-- group button -->\n <button\n class=\"c8y-asset-selector__btn text-truncate\"\n [attr.aria-expanded]=\"!node.open\"\n *ngIf=\"node.isGroup() || node.hasChildDevices()\"\n (click)=\"click()\"\n >\n <i\n class=\"c8y-icon c8y-icon-duocolor m-r-4 text-16\"\n [c8yIcon]=\"node.icon\"\n [title]=\"'Smart group' | translate\"\n *ngIf=\"node.icon === 'c8y-group-smart'\"\n ></i>\n <i\n class=\"c8y-icon c8y-icon-duocolor m-r-4 text-16\"\n [c8yIcon]=\"node.icon\"\n [title]=\"'Group' | translate\"\n *ngIf=\"node.icon !== 'c8y-group-smart'\"\n ></i>\n <span title=\"{{ breadcrumb }}\">\n {{ node.translateLabel ? (node.label | translate) : node.label }}\n <!-- use just for search results to display the path -->\n <p\n class=\"text-truncate\"\n *ngIf=\"showPath\"\n >\n <small\n class=\"text-muted\"\n title=\"{{ breadcrumb }}\"\n >\n <em>{{ breadcrumb }}</em>\n </small>\n </p>\n <!-- up to here -->\n </span>\n </button>\n <!-- not a group button -->\n <button\n class=\"flex-grow\"\n title=\"{{ breadcrumb }}\"\n type=\"button\"\n *ngIf=\"!node.isGroup() && !node.hasChildDevices()\"\n [ngClass]=\"{\n 'btn btn-default btn-sm m-b-8 m-r-8 d-flex j-c-center': node.icon === 'plus',\n 'c8y-asset-selector__btn text-truncate': node.icon != 'plus'\n }\"\n (click)=\"selected(node)\"\n >\n <i\n class=\"c8y-icon c8y-icon-duocolor m-r-4 text-16\"\n [c8yIcon]=\"node.icon\"\n [title]=\"'Smart group' | translate\"\n *ngIf=\"node.icon === 'c8y-group-smart'\"\n ></i>\n <i\n class=\"c8y-icon m-r-4\"\n [c8yIcon]=\"node.icon\"\n [title]=\"'Group' | translate\"\n *ngIf=\"node.icon !== 'c8y-group-smart'\"\n [ngClass]=\"{ 'c8y-icon-duocolor text-16 ': node.icon != 'plus' }\"\n ></i>\n <span title=\"{{ breadcrumb }}\">\n {{ node.translateLabel ? (node.label | translate) : node.label }}\n <!-- use just for search results to display the path -->\n <p\n class=\"text-truncate text-muted small\"\n *ngIf=\"showPath\"\n >\n <em>{{ breadcrumb }}</em>\n </p>\n <!-- up to here -->\n </span>\n </button>\n </div>\n <div\n class=\"collapse\"\n *ngIf=\"node.countChildren()\"\n [collapse]=\"!node.open\"\n [isAnimated]=\"true\"\n [attr.role]=\"'group'\"\n >\n <c8y-asset-selector-node\n *ngFor=\"let childNode of node.children\"\n [node]=\"childNode\"\n [preselected]=\"preselected || []\"\n [disabled]=\"disabled\"\n [multi]=\"multi\"\n [active]=\"active\"\n [attr.role]=\"view === 'tree' ? 'treeitem' : 'listitem'\"\n (onSelect)=\"onSelect.emit($event)\"\n (onDeselect)=\"onDeselect.emit($event)\"\n ></c8y-asset-selector-node>\n </div>\n</div>\n\n<!-- Miller columns -->\n<div *ngIf=\"view === 'miller'\">\n <div\n class=\"miller-column__item bg-inherit\"\n title=\"{{ breadcrumb | translate }}\"\n *ngIf=\"node && !node.root && !node.hidden && node !== rootNode\"\n [ngClass]=\"{\n active: isActive(),\n 'miller-column__item--more': node.toString() === 'LoadMoreNode'\n }\"\n >\n <div\n class=\"m-l-4 m-r-4 miller-column__item__checkbox\"\n *ngIf=\"node.toString() !== 'LoadMoreNode'\"\n >\n <label [ngClass]=\"{ 'c8y-radio': !multi, 'c8y-checkbox': multi }\">\n <input\n id=\"nodeLabel2\"\n [type]=\"multi ? 'checkbox' : 'radio'\"\n (change)=\"selected(node)\"\n [checked]=\"isSelected()\"\n [disabled]=\"disabled || !node.groupsSelectable && node.isGroup()\"\n />\n <span></span>\n <span\n class=\"sr-only\"\n for=\"nodeLabel2\"\n translate\n >\n Node label\n </span>\n </label>\n </div>\n\n <button\n title=\"{{ breadcrumb | translate }}\"\n type=\"button\"\n [ngClass]=\"{\n 'btn btn-default btn-sm d-flex flex-grow j-c-center m-l-16 m-r-16 m-b-4 m-t-4':\n node.toString() === 'LoadMoreNode',\n 'miller-column__item__btn': node.toString() !== 'LoadMoreNode',\n 'btn-pending': node.loading && node.toString() === 'LoadMoreNode'\n }\"\n (click)=\"millerViewClick(node)\"\n >\n <i\n class=\"c8y-icon m-r-4\"\n [c8yIcon]=\"node.icon\"\n [ngClass]=\"{ 'c8y-icon-duocolor text-16': node.toString() !== 'LoadMoreNode' }\"\n ></i>\n <div class=\"text-left text-truncate\">\n <p\n class=\"text-truncate\"\n title=\"{{ node.translateLabel ? (node.label | translate) : node.label }}\"\n >\n {{ node.translateLabel ? (node.label | translate) : node.label }}\n </p>\n <!-- use just for search results to display the path -->\n <small\n class=\"text-muted text-truncate\"\n title=\"{{ breadcrumb }}\"\n *ngIf=\"showPath\"\n >\n <em>{{ breadcrumb }}</em>\n </small>\n <!-- up to here -->\n </div>\n <span\n class=\"p-l-4 m-l-auto\"\n *ngIf=\"node.isGroup() || node.hasChildDevices()\"\n >\n <i c8yIcon=\"angle-right\"></i>\n </span>\n </button>\n </div>\n\n <div\n role=\"list\"\n *ngIf=\"node\"\n [ngClass]=\"{ hidden: node !== rootNode }\"\n >\n <c8y-asset-selector-node\n role=\"listitem\"\n *ngFor=\"let childNode of node.children\"\n [node]=\"childNode\"\n [rootNode]=\"rootNode\"\n [preselected]=\"preselected || []\"\n [multi]=\"multi\"\n [view]=\"view\"\n [index]=\"index\"\n [active]=\"active\"\n [disabled]=\"disabled\"\n [handleNextMillerViewColumn]=\"handleNextMillerViewColumn\"\n (onSelect)=\"onSelect.emit($event)\"\n (onDeselect)=\"onDeselect.emit($event)\"\n ></c8y-asset-selector-node>\n </div>\n</div>\n" }] }], ctorParameters: () => [{ type: i1.TranslateService }, { type: i0.ChangeDetectorRef }, { type: i2.AssetSelectorService }], propDecorators: { node: [{ type: Input }], rootNode: [{ type: Input }], preselected: [{ type: Input }], showPath: [{ type: Input }], multi: [{ type: Input }], view: [{ type: Input }], index: [{ type: Input }], active: [{ type: Input }], handleNextMillerViewColumn: [{ type: Input }], disabled: [{ type: Input }], isLoadingState: [{ type: Output }], onSelect: [{ type: Output }], onDeselect: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXQtc2VsZWN0b3Itbm9kZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9hc3NldHMtbmF2aWdhdG9yL2Fzc2V0LXNlbGVjdG9yL2Fzc2V0LXNlbGVjdG9yLW5vZGUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vYXNzZXRzLW5hdmlnYXRvci9hc3NldC1zZWxlY3Rvci9hc3NldC1zZWxlY3Rvci1ub2RlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFbEcsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNuRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDOzs7Ozs7O0FBTXpDLE1BQU0sT0FBTywwQkFBMEI7SUFtRXJDOztPQUVHO0lBQ0gsSUFBSSxXQUFXO1FBQ2IsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNuRSxDQUFDO0lBRUQ7O09BRUc7SUFDSCxZQUNVLGdCQUFrQyxFQUNsQyxFQUFxQixFQUN0QixvQkFBMEM7UUFG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QkFJRyxLQUFLO3NCQUFiLEtBQUs7Z0JBSUcsSUFBSTtzQkFBWixLQUFLO2dCQUtHLEtBQUs7c0JBQWIsS0FBSztnQkFJRyxNQUFNO3NCQUFkLEtBQUs7Z0JBSUcsMEJBQTBCO3NCQUFsQyxLQUFLO2dCQUVHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBSUksY0FBYztzQkFBdkIsTUFBTTtnQkFJRyxRQUFRO3NCQUFqQixNQUFNO2dCQUlHLFVBQVU7c0JBQW5CLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSUlkZW50aWZpZWQsIElNYW5hZ2VkT2JqZWN0IH0gZnJvbSAnQGM4eS9jbGllbnQnO1xuaW1wb3J0IHsgZ2V0dGV4dCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlsdGVyLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBBc3NldHNOYXZpZ2F0b3JBY3Rpb24gfSBmcm9tICcuLi9hY3Rpb24uZW51bSc7XG5pbXBvcnQgeyBBc3NldFNlbGVjdG9yU2VydmljZSB9IGZyb20gJy4vYXNzZXQtc2VsZWN0b3Iuc2VydmljZSc7XG5pbXBvcnQgeyBHcm91cE5vZGUgfSBmcm9tICcuL2dyb3VwLW5vZGUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktYXNzZXQtc2VsZWN0b3Itbm9kZScsXG4gIHRlbXBsYXRlVXJsOiAnLi9hc3NldC1zZWxlY3Rvci1ub2RlLmNvbXBvbmVudC5odG1sJ1xufSlcbmV4cG9ydCBjbGFzcyBBc3NldFNlbGVjdG9yTm9kZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIC8qKlxuICAgKiBUaGUgY3VycmVudCBub2RlLlxuICAgKi9cbiAgQElucHV0KCkgbm9kZTogR3JvdXBOb2RlO1xuICAvKipcbiAgICogUm9vdCBub2RlLiBOb2RlIGZvdW5kIGF0IHRoZSB0b3Agb2YgdGhlIGhpZXJhcmNoeS5cbiAgICovXG4gIEBJbnB1dCgpIHJvb3ROb2RlOiBHcm91cE5vZGU7XG4gIC8qKlxuICAgKiBBbGwgcHJlc2VsZWN0ZWQgaXRlbXMuXG4gICAqL1xuICBASW5wdXQoKSBwcmVzZWxlY3RlZDogSUlkZW50aWZpZWQgfCBJSWRlbnRpZmllZFtdID0gW107XG4gIC8qKlxuICAgKiBTaG91bGQgdGhlIHBhdGggYmUgc2hvd24uXG4gICAqL1xuICBASW5wdXQoKSBzaG93UGF0aCA9IGZhbHNlO1xuICAvKipcbiAgICogQ2FuIHRoZSB1c2VyIHNlbGVjdCBtdWx0aXBsZSBhc3NldHMuXG4gICAqL1xuICBASW5wdXQoKSBtdWx0aSA9IGZhbHNlO1xuICAvKipcbiAgICogVGhlIGN1cnJlbnQgcGF0aCB0byB0aGUgbm9kZS5cbiAgICovXG4gIEBJbnB1dCgpIHZpZXc6ICd0cmVlJyB8ICdtaWxsZXInID0gJ3RyZWUnO1xuICAvKipcbiAgICogVXNlZCBvbmx5IGZvciBtaWxsZXItdmlldywgZGlzcGxheXMgdGhlIGNvbHVtbiBsZXZlbCBmb3IgdGhlIGN1cnJlbnQgbm9kZS5cbiAgICogRS5nIGlmIHRoZSBpbmRleCBpcyBvbmUsIHRoaXMgd2lsbCBiZSBzZWNvbmQgY29sdW1uLlxuICAgKi9cbiAgQElucHV0KCkgaW5kZXg7XG4gIC8qKlxuICAgKiBTZXRzIHRoZSBhY3RpdmUgbm9kZS5cbiAgICovXG4gIEBJbnB1dCgpIGFjdGl2ZTogR3JvdXBOb2RlO1xuICAvKipcbiAgICogQSBmdW5jdGlvbiB0aGF0IHNob3VsZCB2ZXJpZnkgdGhlIG5lZWQgdG8gYWRkIGEgY29sdW1uIHdoZW4gYSBub2RlIGlzIGNsaWNrZWQuXG4gICAqL1xuICBASW5wdXQoKSBoYW5kbGVOZXh0TWlsbGVyVmlld0NvbHVtbjogKG5vZGU6IEdyb3VwTm9kZSwgaW5kZXg6IG51bWJlcikgPT4gYm9vbGVhbjtcblxuICBASW5wdXQoKSBkaXNhYmxlZCA9IGZhbHNlO1xuICAvKipcbiAgICogRXZlbnQsIHdoaWNoIGluZGljYXRlcyB3aGV0aGVyIHRoZSBsb2FkaW5nIG9mIHRoZSBub2RlIGhhcyBjb21wbGV0ZWQuXG4gICAqL1xuICBAT3V0cHV0KCkgaXNMb2FkaW5nU3RhdGU6IEV2ZW50RW1pdHRlcjxib29sZWFuPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgLyoqXG4gICAqIEV2ZW50IHRoYXQgZW1pdHMgd2hlbiBhIG5vZGUgaXMgc2VsZWN0ZWQuXG4gICAqL1xuICBAT3V0cHV0KCkgb25TZWxlY3Q6IEV2ZW50RW1pdHRlcjxJTWFuYWdlZE9iamVjdD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIC8qKlxuICAgKiBFdmVudCB0aGF0IGVtaXRzIHdoZW4gYSBub2RlIGlzIGRlc2VsZWN0ZWQuXG4gICAqL1xuICBAT3V0cHV0KCkgb25EZXNlbGVjdDogRXZlbnRFbWl0dGVyPHsgZGVzZWxlY3RNb2RlOiAnc2luZ2xlJyB8ICdhbGwnOyBtbzogSU1hbmFnZWRPYmplY3QgfT4gPVxuICAgIG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICBicmVhZGNydW1iOiBzdHJpbmc7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBsZXZlbCA9IDA7XG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICB1bnN1YnNjcmliZSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBpc05vZGVTZWxlY3RhYmxlID0gdHJ1ZTtcblxuICAvKiogc2V0cyB0aGUgYGJ0bi1wZW5kaW5nYCBjbGFzcyBpbiB0aGUgbG9hZCBtb3JlIGJ1dHRvbiAqL1xuICBpc0xvYWRpbmcgPSBmYWxzZTtcbiAgLyoqXG4gICAqIEBpZ25vcmVcbiAgICovXG4gIGdldCBleHBhbmRUaXRsZSgpIHtcbiAgICByZXR1cm4gIXRoaXMubm9kZS5vcGVuID8gZ2V0dGV4dCgnRXhwYW5kJykgOiBnZXR0ZXh0KCdDb2xsYXBzZScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpZ25vcmUgb25seSBkaVxuICAgKi9cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSB0cmFuc2xhdGVTZXJ2aWNlOiBUcmFuc2xhdGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2Q6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHB1YmxpYyBhc3NldFNlbGVjdG9yU2VydmljZTogQXNzZXRTZWxlY3RvclNlcnZpY2VcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBAaWdub3JlXG4gICAqL1xuICBhc3luYyBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmlzTm9kZVNlbGVjdGFibGUgPSB0aGlzLmFzc2V0U2VsZWN0b3JTZXJ2aWNlLmlzTm9kZVNlbGVjdGFibGUodGhpcy5ub2RlKTtcbiAgICB0aGlzLmJyZWFkY3J1bWIgPSB0aGlzLm5vZGUubGFiZWw7XG4gICAgdGhpcy5zZXR1cEJyZWFkY3J1bWJzQW5kTGV2ZWwodGhpcy5ub2RlKTtcblxuICAgIGlmICh0aGlzLm5vZGUgaW5zdGFuY2VvZiBHcm91cE5vZGUpIHtcbiAgICAgIHRoaXMubm9kZS5ob29rRXZlbnRzKCk7XG4gICAgfVxuXG4gICAgLy8gb3BlbiBvbiBzdGFydHVwXG4gICAgaWYgKHRoaXMubm9kZS5yb290KSB7XG4gICAgICB0aGlzLmNsaWNrKCk7XG4gICAgfVxuXG4gICAgLy8gdXNlZCBmb3IgbG9hZGluZyBhbmQgdG8gdHJpZ2dlciBjaGFuZ2UgZGV0ZWN0aW9uIHdoZW4gdGhlIG5vZGUgaXMgbm8gbG9uZ2VyIGxvYWRpbmcuXG4gICAgaWYgKHRoaXMubm9kZS5ldmVudHMpIHtcbiAgICAgIHRoaXMubm9kZS5ldmVudHNcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgdGFrZVVudGlsKHRoaXMudW5zdWJzY3JpYmUkKSxcbiAgICAgICAgICBmaWx0ZXIoKGE6IEFzc2V0c05hdmlnYXRvckFjdGlvbikgPT4gYSA9PT0gQXNzZXRzTmF2aWdhdG9yQWN0aW9uLkxPQURJTkdfRE9ORSlcbiAgICAgICAgKVxuICAgICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZ1N0YXRlLmVtaXQoZmFsc2UpO1xuICAgICAgICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gICAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBPcGVucyBhIG5vZGUuXG4gICAqL1xuICBjbGljaygpIHtcbiAgICB0aGlzLm5vZGUub3BlbiA9ICF0aGlzLm5vZGUub3BlbjtcbiAgICB0aGlzLm5vZGUuY2xpY2soeyBvcGVuOiB0aGlzLm5vZGUub3BlbiB9KTtcbiAgfVxuXG4gIHNldHVwQnJlYWRjcnVtYnNBbmRMZXZlbChub2RlOiBHcm91cE5vZGUpIHtcbiAgICBpZiAobm9kZS5wYXJlbnRzICYmIG5vZGUucGFyZW50cy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHBhcmVudCA9IG5vZGUucGFyZW50c1swXSBhcyBHcm91cE5vZGU7XG4gICAgICB0aGlzLmJyZWFkY3J1bWIgPVxuICAgICAgICB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudChwYXJlbnQubGFiZWwpICtcbiAgICAgICAgJyA+ICcgK1xuICAgICAgICB0aGlzLnRyYW5zbGF0ZVNlcnZpY2UuaW5zdGFudCh0aGlzLmJyZWFkY3J1bWIpO1xuICAgICAgdGhpcy5sZXZlbCsrO1xuXG4gICAgICB0aGlzLnNldHVwQnJlYWRjcnVtYnNBbmRMZXZlbChwYXJlbnQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3RzIHRoZSBub2RlIGFuZCBlbWl0cyBhIGNoYW5nZSBvbiB0aGUgcGFyZW50IGNvbXBvbmVudC5cbiAgICogQHBhcmFtIG5vZGUgVGhlIG5vZGUgdG8gc2VsZWN0LlxuICAgKi9cbiAgc2VsZWN0ZWQobm9kZTogR3JvdXBOb2RlKSB7XG4gICAgaWYgKG5vZGUubW8pIHtcbiAgICAgIHRoaXMudXBkYXRlU2VsZWN0aW9uKG5vZGUubW8pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmNsaWNrKCk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyBjbGlja3Mgb24gYSBpdGVtIGluIE1pbGxlciBWaWV3LlxuICAgKiBAcGFyYW0gbm9kZSBUaGUgbm9kZSB0aGF0IHdhcyBjbGlja2VkLlxuICAgKi9cbiAgbWlsbGVyVmlld0NsaWNrKG5vZGU6IEdyb3VwTm9kZSkge1xuICAgIG5vZGUuYnJlYWRjcnVtYiA9IHRoaXMuYnJlYWRjcnVtYjtcblxuICAgIGlmICghdGhpcy5oYW5kbGVOZXh0TWlsbGVyVmlld0NvbHVtbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBzaG91bGRIYW5kbGVEZWZhdWx0ID0gdGhpcy5oYW5kbGVOZXh0TWlsbGVyVmlld0NvbHVtbihub2RlLCB0aGlzLmluZGV4KTtcbiAgICBpZiAoc2hvdWxkSGFuZGxlRGVmYXVsdCkge1xuICAgICAgdGhpcy5zZWxlY3RlZChub2RlKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQGlnbm9yZVxuICAgKi9cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy51bnN1YnNjcmliZSQubmV4dCgpO1xuICAgIHRoaXMudW5zdWJzY3JpYmUkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBpc1NlbGVjdGVkKCkge1xuICAgIGlmICghdGhpcy5ub2RlLm1vKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmFzc2V0U2VsZWN0b3JTZXJ2aWNlLmdldEluZGV4T2ZTZWxlY3RlZCh0aGlzLnByZXNlbGVjdGVkLCB0aGlzLm5vZGUubW8pID4gLTE7XG4gIH1cblxuICBpc0FjdGl2ZSgpIHtcbiAgICBpZiAodGhpcy5hY3RpdmUgJiYgdGhpcy5ub2RlLm1vKSB7XG4gICAgICByZXR1cm4gdGhpcy5hY3RpdmUubW8/LmlkID09PSB0aGlzLm5vZGUubW8uaWQ7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlU2VsZWN0aW9uKHNlbGVjdGVkTW86IElNYW5hZ2VkT2JqZWN0KSB7XG4gICAgaWYgKCF0aGlzLm11bHRpKSB7XG4gICAgICB0aGlzLm9uRGVzZWxlY3QuZW1pdCh7IGRlc2VsZWN0TW9kZTogJ2FsbCcsIG1vOiBzZWxlY3RlZE1vIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5pc1NlbGVjdGVkKCkpIHtcbiAgICAgIHRoaXMub25EZXNlbGVjdC5lbWl0KHsgZGVzZWxlY3RNb2RlOiAnc2luZ2xlJywgbW86IHNlbGVjdGVkTW8gfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMub25TZWxlY3QuZW1pdChzZWxlY3RlZE1vKTtcbiAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICB9XG59XG4iLCI8IS0tIEhpZXJhcmNoeSB0cmVlIC0tPlxuPGRpdlxuICBjbGFzcz1cImM4eS1hc3NldC1zZWxlY3Rvcl9faXRlbVwiXG4gIFtuZ1N0eWxlXT1cIntcbiAgICAnbWFyZ2luLWxlZnQnOiBsZXZlbCA+IDEgPyAxNiArICdweCcgOiAnMCdcbiAgfVwiXG4gICpuZ0lmPVwidmlldyA9PT0gJ3RyZWUnXCJcbiAgW2F0dHIucm9sZV09XCJ2aWV3ID09PSAndHJlZScgPyAndHJlZScgOiAnbGlzdCdcIlxuICBbbmdDbGFzc109XCJ7XG4gICAgJ2M4eS1hc3NldC1zZWxlY3Rvcl9faXRlbS0tbW9yZSc6IG5vZGU/Lmljb24gPT09ICdwbHVzJyxcbiAgICAnYzh5LWFzc2V0LXNlbGVjdG9yX19pdGVtLS1zdGFydCc6IGxldmVsID09PSAwXG4gIH1cIlxuPlxuICA8ZGl2XG4gICAgY2xhc3M9XCJjOHktYXNzZXQtc2VsZWN0b3JfX25vZGVcIlxuICAgIHRpdGxlPVwie3sgYnJlYWRjcnVtYiB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgKm5nSWY9XCJub2RlICYmICFub2RlLnJvb3QgJiYgIW5vZGUuaGlkZGVuXCJcbiAgICBbYXR0ci5yb2xlXT1cInZpZXcgPT09ICd0cmVlJyA/ICd0cmVlaXRlbScgOiAnbGlzdGl0ZW0nXCJcbiAgICBbbmdDbGFzc109XCJ7ICdjOHktYXNzZXQtc2VsZWN0b3JfX25vZGUtLW9wZW4nOiBub2RlPy5vcGVuIH1cIlxuICA+XG4gICAgPCEtLSBleHBhbmQgYnV0dG9uIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJjOHktYXNzZXQtc2VsZWN0b3JfX25vZGVfX2J0bi1zcGFjZXJcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgY2xhc3M9XCJjb2xsYXBzZS1idG4gYnRuLWRvdFwiXG4gICAgICAgIFt0aXRsZV09XCJleHBhbmRUaXRsZSB8IHRyYW5zbGF0ZVwiXG4gICAgICAgIFthdHRyLmFyaWEtZXhwYW5kZWRdPVwibm9kZS5vcGVuXCJcbiAgICAgICAgKGNsaWNrKT1cImNsaWNrKClcIlxuICAgICAgICAqbmdJZj1cIm5vZGUuaXNHcm91cCgpIHx8IG5vZGUuaGFzQ2hpbGREZXZpY2VzKClcIlxuICAgICAgPlxuICAgICAgICA8aSBjOHlJY29uPVwiYW5nbGUtcmlnaHRcIj48L2k+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cImQtZmxleCBhLWktY2VudGVyIHAtdC00IHAtYi00XCJcbiAgICAgICpuZ0lmPVwibm9kZS50b1N0cmluZygpICE9PSAnTG9hZE1vcmVOb2RlJyAmJiBpc05vZGVTZWxlY3RhYmxlXCJcbiAgICA+XG4gICAgICA8bGFiZWwgW25nQ2xhc3NdPVwieyAnYzh5LWNoZWNrYm94JzogbXVsdGksICdjOHktcmFkaW8nOiAhbXVsdGkgfVwiPlxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICBpZD1cIm5vZGVMYWJlbFwiXG4gICAgICAgICAgW3R5cGVdPVwibXVsdGkgPyAnY2hlY2tib3gnIDogJ3JhZGlvJ1wiXG4gICAgICAgICAgKGNoYW5nZSk9XCJzZWxlY3RlZChub2RlKVwiXG4gICAgICAgICAgW2NoZWNrZWRdPVwiaXNTZWxlY3RlZCgpXCJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWQgfHwgIW5vZGUuZ3JvdXBzU2VsZWN0YWJsZSAmJiBub2RlLmlzR3JvdXAoKVwiXG4gICAgICAgIC8+XG4gICAgICAgIDxzcGFuPjwvc3Bhbj5cbiAgICAgICAgPHNwYW5cbiAgICAgICAgICBjbGFzcz1cInNyLW9ubHlcIlxuICAgICAgICAgIGZvcj1cIm5vZGVMYWJlbFwiXG4gICAgICAgICAgdHJhbnNsYXRlXG4gICAgICAgID5cbiAgICAgICAgICBOb2RlIGxhYmVsXG4gICAgICAgIDwvc3Bhbj5cbiAgICAgIDwvbGFiZWw+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIGdyb3VwIGJ1dHRvbiAtLT5cbiAgICA8YnV0dG9uXG4gICAgICBjbGFzcz1cImM4eS1hc3NldC1zZWxlY3Rvcl9fYnRuIHRleHQtdHJ1bmNhdGVcIlxuICAgICAgW2F0dHIuYXJpYS1leHBhbmRlZF09XCIhbm9kZS5vcGVuXCJcbiAgICAgICpuZ0lmPVwibm9kZS5pc0dyb3VwKCkgfHwgbm9kZS5oYXNDaGlsZERldmljZXMoKVwiXG4gICAgICAoY2xpY2spPVwiY2xpY2soKVwiXG4gICAgPlxuICAgICAgPGlcbiAgICAgICAgY2xhc3M9XCJjOHktaWNvbiBjOHktaWNvbi1kdW9jb2xvciBtLXItNCB0ZXh0LTE2XCJcbiAgICAgICAgW2M4eUljb25dPVwibm9kZS5pY29uXCJcbiAgICAgICAgW3RpdGxlXT1cIidTbWFydCBncm91cCcgfCB0cmFuc2xhdGVcIlxuICAgICAgICAqbmdJZj1cIm5vZGUuaWNvbiA9PT0gJ2M4eS1ncm91cC1zbWFydCdcIlxuICAgICAgPjwvaT5cbiAgICAgIDxpXG4gICAgICAgIGNsYXNzPVwiYzh5LWljb24gYzh5LWljb24tZHVvY29sb3IgbS1yLTQgdGV4dC0xNlwiXG4gICAgICAgIFtjOHlJY29uXT1cIm5vZGUuaWNvblwiXG4gICAgICAgIFt0aXRsZV09XCInR3JvdXAnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgKm5nSWY9XCJub2RlLmljb24gIT09ICdjOHktZ3JvdXAtc21hcnQnXCJcbiAgICAgID48L2k+XG4gICAgICA8c3BhbiB0aXRsZT1cInt7IGJyZWFkY3J1bWIgfX1cIj5cbiAgICAgICAge3sgbm9kZS50cmFuc2xhdGVMYWJlbCA/IChub2RlLmxhYmVsIHwgdHJhbnNsYXRlKSA6IG5vZGUubGFiZWwgfX1cbiAgICAgICAgPCEtLSB1c2UganVzdCBmb3Igc2VhcmNoIHJlc3VsdHMgdG8gZGlzcGxheSB0aGUgcGF0aCAtLT5cbiAgICAgICAgPHBcbiAgICAgICAgICBjbGFzcz1cInRleHQtdHJ1bmNhdGVcIlxuICAgICAgICAgICpuZ0lmPVwic2hvd1BhdGhcIlxuICAgICAgICA+XG4gICAgICAgICAgPHNtYWxsXG4gICAgICAgICAgICBjbGFzcz1cInRleHQtbXV0ZWRcIlxuICAgICAgICAgICAgdGl0bGU9XCJ7eyBicmVhZGNydW1iIH19XCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8ZW0+e3sgYnJlYWRjcnVtYiB9fTwvZW0+XG4gICAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgPC9wPlxuICAgICAgICA8IS0tIHVwIHRvIGhlcmUgLS0+XG4gICAgICA8L3NwYW4+XG4gICAgPC9idXR0b24+XG4gICAgPCEtLSBub3QgYSBncm91cCBidXR0b24gLS0+XG4gICAgPGJ1dHRvblxuICAgICAgY2xhc3M9XCJmbGV4LWdyb3dcIlxuICAgICAgdGl0bGU9XCJ7eyBicmVhZGNydW1iIH19XCJcbiAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgKm5nSWY9XCIhbm9kZS5pc0dyb3VwKCkgJiYgIW5vZGUuaGFzQ2hpbGREZXZpY2VzKClcIlxuICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAnYnRuIGJ0bi1kZWZhdWx0IGJ0bi1zbSBtLWItOCBtLXItOCBkLWZsZXggai1jLWNlbnRlcic6IG5vZGUuaWNvbiA9PT0gJ3BsdXMnLFxuICAgICAgICAnYzh5LWFzc2V0LXNlbGVjdG9yX19idG4gdGV4dC10cnVuY2F0ZSc6IG5vZGUuaWNvbiAhPSAncGx1cydcbiAgICAgIH1cIlxuICAgICAgKGNsaWNrKT1cInNlbGVjdGVkKG5vZGUpXCJcbiAgICA+XG4gICAgICA8aVxuICAgICAgICBjbGFzcz1cImM4eS1pY29uIGM4eS1pY29uLWR1b2NvbG9yIG0tci00IHRleHQtMTZcIlxuICAgICAgICBbYzh5SWNvbl09XCJub2RlLmljb25cIlxuICAgICAgICBbdGl0bGVdPVwiJ1NtYXJ0IGdyb3VwJyB8IHRyYW5zbGF0ZVwiXG4gICAgICAgICpuZ0lmPVwibm9kZS5pY29uID09PSAnYzh5LWdyb3VwLXNtYXJ0J1wiXG4gICAgICA+PC9pPlxuICAgICAgPGlcbiAgICAgICAgY2xhc3M9XCJjOHktaWNvbiBtLXItNFwiXG4gICAgICAgIFtjOHlJY29uXT1cIm5vZGUuaWNvblwiXG4gICAgICAgIFt0aXRsZV09XCInR3JvdXAnIHwgdHJhbnNsYXRlXCJcbiAgICAgICAgKm5nSWY9XCJub2RlLmljb24gIT09ICdjOHktZ3JvdXAtc21hcnQnXCJcbiAgICAgICAgW25nQ2xhc3NdPVwieyAnYzh5LWljb24tZHVvY29sb3IgdGV4dC0xNiAnOiBub2RlLmljb24gIT0gJ3BsdXMnIH1cIlxuICAgICAgPjwvaT5cbiAgICAgIDxzcGFuIHRpdGxlPVwie3sgYnJlYWRjcnVtYiB9fVwiPlxuICAgICAgICB7eyBub2RlLnRyYW5zbGF0ZUxhYmVsID8gKG5vZGUubGFiZWwgfCB0cmFuc2xhdGUpIDogbm9kZS5sYWJlbCB9fVxuICAgICAgICA8IS0tIHVzZSBqdXN0IGZvciBzZWFyY2ggcmVzdWx0cyB0byBkaXNwbGF5IHRoZSBwYXRoIC0tPlxuICAgICAgICA8cFxuICAgICAgICAgIGNsYXNzPVwidGV4dC10cnVuY2F0ZSB0ZXh0LW11dGVkIHNtYWxsXCJcbiAgICAgICAgICAqbmdJZj1cInNob3dQYXRoXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxlbT57eyBicmVhZGNydW1iIH19PC9lbT5cbiAgICAgICAgPC9wPlxuICAgICAgICA8IS0tIHVwIHRvIGhlcmUgLS0+XG4gICAgICA8L3NwYW4+XG4gICAgPC9idXR0b24+XG4gIDwvZGl2PlxuICA8ZGl2XG4gICAgY2xhc3M9XCJjb2xsYXBzZVwiXG4gICAgKm5nSWY9XCJub2RlLmNvdW50Q2hpbGRyZW4oKVwiXG4gICAgW2NvbGxhcHNlXT1cIiFub2RlLm9wZW5cIlxuICAgIFtpc0FuaW1hdGVkXT1cInRydWVcIlxuICAgIFthdHRyLnJvbGVdPVwiJ2dyb3VwJ1wiXG4gID5cbiAgICA8Yzh5LWFzc2V0LXNlbGVjdG9yLW5vZGVcbiAgICAgICpuZ0Zvcj1cImxldCBjaGlsZE5vZGUgb2Ygbm9kZS5jaGlsZHJlblwiXG4gICAgICBbbm9kZV09XCJjaGlsZE5vZGVcIlxuICAgICAgW3ByZXNlbGVjdGVkXT1cInByZXNlbGVjdGVkIHx8IFtdXCJcbiAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gICAgICBbbXVsdGldPVwibXVsdGlcIlxuICAgICAgW2FjdGl2ZV09XCJhY3RpdmVcIlxuICAgICAgW2F0dHIucm9sZV09XCJ2aWV3ID09PSAndHJlZScgPyAndHJlZWl0ZW0nIDogJ2xpc3RpdGVtJ1wiXG4gICAgICAob25TZWxlY3QpPVwib25TZWxlY3QuZW1pdCgkZXZlbnQpXCJcbiAgICAgIChvbkRlc2VsZWN0KT1cIm9uRGVzZWxlY3QuZW1pdCgkZXZlbnQpXCJcbiAgICA+PC9jOHktYXNzZXQtc2VsZWN0b3Itbm9kZT5cbiAgPC9kaXY+XG48L2Rpdj5cblxuPCEtLSBNaWxsZXIgY29sdW1ucyAtLT5cbjxkaXYgKm5nSWY9XCJ2aWV3ID09PSAnbWlsbGVyJ1wiPlxuICA8ZGl2XG4gICAgY2xhc3M9XCJtaWxsZXItY29sdW1uX19pdGVtIGJnLWluaGVyaXRcIlxuICAgIHRpdGxlPVwie3sgYnJlYWRjcnVtYiB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgKm5nSWY9XCJub2RlICYmICFub2RlLnJvb3QgJiYgIW5vZGUuaGlkZGVuICYmIG5vZGUgIT09IHJvb3ROb2RlXCJcbiAgICBbbmdDbGFzc109XCJ7XG4gICAgICBhY3RpdmU6IGlzQWN0aXZlKCksXG4gICAgICAnbWlsbGVyLWNvbHVtbl9faXRlbS0tbW9yZSc6IG5vZGUudG9TdHJpbmcoKSA9PT0gJ0xvYWRNb3JlTm9kZSdcbiAgICB9XCJcbiAgPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwibS1sLTQgbS1yLTQgbWlsbGVyLWNvbHVtbl9faXRlbV9fY2hlY2tib3hcIlxuICAgICAgKm5nSWY9XCJub2RlLnRvU3RyaW5nKCkgIT09ICdMb2FkTW9yZU5vZGUnXCJcbiAgICA+XG4gICAgICA8bGFiZWwgW25nQ2xhc3NdPVwieyAnYzh5LXJhZGlvJzogIW11bHRpLCAnYzh5LWNoZWNrYm94JzogbXVsdGkgfVwiPlxuICAgICAgICA8aW5wdXRcbiAgICAgICAgICBpZD1cIm5vZGVMYWJlbDJcIlxuICAgICAgICAgIFt0eXBlXT1cIm11bHRpID8gJ2NoZWNrYm94JyA6ICdyYWRpbydcIlxuICAgICAgICAgIChjaGFuZ2UpPVwic2VsZWN0ZWQobm9kZSlcIlxuICAgICAgICAgIFtjaGVja2VkXT1cImlzU2VsZWN0ZWQoKVwiXG4gICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkIHx8ICFub2RlLmdyb3Vwc1NlbGVjdGFibGUgJiYgbm9kZS5pc0dyb3VwKClcIlxuICAgICAgICAvPlxuICAgICAgICA8c3Bhbj48L3NwYW4+XG4gICAgICAgIDxzcGFuXG4gICAgICAgICAgY2xhc3M9XCJzci1vbmx5XCJcbiAgICAgICAgICBmb3I9XCJub2RlTGFiZWwyXCJcbiAgICAgICAgICB0cmFuc2xhdGVcbiAgICAgICAgPlxuICAgICAgICAgIE5vZGUgbGFiZWxcbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC9sYWJlbD5cbiAgICA8L2Rpdj5cblxuICAgIDxidXR0b25cbiAgICAgIHRpdGxlPVwie3sgYnJlYWRjcnVtYiB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgIFtuZ0NsYXNzXT1cIntcbiAgICAgICAgJ2J0biBidG4tZGVmYXVsdCBidG4tc20gZC1mbGV4IGZsZXgtZ3JvdyBqLWMtY2VudGVyIG0tbC0xNiBtLXItMTYgbS1iLTQgbS10LTQnOlxuICAgICAgICAgIG5vZGUudG9TdHJpbmcoKSA9PT0gJ0xvYWRNb3JlTm9kZScsXG4gICAgICAgICdtaWxsZXItY29sdW1uX19pdGVtX19idG4nOiBub2RlLnRvU3RyaW5nKCkgIT09ICdMb2FkTW9yZU5vZGUnLFxuICAgICAgICAnYnRuLXBlbmRpbmcnOiBub2RlLmxvYWRpbmcgJiYgbm9kZS50b1N0cmluZygpID09PSAnTG9hZE1vcmVOb2RlJ1xuICAgICAgfVwiXG4gICAgICAoY2xpY2spPVwibWlsbGVyVmlld0NsaWNrKG5vZGUpXCJcbiAgICA+XG4gICAgICA8aVxuICAgICAgICBjbGFzcz1cImM4eS1pY29uIG0tci00XCJcbiAgICAgICAgW2M4eUljb25dPVwibm9kZS5pY29uXCJcbiAgICAgICAgW25nQ2xhc3NdPVwieyAnYzh5LWljb24tZHVvY29sb3IgdGV4dC0xNic6IG5vZGUudG9TdHJpbmcoKSAhPT0gJ0xvYWRNb3JlTm9kZScgfVwiXG4gICAgICA+PC9pPlxuICAgICAgPGRpdiBjbGFzcz1cInRleHQtbGVmdCB0ZXh0LXRydW5jYXRlXCI+XG4gICAgICAgIDxwXG4gICAgICAgICAgY2xhc3M9XCJ0ZXh0LXRydW5jYXRlXCJcbiAgICAgICAgICB0aXRsZT1cInt7IG5vZGUudHJhbnNsYXRlTGFiZWwgPyAobm9kZS5sYWJlbCB8IHRyYW5zbGF0ZSkgOiBub2RlLmxhYmVsIH19XCJcbiAgICAgICAgPlxuICAgICAgICAgIHt7IG5vZGUudHJhbnNsYXRlTGFiZWwgPyAobm9kZS5sYWJlbCB8IHRyYW5zbGF0ZSkgOiBub2RlLmxhYmVsIH19XG4gICAgICAgIDwvcD5cbiAgICAgICAgPCEtLSB1c2UganVzdCBmb3Igc2VhcmNoIHJlc3VsdHMgdG8gZGlzcGxheSB0aGUgcGF0aCAtLT5cbiAgICAgICAgPHNtYWxsXG4gICAgICAgICAgY2xhc3M9XCJ0ZXh0LW11dGVkIHRleHQtdHJ1bmNhdGVcIlxuICAgICAgICAgIHRpdGxlPVwie3sgYnJlYWRjcnVtYiB9fVwiXG4gICAgICAgICAgKm5nSWY9XCJzaG93UGF0aFwiXG4gICAgICAgID5cbiAgICAgICAgICA8ZW0+e3sgYnJlYWRjcnVtYiB9fTwvZW0+XG4gICAgICAgIDwvc21hbGw+XG4gICAgICAgIDwhLS0gdXAgdG8gaGVyZSAtLT5cbiAgICAgIDwvZGl2PlxuICAgICAgPHNwYW5cbiAgICAgICAgY2xhc3M9XCJwLWwtNCBtLWwtYXV0b1wiXG4gICAgICAgICpuZ0lmPVwibm9kZS5pc0dyb3VwKCkgfHwgbm9kZS5oYXNDaGlsZERldmljZXMoKVwiXG4gICAgICA+XG4gICAgICAgIDxpIGM4eUljb249XCJhbmdsZS1yaWdodFwiPjwvaT5cbiAgICAgIDwvc3Bhbj5cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG5cbiAgPGRpdlxuICAgIHJvbGU9XCJsaXN0XCJcbiAgICAqbmdJZj1cIm5vZGVcIlxuICAgIFtuZ0NsYXNzXT1cInsgaGlkZGVuOiBub2RlICE9PSByb290Tm9kZSB9XCJcbiAgPlxuICAgIDxjOHktYXNzZXQtc2VsZWN0b3Itbm9kZVxuICAgICAgcm9sZT1cImxpc3RpdGVtXCJcbiAgICAgICpuZ0Zvcj1cImxldCBjaGlsZE5vZGUgb2Ygbm9kZS5jaGlsZHJlblwiXG4gICAgICBbbm9kZV09XCJjaGlsZE5vZGVcIlxuICAgICAgW3Jvb3ROb2RlXT1cInJvb3ROb2RlXCJcbiAgICAgIFtwcmVzZWxlY3RlZF09XCJwcmVzZWxlY3RlZCB8fCBbXVwiXG4gICAgICBbbXVsdGldPVwibXVsdGlcIlxuICAgICAgW3ZpZXddPVwidmlld1wiXG4gICAgICBbaW5kZXhdPVwiaW5kZXhcIlxuICAgICAgW2FjdGl2ZV09XCJhY3RpdmVcIlxuICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgIFtoYW5kbGVOZXh0TWlsbGVyVmlld0NvbHVtbl09XCJoYW5kbGVOZXh0TWlsbGVyVmlld0NvbHVtblwiXG4gICAgICAob25TZWxlY3QpPVwib25TZWxlY3QuZW1pdCgkZXZlbnQpXCJcbiAgICAgIChvbkRlc2VsZWN0KT1cIm9uRGVzZWxlY3QuZW1pdCgkZXZlbnQpXCJcbiAgICA+PC9jOHktYXNzZXQtc2VsZWN0b3Itbm9kZT5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==