ng2-google-charts
Version:
Google Charts module for Angular 2 and beyond
367 lines • 50.4 kB
JavaScript
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