UNPKG

ng2-google-charts

Version:
367 lines 50.4 kB
import { __awaiter } from "tslib"; import { Component, ElementRef, Input, Output, EventEmitter } from '@angular/core'; import { GoogleChartsDataTable } from '../google-charts-datatable'; import { ChartHTMLTooltip } from './chart-html-tooltip'; import * as i0 from "@angular/core"; import * as i1 from "../google-charts-loader.service"; export var GoogleChartType; (function (GoogleChartType) { GoogleChartType["AnnotationChart"] = "AnnotationChart"; GoogleChartType["AreaChart"] = "AreaChart"; GoogleChartType["BarChart"] = "BarChart"; GoogleChartType["BubbleChart"] = "BubbleChart"; GoogleChartType["Calendar"] = "Calendar"; GoogleChartType["CandlestickChart"] = "CandlestickChart"; GoogleChartType["ColumnChart"] = "ColumnChart"; GoogleChartType["ComboChart"] = "ComboChart"; GoogleChartType["Gantt"] = "Gantt"; GoogleChartType["Gauge"] = "Gauge"; GoogleChartType["GeoChart"] = "GeoChart"; GoogleChartType["Histogram"] = "Histogram"; GoogleChartType["LineChart"] = "LineChart"; GoogleChartType["Map"] = "Map"; GoogleChartType["OrgChart"] = "OrgChart"; GoogleChartType["PieChart"] = "PieChart"; GoogleChartType["Sankey"] = "Sankey"; GoogleChartType["ScatterChart"] = "ScatterChart"; GoogleChartType["SteppedAreaChart"] = "SteppedAreaChart"; GoogleChartType["Table"] = "Table"; GoogleChartType["Timeline"] = "Timeline"; GoogleChartType["TreeMap"] = "TreeMap"; GoogleChartType["VegaChart"] = "VegaChart"; GoogleChartType["WordTree"] = "WordTree"; })(GoogleChartType || (GoogleChartType = {})); export class GoogleChartComponent { constructor(el, loaderService) { this.el = el; this.loaderService = loaderService; this.selectListener = () => { const event = { message: 'select', row: null, column: null, selectedRowValues: [], selectedRowFormattedValues: [], columnLabel: '' }; const s = this.wrapper.visualization.getSelection(); const gs = s[s.length - 1]; if (!gs) { event.message = 'deselect'; return event; } const selection = gs; if (gs.row != null) { event.row = selection.row; const selectedRowValues = []; const selectedRowFormattedValues = []; const dataTable = this.wrapper.getDataTable(); const numberOfColumns = dataTable.getNumberOfColumns(); for (let i = 0; i < numberOfColumns; i++) { selectedRowValues.push(dataTable.getValue(selection.row, i)); selectedRowFormattedValues.push(dataTable.getFormattedValue(selection.row, i)); } event.selectedRowValues = selectedRowValues; event.selectedRowFormattedValues = selectedRowFormattedValues; } if (selection.column != null) { event.column = selection.column; event.columnLabel = this.getColumnLabelAtPosition(selection); } if (gs.name) { event.columnLabel = gs.name; } return event; }; this.chartSelect = new EventEmitter(); this.chartSelectOneTime = new EventEmitter(); this.chartReady = new EventEmitter(); this.chartReadyOneTime = new EventEmitter(); this.chartError = new EventEmitter(); this.chartErrorOneTime = new EventEmitter(); this.mouseOver = new EventEmitter(); this.mouseOverOneTime = new EventEmitter(); this.mouseOut = new EventEmitter(); this.mouseOutOneTime = new EventEmitter(); this.regionClick = new EventEmitter(); this.regionClickOneTime = new EventEmitter(); } ngOnInit() { this.HTMLel = this.el.nativeElement.querySelector('div'); if (Object.isExtensible(this.data)) { this.data.component = this; } this.options = this.data.options; this.init().then(() => { this.draw(); }); } init() { return __awaiter(this, void 0, void 0, function* () { yield this.loaderService.load(); this.recreateWrapper(); }); } recreateWrapper() { if (this.wrapper === undefined || this.wrapper.getChartType() !== this.data.chartType) { this.dataTable = new GoogleChartsDataTable(this.data); this.dataTable.dataTableChanged.subscribe((dt) => { this._draw(); }); // see dataTable in https://developers.google.com/chart/interactive/docs/reference#google.visualization.drawchart let temp = this.data; if (this.data.firstRowIsData) { temp = Object.assign(temp, this.data); temp.dataTable = this.dataTable.getDataTable(); } this.wrapper = new google.visualization.ChartWrapper(temp); this.registerChartWrapperEvents(); /* Calling draw even without data is the only way to pass the HTMl element when using the chart in a dashboard. Don't do this in all other cases: it breaks formatters with remote data source, hence the conditional. */ if (temp.dataTable === undefined && temp.dataSourceUrl === undefined) { try { this.wrapper.draw(this.HTMLel); } catch (err) { } } } } _draw() { return __awaiter(this, void 0, void 0, function* () { const dt = this.dataTable.getDataTable(); if (dt === undefined) { return; } this.convertOptions(); this.recreateWrapper(); this.wrapper.setOptions(this.options); this.wrapper.setDataTable(dt); this.wrapper.draw(this.HTMLel); }); } getDataTable() { return this.dataTable; } draw(value) { if (value === undefined) { value = this.data; } this.options = value.options; this.dataTable.init(value); } getSelectorBySeriesType(seriesType) { const selectors = { bars: 'bar#%s#%r', haxis: 'hAxis#0#label', line: 'point#%s#%r', legend: 'legendentry#%s', area: 'point#%s#%r' }; const selector = selectors[seriesType]; return selector; } /** * Given a column number, counts how many * columns have rol=="data". Those are mapped * one-to-one to the series array. When rol is not defined * a column of type number means a series column. * @param column to inspect */ getSeriesByColumn(column) { let series = 0; const dataTable = this.wrapper.getDataTable(); for (let i = column - 1; i >= 0; i--) { const role = dataTable.getColumnRole(i); const type = dataTable.getColumnType(i); if (role === 'data' || type === 'number') { series++; } } return series; } getBoundingBoxForItem(item) { let boundingBox = { top: 0, left: 0, width: 0, height: 0 }; if (this.cli) { const column = item.column; const series = this.getSeriesByColumn(column); const row = item.row; let seriesType = this.options.seriesType; if (this.options.series && this.options.series[series] && this.options.series[series].type) { seriesType = this.options.series[series].type; } if (seriesType) { let selector = this.getSelectorBySeriesType(seriesType); if (selector) { selector = selector.replace('%s', series + '').replace('%c', column + '').replace('%r', row + ''); const box = this.cli.getBoundingBox(selector); if (box) { boundingBox = box; } } } } return boundingBox; } getValueAtPosition(position) { if (position.row == null) { return null; } const dataTable = this.wrapper.getDataTable(); const value = dataTable.getValue(position.row, position.column); return value; } getColumnTypeAtPosition(position) { const dataTable = this.wrapper.getDataTable(); const type = dataTable.getColumnType(position.column) || ''; return type; } getColumnLabelAtPosition(position) { const dataTable = this.wrapper.getDataTable(); const type = dataTable.getColumnLabel(position.column) || ''; return type; } getHTMLTooltip() { const tooltipER = new ElementRef(this.el.nativeElement.querySelector('.google-visualization-tooltip')); return new ChartHTMLTooltip(tooltipER); } parseMouseEvent(item) { const chartType = this.wrapper.getChartType(); let eventColumn = item.column; if (eventColumn == null) { switch (chartType) { case 'Timeline': eventColumn = this.wrapper.getDataTable().getNumberOfColumns() === 3 ? 0 : 1; break; default: eventColumn = 0; } } const eventRow = item.row; const myItem = { row: eventRow, column: eventColumn }; const event = { position: item, boundingBox: this.getBoundingBoxForItem(myItem), value: this.getValueAtPosition(myItem), columnType: this.getColumnTypeAtPosition(myItem), columnLabel: this.getColumnLabelAtPosition(myItem) }; return event; } registerChartEvents() { const chart = this.wrapper.getChart(); this.cli = chart.getChartLayoutInterface ? chart.getChartLayoutInterface() : null; if (this.mouseOver.observers.length > 0) { google.visualization.events.addListener(chart, 'onmouseover', (item) => { const event = this.parseMouseEvent(item); event.tooltip = this.getHTMLTooltip(); this.mouseOver.emit(event); }); } if (this.mouseOverOneTime.observers.length > 0) { google.visualization.events.addOneTimeListener(chart, 'onmouseover', (item) => { const event = this.parseMouseEvent(item); event.tooltip = this.getHTMLTooltip(); this.mouseOverOneTime.emit(event); }); } if (this.mouseOut.observers.length > 0) { google.visualization.events.addListener(chart, 'onmouseout', (item) => { const event = this.parseMouseEvent(item); this.mouseOut.emit(event); }); } if (this.mouseOutOneTime.observers.length > 0) { google.visualization.events.addOneTimeListener(chart, 'onmouseout', (item) => { const event = this.parseMouseEvent(item); this.mouseOutOneTime.emit(event); }); } if (this.data.chartType === 'GeoChart') { if (this.regionClick.observers.length > 0) { google.visualization.events.addListener(chart, 'regionClick', (item) => { this.regionClick.emit(item); }); } if (this.regionClickOneTime.observers.length > 0) { google.visualization.events.addOneTimeListener(chart, 'regionClick', (item) => { this.regionClick.emit(item); }); } } } registerChartWrapperEvents() { google.visualization.events.addListener(this.wrapper, 'ready', () => { this.chartReady.emit({ message: 'Chart ready' }); }); google.visualization.events.addOneTimeListener(this.wrapper, 'ready', () => { this.chartReadyOneTime.emit({ message: 'Chart ready (one time)' }); this.registerChartEvents(); }); google.visualization.events.addListener(this.wrapper, 'error', (error) => { this.chartError.emit(error); }); google.visualization.events.addOneTimeListener(this.wrapper, 'error', (error) => { this.chartErrorOneTime.emit(error); }); this.addListener(this.wrapper, 'select', this.selectListener, this.chartSelect); this.addOneTimeListener(this.wrapper, 'select', this.selectListener, this.chartSelectOneTime); } addListener(source, eventType, listenerFn, evEmitter) { google.visualization.events.addListener(source, eventType, () => { evEmitter.emit(listenerFn()); }); } addOneTimeListener(source, eventType, listenerFn, evEmitter) { google.visualization.events.addOneTimeListener(source, eventType, () => { evEmitter.emit(listenerFn()); }); } convertOptions() { try { this.options = google.charts[this.data.chartType].convertOptions(this.options); } catch (error) { return; } } } GoogleChartComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.14", ngImport: i0, type: GoogleChartComponent, deps: [{ token: i0.ElementRef }, { token: i1.GoogleChartsLoaderService }], target: i0.ɵɵFactoryTarget.Component }); GoogleChartComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.14", type: GoogleChartComponent, selector: "google-chart", inputs: { data: "data" }, outputs: { chartReady: "chartReady", chartReadyOneTime: "chartReadyOneTime", chartError: "chartError", chartErrorOneTime: "chartErrorOneTime", chartSelect: "chartSelect", chartSelectOneTime: "chartSelectOneTime", mouseOver: "mouseOver", mouseOverOneTime: "mouseOverOneTime", mouseOut: "mouseOut", mouseOutOneTime: "mouseOutOneTime", regionClick: "regionClick", regionClickOneTime: "regionClickOneTime" }, ngImport: i0, template: '<div></div>', isInline: true }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.14", ngImport: i0, type: GoogleChartComponent, decorators: [{ type: Component, args: [{ selector: 'google-chart', template: '<div></div>', }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.GoogleChartsLoaderService }]; }, propDecorators: { data: [{ type: Input }], chartReady: [{ type: Output }], chartReadyOneTime: [{ type: Output }], chartError: [{ type: Output }], chartErrorOneTime: [{ type: Output }], chartSelect: [{ type: Output }], chartSelectOneTime: [{ type: Output }], mouseOver: [{ type: Output }], mouseOverOneTime: [{ type: Output }], mouseOut: [{ type: Output }], mouseOutOneTime: [{ type: Output }], regionClick: [{ type: Output }], regionClickOneTime: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ29vZ2xlLWNoYXJ0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nMi1nb29nbGUtY2hhcnRzL3NyYy9saWIvZ29vZ2xlLWNoYXJ0L2dvb2dsZS1jaGFydC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUVBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsVUFBVSxFQUVWLEtBQUssRUFDTCxNQUFNLEVBQ04sWUFBWSxFQUNiLE1BQU0sZUFBZSxDQUFDO0FBR3ZCLE9BQU8sRUFBRSxxQkFBcUIsRUFBa0MsTUFBTSw0QkFBNEIsQ0FBQztBQVduRyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQzs7O0FBU3hELE1BQU0sQ0FBTixJQUFZLGVBeUJYO0FBekJELFdBQVksZUFBZTtJQUN6QixzREFBbUMsQ0FBQTtJQUNuQywwQ0FBdUIsQ0FBQTtJQUN2Qix3Q0FBcUIsQ0FBQTtJQUNyQiw4Q0FBMkIsQ0FBQTtJQUMzQix3Q0FBcUIsQ0FBQTtJQUNyQix3REFBcUMsQ0FBQTtJQUNyQyw4Q0FBMkIsQ0FBQTtJQUMzQiw0Q0FBeUIsQ0FBQTtJQUN6QixrQ0FBZSxDQUFBO0lBQ2Ysa0NBQWUsQ0FBQTtJQUNmLHdDQUFxQixDQUFBO0lBQ3JCLDBDQUF1QixDQUFBO0lBQ3ZCLDBDQUF1QixDQUFBO0lBQ3ZCLDhCQUFXLENBQUE7SUFDWCx3Q0FBcUIsQ0FBQTtJQUNyQix3Q0FBcUIsQ0FBQTtJQUNyQixvQ0FBaUIsQ0FBQTtJQUNqQixnREFBNkIsQ0FBQTtJQUM3Qix3REFBcUMsQ0FBQTtJQUNyQyxrQ0FBZSxDQUFBO0lBQ2Ysd0NBQXFCLENBQUE7SUFDckIsc0NBQW1CLENBQUE7SUFDbkIsMENBQXVCLENBQUE7SUFDdkIsd0NBQXFCLENBQUE7QUFDdkIsQ0FBQyxFQXpCVyxlQUFlLEtBQWYsZUFBZSxRQXlCMUI7QUFNRCxNQUFNLE9BQU8sb0JBQW9CO0lBNkIvQixZ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VTtzQkFBMUIsTUFBTTtnQkFDVSxpQkFBaUI7c0JBQWpDLE1BQU07Z0JBRVUsVUFBVTtzQkFBMUIsTUFBTTtnQkFDVSxpQkFBaUI7c0JBQWpDLE1BQU07Z0JBRVUsV0FBVztzQkFBM0IsTUFBTTtnQkFDVSxrQkFBa0I7c0JBQWxDLE1BQU07Z0JBRVUsU0FBUztzQkFBekIsTUFBTTtnQkFDVSxnQkFBZ0I7c0JBQWhDLE1BQU07Z0JBRVUsUUFBUTtzQkFBeEIsTUFBTTtnQkFDVSxlQUFlO3NCQUEvQixNQUFNO2dCQUVVLFdBQVc7c0JBQTNCLE1BQU07Z0JBQ1Usa0JBQWtCO3NCQUFsQyxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiZGVjbGFyZSB2YXIgZ29vZ2xlOiBhbnk7XG5cbmltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgT25Jbml0LFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBFdmVudEVtaXR0ZXJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IEdvb2dsZUNoYXJ0c0xvYWRlclNlcnZpY2UgfSBmcm9tICcuLi9nb29nbGUtY2hhcnRzLWxvYWRlci5zZXJ2aWNlJztcbmltcG9ydCB7IEdvb2dsZUNoYXJ0c0RhdGFUYWJsZSwgR29vZ2xlQ2hhcnRzRGF0YVRhYmxlSW50ZXJmYWNlIH0gZnJvbSAnLi4vZ29vZ2xlLWNoYXJ0cy1kYXRhdGFibGUnO1xuaW1wb3J0IHsgQ2hhcnRSZWFkeUV2ZW50IH0gZnJvbSAnLi9jaGFydC1yZWFkeS1ldmVudCc7XG5pbXBvcnQgeyBDaGFydEVycm9yRXZlbnQgfSBmcm9tICcuL2NoYXJ0LWVycm9yLWV2ZW50JztcbmltcG9ydCB7IENoYXJ0U2VsZWN0RXZlbnQgfSBmcm9tICcuL2NoYXJ0LXNlbGVjdC1ldmVudCc7XG5pbXBvcnQge1xuICBDaGFydE1vdXNlRXZlbnQsXG4gIENoYXJ0TW91c2VPdmVyRXZlbnQsXG4gIENoYXJ0TW91c2VPdXRFdmVudCxcbiAgQm91bmRpbmdCb3gsXG4gIERhdGFQb2ludFBvc2l0aW9uXG59IGZyb20gJy4vY2hhcnQtbW91c2UtZXZlbnQnO1xuaW1wb3J0IHsgQ2hhcnRIVE1MVG9vbHRpcCB9IGZyb20gJy4vY2hhcnQtaHRtbC10b29sdGlwJztcbmltcG9ydCB7IFJlZ2lvbkNsaWNrRXZlbnQgfSBmcm9tICcuL2dlb2NoYXJ0LWV2ZW50cyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgR29vZ2xlQ2hhcnRJbnRlcmZhY2UgZXh0ZW5kcyBHb29nbGVDaGFydHNEYXRhVGFibGVJbnRlcmZhY2Uge1xuICBjaGFydFR5cGU6IHN0cmluZyB8IEdvb2dsZUNoYXJ0VHlwZTtcbiAgb3B0aW9ucz86IGFueTtcbiAgY29tcG9uZW50PzogR29vZ2xlQ2hhcnRDb21wb25lbnQ7XG59XG5cbmV4cG9ydCBlbnVtIEdvb2dsZUNoYXJ0VHlwZSB7XG4gIEFubm90YXRpb25DaGFydCA9ICdBbm5vdGF0aW9uQ2hhcnQnLFxuICBBcmVhQ2hhcnQgPSAnQXJlYUNoYXJ0JyxcbiAgQmFyQ2hhcnQgPSAnQmFyQ2hhcnQnLFxuICBCdWJibGVDaGFydCA9ICdCdWJibGVDaGFydCcsXG4gIENhbGVuZGFyID0gJ0NhbGVuZGFyJyxcbiAgQ2FuZGxlc3RpY2tDaGFydCA9ICdDYW5kbGVzdGlja0NoYXJ0JyxcbiAgQ29sdW1uQ2hhcnQgPSAnQ29sdW1uQ2hhcnQnLFxuICBDb21ib0NoYXJ0ID0gJ0NvbWJvQ2hhcnQnLFxuICBHYW50dCA9ICdHYW50dCcsXG4gIEdhdWdlID0gJ0dhdWdlJyxcbiAgR2VvQ2hhcnQgPSAnR2VvQ2hhcnQnLFxuICBIaXN0b2dyYW0gPSAnSGlzdG9ncmFtJyxcbiAgTGluZUNoYXJ0ID0gJ0xpbmVDaGFydCcsXG4gIE1hcCA9ICdNYXAnLFxuICBPcmdDaGFydCA9ICdPcmdDaGFydCcsXG4gIFBpZUNoYXJ0ID0gJ1BpZUNoYXJ0JyxcbiAgU2Fua2V5ID0gJ1NhbmtleScsXG4gIFNjYXR0ZXJDaGFydCA9ICdTY2F0dGVyQ2hhcnQnLFxuICBTdGVwcGVkQXJlYUNoYXJ0ID0gJ1N0ZXBwZWRBcmVhQ2hhcnQnLFxuICBUYWJsZSA9ICdUYWJsZScsXG4gIFRpbWVsaW5lID0gJ1RpbWVsaW5lJyxcbiAgVHJlZU1hcCA9ICdUcmVlTWFwJyxcbiAgVmVnYUNoYXJ0ID0gJ1ZlZ2FDaGFydCcsXG4gIFdvcmRUcmVlID0gJ1dvcmRUcmVlJyxcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZ29vZ2xlLWNoYXJ0JyxcbiAgdGVtcGxhdGU6ICc8ZGl2PjwvZGl2PicsXG59KVxuZXhwb3J0IGNsYXNzIEdvb2dsZUNoYXJ0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICBASW5wdXQoKSBwdWJsaWMgZGF0YSE6IEdvb2dsZUNoYXJ0SW50ZXJmYWNlO1xuXG4gIEBPdXRwdXQoKSBwdWJsaWMgY2hhcnRSZWFkeTogRXZlbnRFbWl0dGVyPENoYXJ0UmVhZHlFdmVudD47XG4gIEBPdXRwdXQoKSBwdWJsaWMgY2hhcnRSZWFkeU9uZVRpbWU6IEV2ZW50RW1pdHRlcjxDaGFydFJlYWR5RXZlbnQ+O1xuXG4gIEBPdXRwdXQoKSBwdWJsaWMgY2hhcnRFcnJvcjogRXZlbnRFbWl0dGVyPENoYXJ0RXJyb3JFdmVudD47XG4gIEBPdXRwdXQoKSBwdWJsaWMgY2hhcnRFcnJvck9uZVRpbWU6IEV2ZW50RW1pdHRlcjxDaGFydEVycm9yRXZlbnQ+O1xuXG4gIEBPdXRwdXQoKSBwdWJsaWMgY2hhcnRTZWxlY3Q6IEV2ZW50RW1pdHRlcjxDaGFydFNlbGVjdEV2ZW50PjtcbiAgQE91dHB1dCgpIHB1YmxpYyBjaGFydFNlbGVjdE9uZVRpbWU6IEV2ZW50RW1pdHRlcjxDaGFydFNlbGVjdEV2ZW50PjtcblxuICBAT3V0cHV0KCkgcHVibGljIG1vdXNlT3ZlcjogRXZlbnRFbWl0dGVyPENoYXJ0TW91c2VPdmVyRXZlbnQ+O1xuICBAT3V0cHV0KCkgcHVibGljIG1vdXNlT3Zlck9uZVRpbWU6IEV2ZW50RW1pdHRlcjxDaGFydE1vdXNlT3ZlckV2ZW50PjtcblxuICBAT3V0cHV0KCkgcHVibGljIG1vdXNlT3V0OiBFdmVudEVtaXR0ZXI8Q2hhcnRNb3VzZU91dEV2ZW50PjtcbiAgQE91dHB1dCgpIHB1YmxpYyBtb3VzZU91dE9uZVRpbWU6IEV2ZW50RW1pdHRlcjxDaGFydE1vdXNlT3V0RXZlbnQ+O1xuXG4gIEBPdXRwdXQoKSBwdWJsaWMgcmVnaW9uQ2xpY2s6IEV2ZW50RW1pdHRlcjxSZWdpb25DbGlja0V2ZW50PjtcbiAgQE91dHB1dCgpIHB1YmxpYyByZWdpb25DbGlja09uZVRpbWU6IEV2ZW50RW1pdHRlcjxSZWdpb25DbGlja0V2ZW50PjtcblxuICBwdWJsaWMgd3JhcHBlcjogYW55O1xuICBwcml2YXRlIGNsaTogYW55O1xuICBwcml2YXRlIG9wdGlvbnM6IGFueTtcblxuICBwcml2YXRlIEhUTUxlbCE6IEhUTUxFbGVtZW50O1xuICBwcml2YXRlIGRhdGFUYWJsZSE6IEdvb2dsZUNoYXJ0c0RhdGFUYWJsZTtcblxuICBwdWJsaWMgY29uc3RydWN0b3IocHJpdmF0ZSBlbDogRWxlbWVudFJlZixcbiAgICAgICAgICAgICAgICAgICAgIHByaXZhdGUgbG9hZGVyU2VydmljZTogR29vZ2xlQ2hhcnRzTG9hZGVyU2VydmljZSkge1xuICAgIHRoaXMuY2hhcnRTZWxlY3QgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgdGhpcy5jaGFydFNlbGVjdE9uZVRpbWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgdGhpcy5jaGFydFJlYWR5ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIHRoaXMuY2hhcnRSZWFkeU9uZVRpbWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgdGhpcy5jaGFydEVycm9yID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIHRoaXMuY2hhcnRFcnJvck9uZVRpbWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgdGhpcy5tb3VzZU92ZXIgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgdGhpcy5tb3VzZU92ZXJPbmVUaW1lID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIHRoaXMubW91c2VPdXQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgdGhpcy5tb3VzZU91dE9uZVRpbWUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgdGhpcy5yZWdpb25DbGljayA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICB0aGlzLnJlZ2lvbkNsaWNrT25lVGltZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLkhUTUxlbCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCdkaXYnKTtcbiAgICBpZiAoT2JqZWN0LmlzRXh0ZW5zaWJsZSh0aGlzLmRhdGEpKSB7XG4gICAgICB0aGlzLmRhdGEuY29tcG9uZW50ID0gdGhpcztcbiAgICB9XG4gICAgdGhpcy5vcHRpb25zID0gdGhpcy5kYXRhLm9wdGlvbnM7XG5cbiAgICB0aGlzLmluaXQoKS50aGVuKCgpID0+IHtcbiAgICAgIHRoaXMuZHJhdygpO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGluaXQoKSB7XG4gICAgYXdhaXQgdGhpcy5sb2FkZXJTZXJ2aWNlLmxvYWQoKTtcbiAgICB0aGlzLnJlY3JlYXRlV3JhcHBlcigpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWNyZWF0ZVdyYXBwZXIoKSB7XG4gICAgaWYgKHRoaXMud3JhcHBlciA9PT0gdW5kZWZpbmVkIHx8IHRoaXMud3JhcHBlci5nZXRDaGFydFR5cGUoKSAhPT0gdGhpcy5kYXRhLmNoYXJ0VHlwZSkge1xuICAgICAgdGhpcy5kYXRhVGFibGUgPSBuZXcgR29vZ2xlQ2hhcnRzRGF0YVRhYmxlKHRoaXMuZGF0YSk7XG4gICAgICB0aGlzLmRhdGFUYWJsZS5kYXRhVGFibGVDaGFuZ2VkLnN1YnNjcmliZSgoZHQ6IGFueSkgPT4ge1xuICAgICAgICB0aGlzLl9kcmF3KCk7XG4gICAgICB9KTtcblxuICAgICAgLy8gc2VlIGRhdGFUYWJsZSBpbiBodHRwczovL2RldmVsb3BlcnMuZ29vZ2xlLmNvbS9jaGFydC9pbnRlcmFjdGl2ZS9kb2NzL3JlZmVyZW5jZSNnb29nbGUudmlzdWFsaXphdGlvbi5kcmF3Y2hhcnRcbiAgICAgIGxldCB0ZW1wOiBHb29nbGVDaGFydEludGVyZmFjZSA9IHRoaXMuZGF0YTtcbiAgICAgIGlmICh0aGlzLmRhdGEuZmlyc3RSb3dJc0RhdGEpIHtcbiAgICAgICAgdGVtcCA9IE9iamVjdC5hc3NpZ24odGVtcCwgdGhpcy5kYXRhKTtcbiAgICAgICAgdGVtcC5kYXRhVGFibGUgPSB0aGlzLmRhdGFUYWJsZS5nZXREYXRhVGFibGUoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMud3JhcHBlciA9IG5ldyBnb29nbGUudmlzdWFsaXphdGlvbi5DaGFydFdyYXBwZXIodGVtcCk7XG4gICAgICB0aGlzLnJlZ2lzdGVyQ2hhcnRXcmFwcGVyRXZlbnRzKCk7XG5cbiAgICAgIC8qIENhbGxpbmcgZHJhdyBldmVuIHdpdGhvdXQgZGF0YSBpcyB0aGUgb25seSB3YXkgdG8gcGFzcyB0aGUgSFRNbCBlbGVtZW50XG4gICAgICAgICB3aGVuIHVzaW5nIHRoZSBjaGFydCBpbiBhIGRhc2hib2FyZC4gRG9uJ3QgZG8gdGhpcyBpbiBhbGwgb3RoZXIgY2FzZXM6XG4gICAgICAgICBpdCBicmVha3MgZm9ybWF0dGVycyB3aXRoIHJlbW90ZSBkYXRhIHNvdXJjZSwgaGVuY2UgdGhlIGNvbmRpdGlvbmFsLiAqL1xuICAgICAgaWYgKHRlbXAuZGF0YVRhYmxlID09PSB1bmRlZmluZWQgJiYgdGVtcC5kYXRhU291cmNlVXJsID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB0aGlzLndyYXBwZXIuZHJhdyh0aGlzLkhUTUxlbCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycikge31cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIF9kcmF3KCkge1xuICAgIGNvbnN0IGR0ID0gdGhpcy5kYXRhVGFibGUuZ2V0RGF0YVRhYmxlKCk7XG4gICAgaWYgKGR0ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jb252ZXJ0T3B0aW9ucygpO1xuICAgIHRoaXMucmVjcmVhdGVXcmFwcGVyKCk7XG4gICAgdGhpcy53cmFwcGVyLnNldE9wdGlvbnModGhpcy5vcHRpb25zKTtcbiAgICB0aGlzLndyYXBwZXIuc2V0RGF0YVRhYmxlKGR0KTtcbiAgICB0aGlzLndyYXBwZXIuZHJhdyh0aGlzLkhUTUxlbCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0RGF0YVRhYmxlKCk6IEdvb2dsZUNoYXJ0c0RhdGFUYWJsZSB7XG4gICAgcmV0dXJuIHRoaXMuZGF0YVRhYmxlO1xuICB9XG5cbiAgcHVibGljIGRyYXcodmFsdWU/OiBHb29nbGVDaGFydEludGVyZmFjZSkge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YWx1ZSA9IHRoaXMuZGF0YTtcbiAgICB9XG4gICAgdGhpcy5vcHRpb25zID0gdmFsdWUub3B0aW9ucztcbiAgICB0aGlzLmRhdGFUYWJsZS5pbml0KHZhbHVlKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U2VsZWN0b3JCeVNlcmllc1R5cGUoc2VyaWVzVHlwZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBzZWxlY3RvcnM6IGFueSA9IHtcbiAgICAgIGJhcnMgOiAnYmFyIyVzIyVyJyxcbiAgICAgIGhheGlzIDogJ2hBeGlzIzAjbGFiZWwnLFxuICAgICAgbGluZTogJ3BvaW50IyVzIyVyJyxcbiAgICAgIGxlZ2VuZCA6ICdsZWdlbmRlbnRyeSMlcycsXG4gICAgICBhcmVhOiAncG9pbnQjJXMjJXInXG4gICAgfTtcblxuICAgIGNvbnN0IHNlbGVjdG9yOiBzdHJpbmcgPSBzZWxlY3RvcnNbc2VyaWVzVHlwZV07XG5cbiAgICByZXR1cm4gc2VsZWN0b3I7XG4gIH1cblxuIC8qKlxuICAqIEdpdmVuIGEgY29sdW1uIG51bWJlciwgY291bnRzIGhvdyBtYW55XG4gICogY29sdW1ucyBoYXZlIHJvbD09XCJkYXRhXCIuIFRob3NlIGFyZSBtYXBwZWRcbiAgKiBvbmUtdG8tb25lIHRvIHRoZSBzZXJpZXMgYXJyYXkuIFdoZW4gcm9sIGlzIG5vdCBkZWZpbmVkXG4gICogYSBjb2x1bW4gb2YgdHlwZSBudW1iZXIgbWVhbnMgYSBzZXJpZXMgY29sdW1uLlxuICAqIEBwYXJhbSBjb2x1bW4gdG8gaW5zcGVjdFxuICAqL1xuICBwcml2YXRlIGdldFNlcmllc0J5Q29sdW1uKGNvbHVtbjogbnVtYmVyKTogbnVtYmVyICB7XG4gICAgbGV0IHNlcmllcyA9IDA7XG4gICAgY29uc3QgZGF0YVRhYmxlID0gdGhpcy53cmFwcGVyLmdldERhdGFUYWJsZSgpO1xuICAgIGZvciAobGV0IGkgPSBjb2x1bW4gLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgY29uc3Qgcm9sZSA9IGRhdGFUYWJsZS5nZXRDb2x1bW5Sb2xlKGkpO1xuICAgICAgY29uc3QgdHlwZSA9IGRhdGFUYWJsZS5nZXRDb2x1bW5UeXBlKGkpO1xuICAgICAgaWYgKHJvbGUgPT09ICdkYXRhJyB8fCB0eXBlID09PSAnbnVtYmVyJykge1xuICAgICAgICBzZXJpZXMrKztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNlcmllcztcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Qm91bmRpbmdCb3hGb3JJdGVtKGl0ZW06IERhdGFQb2ludFBvc2l0aW9uKTogQm91bmRpbmdCb3gge1xuICAgIGxldCBib3VuZGluZ0JveCA9IHt0b3A6IDAsIGxlZnQ6IDAsIHdpZHRoOiAwLCBoZWlnaHQ6IDB9O1xuICAgIGlmICh0aGlzLmNsaSkge1xuICAgICAgY29uc3QgY29sdW1uID0gaXRlbS5jb2x1bW47XG4gICAgICBjb25zdCBzZXJpZXMgPSB0aGlzLmdldFNlcmllc0J5Q29sdW1uKGNvbHVtbik7XG4gICAgICBjb25zdCByb3cgPSBpdGVtLnJvdztcbiAgICAgIGxldCBzZXJpZXNUeXBlID0gdGhpcy5vcHRpb25zLnNlcmllc1R5cGU7XG4gICAgICBpZiAodGhpcy5vcHRpb25zLnNlcmllcyAmJiB0aGlzLm9wdGlvbnMuc2VyaWVzW3Nlcmllc10gJiYgdGhpcy5vcHRpb25zLnNlcmllc1tzZXJpZXNdLnR5cGUpIHtcbiAgICAgICAgc2VyaWVzVHlwZSA9IHRoaXMub3B0aW9ucy5zZXJpZXNbc2VyaWVzXS50eXBlO1xuICAgICAgfVxuICAgICAgaWYgKHNlcmllc1R5cGUpIHtcbiAgICAgICAgbGV0IHNlbGVjdG9yID0gdGhpcy5nZXRTZWxlY3RvckJ5U2VyaWVzVHlwZShzZXJpZXNUeXBlKTtcbiAgICAgICAgaWYgKHNlbGVjdG9yKSB7XG4gICAgICAgICAgICAgc2VsZWN0b3IgPSBzZWxlY3Rvci5yZXBsYWNlKCclcycsIHNlcmllcyArICcnKS5yZXBsYWNlKCclYycsIGNvbHVtbiArICcnKS5yZXBsYWNlKCclcicsIHJvdyArICcnKTtcbiAgICAgICAgICAgICBjb25zdCBib3ggPSB0aGlzLmNsaS5nZXRCb3VuZGluZ0JveChzZWxlY3Rvcik7XG4gICAgICAgICAgICAgaWYgKGJveCkge1xuICAgICAgICAgICAgICBib3VuZGluZ0JveCA9IGJveDtcbiAgICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYm91bmRpbmdCb3g7XG4gIH1cblxuICBwcml2YXRlIGdldFZhbHVlQXRQb3NpdGlvbihwb3NpdGlvbjogRGF0YVBvaW50UG9zaXRpb24pOiBhbnkge1xuICAgIGlmIChwb3NpdGlvbi5yb3cgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0IGRhdGFUYWJsZSA9IHRoaXMud3JhcHBlci5nZXREYXRhVGFibGUoKTtcbiAgICBjb25zdCB2YWx1ZSA9IGRhdGFUYWJsZS5nZXRWYWx1ZShwb3NpdGlvbi5yb3csIHBvc2l0aW9uLmNvbHVtbik7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDb2x1bW5UeXBlQXRQb3NpdGlvbihwb3NpdGlvbjogRGF0YVBvaW50UG9zaXRpb24pOiBzdHJpbmcge1xuICAgICAgY29uc3QgZGF0YVRhYmxlID0gdGhpcy53cmFwcGVyLmdldERhdGFUYWJsZSgpO1xuICAgICAgY29uc3QgdHlwZSA9IGRhdGFUYWJsZS5nZXRDb2x1bW5UeXBlKHBvc2l0aW9uLmNvbHVtbikgfHwgJyc7XG4gICAgICByZXR1cm4gdHlwZTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29sdW1uTGFiZWxBdFBvc2l0aW9uKHBvc2l0aW9uOiBEYXRhUG9pbnRQb3NpdGlvbik6IHN0cmluZyB7XG4gICAgICBjb25zdCBkYXRhVGFibGUgPSB0aGlzLndyYXBwZXIuZ2V0RGF0YVRhYmxlKCk7XG4gICAgICBjb25zdCB0eXBlID0gZGF0YVRhYmxlLmdldENvbHVtbkxhYmVsKHBvc2l0aW9uLmNvbHVtbikgfHwgJyc7XG4gICAgICByZXR1cm4gdHlwZTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0SFRNTFRvb2x0aXAoKTogQ2hhcnRIVE1MVG9vbHRpcCB7XG4gICAgY29uc3QgdG9vbHRpcEVSID0gbmV3IEVsZW1lbnRSZWYodGhpcy5lbC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5nb29nbGUtdmlzdWFsaXphdGlvbi10b29sdGlwJykpO1xuICAgIHJldHVybiBuZXcgQ2hhcnRIVE1MVG9vbHRpcCh0b29sdGlwRVIpO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZU1vdXNlRXZlbnQoaXRlbTogRGF0YVBvaW50UG9zaXRpb24pOiBDaGFydE1vdXNlRXZlbnQge1xuICAgIGNvbnN0IGNoYXJ0VHlwZSA9IHRoaXMud3JhcHBlci5nZXRDaGFydFR5cGUoKTtcbiAgICBsZXQgZXZlbnRDb2x1bW4gPSBpdGVtLmNvbHVtbjtcbiAgICBpZiAoZXZlbnRDb2x1bW4gPT0gbnVsbCkge1xuICAgICAgc3dpdGNoIChjaGFydFR5cGUpIHtcbiAgICAgICAgY2FzZSAnVGltZWxpbmUnOlxuICAgICAgICAgIGV2ZW50Q29sdW1uID0gdGhpcy53cmFwcGVyLmdldERhdGFUYWJsZSgpLmdldE51bWJlck9mQ29sdW1ucygpID09PSAzID8gMCA6IDE7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgZXZlbnRDb2x1bW4gPSAwO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCBldmVudFJvdyA9IGl0ZW0ucm93O1xuICAgIGNvbnN0IG15SXRlbSA9IHtcbiAgICAgIHJvdzogZXZlbnRSb3csXG4gICAgICBjb2x1bW46IGV2ZW50Q29sdW1uXG4gICAgfTtcbiAgICBjb25zdCBldmVudCA9IHtcbiAgICAgIHBvc2l0aW9uOiBpdGVtLFxuICAgICAgYm91bmRpbmdCb3g6IHRoaXMuZ2V0Qm91bmRpbmdCb3hGb3JJdGVtKG15SXRlbSksXG4gICAgICB2YWx1ZTogdGhpcy5nZXRWYWx1ZUF0UG9zaXRpb24obXlJdGVtKSxcbiAgICAgIGNvbHVtblR5cGU6IHRoaXMuZ2V0Q29sdW1uVHlwZUF0UG9zaXRpb24obXlJdGVtKSxcbiAgICAgIGNvbHVtbkxhYmVsOiB0aGlzLmdldENvbHVtbkxhYmVsQXRQb3NpdGlvbihteUl0ZW0pXG4gICAgfTtcbiAgICByZXR1cm4gZXZlbnQ7XG4gIH1cblxuICBwcml2YXRlIHJlZ2lzdGVyQ2hhcnRFdmVudHMoKTogdm9pZCB7XG4gICAgY29uc3QgY2hhcnQgPSB0aGlzLndyYXBwZXIuZ2V0Q2hhcnQoKTtcbiAgICB0aGlzLmNsaSA9IGNoYXJ0LmdldENoYXJ0TGF5b3V0SW50ZXJmYWNlID8gY2hhcnQuZ2V0Q2hhcnRMYXlvdXRJbnRlcmZhY2UoKSA6IG51bGw7XG4gICAgaWYgKHRoaXMubW91c2VPdmVyLm9ic2VydmVycy5sZW5ndGggPiAwKSB7XG4gICAgICBnb29nbGUudmlzdWFsaXphdGlvbi5ldmVudHMuYWRkTGlzdGVuZXIoY2hhcnQsICdvbm1vdXNlb3ZlcicsIChpdGVtOiBEYXRhUG9pbnRQb3NpdGlvbikgPT4ge1xuICAgICAgICBjb25zdCBldmVudDogQ2hhcnRNb3VzZU92ZXJFdmVudCA9IHRoaXMucGFyc2VNb3VzZUV2ZW50KGl0ZW0pIGFzIENoYXJ0TW91c2VPdmVyRXZlbnQ7XG4gICAgICAgIGV2ZW50LnRvb2x0aXAgPSB0aGlzLmdldEhUTUxUb29sdGlwKCk7XG4gICAgICAgIHRoaXMubW91c2VPdmVyLmVtaXQoZXZlbnQpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGlmICh0aGlzLm1vdXNlT3Zlck9uZVRpbWUub2JzZXJ2ZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgIGdvb2dsZS52aXN1YWxpemF0aW9uLmV2ZW50cy5hZGRPbmVUaW1lTGlzdGVuZXIoY2hhcnQsICdvbm1vdXNlb3ZlcicsIChpdGVtOiBEYXRhUG9pbnRQb3NpdGlvbikgPT4ge1xuICAgICAgICBjb25zdCBldmVudDogQ2hhcnRNb3VzZU92ZXJFdmVudCA9IHRoaXMucGFyc2VNb3VzZUV2ZW50KGl0ZW0pIGFzIENoYXJ0TW91c2VPdmVyRXZlbnQ7XG4gICAgICAgIGV2ZW50LnRvb2x0aXAgPSB0aGlzLmdldEhUTUxUb29sdGlwKCk7XG4gICAgICAgIHRoaXMubW91c2VPdmVyT25lVGltZS5lbWl0KGV2ZW50KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm1vdXNlT3V0Lm9ic2VydmVycy5sZW5ndGggPiAwKSB7XG4gICAgICBnb29nbGUudmlzdWFsaXphdGlvbi5ldmVudHMuYWRkTGlzdGVuZXIoY2hhcnQsICdvbm1vdXNlb3V0JywgKGl0ZW06IERhdGFQb2ludFBvc2l0aW9uKSA9PiB7XG4gICAgICAgIGNvbnN0IGV2ZW50OiBDaGFydE1vdXNlT3V0RXZlbnQgPSB0aGlzLnBhcnNlTW91c2VFdmVudChpdGVtKSBhcyBDaGFydE1vdXNlT3V0RXZlbnQ7XG4gICAgICAgIHRoaXMubW91c2VPdXQuZW1pdChldmVudCk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5tb3VzZU91dE9uZVRpbWUub2JzZXJ2ZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgIGdvb2dsZS52aXN1YWxpemF0aW9uLmV2ZW50cy5hZGRPbmVUaW1lTGlzdGVuZXIoY2hhcnQsICdvbm1vdXNlb3V0JywgKGl0ZW06IERhdGFQb2ludFBvc2l0aW9uKSA9PiB7XG4gICAgICAgIGNvbnN0IGV2ZW50OiBDaGFydE1vdXNlT3V0RXZlbnQgPSB0aGlzLnBhcnNlTW91c2VFdmVudChpdGVtKSBhcyBDaGFydE1vdXNlT3V0RXZlbnQ7XG4gICAgICAgIHRoaXMubW91c2VPdXRPbmVUaW1lLmVtaXQoZXZlbnQpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuZGF0YS5jaGFydFR5cGUgPT09ICdHZW9DaGFydCcpIHtcbiAgICAgIGlmICh0aGlzLnJlZ2lvbkNsaWNrLm9ic2VydmVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGdvb2dsZS52aXN1YWxpemF0aW9uLmV2ZW50cy5hZGRMaXN0ZW5lcihjaGFydCwgJ3JlZ2lvbkNsaWNrJywgKGl0ZW06IFJlZ2lvbkNsaWNrRXZlbnQpID0+IHtcbiAgICAgICAgICB0aGlzLnJlZ2lvbkNsaWNrLmVtaXQoaXRlbSk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgaWYgKHRoaXMucmVnaW9uQ2xpY2tPbmVUaW1lLm9ic2VydmVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGdvb2dsZS52aXN1YWxpemF0aW9uLmV2ZW50cy5hZGRPbmVUaW1lTGlzdGVuZXIoY2hhcnQsICdyZWdpb25DbGljaycsIChpdGVtOiBSZWdpb25DbGlja0V2ZW50KSA9PiB7XG4gICAgICAgICAgdGhpcy5yZWdpb25DbGljay5lbWl0KGl0ZW0pO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlZ2lzdGVyQ2hhcnRXcmFwcGVyRXZlbnRzKCk6IHZvaWQge1xuICAgIGdvb2dsZS52aXN1YWxpemF0aW9uLmV2ZW50cy5hZGRMaXN0ZW5lcih0aGlzLndyYXBwZXIsICdyZWFkeScsICgpID0+IHtcbiAgICAgIHRoaXMuY2hhcnRSZWFkeS5lbWl0KHttZXNzYWdlOiAnQ2hhcnQgcmVhZHknfSk7XG4gICAgfSk7XG5cbiAgICBnb29nbGUudmlzdWFsaXphdGlvbi5ldmVudHMuYWRkT25lVGltZUxpc3RlbmVyKHRoaXMud3JhcHBlciwgJ3JlYWR5JywgKCkgPT4ge1xuICAgICAgdGhpcy5jaGFydFJlYWR5T25lVGltZS5lbWl0KHttZXNzYWdlOiAnQ2hhcnQgcmVhZHkgKG9uZSB0aW1lKSd9KTtcbiAgICAgIHRoaXMucmVnaXN0ZXJDaGFydEV2ZW50cygpO1xuICAgIH0pO1xuXG4gICAgZ29vZ2xlLnZpc3VhbGl6YXRpb24uZXZlbnRzLmFkZExpc3RlbmVyKHRoaXMud3JhcHBlciwgJ2Vycm9yJywgKGVycm9yOiBhbnkpID0+IHtcbiAgICAgIHRoaXMuY2hhcnRFcnJvci5lbWl0KGVycm9yIGFzIENoYXJ0RXJyb3JFdmVudCk7XG4gICAgfSk7XG5cbiAgICBnb29nbGUudmlzdWFsaXphdGlvbi5ldmVudHMuYWRkT25lVGltZUxpc3RlbmVyKHRoaXMud3JhcHBlciwgJ2Vycm9yJywgKGVycm9yOiBhbnkpID0+IHtcbiAgICAgIHRoaXMuY2hhcnRFcnJvck9uZVRpbWUuZW1pdChlcnJvciBhcyBDaGFydEVycm9yRXZlbnQpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5hZGRMaXN0ZW5lcih0aGlzLndyYXBwZXIsICdzZWxlY3QnLCB0aGlzLnNlbGVjdExpc3RlbmVyLCB0aGlzLmNoYXJ0U2VsZWN0KTtcbiAgICB0aGlzLmFkZE9uZVRpbWVMaXN0ZW5lcih0aGlzLndyYXBwZXIsICdzZWxlY3QnLCB0aGlzLnNlbGVjdExpc3RlbmVyLCB0aGlzLmNoYXJ0U2VsZWN0T25lVGltZSk7XG4gIH1cblxuICBwcml2YXRlIGFkZExpc3RlbmVyKHNvdXJjZTogYW55LCBldmVudFR5cGU6IHN0cmluZywgbGlzdGVuZXJGbjogYW55LCBldkVtaXR0ZXI6IEV2ZW50RW1pdHRlcjxhbnk+KSB7XG4gICAgZ29vZ2xlLnZpc3VhbGl6YXRpb24uZXZlbnRzLmFkZExpc3RlbmVyKHNvdXJjZSwgZXZlbnRUeXBlLCAoKSA9PiB7XG4gICAgICBldkVtaXR0ZXIuZW1pdChsaXN0ZW5lckZuKCkpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRPbmVUaW1lTGlzdGVuZXIoc291cmNlOiBhbnksIGV2ZW50VHlwZTogc3RyaW5nLCBsaXN0ZW5lckZuOiBhbnksIGV2RW1pdHRlcjogRXZlbnRFbWl0dGVyPGFueT4pIHtcbiAgICBnb29nbGUudmlzdWFsaXphdGlvbi5ldmVudHMuYWRkT25lVGltZUxpc3RlbmVyKHNvdXJjZSwgZXZlbnRUeXBlLCAoKSA9PiB7XG4gICAgICBldkVtaXR0ZXIuZW1pdChsaXN0ZW5lckZuKCkpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzZWxlY3RMaXN0ZW5lciA9ICgpID0+IHtcbiAgICBjb25zdCBldmVudDogQ2hhcnRTZWxlY3RFdmVudCA9IHtcbiAgICAgIG1lc3NhZ2U6ICdzZWxlY3QnLFxuICAgICAgcm93OiBudWxsLFxuICAgICAgY29sdW1uOiBudWxsLFxuICAgICAgc2VsZWN0ZWRSb3dWYWx1ZXM6IFtdLFxuICAgICAgc2VsZWN0ZWRSb3dGb3JtYXR0ZWRWYWx1ZXM6IFtdLFxuICAgICAgY29sdW1uTGFiZWw6ICcnXG4gICAgfTtcbiAgICBjb25zdCBzID0gdGhpcy53cmFwcGVyLnZpc3VhbGl6YXRpb24uZ2V0U2VsZWN0aW9uKCk7XG4gICAgY29uc3QgZ3MgPSBzW3MubGVuZ3RoIC0gMV07XG4gICAgaWYgKCFncykge1xuICAgICAgZXZlbnQubWVzc2FnZSA9ICdkZXNlbGVjdCc7XG4gICAgICByZXR1cm4gZXZlbnQ7XG4gICAgfVxuICAgIGNvbnN0IHNlbGVjdGlvbjogRGF0YVBvaW50UG9zaXRpb24gPSBncztcbiAgICBpZiAoZ3Mucm93ICE9IG51bGwpIHtcbiAgICAgIGV2ZW50LnJvdyA9IHNlbGVjdGlvbi5yb3c7XG5cbiAgICAgIGNvbnN0IHNlbGVjdGVkUm93VmFsdWVzID0gW107XG4gICAgICBjb25zdCBzZWxlY3RlZFJvd0Zvcm1hdHRlZFZhbHVlcyA9IFtdO1xuICAgICAgY29uc3QgZGF0YVRhYmxlID0gdGhpcy53cmFwcGVyLmdldERhdGFUYWJsZSgpO1xuICAgICAgY29uc3QgbnVtYmVyT2ZDb2x1bW5zID0gZGF0YVRhYmxlLmdldE51bWJlck9mQ29sdW1ucygpO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1iZXJPZkNvbHVtbnM7IGkrKykge1xuICAgICAgICBzZWxlY3RlZFJvd1ZhbHVlcy5wdXNoKGRhdGFUYWJsZS5nZXRWYWx1ZShzZWxlY3Rpb24ucm93LCBpKSk7XG4gICAgICAgIHNlbGVjdGVkUm93Rm9ybWF0dGVkVmFsdWVzLnB1c2goZGF0YVRhYmxlLmdldEZvcm1hdHRlZFZhbHVlKHNlbGVjdGlvbi5yb3csIGkpKTtcbiAgICAgIH1cbiAgICAgIGV2ZW50LnNlbGVjdGVkUm93VmFsdWVzID0gc2VsZWN0ZWRSb3dWYWx1ZXM7XG4gICAgICBldmVudC5zZWxlY3RlZFJvd0Zvcm1hdHRlZFZhbHVlcyA9IHNlbGVjdGVkUm93Rm9ybWF0dGVkVmFsdWVzO1xuICAgIH1cbiAgICBpZiAoc2VsZWN0aW9uLmNvbHVtbiAhPSBudWxsKSB7XG4gICAgICBldmVudC5jb2x1bW4gPSBzZWxlY3Rpb24uY29sdW1uO1xuICAgICAgZXZlbnQuY29sdW1uTGFiZWwgPSB0aGlzLmdldENvbHVtbkxhYmVsQXRQb3NpdGlvb