UNPKG

@senx/warpview

Version:
167 lines 36 kB
/* * Copyright 2021 SenX S.A.S. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import { Component, ElementRef, EventEmitter, Input, Output, Renderer2, ViewChild, ViewEncapsulation } from '@angular/core'; import { GTS } from '../../../model/GTS'; import { Logger } from '../../../utils/logger'; import { GTSLib } from '../../../utils/gts.lib'; import { ColorLib } from '../../../utils/color-lib'; import { Param } from '../../../model/param'; import { Observable } from 'rxjs'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; /** * */ export class WarpViewChipComponent { constructor(renderer) { this.renderer = renderer; this.param = new Param(); this.options = new Param(); this.warpViewSelectedGTS = new EventEmitter(); // the first character triggers change each filter apply to trigger events. it must be discarded. this._gtsFilter = 'x'; this._debug = false; this._hiddenData = []; this._node = { selected: true, gts: GTS, }; this.LOG = new Logger(WarpViewChipComponent, this.debug); } set debug(debug) { this._debug = debug; this.LOG.setDebug(debug); } get debug() { return this._debug; } set hiddenData(hiddenData) { if (JSON.stringify(hiddenData) !== JSON.stringify(this._hiddenData)) { this._hiddenData = hiddenData; this.LOG.debug(['hiddenData'], hiddenData, this._node, this._node.gts, this._node.gts.c); if (!!this._node && !!this._node.gts && !!this._node.gts.c) { this.setState(this._hiddenData.indexOf(this._node.gts.id) === -1); } } } get hiddenData() { return this._hiddenData; } set gtsFilter(gtsFilter) { this._gtsFilter = gtsFilter; if (this._gtsFilter.slice(1) !== '') { this.setState(new RegExp(this._gtsFilter.slice(1), 'gi').test(GTSLib.serializeGtsMetadata(this._node.gts))); } else { this.setState(true); } } get gtsFilter() { return this._gtsFilter; } ngOnInit() { this._node = { ...this.node, selected: this._hiddenData.indexOf(this.node.gts.id) === -1 }; if (!!this.events) { // this.eventsSubscription = this.events.subscribe(state => this.setState(state)); } } ngOnDestroy() { if (!!this.eventsSubscription) { this.eventsSubscription.unsubscribe(); } } ngAfterViewInit() { if (this.gtsFilter.slice(1) !== '' && new RegExp(this.gtsFilter.slice(1), 'gi').test(GTSLib.serializeGtsMetadata(this._node.gts)) || this.hiddenData.indexOf(this._node.gts.id) > -1) { this.setState(false); } else { this.colorizeChip(); } } colorizeChip() { if (!!this.chip) { if (!!this._node.selected) { const c = ColorLib.getColor(this._node.gts.id, this.options.scheme); const color = (this.param || { datasetColor: c }).datasetColor || c; this.renderer.setStyle(this.chip.nativeElement, 'background-color', color); this.renderer.setStyle(this.chip.nativeElement, 'border-color', color); } else { this.renderer.setStyle(this.chip.nativeElement, 'background-color', 'transparent'); } } } toArray(obj) { if (obj === undefined) { return []; } return Object.keys(obj).map(key => ({ name: key, value: obj[key] })); } switchPlotState(event) { event.preventDefault(); this.setState(!this._node.selected); return false; } setState(state) { if (this._node && this._node.gts) { this.LOG.debug(['switchPlotState'], state, this._node.selected); if (this._node.selected !== state) { this._node.selected = !!state; this.LOG.debug(['switchPlotState'], 'emit'); this.warpViewSelectedGTS.emit(this._node); } this.colorizeChip(); } } identify(index, item) { return index; } } WarpViewChipComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: WarpViewChipComponent, deps: [{ token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Component }); WarpViewChipComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: WarpViewChipComponent, selector: "warpview-chip", inputs: { node: "node", param: "param", options: "options", events: "events", debug: "debug", hiddenData: "hiddenData", gtsFilter: "gtsFilter" }, outputs: { warpViewSelectedGTS: "warpViewSelectedGTS" }, viewQueries: [{ propertyName: "chip", first: true, predicate: ["chip"], descendants: true }], ngImport: i0, template: "<!--\n ~ Copyright 2021 SenX S.A.S.\n ~\n ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ http://www.apache.org/licenses/LICENSE-2.0\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n ~\n -->\n\n<div>\n <span (click)=\"switchPlotState($event)\" *ngIf=\"_node && _node.gts && _node.gts.l\">\n <i class=\"normal\" #chip></i>\n <span class=\"gtsInfo\">\n <span class='gts-classname'>&nbsp;{{_node.gts.c}}</span>\n <span class='gts-separator'>&#x007B; </span>\n <span *ngFor=\"let label of toArray(_node.gts.l); index as index; last as last; trackBy:identify\">\n <span class='gts-labelname'>{{label.name}}</span>\n <span class='gts-separator'>=</span>\n <span class='gts-labelvalue'>{{label.value}}</span>\n <span [hidden]=\"last\">, </span>\n </span>\n <span class=\"gts-separator\"> &#x007D; </span>\n <span class='gts-separator'>&#x007B; </span>\n <span *ngFor=\"let label of toArray(_node.gts.a); index as index; last as last; trackBy:identify\">\n <span class='gts-attrname'>{{label.name}}</span>\n <span class='gts-separator'>=</span>\n <span class='gts-attrvalue'>{{label.value}}</span>\n <span [hidden]=\"last\">, </span>\n </span>\n <span class=\"gts-separator\"> &#x007D;</span>\n </span>\n </span>\n</div>\n", styles: [":root{--warp-view-chart-width: 100%;--warp-view-chart-height: 100%;--warp-view-datagrid-cell-padding: 5px;--warp-view-map-margin: 0;--warp-view-switch-height: 30px;--warp-view-switch-width: 100px;--warp-view-switch-radius: 18px;--warp-view-plot-chart-height: 100%;--warp-view-slider-pointer-size: 65px;--warp-view-resize-handle-height: 10px;--warp-view-tile-width: 100%;--warp-view-tile-height: 100%;--warp-view-font-color: #000000;--warp-view-bar-color: #dc3545;--warp-view-datagrid-odd-bg-color: #ffffff;--warp-view-datagrid-odd-color: #404040;--warp-view-datagrid-even-bg-color: #c0c0c0;--warp-view-datagrid-even-color: #000000;--warp-view-pagination-border-color: #c0c0c0;--warp-view-pagination-bg-color: #ffffff;--warp-view-pagination-active-bg-color: #4CAF50;--warp-view-pagination-active-color: #ffffff;--warp-view-pagination-active-border-color: #4CAF50;--warp-view-pagination-hover-bg-color: #c0c0c0;--warp-view-pagination-hover-color: #000000;--warp-view-pagination-hover-border-color: #c0c0c0;--warp-view-pagination-disabled-color: #c0c0c0;--warp-view-switch-inset-color: #c0c0c0;--warp-view-switch-inset-checked-color: #00cd00;--warp-view-switch-handle-color: radial-gradient(#ffffff 15%, #c0c0c0 100%);--warp-view-switch-handle-checked-color: radial-gradient(#ffffff 15%, #00cd00 100%);--warp-view-resize-handle-color: #c0c0c0;--warp-view-chart-legend-bg: #ffffff;--warp-view-chart-legend-color: #404040;--gts-classname-font-color: #004eff;--gts-labelname-font-color: #19A979;--gts-attrname-font-color: #ED4A7B;--gts-separator-font-color: #a0a0a0;--gts-labelvalue-font-color: #000000;--gts-attrvalue-font-color: #000000;--gts-stack-font-color: #000000;--gts-tree-expanded-icon: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA7klEQVQ4T82TMW7CQBBF/0g+QOpINEkVCmpaLoBm5COk5QYoaeAY3MDSei2LGu4QKakiBA1tCpTK8kS2sLVe2xSh8XSrnf9m/s4s4c6gO/UYGEBEXlT1bK396bFGIjIJguA7iqJLkVNbYOZXItoQ0QHAzBhz9CCFeAVgCeAjy7Jpmqa/NUBEEgDzktqGuOKKO47j+KsGhGH4lOf5HsDIg5ycyqVYVd+steuGheLAzM9EtPMgW1VdVGWJ6N0YU1gpozVGH+K+gy/uBHR1crXUqNzbQXXhduJ69sd7cxOZ+UFVH5Mk+exb+YGt8n9+5h8up1sReYC0WAAAAABJRU5ErkJggg==);--gts-tree-collapsed-icon: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA0UlEQVQ4T6WTUW7CQAxEPQdozxYb9Qb94Aj9gQSoVCp6lMr21doDZFCQiFCU3YDY//d2PeOFPHnwJC+zAlVdA/jp+/6YmZ+1S0qCPxF5HUAAO3fvSpKS4ENEvm6gfUS0c5JiBma2Ibm/QiQPmbmdSqohquoA7GqSxRaapmkBjBkAeHP336t0UWBmHcnb+VcR4XcJpjDJLjPHkS4tleqZubmNiDHU6gumDQDYuvvh7hpV9V9EXgaA5Ka2jbMjmNk7yZOIfEfE8eFVfuSDLda4JDsD3FNdEckTC0YAAAAASUVORK5CYII=);--warp-view-popup-bg-color: #ffffff;--warp-view-popup-border-color: rgba(0, 0, 0, .2);--warp-view-popup-header-bg-color: #c0c0c0;--warp-view-popup-title-color: #404040;--warp-view-popup-close-color: #404040;--warp-view-popup-body-bg-color: #ffffff;--warp-view-popup-body-color: #000000;--warp-view-annotationtooltip-value-font-color: #004eff;--warp-view-annotationtooltip-font-color: #404040;--warp-view-spinner-color: #ff9900;--warp-view-tooltip-bg: #ffffff;--warp-view-tooltip-color: #000000;--warp-slider-connect-color: #ff9900;--warp-slider-handle-bg-color: #ffffff;--warp-slider-handle-color: #004eff;--warp-slider-handle-shadow: inset 0 0 1px #ffffff, inset 0 1px 7px #c0c0c0, 0 3px 6px -3px #a0a0a0}.noData{width:100%;text-align:center;color:var(--warp-view-chart-legend-color);position:relative}.js-plotly-plot .plotly .cursor-ew-resize{cursor:default!important}/*!\n * Copyright 2021 SenX S.A.S.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */.gts-classname{color:var(--gts-classname-font-color)}.gts-labelname{color:var(--gts-labelname-font-color)}.gts-attrname{color:var(--gts-attrname-font-color)}.gts-separator{color:var(--gts-separator-font-color)}.gts-labelvalue{color:var(--gts-labelvalue-font-color);font-style:italic}.gts-attrvalue{color:var(--gts-attrvalue-font-color);font-style:italic}:host div span{cursor:pointer}:host .normal{border-radius:50%;background-color:#bbb;display:inline-block;width:5px;height:5px;border:2px solid #454545;margin-top:auto;margin-bottom:auto;vertical-align:middle;cursor:pointer}\n"], directives: [{ type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], encapsulation: i0.ViewEncapsulation.ShadowDom }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: WarpViewChipComponent, decorators: [{ type: Component, args: [{ selector: 'warpview-chip', encapsulation: ViewEncapsulation.ShadowDom, template: "<!--\n ~ Copyright 2021 SenX S.A.S.\n ~\n ~ Licensed under the Apache License, Version 2.0 (the \"License\");\n ~ you may not use this file except in compliance with the License.\n ~ You may obtain a copy of the License at\n ~\n ~ http://www.apache.org/licenses/LICENSE-2.0\n ~\n ~ Unless required by applicable law or agreed to in writing, software\n ~ distributed under the License is distributed on an \"AS IS\" BASIS,\n ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n ~ See the License for the specific language governing permissions and\n ~ limitations under the License.\n ~\n -->\n\n<div>\n <span (click)=\"switchPlotState($event)\" *ngIf=\"_node && _node.gts && _node.gts.l\">\n <i class=\"normal\" #chip></i>\n <span class=\"gtsInfo\">\n <span class='gts-classname'>&nbsp;{{_node.gts.c}}</span>\n <span class='gts-separator'>&#x007B; </span>\n <span *ngFor=\"let label of toArray(_node.gts.l); index as index; last as last; trackBy:identify\">\n <span class='gts-labelname'>{{label.name}}</span>\n <span class='gts-separator'>=</span>\n <span class='gts-labelvalue'>{{label.value}}</span>\n <span [hidden]=\"last\">, </span>\n </span>\n <span class=\"gts-separator\"> &#x007D; </span>\n <span class='gts-separator'>&#x007B; </span>\n <span *ngFor=\"let label of toArray(_node.gts.a); index as index; last as last; trackBy:identify\">\n <span class='gts-attrname'>{{label.name}}</span>\n <span class='gts-separator'>=</span>\n <span class='gts-attrvalue'>{{label.value}}</span>\n <span [hidden]=\"last\">, </span>\n </span>\n <span class=\"gts-separator\"> &#x007D;</span>\n </span>\n </span>\n</div>\n", styles: [":root{--warp-view-chart-width: 100%;--warp-view-chart-height: 100%;--warp-view-datagrid-cell-padding: 5px;--warp-view-map-margin: 0;--warp-view-switch-height: 30px;--warp-view-switch-width: 100px;--warp-view-switch-radius: 18px;--warp-view-plot-chart-height: 100%;--warp-view-slider-pointer-size: 65px;--warp-view-resize-handle-height: 10px;--warp-view-tile-width: 100%;--warp-view-tile-height: 100%;--warp-view-font-color: #000000;--warp-view-bar-color: #dc3545;--warp-view-datagrid-odd-bg-color: #ffffff;--warp-view-datagrid-odd-color: #404040;--warp-view-datagrid-even-bg-color: #c0c0c0;--warp-view-datagrid-even-color: #000000;--warp-view-pagination-border-color: #c0c0c0;--warp-view-pagination-bg-color: #ffffff;--warp-view-pagination-active-bg-color: #4CAF50;--warp-view-pagination-active-color: #ffffff;--warp-view-pagination-active-border-color: #4CAF50;--warp-view-pagination-hover-bg-color: #c0c0c0;--warp-view-pagination-hover-color: #000000;--warp-view-pagination-hover-border-color: #c0c0c0;--warp-view-pagination-disabled-color: #c0c0c0;--warp-view-switch-inset-color: #c0c0c0;--warp-view-switch-inset-checked-color: #00cd00;--warp-view-switch-handle-color: radial-gradient(#ffffff 15%, #c0c0c0 100%);--warp-view-switch-handle-checked-color: radial-gradient(#ffffff 15%, #00cd00 100%);--warp-view-resize-handle-color: #c0c0c0;--warp-view-chart-legend-bg: #ffffff;--warp-view-chart-legend-color: #404040;--gts-classname-font-color: #004eff;--gts-labelname-font-color: #19A979;--gts-attrname-font-color: #ED4A7B;--gts-separator-font-color: #a0a0a0;--gts-labelvalue-font-color: #000000;--gts-attrvalue-font-color: #000000;--gts-stack-font-color: #000000;--gts-tree-expanded-icon: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA7klEQVQ4T82TMW7CQBBF/0g+QOpINEkVCmpaLoBm5COk5QYoaeAY3MDSei2LGu4QKakiBA1tCpTK8kS2sLVe2xSh8XSrnf9m/s4s4c6gO/UYGEBEXlT1bK396bFGIjIJguA7iqJLkVNbYOZXItoQ0QHAzBhz9CCFeAVgCeAjy7Jpmqa/NUBEEgDzktqGuOKKO47j+KsGhGH4lOf5HsDIg5ycyqVYVd+steuGheLAzM9EtPMgW1VdVGWJ6N0YU1gpozVGH+K+gy/uBHR1crXUqNzbQXXhduJ69sd7cxOZ+UFVH5Mk+exb+YGt8n9+5h8up1sReYC0WAAAAABJRU5ErkJggg==);--gts-tree-collapsed-icon: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA0UlEQVQ4T6WTUW7CQAxEPQdozxYb9Qb94Aj9gQSoVCp6lMr21doDZFCQiFCU3YDY//d2PeOFPHnwJC+zAlVdA/jp+/6YmZ+1S0qCPxF5HUAAO3fvSpKS4ENEvm6gfUS0c5JiBma2Ibm/QiQPmbmdSqohquoA7GqSxRaapmkBjBkAeHP336t0UWBmHcnb+VcR4XcJpjDJLjPHkS4tleqZubmNiDHU6gumDQDYuvvh7hpV9V9EXgaA5Ka2jbMjmNk7yZOIfEfE8eFVfuSDLda4JDsD3FNdEckTC0YAAAAASUVORK5CYII=);--warp-view-popup-bg-color: #ffffff;--warp-view-popup-border-color: rgba(0, 0, 0, .2);--warp-view-popup-header-bg-color: #c0c0c0;--warp-view-popup-title-color: #404040;--warp-view-popup-close-color: #404040;--warp-view-popup-body-bg-color: #ffffff;--warp-view-popup-body-color: #000000;--warp-view-annotationtooltip-value-font-color: #004eff;--warp-view-annotationtooltip-font-color: #404040;--warp-view-spinner-color: #ff9900;--warp-view-tooltip-bg: #ffffff;--warp-view-tooltip-color: #000000;--warp-slider-connect-color: #ff9900;--warp-slider-handle-bg-color: #ffffff;--warp-slider-handle-color: #004eff;--warp-slider-handle-shadow: inset 0 0 1px #ffffff, inset 0 1px 7px #c0c0c0, 0 3px 6px -3px #a0a0a0}.noData{width:100%;text-align:center;color:var(--warp-view-chart-legend-color);position:relative}.js-plotly-plot .plotly .cursor-ew-resize{cursor:default!important}/*!\n * Copyright 2021 SenX S.A.S.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */.gts-classname{color:var(--gts-classname-font-color)}.gts-labelname{color:var(--gts-labelname-font-color)}.gts-attrname{color:var(--gts-attrname-font-color)}.gts-separator{color:var(--gts-separator-font-color)}.gts-labelvalue{color:var(--gts-labelvalue-font-color);font-style:italic}.gts-attrvalue{color:var(--gts-attrvalue-font-color);font-style:italic}:host div span{cursor:pointer}:host .normal{border-radius:50%;background-color:#bbb;display:inline-block;width:5px;height:5px;border:2px solid #454545;margin-top:auto;margin-bottom:auto;vertical-align:middle;cursor:pointer}\n"] }] }], ctorParameters: function () { return [{ type: i0.Renderer2 }]; }, propDecorators: { chip: [{ type: ViewChild, args: ['chip'] }], node: [{ type: Input, args: ['node'] }], param: [{ type: Input, args: ['param'] }], options: [{ type: Input, args: ['options'] }], events: [{ type: Input }], debug: [{ type: Input, args: ['debug'] }], hiddenData: [{ type: Input, args: ['hiddenData'] }], gtsFilter: [{ type: Input, args: ['gtsFilter'] }], warpViewSelectedGTS: [{ type: Output, args: ['warpViewSelectedGTS'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FycC12aWV3LWNoaXAuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvd2FycHZpZXctbmcvc3JjL2xpYi9lbGVtZW50cy93YXJwLXZpZXctZ3RzLXRyZWUvd2FycC12aWV3LWNoaXAvd2FycC12aWV3LWNoaXAuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvd2FycHZpZXctbmcvc3JjL2xpYi9lbGVtZW50cy93YXJwLXZpZXctZ3RzLXRyZWUvd2FycC12aWV3LWNoaXAvd2FycC12aWV3LWNoaXAuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7OztHQWVHO0FBRUgsT0FBTyxFQUVMLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLEtBQUssRUFHTCxNQUFNLEVBQ04sU0FBUyxFQUNULFNBQVMsRUFDVCxpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLEdBQUcsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBQ3ZDLE9BQU8sRUFBQyxNQUFNLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUM3QyxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFDOUMsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLDBCQUEwQixDQUFDO0FBQ2xELE9BQU8sRUFBQyxLQUFLLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUMzQyxPQUFPLEVBQUMsVUFBVSxFQUFlLE1BQU0sTUFBTSxDQUFDOzs7QUFFOUM7O0dBRUc7QUFPSCxNQUFNLE9BQU8scUJBQXFCO0lBMERoQyxZQUFvQixRQUFtQjtRQUFuQixhQUFRLEdBQVIsUUFBUSxDQUFXO1FBcER2QixVQUFLLEdBQVUsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUN6QixZQUFPLEdBQVUsSUFBSSxLQUFLLEVBQUUsQ0FB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QUFDLENBQUMsS0FBSyxDQUFDO2dCQUM5QixJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLGlCQUFpQixDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzVDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQzNDO1lBQ0QsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1NBQ3JCO0lBQ0gsQ0FBQztJQUVELFFBQVEsQ0FBQyxLQUFLLEVBQUUsSUFBSTtRQUNsQixPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7O2tIQTVIVSxxQkFBcUI7c0dBQXJCLHFCQUFxQiw4VkM5Q2xDLDJ4REF5Q0E7MkZES2EscUJBQXFCO2tCQU5qQyxTQUFTOytCQUNFLGVBQWUsaUJBR1YsaUJBQWlCLENBQUMsU0FBUztnR0FLdkIsSUFBSTtzQkFBdEIsU0FBUzt1QkFBQyxNQUFNO2dCQUVGLElBQUk7c0JBQWxCLEtBQUs7dUJBQUMsTUFBTTtnQkFDRyxLQUFLO3NCQUFwQixLQUFLO3VCQUFDLE9BQU87Z0JBQ0ksT0FBTztzQkFBeEIsS0FBSzt1QkFBQyxTQUFTO2dCQUNQLE1BQU07c0JBQWQsS0FBSztnQkFFYyxLQUFLO3NCQUF4QixLQUFLO3VCQUFDLE9BQU87Z0JBU1csVUFBVTtzQkFBbEMsS0FBSzt1QkFBQyxZQUFZO2dCQWNLLFNBQVM7c0JBQWhDLEtBQUs7dUJBQUMsV0FBVztnQkFhYSxtQkFBbUI7c0JBQWpELE1BQU07dUJBQUMscUJBQXFCIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqICBDb3B5cmlnaHQgMjAyMSAgU2VuWCBTLkEuUy5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFJlbmRlcmVyMixcbiAgVmlld0NoaWxkLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7R1RTfSBmcm9tICcuLi8uLi8uLi9tb2RlbC9HVFMnO1xuaW1wb3J0IHtMb2dnZXJ9IGZyb20gJy4uLy4uLy4uL3V0aWxzL2xvZ2dlcic7XG5pbXBvcnQge0dUU0xpYn0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvZ3RzLmxpYic7XG5pbXBvcnQge0NvbG9yTGlifSBmcm9tICcuLi8uLi8uLi91dGlscy9jb2xvci1saWInO1xuaW1wb3J0IHtQYXJhbX0gZnJvbSAnLi4vLi4vLi4vbW9kZWwvcGFyYW0nO1xuaW1wb3J0IHtPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xuXG4vKipcbiAqXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3dhcnB2aWV3LWNoaXAnLFxuICB0ZW1wbGF0ZVVybDogJy4vd2FycC12aWV3LWNoaXAuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi93YXJwLXZpZXctY2hpcC5jb21wb25lbnQuc2NzcyddLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5TaGFkb3dEb21cbn0pXG5leHBvcnQgY2xhc3MgV2FycFZpZXdDaGlwQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICBwcml2YXRlIGV2ZW50c1N1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuXG4gIEBWaWV3Q2hpbGQoJ2NoaXAnKSBjaGlwOiBFbGVtZW50UmVmO1xuXG4gIEBJbnB1dCgnbm9kZScpIG5vZGU6IGFueTtcbiAgQElucHV0KCdwYXJhbScpIHBhcmFtOiBQYXJhbSA9IG5ldyBQYXJhbSgpO1xuICBASW5wdXQoJ29wdGlvbnMnKSBvcHRpb25zOiBQYXJhbSA9IG5ldyBQYXJhbSgpO1xuICBASW5wdXQoKSBldmVudHM6IE9ic2VydmFibGU8Ym9vbGVhbj47XG5cbiAgQElucHV0KCdkZWJ1ZycpIHNldCBkZWJ1ZyhkZWJ1ZzogYm9vbGVhbikge1xuICAgIHRoaXMuX2RlYnVnID0gZGVidWc7XG4gICAgdGhpcy5MT0cuc2V0RGVidWcoZGVidWcpO1xuICB9XG5cbiAgZ2V0IGRlYnVnKCkge1xuICAgIHJldHVybiB0aGlzLl9kZWJ1ZztcbiAgfVxuXG4gIEBJbnB1dCgnaGlkZGVuRGF0YScpIHNldCBoaWRkZW5EYXRhKGhpZGRlbkRhdGE6IG51bWJlcltdKSB7XG4gICAgaWYgKEpTT04uc3RyaW5naWZ5KGhpZGRlbkRhdGEpICE9PSBKU09OLnN0cmluZ2lmeSh0aGlzLl9oaWRkZW5EYXRhKSkge1xuICAgICAgdGhpcy5faGlkZGVuRGF0YSA9IGhpZGRlbkRhdGE7XG4gICAgICB0aGlzLkxPRy5kZWJ1ZyhbJ2hpZGRlbkRhdGEnXSwgaGlkZGVuRGF0YSwgdGhpcy5fbm9kZSwgdGhpcy5fbm9kZS5ndHMsIHRoaXMuX25vZGUuZ3RzLmMpO1xuICAgICAgaWYgKCEhdGhpcy5fbm9kZSAmJiAhIXRoaXMuX25vZGUuZ3RzICYmICEhdGhpcy5fbm9kZS5ndHMuYykge1xuICAgICAgICB0aGlzLnNldFN0YXRlKHRoaXMuX2hpZGRlbkRhdGEuaW5kZXhPZih0aGlzLl9ub2RlLmd0cy5pZCkgPT09IC0xKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBnZXQgaGlkZGVuRGF0YSgpOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2hpZGRlbkRhdGE7XG4gIH1cblxuICBASW5wdXQoJ2d0c0ZpbHRlcicpIHNldCBndHNGaWx0ZXIoZ3RzRmlsdGVyOiBzdHJpbmcpIHtcbiAgICB0aGlzLl9ndHNGaWx0ZXIgPSBndHNGaWx0ZXI7XG4gICAgaWYgKHRoaXMuX2d0c0ZpbHRlci5zbGljZSgxKSAhPT0gJycpIHtcbiAgICAgIHRoaXMuc2V0U3RhdGUobmV3IFJlZ0V4cCh0aGlzLl9ndHNGaWx0ZXIuc2xpY2UoMSksICdnaScpLnRlc3QoR1RTTGliLnNlcmlhbGl6ZUd0c01ldGFkYXRhKHRoaXMuX25vZGUuZ3RzKSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNldFN0YXRlKHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBndHNGaWx0ZXIoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2d0c0ZpbHRlcjtcbiAgfVxuXG4gIEBPdXRwdXQoJ3dhcnBWaWV3U2VsZWN0ZWRHVFMnKSB3YXJwVmlld1NlbGVjdGVkR1RTID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgcHJpdmF0ZSBMT0c6IExvZ2dlcjtcbiAgLy8gdGhlIGZpcnN0IGNoYXJhY3RlciB0cmlnZ2VycyBjaGFuZ2UgZWFjaCBmaWx0ZXIgYXBwbHkgdG8gdHJpZ2dlciBldmVudHMuIGl0IG11c3QgYmUgZGlzY2FyZGVkLlxuICBwcml2YXRlIF9ndHNGaWx0ZXIgPSAneCc7XG4gIHByaXZhdGUgX2RlYnVnID0gZmFsc2U7XG4gIHByaXZhdGUgX2hpZGRlbkRhdGE6IG51bWJlcltdID0gW107XG4gIF9ub2RlOiBhbnkgPSB7XG4gICAgc2VsZWN0ZWQ6IHRydWUsXG4gICAgZ3RzOiBHVFMsXG4gIH07XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZW5kZXJlcjogUmVuZGVyZXIyKSB7XG4gICAgdGhpcy5MT0cgPSBuZXcgTG9nZ2VyKFdhcnBWaWV3Q2hpcENvbXBvbmVudCwgdGhpcy5kZWJ1Zyk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLl9ub2RlID0gey4uLnRoaXMubm9kZSwgc2VsZWN0ZWQ6IHRoaXMuX2hpZGRlbkRhdGEuaW5kZXhPZih0aGlzLm5vZGUuZ3RzLmlkKSA9PT0gLTF9O1xuICAgIGlmICghIXRoaXMuZXZlbnRzKSB7XG4gICAgLy8gIHRoaXMuZXZlbnRzU3Vic2NyaXB0aW9uID0gdGhpcy5ldmVudHMuc3Vic2NyaWJlKHN0YXRlID0+IHRoaXMuc2V0U3RhdGUoc3RhdGUpKTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICBpZiAoISF0aGlzLmV2ZW50c1N1YnNjcmlwdGlvbikge1xuICAgICAgdGhpcy5ldmVudHNTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgaWYgKHRoaXMuZ3RzRmlsdGVyLnNsaWNlKDEpICE9PSAnJyAmJiBuZXcgUmVnRXhwKHRoaXMuZ3RzRmlsdGVyLnNsaWNlKDEpLCAnZ2knKS50ZXN0KEdUU0xpYi5zZXJpYWxpemVHdHNNZXRhZGF0YSh0aGlzLl9ub2RlLmd0cykpXG4gICAgICB8fCB0aGlzLmhpZGRlbkRhdGEuaW5kZXhPZih0aGlzLl9ub2RlLmd0cy5pZCkgPiAtMSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZShmYWxzZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29sb3JpemVDaGlwKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjb2xvcml6ZUNoaXAoKSB7XG4gICAgaWYgKCEhdGhpcy5jaGlwKSB7XG4gICAgICBpZiAoISF0aGlzLl9ub2RlLnNlbGVjdGVkKSB7XG4gICAgICAgIGNvbnN0IGMgPSBDb2xvckxpYi5nZXRDb2xvcih0aGlzLl9ub2RlLmd0cy5pZCwgdGhpcy5vcHRpb25zLnNjaGVtZSk7XG4gICAgICAgIGNvbnN0IGNvbG9yID0gKHRoaXMucGFyYW0gfHwge2RhdGFzZXRDb2xvcjogY30pLmRhdGFzZXRDb2xvciB8fCBjO1xuICAgICAgICB0aGlzLnJlbmRlcmVyLnNldFN0eWxlKHRoaXMuY2hpcC5uYXRpdmVFbGVtZW50LCAnYmFja2dyb3VuZC1jb2xvcicsIGNvbG9yKTtcbiAgICAgICAgdGhpcy5yZW5kZXJlci5zZXRTdHlsZSh0aGlzLmNoaXAubmF0aXZlRWxlbWVudCwgJ2JvcmRlci1jb2xvcicsIGNvbG9yKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucmVuZGVyZXIuc2V0U3R5bGUodGhpcy5jaGlwLm5hdGl2ZUVsZW1lbnQsICdiYWNrZ3JvdW5kLWNvbG9yJywgJ3RyYW5zcGFyZW50Jyk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdG9BcnJheShvYmopIHtcbiAgICBpZiAob2JqID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKG9iaikubWFwKGtleSA9PiAoe25hbWU6IGtleSwgdmFsdWU6IG9ialtrZXldfSkpO1xuICB9XG5cbiAgc3dpdGNoUGxvdFN0YXRlKGV2ZW50OiBVSUV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLnNldFN0YXRlKCF0aGlzLl9ub2RlLnNlbGVjdGVkKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBwcml2YXRlIHNldFN0YXRlKHN0YXRlOiBib29sZWFuKSB7XG4gICAgaWYgKHRoaXMuX25vZGUgJiYgdGhpcy5fbm9kZS5ndHMpIHtcbiAgICAgIHRoaXMuTE9HLmRlYnVnKFsnc3dpdGNoUGxvdFN0YXRlJ10sIHN0YXRlLCB0aGlzLl9ub2RlLnNlbGVjdGVkKTtcbiAgICAgIGlmICh0aGlzLl9ub2RlLnNlbGVjdGVkICE9PSBzdGF0ZSkge1xuICAgICAgICB0aGlzLl9ub2RlLnNlbGVjdGVkID0gISFzdGF0ZTtcbiAgICAgICAgdGhpcy5MT0cuZGVidWcoWydzd2l0Y2hQbG90U3RhdGUnXSwgJ2VtaXQnKTtcbiAgICAgICAgdGhpcy53YXJwVmlld1NlbGVjdGVkR1RTLmVtaXQodGhpcy5fbm9kZSk7XG4gICAgICB9XG4gICAgICB0aGlzLmNvbG9yaXplQ2hpcCgpO1xuICAgIH1cbiAgfVxuXG4gIGlkZW50aWZ5KGluZGV4LCBpdGVtKSB7XG4gICAgcmV0dXJuIGluZGV4O1xuICB9XG59XG4iLCI8IS0tXG4gIH4gIENvcHlyaWdodCAyMDIxICBTZW5YIFMuQS5TLlxuICB+XG4gIH4gIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gIH4gIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAgfiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gIH5cbiAgfiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAgflxuICB+ICBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gIH4gIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAgfiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gIH4gIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAgfiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gIH5cbiAgLS0+XG5cbjxkaXY+XG4gICA8c3BhbiAoY2xpY2spPVwic3dpdGNoUGxvdFN0YXRlKCRldmVudClcIiAqbmdJZj1cIl9ub2RlICYmIF9ub2RlLmd0cyAmJiBfbm9kZS5ndHMubFwiPlxuICAgICA8aSBjbGFzcz1cIm5vcm1hbFwiICNjaGlwPjwvaT5cbiAgICAgPHNwYW4gY2xhc3M9XCJndHNJbmZvXCI+XG4gICAgICAgPHNwYW4gY2xhc3M9J2d0cy1jbGFzc25hbWUnPiZuYnNwO3t7X25vZGUuZ3RzLmN9fTwvc3Bhbj5cbiAgICAgICA8c3BhbiBjbGFzcz0nZ3RzLXNlcGFyYXRvcic+JiN4MDA3QjsgPC9zcGFuPlxuICAgICAgIDxzcGFuICpuZ0Zvcj1cImxldCBsYWJlbCBvZiB0b0FycmF5KF9ub2RlLmd0cy5sKTsgaW5kZXggYXMgaW5kZXg7IGxhc3QgYXMgbGFzdDsgdHJhY2tCeTppZGVudGlmeVwiPlxuICAgICAgICAgPHNwYW4gY2xhc3M9J2d0cy1sYWJlbG5hbWUnPnt7bGFiZWwubmFtZX19PC9zcGFuPlxuICAgICAgICAgPHNwYW4gY2xhc3M9J2d0cy1zZXBhcmF0b3InPj08L3NwYW4+XG4gICAgICAgICA8c3BhbiBjbGFzcz0nZ3RzLWxhYmVsdmFsdWUnPnt7bGFiZWwudmFsdWV9fTwvc3Bhbj5cbiAgICAgICAgIDxzcGFuIFtoaWRkZW5dPVwibGFzdFwiPiwgPC9zcGFuPlxuICAgICAgIDwvc3Bhbj5cbiAgICAgICA8c3BhbiBjbGFzcz1cImd0cy1zZXBhcmF0b3JcIj4gJiN4MDA3RDsgPC9zcGFuPlxuICAgICAgICAgPHNwYW4gY2xhc3M9J2d0cy1zZXBhcmF0b3InPiYjeDAwN0I7IDwvc3Bhbj5cbiAgICAgICAgIDxzcGFuICpuZ0Zvcj1cImxldCBsYWJlbCBvZiB0b0FycmF5KF9ub2RlLmd0cy5hKTsgaW5kZXggYXMgaW5kZXg7IGxhc3QgYXMgbGFzdDsgdHJhY2tCeTppZGVudGlmeVwiPlxuICAgICAgICAgICA8c3BhbiBjbGFzcz0nZ3RzLWF0dHJuYW1lJz57e2xhYmVsLm5hbWV9fTwvc3Bhbj5cbiAgICAgICAgICAgPHNwYW4gY2xhc3M9J2d0cy1zZXBhcmF0b3InPj08L3NwYW4+XG4gICAgICAgICAgIDxzcGFuIGNsYXNzPSdndHMtYXR0cnZhbHVlJz57e2xhYmVsLnZhbHVlfX08L3NwYW4+XG4gICAgICAgICAgIDxzcGFuIFtoaWRkZW5dPVwibGFzdFwiPiwgPC9zcGFuPlxuICAgICAgICAgPC9zcGFuPlxuICAgICAgIDxzcGFuIGNsYXNzPVwiZ3RzLXNlcGFyYXRvclwiPiAmI3gwMDdEOzwvc3Bhbj5cbiAgICAgICA8L3NwYW4+XG4gICA8L3NwYW4+XG48L2Rpdj5cbiJdfQ==