@senx/warpview
Version:
WarpView Elements
406 lines • 56.7 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 { ChartLib } from '../utils/chart-lib';
import { Param } from '../model/param';
import { GTSLib } from '../utils/gts.lib';
import { Directive, ElementRef, EventEmitter, Input, NgZone, Output, Renderer2, ViewChild } from '@angular/core';
import { SizeService } from '../services/resize.service';
import { PlotlyComponent } from '../plotly/plotly.component';
import * as i0 from "@angular/core";
import * as i1 from "../services/resize.service";
// tslint:disable-next-line:directive-class-suffix
export class WarpViewComponent {
constructor(el, renderer, sizeService, ngZone) {
this.el = el;
this.renderer = renderer;
this.sizeService = sizeService;
this.ngZone = ngZone;
this.width = ChartLib.DEFAULT_WIDTH;
this.height = ChartLib.DEFAULT_HEIGHT;
this.drawn = false;
this.chartDraw = new EventEmitter();
this.defOptions = ChartLib.mergeDeep(new Param(), {
dotsLimit: 1000,
heatControls: false,
showRangeSelector: false,
gridLineColor: '#8e8e8e',
showDots: false,
timeZone: 'UTC',
timeUnit: 'us',
showControls: true,
// bounds: {}
});
this._debug = false;
this._responsive = true;
this._unit = '';
this._autoResize = true;
this._hiddenData = [];
this.tooltipPosition = { top: '-10000px', left: '-1000px' };
this.loading = true;
this.noData = true;
this._options = new Param();
this.layout = {
showlegend: false,
margin: {
t: 10,
b: 25,
r: 10,
l: 10
}
};
this.plotlyConfig = {
responsive: true,
showAxisDragHandles: true,
scrollZoom: true,
doubleClick: 'reset+autosize',
showTips: true,
plotGlPixelRatio: 1,
staticPlot: false,
displaylogo: false,
modeBarButtonsToRemove: [
'lasso2d', 'select2d', 'toggleSpikelines', 'toggleHover', 'hoverClosest3d', 'autoScale2d',
'hoverClosestGeo', 'hoverClosestGl2d', 'hoverClosestPie', 'toggleHover',
'hoverClosestCartesian', 'hoverCompareCartesian'
]
};
this.sizeService.sizeChanged$.subscribe((size) => {
if (el.nativeElement.parentElement) {
const parentSize = this.getContentBounds(el.nativeElement.parentElement);
if (this._responsive) {
this.height = parentSize.h;
this.width = parentSize.w;
}
if (!!this.graph && this._responsive && parentSize.h > 0 && this._autoResize) {
const layout = {
width: parentSize.w,
height: this._autoResize ? parentSize.h : this.layout.height
};
if (this.layout.width !== layout.width || this.layout.height !== layout.height) {
setTimeout(() => this.layout = { ...this.layout, ...layout });
this.LOG.debug(['sizeChanged$'], this.layout.width, this.layout.height);
this.resize(layout);
}
}
}
});
}
set hiddenData(hiddenData) {
this._hiddenData = hiddenData;
}
get hiddenData() {
return this._hiddenData;
}
set unit(unit) {
this._unit = unit;
if (!!this._data) {
this.update(undefined, false);
}
}
get unit() {
return this._unit;
}
set debug(debug) {
if (typeof debug === 'string') {
debug = 'true' === debug;
}
this._debug = debug;
this.LOG.setDebug(debug);
}
get debug() {
return this._debug;
}
set responsive(responsive) {
if (typeof responsive === 'string') {
responsive = 'true' === responsive;
}
this._responsive = responsive;
}
get responsive() {
return this._responsive;
}
set options(options) {
this.LOG.debug(['onOptions'], options, { ...this._options });
if (typeof options === 'string') {
options = JSON.parse(options);
}
if (JSON.stringify(options) !== JSON.stringify(this._options)) {
this.drawn = false;
this.LOG.debug(['onOptions', 'changed'], options, { ...this._options });
this._options = ChartLib.mergeDeep(this._options, options);
this.LOG.debug(['onOptions', 'changed 2'], { ...this._options });
if (!!this._data) {
this.update(this._options, false);
}
}
}
set data(data) {
this.LOG.debug(['onData', 'pre', 'WVC'], this._data);
if (data) {
this.drawn = false;
const newData = GTSLib.getData(data);
if (JSON.stringify(newData) !== JSON.stringify(this._data)) {
this._data = newData;
this.update(this._options, true);
this.LOG.debug(['onData', 'WVC'], this._data);
}
}
}
legendFormatter(x, series, highlighted = -1) {
const displayedCurves = [];
if (x === null) {
// This happens when there's no selection and {legend: 'always'} is set.
return `<br>
${series.map(s => {
// FIXME : if (!s.isVisible) return;
let labeledData = GTSLib.formatLabel(s.data.text || '') + ': ' + ((this._options.horizontal ? s.x : s.y) || s.r || '');
let color = s.data.line.color;
if (!!s.data.marker) {
if (GTSLib.isArray(s.data.marker.color)) {
color = s.data.marker.color[0];
}
else {
color = s.data.marker.color;
}
}
if (s.curveNumber === highlighted) {
labeledData = `<i class="chip"
style="background-color: ${color};border: 2px solid ${color};"></i> ${labeledData}`;
}
return labeledData;
}).join('<br>')}`;
}
let html = '';
if (!!series[0]) {
x = series[0].x || series[0].theta;
}
html += `<b>${x}</b><br />`;
// put the highlighted one(s?) first, keep only visible, keep only 50 first ones.
series = series.sort((sa, sb) => (sa.curveNumber === highlighted) ? -1 : 1);
series
// .filter(s => s.isVisible && s.yHTML)
.slice(0, 50)
.forEach((s, i) => {
if (displayedCurves.indexOf(s.curveNumber) <= -1) {
displayedCurves.push(s.curveNumber);
let value = series[0].data.orientation === 'h' ? s.x : s.y;
if (!value && value !== 0) {
value = s.r;
}
let labeledData = GTSLib.formatLabel(s.data.text || '') + ': ' + value;
if (s.curveNumber === highlighted) {
labeledData = `<b>${labeledData}</b>`;
}
let color = s.data.line ? s.data.line.color : '';
if (!!s.data.marker) {
if (GTSLib.isArray(s.data.marker.color)) {
color = s.data.marker.color[0];
}
else {
color = s.data.marker.color;
}
}
html += `<i class="chip" style="background-color: ${color};border: 2px solid ${color};"></i> ${labeledData}`;
if (i < series.length) {
html += '<br>';
}
}
});
return html;
}
initChart(el, resize = true, customData = false, firstDraw = false) {
if (!!this.drawn) {
return true;
}
const parentSize = this.getContentBounds(el.nativeElement.parentElement);
if (this._responsive) {
if (resize) {
if (this._autoResize && (parentSize.h === 0 || this.height !== parentSize.h)
|| parentSize.w === 0 || this.width !== parentSize.w) {
if (this._autoResize) {
this.height = parentSize.h;
}
this.width = parentSize.w;
if (this.height >= 0) {
setTimeout(() => {
this.LOG.debug(['initChart'], 'setTimeout');
return this.initChart(el, resize, customData, firstDraw);
}, 100);
}
return false;
}
else {
if (this._autoResize) {
this.height = parentSize.h;
}
this.width = parentSize.w;
}
}
}
this.LOG.debug(['initChart', 'this._data'], this._data, this._options);
if (!this._data || !this._data.data || this._data.data.length === 0 || !this._options) {
this.loading = false;
this.LOG.debug(['initChart', 'nodata']);
this.noData = true;
this.chartDraw.emit();
return false;
}
this._options = ChartLib.mergeDeep(this.defOptions, this._options || {});
const dataModel = this._data;
this._options = ChartLib.mergeDeep(this._options || {}, this._data.globalParams);
this.LOG.debug(['initChart', 'this._options.timeMode'], this._options.timeMode);
if (!this._options.timeMode) {
this._options.timeMode = this._type === 'display' ? 'custom' : 'date';
}
this.LOG.debug(['initChart', 'this._options.timeMode'], this._options.timeMode, this._options);
this.loading = !this._options.isRefresh;
this.divider = GTSLib.getDivider(this._options.timeUnit);
this.plotlyData = this.convert(dataModel, firstDraw);
this.plotlyConfig.responsive = this._responsive;
this.layout.paper_bgcolor = 'rgba(0,0,0,0)';
this.layout.plot_bgcolor = 'rgba(0,0,0,0)';
if (!this._responsive) {
this.layout.width = this.width || ChartLib.DEFAULT_WIDTH;
if (!this.height && this._autoResize) {
this.layout.height = this.height || ChartLib.DEFAULT_HEIGHT;
}
}
else {
this.layout.width = this.width || parentSize.w;
if (!this.height && this._autoResize) {
this.layout.height = this.height || parentSize.h;
}
}
this.LOG.debug(['initiChart', 'plotlyData'], this.plotlyData);
this.loading = false;
this.chartDraw.emit();
if (!customData) {
this.noData = (this.plotlyData || []).length === 0;
}
return true;
}
afterPlot(plotlyInstance) {
this.LOG.debug(['afterPlot', 'plotlyInstance'], plotlyInstance);
this.loading = false;
this.drawn = true;
this.rect = this.graph.getBoundingClientRect();
this.chartDraw.emit();
}
hideTooltip(timeout = 1000) {
if (!!this.hideTooltipTimer) {
clearTimeout(this.hideTooltipTimer);
}
this.hideTooltipTimer = setTimeout(() => {
this.toolTip.nativeElement.style.display = 'none';
}, timeout);
}
unhover(data, point) {
}
hover(data, highlighted = 0) {
this.renderer.setStyle(this.toolTip.nativeElement, 'display', 'block');
this.hideTooltip(3000);
const p = data.points.filter(pt => pt.curveNumber === highlighted)[0];
const content = this.legendFormatter(this._options.horizontal ?
(data.yvals || [''])[0] :
(data.xvals || [''])[0], data.points, highlighted);
if (!!p) {
let left = (data.event.clientX - this.el.nativeElement.getBoundingClientRect().x + 20) + 'px';
if (data.event.offsetX > this.chartContainer.nativeElement.clientWidth / 2) {
left = Math.max(0, data.event.clientX - this.el.nativeElement.getBoundingClientRect().x - this.toolTip.nativeElement.clientWidth - 20) + 'px';
}
let top = data.event.clientY - this.el.nativeElement.getBoundingClientRect().y;
top = Math.min(this.el.nativeElement.getBoundingClientRect().height - this.toolTip.nativeElement.getBoundingClientRect().height - 20, top);
this.moveTooltip(top + 'px', left, content);
}
}
getTooltipPosition() {
return {
top: this.tooltipPosition.top,
left: this.tooltipPosition.left,
};
}
moveTooltip(top, left, content) {
const div = this.toolTip.nativeElement;
this.LOG.debug(['hover - moveTooltip'], top, left);
div.innerHTML = content;
div.style.top = top;
div.style.left = left;
}
relayout($event) {
}
getLabelColor(el) {
return this.getCSSColor(el, '--warp-view-chart-label-color', '#8e8e8e').trim();
}
getGridColor(el) {
return this.getCSSColor(el, '--warp-view-chart-grid-color', '#8e8e8e').trim();
}
getCSSColor(el, property, defColor) {
const color = getComputedStyle(el).getPropertyValue(property).trim();
return color === '' ? defColor : color;
}
getContentBounds(el) {
return {
h: el.clientHeight
- parseInt(getComputedStyle(el, null).getPropertyValue('padding-top'), 10)
- parseInt(getComputedStyle(el, null).getPropertyValue('padding-bottom'), 10),
w: el.clientWidth
- parseInt(getComputedStyle(el, null).getPropertyValue('padding-left'), 10)
- parseInt(getComputedStyle(el, null).getPropertyValue('padding-right'), 10)
};
}
}
WarpViewComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: WarpViewComponent, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1.SizeService }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
WarpViewComponent.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.2.1", type: WarpViewComponent, inputs: { width: "width", height: "height", hiddenData: "hiddenData", unit: "unit", debug: "debug", responsive: "responsive", options: "options", data: "data" }, outputs: { chartDraw: "chartDraw" }, viewQueries: [{ propertyName: "toolTip", first: true, predicate: ["toolTip"], descendants: true, static: true }, { propertyName: "graph", first: true, predicate: ["graph"], descendants: true }, { propertyName: "chartContainer", first: true, predicate: ["chartContainer"], descendants: true, static: true }], ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: WarpViewComponent, decorators: [{
type: Directive
}], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.SizeService }, { type: i0.NgZone }]; }, propDecorators: { toolTip: [{
type: ViewChild,
args: ['toolTip', { static: true }]
}], graph: [{
type: ViewChild,
args: ['graph']
}], chartContainer: [{
type: ViewChild,
args: ['chartContainer', { static: true }]
}], width: [{
type: Input,
args: ['width']
}], height: [{
type: Input,
args: ['height']
}], hiddenData: [{
type: Input,
args: ['hiddenData']
}], unit: [{
type: Input,
args: ['unit']
}], debug: [{
type: Input,
args: ['debug']
}], responsive: [{
type: Input,
args: ['responsive']
}], options: [{
type: Input,
args: ['options']
}], data: [{
type: Input,
args: ['data']
}], chartDraw: [{
type: Output,
args: ['chartDraw']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FycC12aWV3LWNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3dhcnB2aWV3LW5nL3NyYy9saWIvZWxlbWVudHMvd2FycC12aWV3LWNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sb0JBQW9CLENBQUM7QUFDNUMsT0FBTyxFQUFDLEtBQUssRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBSXJDLE9BQU8sRUFBQyxNQUFNLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQztBQUN4QyxPQUFPLEVBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUMvRyxPQUFPLEVBQU8sV0FBVyxFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDN0QsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLDRCQUE0QixDQUFDOzs7QUFNM0Qsa0RBQWtEO0FBQ2xELE1BQU0sT0FBZ0IsaUJBQWlCO0lBd0lyQyxZQUNTLEVBQWMsRUFDZCxRQUFtQixFQUNuQixXQUF3QixFQUN4QixNQUFjO1FBSGQsT0FBRSxHQUFGLEVBQUUsQ0FBWTtRQUNkLGFBQVEsR0FBUixRQUFRLENBQVc7UUFDbkIsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDeEIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQXZJUCxVQUFLLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQztRQUM5QixXQUFNLEdBQUcsUUFBUSxDQUFDLGNBQWMsQ0FBQztRQUN4QyxVQUFLLEdBQUcsS0FBSyxDQUFDO1FBMEVILGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBTyxDQUFDO1FBRy9DLGVBQVUsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUksS0FBSyxF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QVM7dUJBQUMsU0FBUyxFQUFFLEVBQUMsTUFBTSxFQUFFLElBQUksRUFBQztnQkFDaEIsS0FBSztzQkFBeEIsU0FBUzt1QkFBQyxPQUFPO2dCQUMyQixjQUFjO3NCQUExRCxTQUFTO3VCQUFDLGdCQUFnQixFQUFFLEVBQUMsTUFBTSxFQUFFLElBQUksRUFBQztnQkFFM0IsS0FBSztzQkFBcEIsS0FBSzt1QkFBQyxPQUFPO2dCQUNHLE1BQU07c0JBQXRCLEtBQUs7dUJBQUMsUUFBUTtnQkFJVSxVQUFVO3NCQUFsQyxLQUFLO3VCQUFDLFlBQVk7Z0JBUUEsSUFBSTtzQkFBdEIsS0FBSzt1QkFBQyxNQUFNO2dCQVdPLEtBQUs7c0JBQXhCLEtBQUs7dUJBQUMsT0FBTztnQkFZVyxVQUFVO3NCQUFsQyxLQUFLO3VCQUFDLFlBQVk7Z0JBV0csT0FBTztzQkFBNUIsS0FBSzt1QkFBQyxTQUFTO2dCQWdCRyxJQUFJO3NCQUF0QixLQUFLO3VCQUFDLE1BQU07Z0JBYVEsU0FBUztzQkFBN0IsTUFBTTt1QkFBQyxXQUFXIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqICBDb3B5cmlnaHQgMjAyMSAgU2VuWCBTLkEuUy5cbiAqXG4gKiAgTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqICB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiAgWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKlxuICogICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqICBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiAgV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiAgU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuXG5pbXBvcnQge0NoYXJ0TGlifSBmcm9tICcuLi91dGlscy9jaGFydC1saWInO1xuaW1wb3J0IHtQYXJhbX0gZnJvbSAnLi4vbW9kZWwvcGFyYW0nO1xuaW1wb3J0IHtMb2dnZXJ9IGZyb20gJy4uL3V0aWxzL2xvZ2dlcic7XG5pbXBvcnQge0RhdGFNb2RlbH0gZnJvbSAnLi4vbW9kZWwvZGF0YU1vZGVsJztcbmltcG9ydCB7R1RTfSBmcm9tICcuLi9tb2RlbC9HVFMnO1xuaW1wb3J0IHtHVFNMaWJ9IGZyb20gJy4uL3V0aWxzL2d0cy5saWInO1xuaW1wb3J0IHtEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE5nWm9uZSwgT3V0cHV0LCBSZW5kZXJlcjIsIFZpZXdDaGlsZH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1NpemUsIFNpemVTZXJ2aWNlfSBmcm9tICcuLi9zZXJ2aWNlcy9yZXNpemUuc2VydmljZSc7XG5pbXBvcnQge1Bsb3RseUNvbXBvbmVudH0gZnJvbSAnLi4vcGxvdGx5L3Bsb3RseS5jb21wb25lbnQnO1xuaW1wb3J0IHtDb25maWd9IGZyb20gJ3Bsb3RseS5qcyc7XG5cbmV4cG9ydCB0eXBlIFZpc2liaWxpdHlTdGF0ZSA9ICd1bmtub3duJyB8ICdub3RoaW5nUGxvdHRhYmxlJyB8ICdwbG90dGFibGVzQWxsSGlkZGVuJyB8ICdwbG90dGFibGVTaG93bic7XG5cbkBEaXJlY3RpdmUoKVxuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRpcmVjdGl2ZS1jbGFzcy1zdWZmaXhcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBXYXJwVmlld0NvbXBvbmVudCB7XG4gIEBWaWV3Q2hpbGQoJ3Rvb2xUaXAnLCB7c3RhdGljOiB0cnVlfSkgdG9vbFRpcDogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgnZ3JhcGgnKSBncmFwaDogUGxvdGx5Q29tcG9uZW50O1xuICBAVmlld0NoaWxkKCdjaGFydENvbnRhaW5lcicsIHtzdGF0aWM6IHRydWV9KSBjaGFydENvbnRhaW5lcjogRWxlbWVudFJlZjtcblxuICBASW5wdXQoJ3dpZHRoJykgd2lkdGggPSBDaGFydExpYi5ERUZBVUxUX1dJRFRIO1xuICBASW5wdXQoJ2hlaWdodCcpIGhlaWdodCA9IENoYXJ0TGliLkRFRkFVTFRfSEVJR0hUO1xuICBwcm90ZWN0ZWQgZHJhd24gPSBmYWxzZTtcbiAgcHJvdGVjdGVkIF90eXBlOiBzdHJpbmc7XG5cbiAgQElucHV0KCdoaWRkZW5EYXRhJykgc2V0IGhpZGRlbkRhdGEoaGlkZGVuRGF0YTogbnVtYmVyW10pIHtcbiAgICB0aGlzLl9oaWRkZW5EYXRhID0gaGlkZGVuRGF0YTtcbiAgfVxuXG4gIGdldCBoaWRkZW5EYXRhKCk6IG51bWJlcltdIHtcbiAgICByZXR1cm4gdGhpcy5faGlkZGVuRGF0YTtcbiAgfVxuXG4gIEBJbnB1dCgndW5pdCcpIHNldCB1bml0KHVuaXQ6IHN0cmluZykge1xuICAgIHRoaXMuX3VuaXQgPSB1bml0O1xuICAgIGlmICghIXRoaXMuX2RhdGEpIHtcbiAgICAgIHRoaXMudXBkYXRlKHVuZGVmaW5lZCwgZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIGdldCB1bml0KCkge1xuICAgIHJldHVybiB0aGlzLl91bml0O1xuICB9XG5cbiAgQElucHV0KCdkZWJ1ZycpIHNldCBkZWJ1ZyhkZWJ1ZzogYm9vbGVhbiB8IHN0cmluZykge1xuICAgIGlmICh0eXBlb2YgZGVidWcgPT09ICdzdHJpbmcnKSB7XG4gICAgICBkZWJ1ZyA9ICd0cnVlJyA9PT0gZGVidWc7XG4gICAgfVxuICAgIHRoaXMuX2RlYnVnID0gZGVidWc7XG4gICAgdGhpcy5MT0cuc2V0RGVidWcoZGVidWcpO1xuICB9XG5cbiAgZ2V0IGRlYnVnKCkge1xuICAgIHJldHVybiB0aGlzLl9kZWJ1ZztcbiAgfVxuXG4gIEBJbnB1dCgncmVzcG9uc2l2ZScpIHNldCByZXNwb25zaXZlKHJlc3BvbnNpdmU6IGJvb2xlYW4gfCBzdHJpbmcpIHtcbiAgICBpZiAodHlwZW9mIHJlc3BvbnNpdmUgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXNwb25zaXZlID0gJ3RydWUnID09PSByZXNwb25zaXZlO1xuICAgIH1cbiAgICB0aGlzLl9yZXNwb25zaXZlID0gcmVzcG9uc2l2ZTtcbiAgfVxuXG4gIGdldCByZXNwb25zaXZlKCkge1xuICAgIHJldHVybiB0aGlzLl9yZXNwb25zaXZlO1xuICB9XG5cbiAgQElucHV0KCdvcHRpb25zJykgc2V0IG9wdGlvbnMob3B0aW9uczogUGFyYW0gfCBzdHJpbmcpIHtcbiAgICB0aGlzLkxPRy5kZWJ1ZyhbJ29uT3B0aW9ucyddLCBvcHRpb25zLCB7Li4udGhpcy5fb3B0aW9uc30pO1xuICAgIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIG9wdGlvbnMgPSBKU09OLnBhcnNlKG9wdGlvbnMpO1xuICAgIH1cbiAgICBpZiAoSlNPTi5zdHJpbmdpZnkob3B0aW9ucykgIT09IEpTT04uc3RyaW5naWZ5KHRoaXMuX29wdGlvbnMpKSB7XG4gICAgICB0aGlzLmRyYXduID0gZmFsc2U7XG4gICAgICB0aGlzLkxPRy5kZWJ1ZyhbJ29uT3B0aW9ucycsICdjaGFuZ2VkJ10sIG9wdGlvbnMsIHsuLi50aGlzLl9vcHRpb25zfSk7XG4gICAgICB0aGlzLl9vcHRpb25zID0gQ2hhcnRMaWIubWVyZ2VEZWVwPFBhcmFtPih0aGlzLl9vcHRpb25zLCBvcHRpb25zIGFzIFBhcmFtKTtcbiAgICAgIHRoaXMuTE9HLmRlYnVnKFsnb25PcHRpb25zJywgJ2NoYW5nZWQgMiddLCB7Li4udGhpcy5fb3B0aW9uc30pO1xuICAgICAgaWYgKCEhdGhpcy5fZGF0YSkge1xuICAgICAgICB0aGlzLnVwZGF0ZSh0aGlzLl9vcHRpb25zLCBmYWxzZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgQElucHV0KCdkYXRhJykgc2V0IGRhdGEoZGF0YTogc3RyaW5nIHwgRGF0YU1vZGVsIHwgR1RTW10pIHtcbiAgICB0aGlzLkxPRy5kZWJ1ZyhbJ29uRGF0YScsICdwcmUnLCAnV1ZDJ10sIHRoaXMuX2RhdGEpO1xuICAgIGlmIChkYXRhKSB7XG4gICAgICB0aGlzLmRyYXduID0gZmFsc2U7XG4gICAgICBjb25zdCBuZXdEYXRhID0gR1RTTGliLmdldERhdGEoZGF0YSk7XG4gICAgICBpZiAoSlNPTi5zdHJpbmdpZnkobmV3RGF0YSkgIT09IEpTT04uc3RyaW5naWZ5KHRoaXMuX2RhdGEpKSB7XG4gICAgICAgIHRoaXMuX2RhdGEgPSBuZXdEYXRhO1xuICAgICAgICB0aGlzLnVwZGF0ZSh0aGlzLl9vcHRpb25zLCB0cnVlKTtcbiAgICAgICAgdGhpcy5MT0cuZGVidWcoWydvbkRhdGEnLCAnV1ZDJ10sIHRoaXMuX2RhdGEpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIEBPdXRwdXQoJ2NoYXJ0RHJhdycpIGNoYXJ0RHJhdyA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG4gIHByb3RlY3RlZCBMT0c6IExvZ2dlcjtcbiAgcHJvdGVjdGVkIGRlZk9wdGlvbnMgPSBDaGFydExpYi5tZXJnZURlZXAobmV3IFBhcmFtKCksIHtcbiAgICBkb3RzTGltaXQ6IDEwMDAsXG4gICAgaGVhdENvbnRyb2xzOiBmYWxzZSxcbiAgICBzaG93UmFuZ2VTZWxlY3RvcjogZmFsc2UsXG4gICAgZ3JpZExpbmVDb2xvcjogJyM4ZThlOGUnLFxuICAgIHNob3dEb3RzOiBmYWxzZSxcbiAgICB0aW1lWm9uZTogJ1VUQycsXG4gICAgdGltZVVuaXQ6ICd1cycsXG4gICAgc2hvd0NvbnRyb2xzOiB0cnVlLFxuICAgIC8vIGJvdW5kczoge31cbiAgfSkgYXMgUGFyYW07XG5cbiAgcHJvdGVjdGVkIF9kZWJ1ZyA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgX3Jlc3BvbnNpdmUgPSB0cnVlO1xuICBwcm90ZWN0ZWQgX3VuaXQgPSAnJztcbiAgcHJvdGVjdGVkIF9kYXRhOiBEYXRhTW9kZWw7XG4gIHByb3RlY3RlZCBfYXV0b1Jlc2l6ZSA9IHRydWU7XG4gIHByb3RlY3RlZCBfaGlkZGVuRGF0YTogbnVtYmVyW10gPSBbXTtcbiAgcHJvdGVjdGVkIGRpdmlkZXI6IG51bWJlcjtcblxuICB0b29sdGlwUG9zaXRpb246IGFueSA9IHt0b3A6ICctMTAwMDBweCcsIGxlZnQ6ICctMTAwMHB4J307XG4gIGxvYWRpbmcgPSB0cnVlO1xuICBub0RhdGEgPSB0cnVlO1xuICBfb3B0aW9uczogUGFyYW0gPSBuZXcgUGFyYW0oKTtcbiAgbGF5b3V0OiBQYXJ0aWFsPGFueT4gPSB7XG4gICAgc2hvd2xlZ2VuZDogZmFsc2UsXG4gICAgbWFyZ2luOiB7XG4gICAgICB0OiAxMCxcbiAgICAgIGI6IDI1LFxuICAgICAgcjogMTAsXG4gICAgICBsOiAxMFxuICAgIH1cbiAgfTtcbiAgcGxvdGx5Q29uZmlnOiBQYXJ0aWFsPENvbmZpZz4gPSB7XG4gICAgcmVzcG9uc2l2ZTogdHJ1ZSxcbiAgICBzaG93QXhpc0RyYWdIYW5kbGVzOiB0cnVlLFxuICAgIHNjcm9sbFpvb206IHRydWUsXG4gICAgZG91YmxlQ2xpY2s6ICdyZXNldCthdXRvc2l6ZScsXG4gICAgc2hvd1RpcHM6IHRydWUsXG4gICAgcGxvdEdsUGl4ZWxSYXRpbzogMSxcbiAgICBzdGF0aWNQbG90OiBmYWxzZSxcbiAgICBkaXNwbGF5bG9nbzogZmFsc2UsXG4gICAgbW9kZUJhckJ1dHRvbnNUb1JlbW92ZTogW1xuICAgICAgJ2xhc3NvMmQnLCAnc2VsZWN0MmQnLCAndG9nZ2xlU3Bpa2VsaW5lcycsICd0b2dnbGVIb3ZlcicsICdob3ZlckNsb3Nlc3QzZCcsICdhdXRvU2NhbGUyZCcsXG4gICAgICAnaG92ZXJDbG9zZXN0R2VvJywgJ2hvdmVyQ2xvc2VzdEdsMmQnLCAnaG92ZXJDbG9zZXN0UGllJywgJ3RvZ2dsZUhvdmVyJyxcbiAgICAgICdob3ZlckNsb3Nlc3RDYXJ0ZXNpYW4nLCAnaG92ZXJDb21wYXJlQ2FydGVzaWFuJ1xuICAgIF1cbiAgfTtcbiAgcGxvdGx5RGF0YTogUGFydGlhbDxhbnk+W107XG4gIHByaXZhdGUgaGlkZVRvb2x0aXBUaW1lcjogYW55O1xuICBwcml2YXRlIHJlY3Q6IGFueTtcblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGVsOiBFbGVtZW50UmVmLFxuICAgIHB1YmxpYyByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHB1YmxpYyBzaXplU2VydmljZTogU2l6ZVNlcnZpY2UsXG4gICAgcHVibGljIG5nWm9uZTogTmdab25lXG4gICkge1xuICAgIHRoaXMuc2l6ZVNlcnZpY2Uuc2l6ZUNoYW5nZWQkLnN1YnNjcmliZSgoc2l6ZTogU2l6ZSkgPT4ge1xuICAgICAgaWYgKChlbC5uYXRpdmVFbGVtZW50IGFzIEhUTUxFbGVtZW50KS5wYXJlbnRFbGVtZW50KSB7XG4gICAgICAgIGNvbnN0IHBhcmVudFNpemUgPSB0aGlzLmdldENvbnRlbnRCb3VuZHMoKGVsLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQpLnBhcmVudEVsZW1lbnQpO1xuICAgICAgICBpZiAodGhpcy5fcmVzcG9uc2l2ZSkge1xuICAgICAgICAgIHRoaXMuaGVpZ2h0ID0gcGFyZW50U2l6ZS5oO1xuICAgICAgICAgIHRoaXMud2lkdGggPSBwYXJlbnRTaXplLnc7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCEhdGhpcy5ncmFwaCAmJiB0aGlzLl9yZXNwb25zaXZlICYmIHBhcmVudFNpemUuaCA+IDAgJiYgdGhpcy5fYXV0b1Jlc2l6ZSkge1xuICAgICAgICAgIGNvbnN0IGxheW91dCA9IHtcbiAgICAgICAgICAgIHdpZHRoOiBwYXJlbnRTaXplLncsXG4gICAgICAgICAgICBoZWlnaHQ6IHRoaXMuX2F1dG9SZXNpemUgPyBwYXJlbnRTaXplLmggOiB0aGlzLmxheW91dC5oZWlnaHRcbiAgICAgICAgICB9O1xuICAgICAgICAgIGlmICh0aGlzLmxheW91dC53aWR0aCAhPT0gbGF5b3V0LndpZHRoIHx8IHRoaXMubGF5b3V0LmhlaWdodCAhPT0gbGF5b3V0LmhlaWdodCkge1xuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmxheW91dCA9IHsuLi50aGlzLmxheW91dCwgLi4ubGF5b3V0fSk7XG4gICAgICAgICAgICB0aGlzLkxPRy5kZWJ1ZyhbJ3NpemVDaGFuZ2VkJCddLCB0aGlzLmxheW91dC53aWR0aCwgdGhpcy5sYXlvdXQuaGVpZ2h0KTtcbiAgICAgICAgICAgIHRoaXMucmVzaXplKGxheW91dCk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgdXBkYXRlKG9wdGlvbnM6IFBhcmFtLCByZWZyZXNoOiBib29sZWFuKTogdm9pZDtcblxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgY29udmVydChkYXRhOiBEYXRhTW9kZWwsIGZpcnN0RHJhdz86IGJvb2xlYW4pOiBQYXJ0aWFsPGFueT5bXTtcblxuICBwcm90ZWN0ZWQgYWJzdHJhY3QgcmVzaXplKGxheW91dDogeyB3aWR0aDogbnVtYmVyOyBoZWlnaHQ6IGFueSB9KTtcblxuICBwcm90ZWN0ZWQgbGVnZW5kRm9ybWF0dGVyKHgsIHNlcmllcywgaGlnaGxpZ2h0ZWQgPSAtMSk6IHN0cmluZyB7XG4gICAgY29uc3QgZGlzcGxheWVkQ3VydmVzID0gW107XG4gICAgaWYgKHggPT09IG51bGwpIHtcbiAgICAgIC8vIFRoaXMgaGFwcGVucyB3aGVuIHRoZXJlJ3Mgbm8gc2VsZWN0aW9uIGFuZCB7bGVnZW5kOiAnYWx3YXlzJ30gaXMgc2V0LlxuICAgICAgcmV0dXJuIGA8YnI+XG4gICAgICAke3Nlcmllcy5tYXAocyA9PiB7XG4gICAgICAgIC8vIEZJWE1FIDogIGlmICghcy5pc1Zpc2libGUpIHJldHVybjtcbiAgICAgICAgbGV0IGxhYmVsZWREYXRhID0gR1RTTGliLmZvcm1hdExhYmVsKHMuZGF0YS50ZXh0IHx8ICcnKSArICc6ICcgKyAoKHRoaXMuX29wdGlvbnMuaG9yaXpvbnRhbCA/IHMueCA6IHMueSkgfHwgcy5yIHx8ICcnKTtcbiAgICAgICAgbGV0IGNvbG9yID0gcy5kYXRhLmxpbmUuY29sb3I7XG4gICAgICAgIGlmICghIXMuZGF0YS5tYXJrZXIpIHtcbiAgICAgICAgICBpZiAoR1RTTGliLmlzQXJyYXkocy5kYXRhLm1hcmtlci5jb2xvcikpIHtcbiAgICAgICAgICAgIGNvbG9yID0gcy5kYXRhLm1hcmtlci5jb2xvclswXTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29sb3IgPSBzLmRhdGEubWFya2VyLmNvbG9yO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAocy5jdXJ2ZU51bWJlciA9PT0gaGlnaGxpZ2h0ZWQpIHtcbiAgICAgICAgICBsYWJlbGVkRGF0YSA9IGA8aSBjbGFzcz1cImNoaXBcIlxuICAgIHN0eWxlPVwiYmFja2dyb3VuZC1jb2xvcjogJHtjb2xvcn07Ym9yZGVyOiAycHggc29saWQgJHtjb2xvcn07XCI+PC9pPiAke2xhYmVsZWREYXRhfWA7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGxhYmVsZWREYXRhO1xuICAgICAgfSkuam9pbignPGJyPicpfWA7XG4gICAgfVxuXG4gICAgbGV0IGh0bWwgPSAnJztcbiAgICBpZiAoISFzZXJpZXNbMF0pIHtcbiAgICAgIHggPSBzZXJpZXNbMF0ueCB8fCBzZXJpZXNbMF0udGhldGE7XG4gICAgfVxuICAgIGh0bWwgKz0gYDxiPiR7eH08L2I+PGJyIC8+YDtcbiAgICAvLyBwdXQgdGhlIGhpZ2hsaWdodGVkIG9uZShzPykgZmlyc3QsIGtlZXAgb25seSB2aXNpYmxlLCBrZWVwIG9ubHkgNTAgZmlyc3Qgb25lcy5cbiAgICBzZXJpZXMgPSBzZXJpZXMuc29ydCgoc2EsIHNiKSA9PiAoc2EuY3VydmVOdW1iZXIgPT09IGhpZ2hsaWdodGVkKSA/IC0xIDogMSk7XG4gICAgc2VyaWVzXG4gICAgICAvLyAuZmlsdGVyKHMgPT4gcy5pc1Zpc2libGUgJiYgcy55SFRNTClcbiAgICAgIC5zbGljZSgwLCA1MClcbiAgICAgIC5mb3JFYWNoKChzLCBpKSA9PiB7XG4gICAgICAgIGlmIChkaXNwbGF5ZWRDdXJ2ZXMuaW5kZXhPZihzLmN1cnZlTnVtYmVyKSA8PSAtMSkge1xuICAgICAgICAgIGRpc3BsYXllZEN1cnZlcy5wdXNoKHMuY3VydmVOdW1iZXIpO1xuICAgICAgICAgIGxldCB2YWx1ZSA9IHNlcmllc1swXS5kYXRhLm9yaWVudGF0aW9uID09PSAnaCcgPyBzLnggOiBzLnk7XG4gICAgICAgICAgaWYgKCF2YWx1ZSAmJiB2YWx1ZSAhPT0gMCkge1xuICAgICAgICAgICAgdmFsdWUgPSBzLnI7XG4gICAgICAgICAgfVxuICAgICAgICAgIGxldCBsYWJlbGVkRGF0YSA9IEdUU0xpYi5mb3JtYXRMYWJlbChzLmRhdGEudGV4dCB8fCAnJykgKyAnOiAnICsgdmFsdWU7XG4gICAgICAgICAgaWYgKHMuY3VydmVOdW1iZXIgPT09IGhpZ2hsaWdodGVkKSB7XG4gICAgICAgICAgICBsYWJlbGVkRGF0YSA9IGA8Yj4ke2xhYmVsZWREYXRhfTwvYj5gO1xuICAgICAgICAgIH1cbiAgICAgICAgICBsZXQgY29sb3IgPSBzLmRhdGEubGluZSA/IHMuZGF0YS5saW5lLmNvbG9yIDogJyc7XG4gICAgICAgICAgaWYgKCEhcy5kYXRhLm1hcmtlcikge1xuICAgICAgICAgICAgaWYgKEdUU0xpYi5pc0FycmF5KHMuZGF0YS5tYXJrZXIuY29sb3IpKSB7XG4gICAgICAgICAgICAgIGNvbG9yID0gcy5kYXRhLm1hcmtlci5jb2xvclswXTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGNvbG9yID0gcy5kYXRhLm1hcmtlci5jb2xvcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgaHRtbCArPSBgPGkgY2xhc3M9XCJjaGlwXCIgc3R5bGU9XCJiYWNrZ3JvdW5kLWNvbG9yOiAke2NvbG9yfTtib3JkZXI6IDJweCBzb2xpZCAke2NvbG9yfTtcIj48L2k+Jm5ic3A7JHtsYWJlbGVkRGF0YX1gO1xuICAgICAgICAgIGlmIChpIDwgc2VyaWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgaHRtbCArPSAnPGJyPic7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICByZXR1cm4gaHRtbDtcbiAgfVxuXG4gIHByb3RlY3RlZCBpbml0Q2hhcnQoZWw6IEVsZW1lbnRSZWYsIHJlc2l6ZSA9IHRydWUsIGN1c3RvbURhdGEgPSBmYWxzZSwgZmlyc3REcmF3ID0gZmFsc2UpOiBib29sZWFuIHtcbiAgICBpZiAoISF0aGlzLmRyYXduKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgcGFyZW50U2l6ZSA9IHRoaXMuZ2V0Q29udGVudEJvdW5kcygoZWwubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudCkucGFyZW50RWxlbWVudCk7XG4gICAgaWYgKHRoaXMuX3Jlc3BvbnNpdmUpIHtcbiAgICAgIGlmIChyZXNpemUpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIHRoaXMuX2F1dG9SZXNpemUgJiYgKHBhcmVudFNpemUuaCA9PT0gMCB8fCB0aGlzLmhlaWdodCAhPT0gcGFyZW50U2l6ZS5oKVxuICAgICAgICAgIHx8IHBhcmVudFNpemUudyA9PT0gMCB8fCB0aGlzLndpZHRoICE9PSBwYXJlbnRTaXplLncpIHtcbiAgICAgICAgICBpZiAodGhpcy5fYXV0b1Jlc2l6ZSkge1xuICAgICAgICAgICAgdGhpcy5oZWlnaHQgPSBwYXJlbnRTaXplLmg7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMud2lkdGggPSBwYXJlbnRTaXplLnc7XG4gICAgICAgICAgaWYgKHRoaXMuaGVpZ2h0ID49IDApIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgICAgICB0aGlzLkxPRy5kZWJ1ZyhbJ2luaXRDaGFydCddLCAnc2V0VGltZW91dCcpO1xuICAgICAgICAgICAgICByZXR1cm4gdGhpcy5pbml0Q2hhcnQoZWwsIHJlc2l6ZSwgY3VzdG9tRGF0YSwgZmlyc3REcmF3KTtcbiAgICAgICAgICAgIH0sIDEwMCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAodGhpcy5fYXV0b1Jlc2l6ZSkge1xuICAgICAgICAgICAgdGhpcy5oZWlnaHQgPS