@senx/warpview
Version:
WarpView Elements
184 lines • 36.9 kB
JavaScript
/*
* 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, NgZone, Output, Renderer2, ViewEncapsulation } from '@angular/core';
import { WarpViewComponent } from '../warp-view-component';
import { ColorLib } from '../../utils/color-lib';
import deepEqual from 'deep-equal';
import { SizeService } from '../../services/resize.service';
import { Logger } from '../../utils/logger';
import { ChartLib } from '../../utils/chart-lib';
import { GTSLib } from '../../utils/gts.lib';
import * as i0 from "@angular/core";
import * as i1 from "../../services/resize.service";
import * as i2 from "../warp-view-spinner/warp-view-spinner.component";
import * as i3 from "../../plotly/plotly.component";
import * as i4 from "@angular/common";
export class WarpViewPieComponent extends WarpViewComponent {
constructor(el, renderer, sizeService, ngZone) {
super(el, renderer, sizeService, ngZone);
this.el = el;
this.renderer = renderer;
this.sizeService = sizeService;
this.ngZone = ngZone;
this.chartDraw = new EventEmitter();
this._type = 'pie';
this.layout = {
showlegend: true,
legend: {
orientation: 'h',
bgcolor: 'transparent',
},
orientation: 270,
margin: {
t: 10,
b: 25,
r: 10,
l: 10
}
};
this.LOG = new Logger(WarpViewPieComponent, this._debug);
}
set type(type) {
this._type = type;
this.drawChart();
}
update(options, refresh) {
this.LOG.debug(['onOptions', 'before'], this._options, options);
if (!deepEqual(options, this._options)) {
this.LOG.debug(['options', 'changed'], options);
this._options = ChartLib.mergeDeep(this._options, options);
}
this.drawChart();
}
ngOnInit() {
this._options = this._options || this.defOptions;
}
drawChart() {
if (!this.initChart(this.el)) {
return;
}
this.LOG.debug(['drawChart', 'this.layout'], this.layout);
this.LOG.debug(['drawChart', 'this.plotlyConfig'], this.plotlyConfig);
this.LOG.debug(['drawChart', 'this.plotlyData'], this.plotlyData);
this.layout.legend.font = {
color: this.getCSSColor(this.el.nativeElement, '--warp-view-font-color', '#000')
};
this.layout.textfont = {
color: this.getCSSColor(this.el.nativeElement, '--warp-view-font-color', '#000')
};
this.loading = false;
}
convert(data) {
const gtsList = GTSLib.flatDeep(data.data);
const plotData = [];
this.LOG.debug(['convert', 'gtsList'], gtsList);
const pieData = {
values: [],
labels: [],
marker: {
colors: [],
line: {
width: 3,
color: [],
}
},
textfont: {
color: this.getLabelColor(this.el.nativeElement)
},
hoverlabel: {
bgcolor: this.getCSSColor(this.el.nativeElement, '--warp-view-chart-legend-bg', '#000000'),
bordercolor: 'grey',
font: {
color: this.getCSSColor(this.el.nativeElement, '--warp-view-chart-legend-color', '#ffffff')
}
},
type: 'pie'
};
const dataList = [];
this.LOG.debug(['convert', 'gtsList'], gtsList);
if (!gtsList || gtsList.length === 0) {
return;
}
const dataStruct = [];
if (GTSLib.isGts(gtsList[0])) {
gtsList.forEach((gts, i) => {
const values = (gts.v || []);
const val = values[values.length - 1] || [];
let value = 0;
if (val.length > 0) {
value = val[val.length - 1];
}
dataStruct.push({
key: GTSLib.serializeGtsMetadata(gts),
value
});
});
}
else {
// custom data format
gtsList.forEach((gts, i) => {
if (gts.hasOwnProperty('key')) {
dataStruct.push({
key: gts.key || '',
value: gts.value || Number.MIN_VALUE
});
}
else {
Object.keys(gts).forEach(k => dataStruct.push({ key: k, value: gts[k] }));
}
});
}
this.LOG.debug(['convert', 'dataStruct'], dataStruct);
dataStruct.forEach((d, i) => {
const c = ColorLib.getColor(i, this._options.scheme);
const color = ((data.params || [])[i] || { datasetColor: c }).datasetColor || c;
pieData.values.push(d.value);
pieData.labels.push(d.key);
pieData.marker.colors.push(ColorLib.transparentize(color));
pieData.marker.line.color.push(color);
if (this._type === 'donut') {
pieData.hole = 0.5;
}
if (this.unit) {
pieData.title = {
text: this.unit
};
}
});
if (pieData.values.length > 0) {
plotData.push(pieData);
}
this.noData = plotData.length === 0;
return plotData;
}
resize(layout) {
//
}
}
WarpViewPieComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: WarpViewPieComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1.SizeService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component });
WarpViewPieComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: WarpViewPieComponent, selector: "warpview-pie", inputs: { type: "type" }, outputs: { chartDraw: "chartDraw" }, usesInheritance: 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 id=\"chartContainer\" #chartContainer>\n <warpview-spinner *ngIf=\"loading\" message=\"Parsing data\"></warpview-spinner>\n <p class=\"noData\" *ngIf=\"noData\">No data to display or wrong data format.</p>\n <div *ngIf=\"!loading && !noData\">\n <warpview-plotly #graph *ngIf=\"plotlyData?.length > 0\"\n [data]=\"plotlyData\" [layout]=\"layout\" [config]=\"plotlyConfig\" (afterPlot)=\"afterPlot()\"\n (relayout)=\"relayout($event)\"\n [updateOnLayoutChange]=\"true\" [updateOnDataChange]=\"true\" [debug]=\"debug\"\n [style]=\"{position: 'relative', width: '100%', height: '100%'}\"></warpview-plotly>\n </div>\n</div>\n", styles: ["/*!\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 */: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}:host{display:block;height:100%}:host #chartContainer{height:100%}:host #chartContainer div{height:100%}:host div.chart{width:var(--warp-view-chart-width);height:var(--warp-view-chart-height)}\n"], components: [{ type: i2.WarpViewSpinnerComponent, selector: "warpview-spinner", inputs: ["message"] }, { type: i3.PlotlyComponent, selector: "warpview-plotly", inputs: ["data", "layout", "config", "debug", "frames", "style", "divId", "revision", "className", "useResizeHandler", "updateOnLayoutChange", "updateOnDataChange", "updateOnlyWithRevision"], outputs: ["initialized", "update", "purge", "error", "afterExport", "afterPlot", "animated", "animatingFrame", "animationInterrupted", "autoSize", "beforeExport", "buttonClicked", "click", "plotly_click", "clickAnnotation", "deselect", "doubleClick", "framework", "hover", "legendClick", "legendDoubleClick", "relayout", "restyle", "redraw", "selected", "selecting", "sliderChange", "sliderEnd", "sliderStart", "transitioning", "transitionInterrupted", "unhover", "relayouting"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], encapsulation: i0.ViewEncapsulation.ShadowDom });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: WarpViewPieComponent, decorators: [{
type: Component,
args: [{ selector: 'warpview-pie', 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 id=\"chartContainer\" #chartContainer>\n <warpview-spinner *ngIf=\"loading\" message=\"Parsing data\"></warpview-spinner>\n <p class=\"noData\" *ngIf=\"noData\">No data to display or wrong data format.</p>\n <div *ngIf=\"!loading && !noData\">\n <warpview-plotly #graph *ngIf=\"plotlyData?.length > 0\"\n [data]=\"plotlyData\" [layout]=\"layout\" [config]=\"plotlyConfig\" (afterPlot)=\"afterPlot()\"\n (relayout)=\"relayout($event)\"\n [updateOnLayoutChange]=\"true\" [updateOnDataChange]=\"true\" [debug]=\"debug\"\n [style]=\"{position: 'relative', width: '100%', height: '100%'}\"></warpview-plotly>\n </div>\n</div>\n", styles: ["/*!\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 */: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}:host{display:block;height:100%}:host #chartContainer{height:100%}:host #chartContainer div{height:100%}:host div.chart{width:var(--warp-view-chart-width);height:var(--warp-view-chart-height)}\n"] }]
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.SizeService }, { type: i0.NgZone }]; }, propDecorators: { type: [{
type: Input,
args: ['type']
}], chartDraw: [{
type: Output,
args: ['chartDraw']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FycC12aWV3LXBpZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy93YXJwdmlldy1uZy9zcmMvbGliL2VsZW1lbnRzL3dhcnAtdmlldy1waWUvd2FycC12aWV3LXBpZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy93YXJwdmlldy1uZy9zcmMvbGliL2VsZW1lbnRzL3dhcnAtdmlldy1waWUvd2FycC12aWV3LXBpZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEVBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBVSxNQUFNLEVBQUUsU0FBUyxFQUFFLGlCQUFpQixFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQy9ILE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFNLHdCQUF3QixDQUFDO0FBRXpELE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQyxPQUFPLFNBQVMsTUFBTSxZQUFZLENBQUM7QUFDbkMsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLCtCQUErQixDQUFDO0FBQzFELE9BQU8sRUFBQyxNQUFNLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQztBQUMxQyxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFFL0MsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLHFCQUFxQixDQUFDOzs7Ozs7QUFTM0MsTUFBTSxPQUFPLG9CQUFxQixTQUFRLGlCQUFpQjtJQWtDekQsWUFDUyxFQUFjLEVBQ2QsUUFBbUIsRUFDbkIsV0FBd0IsRUFDeEIsTUFBYztRQUVyQixLQUFLLENBQUMsRUFBRSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFMbEMsT0FBRSxHQUFG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aEIsQ0FBQzthQUNIO1FBQ0gsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUM3QixRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ3hCO1FBQ0QsSUFBSSxDQUFDLE1BQU0sR0FBRyxRQUFRLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQztRQUNwQyxPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBRU0sTUFBTSxDQUFDLE1BQXNDO1FBQ2xELEVBQUU7SUFDSixDQUFDOztpSEFwSlUsb0JBQW9CO3FHQUFwQixvQkFBb0IsMElDbkNqQyxtMUNBNEJBOzJGRE9hLG9CQUFvQjtrQkFOaEMsU0FBUzsrQkFDRSxjQUFjLGlCQUdULGlCQUFpQixDQUFDLFNBQVM7d0tBSXZCLElBQUk7c0JBQXRCLEtBQUs7dUJBQUMsTUFBTTtnQkFLUSxTQUFTO3NCQUE3QixNQUFNO3VCQUFDLFdBQVciLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogIENvcHlyaWdodCAyMDIxICBTZW5YIFMuQS5TLlxuICpcbiAqICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqICBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiAgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5cbmltcG9ydCB7Q29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBOZ1pvbmUsIE9uSW5pdCwgT3V0cHV0LCBSZW5kZXJlcjIsIFZpZXdFbmNhcHN1bGF0aW9ufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7V2FycFZpZXdDb21wb25lbnR9IGZyb20gJy4uL3dhcnAtdmlldy1jb21wb25lbnQnO1xuaW1wb3J0IHtEYXRhTW9kZWx9IGZyb20gJy4uLy4uL21vZGVsL2RhdGFNb2RlbCc7XG5pbXBvcnQge0NvbG9yTGlifSBmcm9tICcuLi8uLi91dGlscy9jb2xvci1saWInO1xuaW1wb3J0IGRlZXBFcXVhbCBmcm9tICdkZWVwLWVxdWFsJztcbmltcG9ydCB7U2l6ZVNlcnZpY2V9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3Jlc2l6ZS5zZXJ2aWNlJztcbmltcG9ydCB7TG9nZ2VyfSBmcm9tICcuLi8uLi91dGlscy9sb2dnZXInO1xuaW1wb3J0IHtDaGFydExpYn0gZnJvbSAnLi4vLi4vdXRpbHMvY2hhcnQtbGliJztcbmltcG9ydCB7UGFyYW19IGZyb20gJy4uLy4uL21vZGVsL3BhcmFtJztcbmltcG9ydCB7R1RTTGlifSBmcm9tICcuLi8uLi91dGlscy9ndHMubGliJztcbmltcG9ydCB7R1RTfSBmcm9tICcuLi8uLi9tb2RlbC9HVFMnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd3YXJwdmlldy1waWUnLFxuICB0ZW1wbGF0ZVVybDogJy4vd2FycC12aWV3LXBpZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3dhcnAtdmlldy1waWUuY29tcG9uZW50LnNjc3MnXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uU2hhZG93RG9tXG59KVxuZXhwb3J0IGNsYXNzIFdhcnBWaWV3UGllQ29tcG9uZW50IGV4dGVuZHMgV2FycFZpZXdDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gIEBJbnB1dCgndHlwZScpIHNldCB0eXBlKHR5cGU6IHN0cmluZykge1xuICAgIHRoaXMuX3R5cGUgPSB0eXBlO1xuICAgIHRoaXMuZHJhd0NoYXJ0KCk7XG4gIH1cblxuICBAT3V0cHV0KCdjaGFydERyYXcnKSBjaGFydERyYXcgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBwcm90ZWN0ZWQgX3R5cGUgPSAncGllJztcbiAgbGF5b3V0OiBQYXJ0aWFsPGFueT4gPSB7XG4gICAgc2hvd2xlZ2VuZDogdHJ1ZSxcbiAgICBsZWdlbmQ6IHtcbiAgICAgIG9yaWVudGF0aW9uOiAnaCcsXG4gICAgICBiZ2NvbG9yOiAndHJhbnNwYXJlbnQnLFxuICAgIH0sXG4gICAgb3JpZW50YXRpb246IDI3MCxcbiAgICBtYXJnaW46IHtcbiAgICAgIHQ6IDEwLFxuICAgICAgYjogMjUsXG4gICAgICByOiAxMCxcbiAgICAgIGw6IDEwXG4gICAgfVxuICB9O1xuXG4gIHVwZGF0ZShvcHRpb25zLCByZWZyZXNoKTogdm9pZCB7XG4gICAgdGhpcy5MT0cuZGVidWcoWydvbk9wdGlvbnMnLCAnYmVmb3JlJ10sIHRoaXMuX29wdGlvbnMsIG9wdGlvbnMpO1xuICAgIGlmICghZGVlcEVxdWFsKG9wdGlvbnMsIHRoaXMuX29wdGlvbnMpKSB7XG4gICAgICB0aGlzLkxPRy5kZWJ1ZyhbJ29wdGlvbnMnLCAnY2hhbmdlZCddLCBvcHRpb25zKTtcbiAgICAgIHRoaXMuX29wdGlvbnMgPSBDaGFydExpYi5tZXJnZURlZXAodGhpcy5fb3B0aW9ucywgb3B0aW9ucyBhcyBQYXJhbSkgYXMgUGFyYW07XG4gICAgfVxuICAgIHRoaXMuZHJhd0NoYXJ0KCk7XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgZWw6IEVsZW1lbnRSZWYsXG4gICAgcHVibGljIHJlbmRlcmVyOiBSZW5kZXJlcjIsXG4gICAgcHVibGljIHNpemVTZXJ2aWNlOiBTaXplU2VydmljZSxcbiAgICBwdWJsaWMgbmdab25lOiBOZ1pvbmVcbiAgKSB7XG4gICAgc3VwZXIoZWwsIHJlbmRlcmVyLCBzaXplU2VydmljZSwgbmdab25lKTtcbiAgICB0aGlzLkxPRyA9IG5ldyBMb2dnZXIoV2FycFZpZXdQaWVDb21wb25lbnQsIHRoaXMuX2RlYnVnKTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuX29wdGlvbnMgPSB0aGlzLl9vcHRpb25zIHx8IHRoaXMuZGVmT3B0aW9ucztcbiAgfVxuXG4gIGRyYXdDaGFydCgpIHtcbiAgICBpZiAoIXRoaXMuaW5pdENoYXJ0KHRoaXMuZWwpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuTE9HLmRlYnVnKFsnZHJhd0NoYXJ0JywgJ3RoaXMubGF5b3V0J10sIHRoaXMubGF5b3V0KTtcbiAgICB0aGlzLkxPRy5kZWJ1ZyhbJ2RyYXdDaGFydCcsICd0aGlzLnBsb3RseUNvbmZpZyddLCB0aGlzLnBsb3RseUNvbmZpZyk7XG4gICAgdGhpcy5MT0cuZGVidWcoWydkcmF3Q2hhcnQnLCAndGhpcy5wbG90bHlEYXRhJ10sIHRoaXMucGxvdGx5RGF0YSk7XG4gICAgdGhpcy5sYXlvdXQubGVnZW5kLmZvbnQgPSB7XG4gICAgICBjb2xvcjogdGhpcy5nZXRDU1NDb2xvcih0aGlzLmVsLm5hdGl2ZUVsZW1lbnQsICctLXdhcnAtdmlldy1mb250LWNvbG9yJywgJyMwMDAnKVxuICAgIH07XG4gICAgdGhpcy5sYXlvdXQudGV4dGZvbnQgPSB7XG4gICAgICBjb2xvcjogdGhpcy5nZXRDU1NDb2xvcih0aGlzLmVsLm5hdGl2ZUVsZW1lbnQsICctLXdhcnAtdmlldy1mb250LWNvbG9yJywgJyMwMDAnKVxuICAgIH07XG4gICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29udmVydChkYXRhOiBEYXRhTW9kZWwpOiBQYXJ0aWFsPGFueT5bXSB7XG4gICAgY29uc3QgZ3RzTGlzdCA9IEdUU0xpYi5mbGF0RGVlcChkYXRhLmRhdGEgYXMgYW55W10pO1xuICAgIGNvbnN0IHBsb3REYXRhID0gW10gYXMgUGFydGlhbDxhbnk+W107XG4gICAgdGhpcy5MT0cuZGVidWcoWydjb252ZXJ0JywgJ2d0c0xpc3QnXSwgZ3RzTGlzdCk7XG4gICAgY29uc3QgcGllRGF0YSA9IHtcbiAgICAgIHZhbHVlczogW10sXG4gICAgICBsYWJlbHM6IFtdLFxuICAgICAgbWFya2VyOiB7XG4gICAgICAgIGNvbG9yczogW10sXG4gICAgICAgIGxpbmU6IHtcbiAgICAgICAgICB3aWR0aDogMyxcbiAgICAgICAgICBjb2xvcjogW10sXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB0ZXh0Zm9udDoge1xuICAgICAgICBjb2xvcjogdGhpcy5nZXRMYWJlbENvbG9yKHRoaXMuZWwubmF0aXZlRWxlbWVudClcbiAgICAgIH0sXG4gICAgICBob3ZlcmxhYmVsOiB7XG4gICAgICAgIGJnY29sb3I6IHRoaXMuZ2V0Q1NTQ29sb3IodGhpcy5lbC5uYXRpdmVFbGVtZW50LCAnLS13YXJwLXZpZXctY2hhcnQtbGVnZW5kLWJnJywgJyMwMDAwMDAnKSxcbiAgICAgICAgYm9yZGVyY29sb3I6ICdncmV5JyxcbiAgICAgICAgZm9udDoge1xuICAgICAgICAgIGNvbG9yOiB0aGlzLmdldENTU0NvbG9yKHRoaXMuZWwubmF0aXZlRWxlbWVudCwgJy0td2FycC12aWV3LWNoYXJ0LWxlZ2VuZC1jb2xvcicsICcjZmZmZmZmJylcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHR5cGU6ICdwaWUnXG4gICAgfSBhcyBhbnk7XG4gICAgY29uc3QgZGF0YUxpc3QgPSBbXTtcbiAgICB0aGlzLkxPRy5kZWJ1ZyhbJ2NvbnZlcnQnLCAnZ3RzTGlzdCddLCBndHNMaXN0KTtcbiAgICBpZiAoIWd0c0xpc3QgfHwgZ3RzTGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZGF0YVN0cnVjdCA9IFtdO1xuICAgIGlmIChHVFNMaWIuaXNHdHMoZ3RzTGlzdFswXSkpIHtcbiAgICAgIGd0c0xpc3QuZm9yRWFjaCgoZ3RzOiBHVFMsIGkpID0+IHtcbiAgICAgICAgY29uc3QgdmFsdWVzID0gKGd0cy52IHx8IFtdKTtcbiAgICAgICAgY29uc3QgdmFsID0gdmFsdWVzW3ZhbHVlcy5sZW5ndGggLSAxXSB8fCBbXTtcbiAgICAgICAgbGV0IHZhbHVlID0gMDtcbiAgICAgICAgaWYgKHZhbC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdmFsdWUgPSB2YWxbdmFsLmxlbmd0aCAtIDFdO1xuICAgICAgICB9XG4gICAgICAgIGRhdGFTdHJ1Y3QucHVzaCh7XG4gICAgICAgICAga2V5OiBHVFNMaWIuc2VyaWFsaXplR3RzTWV0YWRhdGEoZ3RzKSxcbiAgICAgICAgICB2YWx1ZVxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBjdXN0b20gZGF0YSBmb3JtYXRcbiAgICAgIGd0c0xpc3QuZm9yRWFjaCgoZ3RzLCBpKSA9PiB7XG4gICAgICAgIGlmIChndHMuaGFzT3duUHJvcGVydHkoJ2tleScpKSB7XG4gICAgICAgICAgZGF0YVN0cnVjdC5wdXNoKHtcbiAgICAgICAgICAgIGtleTogZ3RzLmtleSB8fCAnJyxcbiAgICAgICAgICAgIHZhbHVlOiBndHMudmFsdWUgfHwgTnVtYmVyLk1JTl9WQUxVRVxuICAgICAgICAgIH0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIE9iamVjdC5rZXlzKGd0cykuZm9yRWFjaChrID0+IGRhdGFTdHJ1Y3QucHVzaCh7a2V5OiBrLCB2YWx1ZTogZ3RzW2tdfSkpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy5MT0cuZGVidWcoWydjb252ZXJ0JywgJ2RhdGFTdHJ1Y3QnXSwgZGF0YVN0cnVjdCk7XG4gICAgZGF0YVN0cnVjdC5mb3JFYWNoKChkOiBhbnksIGkpID0+IHtcbiAgICAgIGNvbnN0IGMgPSBDb2xvckxpYi5nZXRDb2xvcihpLCB0aGlzLl9vcHRpb25zLnNjaGVtZSk7XG4gICAgICBjb25zdCBjb2xvciA9ICgoZGF0YS5wYXJhbXMgfHwgW10pW2ldIHx8IHtkYXRhc2V0Q29sb3I6IGN9KS5kYXRhc2V0Q29sb3IgfHwgYztcbiAgICAgIHBpZURhdGEudmFsdWVzLnB1c2goZC52YWx1ZSk7XG4gICAgICBwaWVEYXRhLmxhYmVscy5wdXNoKGQua2V5KTtcbiAgICAgIHBpZURhdGEubWFya2VyLmNvbG9ycy5wdXNoKENvbG9yTGliLnRyYW5zcGFyZW50aXplKGNvbG9yKSk7XG4gICAgICBwaWVEYXRhLm1hcmtlci5saW5lLmNvbG9yLnB1c2goY29sb3IpO1xuICAgICAgaWYgKHRoaXMuX3R5cGUgPT09ICdkb251dCcpIHtcbiAgICAgICAgcGllRGF0YS5ob2xlID0gMC41O1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMudW5pdCkge1xuICAgICAgICBwaWVEYXRhLnRpdGxlID0ge1xuICAgICAgICAgIHRleHQ6IHRoaXMudW5pdFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmIChwaWVEYXRhLnZhbHVlcy5sZW5ndGggPiAwKSB7XG4gICAgICBwbG90RGF0YS5wdXNoKHBpZURhdGEpO1xuICAgIH1cbiAgICB0aGlzLm5vRGF0YSA9IHBsb3REYXRhLmxlbmd0aCA9PT0gMDtcbiAgICByZXR1cm4gcGxvdERhdGE7XG4gIH1cblxuICBwdWJsaWMgcmVzaXplKGxheW91dDogeyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IGFueSB9KSB7XG4gICAgLy9cbiAgfVxufVxuIiwiPCEtLVxuICB+ICBDb3B5cmlnaHQgMjAyMSAgU2VuWCBTLkEuUy5cbiAgflxuICB+ICBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICB+ICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gIH4gIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICB+XG4gIH4gICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gIH5cbiAgfiAgVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICB+ICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gIH4gIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICB+ICBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gIH4gIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICB+XG4gIC0tPlxuXG48ZGl2IGlkPVwiY2hhcnRDb250YWluZXJcIiAjY2hhcnRDb250YWluZXI+XG4gIDx3YXJwdmlldy1zcGlubmVyICpuZ0lmPVwibG9hZGluZ1wiIG1lc3NhZ2U9XCJQYXJzaW5nIGRhdGFcIj48L3dhcnB2aWV3LXNwaW5uZXI+XG4gIDxwIGNsYXNzPVwibm9EYXRhXCIgKm5nSWY9XCJub0RhdGFcIj5ObyBkYXRhIHRvIGRpc3BsYXkgb3Igd3JvbmcgZGF0YSBmb3JtYXQuPC9wPlxuICA8ZGl2ICpuZ0lmPVwiIWxvYWRpbmcgJiYgIW5vRGF0YVwiPlxuICAgIDx3YXJwdmlldy1wbG90bHkgI2dyYXBoICpuZ0lmPVwicGxvdGx5RGF0YT8ubGVuZ3RoID4gMFwiXG4gICAgICAgICAgICAgICAgICAgICBbZGF0YV09XCJwbG90bHlEYXRhXCIgW2xheW91dF09XCJsYXlvdXRcIiBbY29uZmlnXT1cInBsb3RseUNvbmZpZ1wiIChhZnRlclBsb3QpPVwiYWZ0ZXJQbG90KClcIlxuICAgICAgICAgICAgICAgICAgICAgKHJlbGF5b3V0KT1cInJlbGF5b3V0KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgW3VwZGF0ZU9uTGF5b3V0Q2hhbmdlXT1cInRydWVcIiBbdXBkYXRlT25EYXRhQ2hhbmdlXT1cInRydWVcIiBbZGVidWddPVwiZGVidWdcIlxuICAgICAgICAgICAgICAgICAgICAgW3N0eWxlXT1cIntwb3NpdGlvbjogJ3JlbGF0aXZlJywgd2lkdGg6ICcxMDAlJywgaGVpZ2h0OiAnMTAwJSd9XCI+PC93YXJwdmlldy1wbG90bHk+XG4gIDwvZGl2PlxuPC9kaXY+XG4iXX0=