UNPKG

@rinminase/ng-charts

Version:

Reactive, responsive, beautiful charts for Angular based on ng2-charts

453 lines 59.1 kB
import { Directive, EventEmitter, Input, Output, } from "@angular/core"; import * as chartJs from "chart.js"; import { getColors } from "./get-colors"; import { cloneDeep } from "lodash-es"; import * as i0 from "@angular/core"; import * as i1 from "./theme.service"; var UpdateType; (function (UpdateType) { UpdateType[UpdateType["Default"] = 0] = "Default"; UpdateType[UpdateType["Update"] = 1] = "Update"; UpdateType[UpdateType["Refresh"] = 2] = "Refresh"; })(UpdateType || (UpdateType = {})); export class BaseChartDirective { constructor(element, themeService) { this.element = element; this.themeService = themeService; this.options = {}; this.chartClick = new EventEmitter(); this.chartHover = new EventEmitter(); this.old = { dataExists: false, dataLength: 0, datasetsExists: false, datasetsLength: 0, datasetsDataObjects: [], datasetsDataLengths: [], colorsExists: false, colors: [], labelsExist: false, labels: [], legendExists: false, legend: {}, }; this.subs = []; } /** * Register a plugin. */ static registerPlugin(plugin) { chartJs.Chart.plugins.register(plugin); } static unregisterPlugin(plugin) { chartJs.Chart.plugins.unregister(plugin); } ngOnInit() { this.ctx = this.element.nativeElement.getContext("2d"); this.refresh(); this.subs.push(this.themeService.colorschemesOptions.subscribe(() => this.themeChanged())); } themeChanged() { this.refresh(); } ngDoCheck() { if (!this.chart) { return; } let updateRequired = UpdateType.Default; const wantUpdate = (x) => { updateRequired = x > updateRequired ? x : updateRequired; }; if (!!this.data !== this.old.dataExists) { this.propagateDataToDatasets(this.data); this.old.dataExists = !!this.data; wantUpdate(UpdateType.Update); } if (this.data && this.data.length !== this.old.dataLength) { this.old.dataLength = (this.data && this.data.length) || 0; wantUpdate(UpdateType.Update); } if (!!this.datasets !== this.old.datasetsExists) { this.old.datasetsExists = !!this.datasets; wantUpdate(UpdateType.Update); } if (this.datasets && this.datasets.length !== this.old.datasetsLength) { this.old.datasetsLength = (this.datasets && this.datasets.length) || 0; wantUpdate(UpdateType.Update); } if (this.datasets && this.datasets.filter((x, i) => x.data !== this.old.datasetsDataObjects[i]) .length) { this.old.datasetsDataObjects = this.datasets.map((x) => x.data); wantUpdate(UpdateType.Update); } if (this.datasets && this.datasets.filter((x, i) => x.data.length !== this.old.datasetsDataLengths[i]).length) { this.old.datasetsDataLengths = this.datasets.map((x) => x.data.length); wantUpdate(UpdateType.Update); } if (!!this.colors !== this.old.colorsExists) { this.old.colorsExists = !!this.colors; this.updateColors(); wantUpdate(UpdateType.Update); } // This smells of inefficiency, might need to revisit this if (this.colors && this.colors.filter((x, i) => !this.colorsEqual(x, this.old.colors[i])) .length) { this.old.colors = this.colors.map((x) => this.copyColor(x)); this.updateColors(); wantUpdate(UpdateType.Update); } if (!!this.labels !== this.old.labelsExist) { this.old.labelsExist = !!this.labels; wantUpdate(UpdateType.Update); } if (this.labels && this.labels.filter((x, i) => !this.labelsEqual(x, this.old.labels[i])) .length) { this.old.labels = this.labels.map((x) => this.copyLabel(x)); wantUpdate(UpdateType.Update); } if (!!this.options.legend !== this.old.legendExists) { this.old.legendExists = !!this.options.legend; wantUpdate(UpdateType.Refresh); } if (this.options.legend && this.options.legend.position !== this.old.legend.position) { this.old.legend.position = this.options.legend.position; wantUpdate(UpdateType.Refresh); } switch (updateRequired) { case UpdateType.Default: break; case UpdateType.Update: this.update(); break; case UpdateType.Refresh: this.refresh(); break; } } copyLabel(a) { if (Array.isArray(a)) { return [...a]; } return a; } labelsEqual(a, b) { return (true && Array.isArray(a) === Array.isArray(b) && (Array.isArray(a) || a === b) && (!Array.isArray(a) || a.length === b.length) && (!Array.isArray(a) || a.filter((x, i) => x !== b[i]).length === 0)); } copyColor(a) { const rc = { backgroundColor: a.backgroundColor, borderWidth: a.borderWidth, borderColor: a.borderColor, borderCapStyle: a.borderCapStyle, borderDash: a.borderDash, borderDashOffset: a.borderDashOffset, borderJoinStyle: a.borderJoinStyle, pointBorderColor: a.pointBorderColor, pointBackgroundColor: a.pointBackgroundColor, pointBorderWidth: a.pointBorderWidth, pointRadius: a.pointRadius, pointHoverRadius: a.pointHoverRadius, pointHitRadius: a.pointHitRadius, pointHoverBackgroundColor: a.pointHoverBackgroundColor, pointHoverBorderColor: a.pointHoverBorderColor, pointHoverBorderWidth: a.pointHoverBorderWidth, pointStyle: a.pointStyle, hoverBackgroundColor: a.hoverBackgroundColor, hoverBorderColor: a.hoverBorderColor, hoverBorderWidth: a.hoverBorderWidth, }; return rc; } colorsEqual(a, b) { if (!a !== !b) { return false; } return (!a || (true && a.backgroundColor === b.backgroundColor && a.borderWidth === b.borderWidth && a.borderColor === b.borderColor && a.borderCapStyle === b.borderCapStyle && a.borderDash === b.borderDash && a.borderDashOffset === b.borderDashOffset && a.borderJoinStyle === b.borderJoinStyle && a.pointBorderColor === b.pointBorderColor && a.pointBackgroundColor === b.pointBackgroundColor && a.pointBorderWidth === b.pointBorderWidth && a.pointRadius === b.pointRadius && a.pointHoverRadius === b.pointHoverRadius && a.pointHitRadius === b.pointHitRadius && a.pointHoverBackgroundColor === b.pointHoverBackgroundColor && a.pointHoverBorderColor === b.pointHoverBorderColor && a.pointHoverBorderWidth === b.pointHoverBorderWidth && a.pointStyle === b.pointStyle && a.hoverBackgroundColor === b.hoverBackgroundColor && a.hoverBorderColor === b.hoverBorderColor && a.hoverBorderWidth === b.hoverBorderWidth)); } updateColors() { this.datasets.forEach((elm, index) => { if (this.colors && this.colors[index]) { Object.assign(elm, this.colors[index]); } else { Object.assign(elm, getColors(this.chartType, index, elm.data.length), { ...elm, }); } }); } ngOnChanges(changes) { let updateRequired = UpdateType.Default; const wantUpdate = (x) => { updateRequired = x > updateRequired ? x : updateRequired; }; // Check if the changes are in the data or datasets or labels or legend if (changes.hasOwnProperty("data") && changes.data.currentValue) { this.propagateDataToDatasets(changes.data.currentValue); wantUpdate(UpdateType.Update); } if (changes.hasOwnProperty("datasets") && changes.datasets.currentValue) { this.propagateDatasetsToData(changes.datasets.currentValue); wantUpdate(UpdateType.Update); } if (changes.hasOwnProperty("labels")) { if (this.chart) { this.chart.data.labels = changes.labels.currentValue; } wantUpdate(UpdateType.Update); } if (changes.hasOwnProperty("legend")) { if (this.chart) { this.chart.config.options.legend.display = changes.legend.currentValue; this.chart.generateLegend(); } wantUpdate(UpdateType.Update); } if (changes.hasOwnProperty("options")) { wantUpdate(UpdateType.Refresh); } switch (updateRequired) { case UpdateType.Update: this.update(); break; case UpdateType.Refresh: case UpdateType.Default: this.refresh(); break; } } ngOnDestroy() { if (this.chart) { this.chart.destroy(); this.chart = void 0; } this.subs.forEach((x) => x.unsubscribe()); } update(duration) { if (this.chart) { return this.chart.update(duration); } return null; } hideDataset(index, hidden) { this.chart.getDatasetMeta(index).hidden = hidden; this.chart.update(); } isDatasetHidden(index) { return this.chart.getDatasetMeta(index).hidden; } toBase64Image() { return this.chart.toBase64Image(); } getChartConfiguration() { const datasets = this.getDatasets(); const options = Object.assign({}, this.options); if (this.legend === false) { options.legend = { display: false }; } // hook for onHover and onClick events options.hover = options.hover || {}; if (!options.hover.onHover) { options.hover.onHover = (event, active) => { if (active && !active.length) { return; } this.chartHover.emit({ event, active }); }; } if (!options.onClick) { options.onClick = (event, active) => { this.chartClick.emit({ event, active }); }; } const mergedOptions = this.smartMerge(options, this.themeService.getColorschemesOptions()); const chartConfig = { type: this.chartType, data: { labels: this.labels || [], datasets, }, plugins: this.plugins, options: mergedOptions, }; return chartConfig; } getChartBuilder(ctx /*, data:any[], options:any*/) { const chartConfig = this.getChartConfiguration(); return new chartJs.Chart(ctx, chartConfig); } smartMerge(options, overrides, level = 0) { if (level === 0) { options = cloneDeep(options); } const keysToUpdate = Object.keys(overrides); keysToUpdate.forEach((key) => { if (Array.isArray(overrides[key])) { const arrayElements = options[key]; if (arrayElements) { arrayElements.forEach((r) => { this.smartMerge(r, overrides[key][0], level + 1); }); } } else if (typeof overrides[key] === "object") { if (!(key in options)) { options[key] = {}; } this.smartMerge(options[key], overrides[key], level + 1); } else { options[key] = overrides[key]; } }); if (level === 0) { return options; } } isMultiLineLabel(label) { return Array.isArray(label); } joinLabel(label) { if (!label) { return null; } if (this.isMultiLineLabel(label)) { return label.join(" "); } else { return label; } } propagateDatasetsToData(datasets) { this.data = this.datasets.map((r) => r.data); if (this.chart) { this.chart.data.datasets = datasets; } this.updateColors(); } propagateDataToDatasets(newDataValues) { if (this.isMultiDataSet(newDataValues)) { if (this.datasets && newDataValues.length === this.datasets.length) { this.datasets.forEach((dataset, i) => { dataset.data = newDataValues[i]; }); } else { this.datasets = newDataValues.map((data, index) => { return { data, label: this.joinLabel(this.labels[index]) || `Label ${index}`, }; }); if (this.chart) { this.chart.data.datasets = this.datasets; } } } else { if (!this.datasets) { this.datasets = [{ data: newDataValues }]; if (this.chart) { this.chart.data.datasets = this.datasets; } } else { this.datasets[0].data = newDataValues; this.datasets.splice(1); // Remove all elements but the first } } this.updateColors(); } isMultiDataSet(data) { return Array.isArray(data[0]); } getDatasets() { if (!this.datasets && !this.data) { throw new Error(`ng-charts configuration error, data or datasets field are required to render chart ${this.chartType}`); } // If `datasets` is defined, use it over the `data` property. if (this.datasets) { this.propagateDatasetsToData(this.datasets); return this.datasets; } if (this.data) { this.propagateDataToDatasets(this.data); return this.datasets; } return null; } refresh() { // if (this.options && this.options.responsive) { // setTimeout(() => this.refresh(), 50); // } // todo: remove this line, it is producing flickering if (this.chart) { this.chart.destroy(); this.chart = void 0; } if (this.ctx) { this.chart = this.getChartBuilder(this.ctx /*, data, this.options*/); } } } BaseChartDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: BaseChartDirective, deps: [{ token: i0.ElementRef }, { token: i1.ThemeService }], target: i0.ɵɵFactoryTarget.Directive }); BaseChartDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.1.0", type: BaseChartDirective, selector: "canvas[baseChart]", inputs: { data: "data", datasets: "datasets", labels: "labels", options: "options", chartType: "chartType", colors: "colors", legend: "legend", plugins: "plugins" }, outputs: { chartClick: "chartClick", chartHover: "chartHover" }, exportAs: ["base-chart"], usesOnChanges: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.1.0", ngImport: i0, type: BaseChartDirective, decorators: [{ type: Directive, args: [{ // tslint:disable-next-line:directive-selector selector: "canvas[baseChart]", exportAs: "base-chart", }] }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i1.ThemeService }]; }, propDecorators: { data: [{ type: Input }], datasets: [{ type: Input }], labels: [{ type: Input }], options: [{ type: Input }], chartType: [{ type: Input }], colors: [{ type: Input }], legend: [{ type: Input }], plugins: [{ type: Input }], chartClick: [{ type: Output }], chartHover: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1jaGFydC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL2Jhc2UtY2hhcnQuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBR1QsWUFBWSxFQUNaLEtBQUssRUFJTCxNQUFNLEdBRVAsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxLQUFLLE9BQU8sTUFBTSxVQUFVLENBQUM7QUFDcEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUl6QyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFDOzs7QUFtQ3RDLElBQUssVUFJSjtBQUpELFdBQUssVUFBVTtJQUNiLGlEQUFPLENBQUE7SUFDUCwrQ0FBTSxDQUFBO0lBQ04saURBQU8sQ0FBQTtBQUNULENBQUMsRUFKSSxVQUFVLEtBQVYsVUFBVSxRQUlkO0FBT0QsTUFBTSxPQUFPLGtCQUFrQjtJQXVEN0IsWUFDVSxPQUFtQixFQUNuQixZQUEwQjtRQUQxQixZQUFPLEdBQVAsT0FBTyxDQUFZO1FBQ25CLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBcERwQixZQUFPLEdBQWlCLEVBQUUsQ0FBQztRQU0xQixlQUFVLEdBR3RCLElBQUksWUFBWSxFQUFFLENBQUM7UUFDUCxlQUFVLEdBR3RCLElBQUksWUFBWSxFQUFFLENBQUM7UUFLaEIsUUFBRyxHQUFhO1lBQ3RCLFVBQVUsRUFBRSxLQUFLO1lBQ2pCLFVBQVUsRUFBRSxDQUFDO1lBQ2IsY0FBYyxFQUFFLEtBQUs7WUFDckIsY0FBYyxFQUFFLENBQUM7WUFDakIsbUJBQW1CLEVBQUUsRUFBRTtZQUN2QixtQkFBbUIsRUFBRSxFQUFFO1lBQ3ZCLFlBQVksRUFBRSxLQUFLO1lBQ25CLE1BQU0sRUFBRSxFQUFFO1lBQ1YsV0FBVyxFQUFFLEtBQUs7WUFDbEIsTUFBTSxFQUFFLEVBQUU7WUFDVixZQUFZLEVBQUUsS0FBSztZ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WCxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDbkUsTUFBTSxFQUNUO1lBQ0EsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUU1RCxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFFcEIsVUFBVSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUMvQjtRQUVELElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUU7WUFDMUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7WUFFckMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUMvQjtRQUVELElBQ0UsSUFBSSxDQUFDLE1BQU07WUFDWCxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDbkUsTUFBTSxFQUNUO1lBQ0EsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUU1RCxVQUFVLENB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RTtZQUNkLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUMsQ0FBQztTQUNyQjtRQUNELElBQUksSUFBSSxDQUFDLEdBQUcsRUFBRTtZQUNaLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLHdCQUF3QixDQUFDLENBQUM7U0FDdEU7SUFDSCxDQUFDOzsrR0E1Z0JVLGtCQUFrQjttR0FBbEIsa0JBQWtCOzJGQUFsQixrQkFBa0I7a0JBTDlCLFNBQVM7bUJBQUM7b0JBQ1QsOENBQThDO29CQUM5QyxRQUFRLEVBQUUsbUJBQW1CO29CQUM3QixRQUFRLEVBQUUsWUFBWTtpQkFDdkI7NEhBR2lCLElBQUk7c0JBQW5CLEtBQUs7Z0JBQ1UsUUFBUTtzQkFBdkIsS0FBSztnQkFDVSxNQUFNO3NCQUFyQixLQUFLO2dCQUNVLE9BQU87c0JBQXRCLEtBQUs7Z0JBQ1UsU0FBUztzQkFBeEIsS0FBSztnQkFDVSxNQUFNO3NCQUFyQixLQUFLO2dCQUNVLE1BQU07c0JBQXJCLEtBQUs7Z0JBQ1UsT0FBTztzQkFBdEIsS0FBSztnQkFFVyxVQUFVO3NCQUExQixNQUFNO2dCQUlVLFVBQVU7c0JBQTFCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBEaXJlY3RpdmUsXG4gIERvQ2hlY2ssXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCAqIGFzIGNoYXJ0SnMgZnJvbSBcImNoYXJ0LmpzXCI7XG5pbXBvcnQgeyBnZXRDb2xvcnMgfSBmcm9tIFwiLi9nZXQtY29sb3JzXCI7XG5pbXBvcnQgeyBEYXRhc2V0Q29sb3IgfSBmcm9tIFwiLi9jb2xvclwiO1xuaW1wb3J0IHsgVGhlbWVTZXJ2aWNlIH0gZnJvbSBcIi4vdGhlbWUuc2VydmljZVwiO1xuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSBcInJ4anNcIjtcbmltcG9ydCB7IGNsb25lRGVlcCB9IGZyb20gXCJsb2Rhc2gtZXNcIjtcblxuZXhwb3J0IHR5cGUgU2luZ2xlRGF0YVNldCA9IG51bWJlcltdIHwgY2hhcnRKcy5DaGFydFBvaW50W107XG5leHBvcnQgdHlwZSBNdWx0aURhdGFTZXQgPSAobnVtYmVyW10gfCBjaGFydEpzLkNoYXJ0UG9pbnRbXSlbXTtcbmV4cG9ydCB0eXBlIFNpbmdsZU9yTXVsdGlEYXRhU2V0ID0gU2luZ2xlRGF0YVNldCB8IE11bHRpRGF0YVNldDtcblxuZXhwb3J0IHR5cGUgUGx1Z2luU2VydmljZUdsb2JhbFJlZ2lzdHJhdGlvbkFuZE9wdGlvbnMgPSBjaGFydEpzLlBsdWdpblNlcnZpY2VHbG9iYWxSZWdpc3RyYXRpb24gJlxuICBjaGFydEpzLlBsdWdpblNlcnZpY2VSZWdpc3RyYXRpb25PcHRpb25zO1xuZXhwb3J0IHR5cGUgU2luZ2xlTGluZUxhYmVsID0gc3RyaW5nO1xuZXhwb3J0IHR5cGUgTXVsdGlMaW5lTGFiZWwgPSBzdHJpbmdbXTtcblxuZXhwb3J0IHR5cGUgQ2hhcnRMYWJlbCA9IFNpbmdsZUxpbmVMYWJlbCB8IE11bHRpTGluZUxhYmVsO1xuZXhwb3J0IHR5cGUgQ2hhcnRDb2xvciA9IERhdGFzZXRDb2xvcltdO1xuZXhwb3J0IHR5cGUgQ2hhcnRUeXBlID0gY2hhcnRKcy5DaGFydFR5cGU7XG5leHBvcnQgdHlwZSBDaGFydERhdGFzZXQgPSBjaGFydEpzLkNoYXJ0RGF0YVNldHM7XG5leHBvcnQgdHlwZSBDaGFydERhdGFzZXRzID0gY2hhcnRKcy5DaGFydERhdGFTZXRzW107XG5leHBvcnQgdHlwZSBDaGFydE9wdGlvbnMgPSBjaGFydEpzLkNoYXJ0T3B0aW9ucztcblxuaW50ZXJmYWNlIE9sZFN0YXRlIHtcbiAgZGF0YUV4aXN0czogYm9vbGVhbjtcbiAgZGF0YUxlbmd0aDogbnVtYmVyO1xuICBkYXRhc2V0c0V4aXN0czogYm9vbGVhbjtcbiAgZGF0YXNldHNMZW5ndGg6IG51bWJlcjtcbiAgZGF0YXNldHNEYXRhT2JqZWN0czogYW55W107XG4gIGRhdGFzZXRzRGF0YUxlbmd0aHM6IG51bWJlcltdO1xuICBjb2xvcnNFeGlzdHM6IGJvb2xlYW47XG4gIGNvbG9yczogRGF0YXNldENvbG9yW107XG4gIGxhYmVsc0V4aXN0OiBib29sZWFuO1xuICBsYWJlbHM6IENoYXJ0TGFiZWxbXTtcbiAgbGVnZW5kRXhpc3RzOiBib29sZWFuO1xuICBsZWdlbmQ6IHtcbiAgICBwb3NpdGlvbj86IHN0cmluZztcbiAgfTtcbn1cblxuZW51bSBVcGRhdGVUeXBlIHtcbiAgRGVmYXVsdCxcbiAgVXBkYXRlLFxuICBSZWZyZXNoLFxufVxuXG5ARGlyZWN0aXZlKHtcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRpcmVjdGl2ZS1zZWxlY3RvclxuICBzZWxlY3RvcjogXCJjYW52YXNbYmFzZUNoYXJ0XVwiLFxuICBleHBvcnRBczogXCJiYXNlLWNoYXJ0XCIsXG59KVxuZXhwb3J0IGNsYXNzIEJhc2VDaGFydERpcmVjdGl2ZVxuICBpbXBsZW1lbnRzIE9uRGVzdHJveSwgT25DaGFuZ2VzLCBPbkluaXQsIE9uRGVzdHJveSwgRG9DaGVjayB7XG4gIEBJbnB1dCgpIHB1YmxpYyBkYXRhOiBTaW5nbGVPck11bHRpRGF0YVNldDtcbiAgQElucHV0KCkgcHVibGljIGRhdGFzZXRzOiBDaGFydERhdGFzZXRzO1xuICBASW5wdXQoKSBwdWJsaWMgbGFiZWxzOiBDaGFydExhYmVsW107XG4gIEBJbnB1dCgpIHB1YmxpYyBvcHRpb25zOiBDaGFydE9wdGlvbnMgPSB7fTtcbiAgQElucHV0KCkgcHVibGljIGNoYXJ0VHlwZTogQ2hhcnRUeXBlO1xuICBASW5wdXQoKSBwdWJsaWMgY29sb3JzOiBEYXRhc2V0Q29sb3JbXTtcbiAgQElucHV0KCkgcHVibGljIGxlZ2VuZDogYm9vbGVhbjtcbiAgQElucHV0KCkgcHVibGljIHBsdWdpbnM6IFBsdWdpblNlcnZpY2VHbG9iYWxSZWdpc3RyYXRpb25BbmRPcHRpb25zW107XG5cbiAgQE91dHB1dCgpIHB1YmxpYyBjaGFydENsaWNrOiBFdmVudEVtaXR0ZXI8e1xuICAgIGV2ZW50PzogTW91c2VFdmVudDtcbiAgICBhY3RpdmU/OiB7fVtdO1xuICB9PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIHB1YmxpYyBjaGFydEhvdmVyOiBFdmVudEVtaXR0ZXI8e1xuICAgIGV2ZW50OiBNb3VzZUV2ZW50O1xuICAgIGFjdGl2ZToge31bXTtcbiAgfT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgcHVibGljIGN0eDogc3RyaW5nO1xuICBwdWJsaWMgY2hhcnQ6IENoYXJ0O1xuXG4gIHByaXZhdGUgb2xkOiBPbGRTdGF0ZSA9IHtcbiAgICBkYXRhRXhpc3RzOiBmYWxzZSxcbiAgICBkYXRhTGVuZ3RoOiAwLFxuICAgIGRhdGFzZXRzRXhpc3RzOiBmYWxzZSxcbiAgICBkYXRhc2V0c0xlbmd0aDogMCxcbiAgICBkYXRhc2V0c0RhdGFPYmplY3RzOiBbXSxcbiAgICBkYXRhc2V0c0RhdGFMZW5ndGhzOiBbXSxcbiAgICBjb2xvcnNFeGlzdHM6IGZhbHNlLFxuICAgIGNvbG9yczogW10sXG4gICAgbGFiZWxzRXhpc3Q6IGZhbHNlLFxuICAgIGxhYmVsczogW10sXG4gICAgbGVnZW5kRXhpc3RzOiBmYWxzZSxcbiAgICBsZWdlbmQ6IHt9LFxuICB9O1xuXG4gIHByaXZhdGUgc3ViczogU3Vic2NyaXB0aW9uW10gPSBbXTtcblxuICAvKipcbiAgICogUmVnaXN0ZXIgYSBwbHVnaW4uXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIHJlZ2lzdGVyUGx1Z2luKFxuICAgIHBsdWdpbjogUGx1Z2luU2VydmljZUdsb2JhbFJlZ2lzdHJhdGlvbkFuZE9wdGlvbnNcbiAgKSB7XG4gICAgY2hhcnRKcy5DaGFydC5wbHVnaW5zLnJlZ2lzdGVyKHBsdWdpbik7XG4gIH1cblxuICBwdWJsaWMgc3RhdGljIHVucmVnaXN0ZXJQbHVnaW4oXG4gICAgcGx1Z2luOiBQbHVnaW5TZXJ2aWNlR2xvYmFsUmVnaXN0cmF0aW9uQW5kT3B0aW9uc1xuICApIHtcbiAgICBjaGFydEpzLkNoYXJ0LnBsdWdpbnMudW5yZWdpc3RlcihwbHVnaW4pO1xuICB9XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgZWxlbWVudDogRWxlbWVudFJlZixcbiAgICBwcml2YXRlIHRoZW1lU2VydmljZTogVGhlbWVTZXJ2aWNlXG4gICkge31cblxuICBwdWJsaWMgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5jdHggPSB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5nZXRDb250ZXh0KFwiMmRcIik7XG4gICAgdGhpcy5yZWZyZXNoKCk7XG4gICAgdGhpcy5zdWJzLnB1c2goXG4gICAgICB0aGlzLnRoZW1lU2VydmljZS5jb2xvcnNjaGVtZXNPcHRpb25zLnN1YnNjcmliZSgoKSA9PiB0aGlzLnRoZW1lQ2hhbmdlZCgpKVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHRoZW1lQ2hhbmdlZCgpIHtcbiAgICB0aGlzLnJlZnJlc2goKTtcbiAgfVxuXG4gIG5nRG9DaGVjaygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY2hhcnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IHVwZGF0ZVJlcXVpcmVkID0gVXBkYXRlVHlwZS5EZWZhdWx0O1xuICAgIGNvbnN0IHdhbnRVcGRhdGUgPSAoeDogVXBkYXRlVHlwZSkgPT4ge1xuICAgICAgdXBkYXRlUmVxdWlyZWQgPSB4ID4gdXBkYXRlUmVxdWlyZWQgPyB4IDogdXBkYXRlUmVxdWlyZWQ7XG4gICAgfTtcblxuICAgIGlmICghIXRoaXMuZGF0YSAhPT0gdGhpcy5vbGQuZGF0YUV4aXN0cykge1xuICAgICAgdGhpcy5wcm9wYWdhdGVEYXRhVG9EYXRhc2V0cyh0aGlzLmRhdGEpO1xuXG4gICAgICB0aGlzLm9sZC5kYXRhRXhpc3RzID0gISF0aGlzLmRhdGE7XG5cbiAgICAgIHdhbnRVcGRhdGUoVXBkYXRlVHlwZS5VcGRhdGUpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmRhdGEgJiYgdGhpcy5kYXRhLmxlbmd0aCAhPT0gdGhpcy5vbGQuZGF0YUxlbmd0aCkge1xuICAgICAgdGhpcy5vbGQuZGF0YUxlbmd0aCA9ICh0aGlzLmRhdGEgJiYgdGhpcy5kYXRhLmxlbmd0aCkgfHwgMDtcblxuICAgICAgd2FudFVwZGF0ZShVcGRhdGVUeXBlLlVwZGF0ZSk7XG4gICAgfVxuXG4gICAgaWYgKCEhdGhpcy5kYXRhc2V0cyAhPT0gdGhpcy5vbGQuZGF0YXNldHNFeGlzdHMpIHtcbiAgICAgIHRoaXMub2xkLmRhdGFzZXRzRXhpc3RzID0gISF0aGlzLmRhdGFzZXRzO1xuXG4gICAgICB3YW50VXBkYXRlKFVwZGF0ZVR5cGUuVXBkYXRlKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5kYXRhc2V0cyAmJiB0aGlzLmRhdGFzZXRzLmxlbmd0aCAhPT0gdGhpcy5vbGQuZGF0YXNldHNMZW5ndGgpIHtcbiAgICAgIHRoaXMub2xkLmRhdGFzZXRzTGVuZ3RoID0gKHRoaXMuZGF0YXNldHMgJiYgdGhpcy5kYXRhc2V0cy5sZW5ndGgpIHx8IDA7XG5cbiAgICAgIHdhbnRVcGRhdGUoVXBkYXRlVHlwZS5VcGRhdGUpO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIHRoaXMuZGF0YXNldHMgJiZcbiAgICAgIHRoaXMuZGF0YXNldHMuZmlsdGVyKCh4LCBpKSA9PiB4LmRhdGEgIT09IHRoaXMub2xkLmRhdGFzZXRzRGF0YU9iamVjdHNbaV0pXG4gICAgICAgIC5sZW5ndGhcbiAgICApIHtcbiAgICAgIHRoaXMub2xkLmRhdGFzZXRzRGF0YU9iamVjdHMgPSB0aGlzLmRhdGFzZXRzLm1hcCgoeCkgPT4geC5kYXRhKTtcblxuICAgICAgd2FudFVwZGF0ZShVcGRhdGVUeXBlLlVwZGF0ZSk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdGhpcy5kYXRhc2V0cyAmJlxuICAgICAgdGhpcy5kYXRhc2V0cy5maWx0ZXIoXG4gICAgICAgICh4LCBpKSA9PiB4LmRhdGEubGVuZ3RoICE9PSB0aGlzLm9sZC5kYXRhc2V0c0RhdGFMZW5ndGhzW2ldXG4gICAgICApLmxlbmd0aFxuICAgICkge1xuICAgICAgdGhpcy5vbGQuZGF0YXNldHNEYXRhTGVuZ3RocyA9IHRoaXMuZGF0YXNldHMubWFwKCh4KSA9PiB4LmRhdGEubGVuZ3RoKTtcblxuICAgICAgd2FudFVwZGF0ZShVcGRhdGVUeXBlLlVwZGF0ZSk7XG4gICAgfVxuXG4gICAgaWYgKCEhdGhpcy5jb2xvcnMgIT09IHRoaXMub2xkLmNvbG9yc0V4aXN0cykge1xuICAgICAgdGhpcy5vbGQuY29sb3JzRXhpc3RzID0gISF0aGlzLmNvbG9ycztcblxuICAgICAgdGhpcy51cGRhdGVDb2xvcnMoKTtcblxuICAgICAgd2FudFVwZGF0ZShVcGRhdGVUeXBlLlVwZGF0ZSk7XG4gICAgfVxuXG4gICAgLy8gVGhpcyBzbWVsbHMgb2YgaW5lZmZpY2llbmN5LCBtaWdodCBuZWVkIHRvIHJldmlzaXQgdGhpc1xuICAgIGlmIChcbiAgICAgIHRoaXMuY29sb3JzICYmXG4gICAgICB0aGlzLmNvbG9ycy5maWx0ZXIoKHgsIGkpID0+ICF0aGlzLmNvbG9yc0VxdWFsKHgsIHRoaXMub2xkLmNvbG9yc1tpXSkpXG4gICAgICAgIC5sZW5ndGhcbiAgICApIHtcbiAgICAgIHRoaXMub2xkLmNvbG9ycyA9IHRoaXMuY29sb3JzLm1hcCgoeCkgPT4gdGhpcy5jb3B5Q29sb3IoeCkpO1xuXG4gICAgICB0aGlzLnVwZGF0ZUNvbG9ycygpO1xuXG4gICAgICB3YW50VXBkYXRlKFVwZGF0ZVR5cGUuVXBkYXRlKTtcbiAgICB9XG5cbiAgICBpZiAoISF0aGlzLmxhYmVscyAhPT0gdGhpcy5vbGQubGFiZWxzRXhpc3QpIHtcbiAgICAgIHRoaXMub2xkLmxhYmVsc0V4aXN0ID0gISF0aGlzLmxhYmVscztcblxuICAgICAgd2FudFVwZGF0ZShVcGRhdGVUeXBlLlVwZGF0ZSk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdGhpcy5sYWJlbHMgJiZcbiAgICAgIHRoaXMubGFiZWxzLmZpbHRlcigoeCwgaSkgPT4gIXRoaXMubGFiZWxzRXF1YWwoeCwgdGhpcy5vbGQubGFiZWxzW2ldKSlcbiAgICAgICAgLmxlbmd0aFxuICAgICkge1xuICAgICAgdGhpcy5vbGQubGFiZWxzID0gdGhpcy5sYWJlbHMubWFwKCh4KSA9PiB0aGlzLmNvcHlMYWJlbCh4KSk7XG5cbiAgICAgIHdhbnRVcGRhdGUoVXBkYXRlVHlwZS5VcGRhdGUpO1xuICAgIH1cblxuICAgIGlmICghIXRoaXMub3B0aW9ucy5sZWdlbmQgIT09IHRoaXMub2xkLmxlZ2VuZEV4aXN0cykge1xuICAgICAgdGhpcy5vbGQubGVnZW5kRXhpc3RzID0gISF0aGlzLm9wdGlvbnMubGVnZW5kO1xuXG4gICAgICB3YW50VXBkYXRlKFVwZGF0ZVR5cGUuUmVmcmVzaCk7XG4gICAgfVxuXG4gICAgaWYgKFxuICAgICAgdGhpcy5vcHRpb25zLmxlZ2VuZCAmJlxuICAgICAgdGhpcy5vcHRpb25zLmxlZ2VuZC5wb3NpdGlvbiAhPT0gdGhpcy5vbGQubGVnZW5kLnBvc2l0aW9uXG4gICAgKSB7XG4gICAgICB0aGlzLm9sZC5sZWdlbmQucG9zaXRpb24gPSB0aGlzLm9wdGlvbnMubGVnZW5kLnBvc2l0aW9uO1xuXG4gICAgICB3YW50VXBkYXRlKFVwZGF0ZVR5cGUuUmVmcmVzaCk7XG4gICAgfVxuXG4gICAgc3dpdGNoICh1cGRhdGVSZXF1aXJlZCBhcyBVcGRhdGVUeXBlKSB7XG4gICAgICBjYXNlIFVwZGF0ZVR5cGUuRGVmYXVsdDpcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFVwZGF0ZVR5cGUuVXBkYXRlOlxuICAgICAgICB0aGlzLnVwZGF0ZSgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgVXBkYXRlVHlwZS5SZWZyZXNoOlxuICAgICAgICB0aGlzLnJlZnJlc2goKTtcbiAgICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgY29weUxhYmVsKGE6IENoYXJ0TGFiZWwpOiBDaGFydExhYmVsIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShhKSkge1xuICAgICAgcmV0dXJuIFsuLi5hXTtcbiAgICB9XG4gICAgcmV0dXJuIGE7XG4gIH1cblxuICBsYWJlbHNFcXVhbChhOiBDaGFydExhYmVsLCBiOiBDaGFydExhYmVsKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRydWUgJiZcbiAgICAgIEFycmF5LmlzQXJyYXkoYSkgPT09IEFycmF5LmlzQXJyYXkoYikgJiZcbiAgICAgIChBcnJheS5pc0FycmF5KGEpIHx8IGEgPT09IGIpICYmXG4gICAgICAoIUFycmF5LmlzQXJyYXkoYSkgfHwgYS5sZW5ndGggPT09IGIubGVuZ3RoKSAmJlxuICAgICAgKCFBcnJheS5pc0FycmF5KGEpIHx8IGEuZmlsdGVyKCh4LCBpKSA9PiB4ICE9PSBiW2ldKS5sZW5ndGggPT09IDApXG4gICAgKTtcbiAgfVxuXG4gIGNvcHlDb2xvcihhOiBEYXRhc2V0Q29sb3IpOiBEYXRhc2V0Q29sb3Ige1xuICAgIGNvbnN0IHJjOiBEYXRhc2V0Q29sb3IgPSB7XG4gICAgICBiYWNrZ3JvdW5kQ29sb3I6IGEuYmFja2dyb3VuZENvbG9yLFxuICAgICAgYm9yZGVyV2lkdGg6IGEuYm9yZGVyV2lkdGgsXG4gICAgICBib3JkZXJDb2xvcjogYS5ib3JkZXJDb2xvcixcbiAgICAgIGJvcmRlckNhcFN0eWxlOiBhLmJvcmRlckNhcFN0eWxlLFxuICAgICAgYm9yZGVyRGFzaDogYS5ib3JkZXJEYXNoLFxuICAgICAgYm9yZGVyRGFzaE9mZnNldDogYS5ib3JkZXJEYXNoT2Zmc2V0LFxuICAgICAgYm9yZGVySm9pblN0eWxlOiBhLmJvcmRlckpvaW5TdHlsZSxcbiAgICAgIHBvaW50Qm9yZGVyQ29sb3I6IGEucG9pbnRCb3JkZXJDb2xvcixcbiAgICAgIHBvaW50QmFja2dyb3VuZENvbG9yOiBhLnBvaW50QmFja2dyb3VuZENvbG9yLFxuICAgICAgcG9pbnRCb3JkZXJXaWR0aDogYS5wb2ludEJvcmRlcldpZHRoLFxuICAgICAgcG9pbnRSYWRpdXM6IGEucG9pbnRSYWRpdXMsXG4gICAgICBwb2ludEhvdmVyUmFkaXVzOiBhLnBvaW50SG92ZXJSYWRpdXMsXG4gICAgICBwb2ludEhpdFJhZGl1czogYS5wb2ludEhpdFJhZGl1cyxcbiAgICAgIHBvaW50SG92ZXJCYWNrZ3JvdW5kQ29sb3I6IGEucG9pbnRIb3ZlckJhY2tncm91bmRDb2xvcixcbiAgICAgIHBvaW50SG92ZXJCb3JkZXJDb2xvcjogYS5wb2ludEhvdmVyQm9yZGVyQ29sb3IsXG4gICAgICBwb2ludEhvdmVyQm9yZGVyV2lkdGg6IGEucG9pbnRIb3ZlckJvcmRlcldpZHRoLFxuICAgICAgcG9pbnRTdHlsZTogYS5wb2ludFN0eWxlLFxuICAgICAgaG92ZXJCYWNrZ3JvdW5kQ29sb3I6IGEuaG92ZXJCYWNrZ3JvdW5kQ29sb3IsXG4gICAgICBob3ZlckJvcmRlckNvbG9yOiBhLmhvdmVyQm9yZGVyQ29sb3IsXG4gICAgICBob3ZlckJvcmRlcldpZHRoOiBhLmhvdmVyQm9yZGVyV2lkdGgsXG4gICAgfTtcblxuICAgIHJldHVybiByYztcbiAgfVxuXG4gIGNvbG9yc0VxdWFsKGE6IERhdGFzZXRDb2xvciwgYjogRGF0YXNldENvbG9yKSB7XG4gICAgaWYgKCFhICE9PSAhYikge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gKFxuICAgICAgIWEgfHxcbiAgICAgICh0cnVlICYmXG4gICAgICAgIGEuYmFja2dyb3VuZENvbG9yID09PSBiLmJhY2tncm91bmRDb2xvciAmJlxuICAgICAgICBhLmJvcmRlcldpZHRoID09PSBiLmJvcmRlcldpZHRoICYmXG4gICAgICAgIGEuYm9yZGVyQ29sb3IgPT09IGIuYm9yZGVyQ29sb3IgJiZcbiAgICAgICAgYS5ib3JkZXJDYXBTdHlsZSA9PT0gYi5ib3JkZXJDYXBTdHlsZSAmJlxuICAgICAgICBhLmJvcmRlckRhc2ggPT09IGIuYm9yZGVyRGFzaCAmJlxuICAgICAgICBhLmJvcmRlckRhc2hPZmZzZXQgPT09IGIuYm9yZGVyRGFzaE9mZnNldCAmJlxuICAgICAgICBhLmJvcmRlckpvaW5TdHlsZSA9PT0gYi5ib3JkZXJKb2luU3R5bGUgJiZcbiAgICAgICAgYS5wb2ludEJvcmRlckNvbG9yID09PSBiLnBvaW50Qm9yZGVyQ29sb3IgJiZcbiAgICAgICAgYS5wb2ludEJhY2tncm91bmRDb2xvciA9PT0gYi5wb2ludEJhY2tncm91bmRDb2xvciAmJlxuICAgICAgICBhLnBvaW50Qm9yZGVyV2lkdGggPT09IGIucG9pbnRCb3JkZXJXaWR0aCAmJlxuICAgICAgICBhLnBvaW50UmFkaXVzID09PSBiLnBvaW50UmFkaXVzICYmXG4gICAgICAgIGEucG9pbnRIb3ZlclJhZGl1cyA9PT0gYi5wb2ludEhvdmVyUmFkaXVzICYmXG4gICAgICAgIGEucG9pbnRIaXRSYWRpdXMgPT09IGIucG9pbnRIaXRSYWRpdXMgJiZcbiAgICAgICAgYS5wb2ludEhvdmVyQmFja2dyb3VuZENvbG9yID09PSBiLnBvaW50SG92ZXJCYWNrZ3JvdW5kQ29sb3IgJiZcbiAgICAgICAgYS5wb2ludEhvdmVyQm9yZGVyQ29sb3IgPT09IGIucG9pbnRIb3ZlckJvcmRlckNvbG9yICYmXG4gICAgICAgIGEucG9pbnRIb3ZlckJvcmRlcldpZHRoID09PSBiLnBvaW50SG92ZXJCb3JkZXJXaWR0aCAmJlxuICAgICAgICBhLnBvaW50U3R5bGUgPT09IGIucG9pbnRTdHlsZSAmJlxuICAgICAgICBhLmhvdmVyQmFja2dyb3VuZENvbG9yID09PSBiLmhvdmVyQmFja2dyb3VuZENvbG9yICYmXG4gICAgICAgIGEuaG92ZXJCb3JkZXJDb2xvciA9PT0gYi5ob3ZlckJvcmRlckNvbG9yICYmXG4gICAgICAgIGEuaG92ZXJCb3JkZXJXaWR0aCA9PT0gYi5ob3ZlckJvcmRlcldpZHRoKVxuICAgICk7XG4gIH1cblxuICB1cGRhdGVDb2xvcnMoKSB7XG4gICAgdGhpcy5kYXRhc2V0cy5mb3JFYWNoKChlbG0sIGluZGV4KSA9PiB7XG4gICAgICBpZiAodGhpcy5jb2xvcnMgJiYgdGhpcy5jb2xvcnNbaW5kZXhdKSB7XG4gICAgICAgIE9iamVjdC5hc3NpZ24oZWxtLCB0aGlzLmNvbG9yc1tpbmRleF0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgT2JqZWN0LmFzc2lnbihlbG0sIGdldENvbG9ycyh0aGlzLmNoYXJ0VHlwZSwgaW5kZXgsIGVsbS5kYXRhLmxlbmd0aCksIHtcbiAgICAgICAgICAuLi5lbG0sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBsZXQgdXBkYXRlUmVxdWlyZWQgPSBVcGRhdGVUeXBlLkRlZmF1bHQ7XG