UNPKG

ng2-charts

Version:

Reactive, responsive, beautiful charts for Angular2 based on Chart.js

726 lines 65.6 kB
/** * @fileoverview added by tsickle * Generated from: lib/base-chart.directive.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Directive, ElementRef, EventEmitter, Input, Output, } from '@angular/core'; import { getColors } from './get-colors'; import { ThemeService } from './theme.service'; import { cloneDeep } from 'lodash-es'; import { Chart, pluginService } from 'chart.js'; /** * @record */ function OldState() { } if (false) { /** @type {?} */ OldState.prototype.dataExists; /** @type {?} */ OldState.prototype.dataLength; /** @type {?} */ OldState.prototype.datasetsExists; /** @type {?} */ OldState.prototype.datasetsLength; /** @type {?} */ OldState.prototype.datasetsDataObjects; /** @type {?} */ OldState.prototype.datasetsDataLengths; /** @type {?} */ OldState.prototype.colorsExists; /** @type {?} */ OldState.prototype.colors; /** @type {?} */ OldState.prototype.labelsExist; /** @type {?} */ OldState.prototype.labels; /** @type {?} */ OldState.prototype.legendExists; /** @type {?} */ OldState.prototype.legend; } /** @enum {number} */ const UpdateType = { Default: 0, Update: 1, Refresh: 2, }; UpdateType[UpdateType.Default] = 'Default'; UpdateType[UpdateType.Update] = 'Update'; UpdateType[UpdateType.Refresh] = 'Refresh'; export class BaseChartDirective { /** * @param {?} element * @param {?} themeService */ 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. * @param {?} plugin * @return {?} */ static registerPlugin(plugin) { pluginService.register(plugin); } /** * @param {?} plugin * @return {?} */ static unregisterPlugin(plugin) { pluginService.unregister(plugin); } /** * @return {?} */ ngOnInit() { this.ctx = this.element.nativeElement.getContext('2d'); this.refresh(); this.subs.push(this.themeService.colorschemesOptions.subscribe((/** * @param {?} r * @return {?} */ r => this.themeChanged(r)))); } /** * @private * @param {?} options * @return {?} */ themeChanged(options) { this.refresh(); } /** * @return {?} */ ngDoCheck() { if (!this.chart) { return; } /** @type {?} */ let updateRequired = UpdateType.Default; /** @type {?} */ const wantUpdate = (/** * @param {?} x * @return {?} */ (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((/** * @param {?} x * @param {?} i * @return {?} */ (x, i) => x.data !== this.old.datasetsDataObjects[i])).length) { this.old.datasetsDataObjects = this.datasets.map((/** * @param {?} x * @return {?} */ x => x.data)); wantUpdate(UpdateType.Update); } if (this.datasets && this.datasets.filter((/** * @param {?} x * @param {?} i * @return {?} */ (x, i) => x.data.length !== this.old.datasetsDataLengths[i])).length) { this.old.datasetsDataLengths = this.datasets.map((/** * @param {?} x * @return {?} */ 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((/** * @param {?} x * @param {?} i * @return {?} */ (x, i) => !this.colorsEqual(x, this.old.colors[i]))).length) { this.old.colors = this.colors.map((/** * @param {?} x * @return {?} */ 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((/** * @param {?} x * @param {?} i * @return {?} */ (x, i) => !this.labelsEqual(x, this.old.labels[i]))).length) { this.old.labels = this.labels.map((/** * @param {?} x * @return {?} */ 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 ((/** @type {?} */ (updateRequired))) { case UpdateType.Default: break; case UpdateType.Update: this.update(); break; case UpdateType.Refresh: this.refresh(); break; } } /** * @param {?} a * @return {?} */ copyLabel(a) { if (Array.isArray(a)) { return [...a]; } return a; } /** * @param {?} a * @param {?} b * @return {?} */ labelsEqual(a, b) { return Array.isArray(a) === Array.isArray(b) && (Array.isArray(a) || a === b) && (!Array.isArray(a) || a.length === b.length) && (!Array.isArray(a) || a.filter((/** * @param {?} x * @param {?} i * @return {?} */ (x, i) => x !== b[i])).length === 0); } /** * @param {?} a * @return {?} */ copyColor(a) { return { 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, }; } /** * @param {?} a * @param {?} b * @return {?} */ colorsEqual(a, b) { if (!a !== !b) { return false; } return !a || (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); } /** * @return {?} */ updateColors() { this.datasets.forEach((/** * @param {?} elm * @param {?} index * @return {?} */ (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), Object.assign({}, elm)); } })); } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { /** @type {?} */ let updateRequired = UpdateType.Default; /** @type {?} */ const wantUpdate = (/** * @param {?} x * @return {?} */ (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 ((/** @type {?} */ (updateRequired))) { case UpdateType.Update: this.update(); break; case UpdateType.Refresh: case UpdateType.Default: this.refresh(); break; } } /** * @return {?} */ ngOnDestroy() { if (this.chart) { this.chart.destroy(); this.chart = void 0; } this.subs.forEach((/** * @param {?} x * @return {?} */ x => x.unsubscribe())); } /** * @param {?=} duration * @return {?} */ update(duration) { if (this.chart) { return this.chart.update(duration); } } /** * @param {?} index * @param {?} hidden * @return {?} */ hideDataset(index, hidden) { this.chart.getDatasetMeta(index).hidden = hidden; this.chart.update(); } /** * @param {?} index * @return {?} */ isDatasetHidden(index) { return this.chart.getDatasetMeta(index).hidden; } /** * @return {?} */ toBase64Image() { return this.chart.toBase64Image(); } /** * @return {?} */ getChartConfiguration() { /** @type {?} */ const datasets = this.getDatasets(); /** @type {?} */ 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 = (/** * @param {?} event * @param {?} active * @return {?} */ (event, active) => { if (active && !active.length) { return; } this.chartHover.emit({ event, active }); }); } if (!options.onClick) { options.onClick = (/** * @param {?=} event * @param {?=} active * @return {?} */ (event, active) => { this.chartClick.emit({ event, active }); }); } /** @type {?} */ const mergedOptions = this.smartMerge(options, this.themeService.getColorschemesOptions()); return { type: this.chartType, data: { labels: this.labels || [], datasets }, plugins: this.plugins, options: mergedOptions, }; } /** * @param {?} ctx * @return {?} */ getChartBuilder(ctx /*, data:any[], options:any*/) { /** @type {?} */ const chartConfig = this.getChartConfiguration(); return new Chart(ctx, chartConfig); } /** * @param {?} options * @param {?} overrides * @param {?=} level * @return {?} */ smartMerge(options, overrides, level = 0) { if (level === 0) { options = cloneDeep(options); } /** @type {?} */ const keysToUpdate = Object.keys(overrides); keysToUpdate.forEach((/** * @param {?} key * @return {?} */ key => { if (Array.isArray(overrides[key])) { /** @type {?} */ const arrayElements = options[key]; if (arrayElements) { arrayElements.forEach((/** * @param {?} r * @return {?} */ 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; } } /** * @private * @param {?} label * @return {?} */ isMultiLineLabel(label) { return Array.isArray(label); } /** * @private * @param {?} label * @return {?} */ joinLabel(label) { if (!label) { return null; } if (this.isMultiLineLabel(label)) { return label.join(' '); } else { return label; } } /** * @private * @param {?} datasets * @return {?} */ propagateDatasetsToData(datasets) { this.data = this.datasets.map((/** * @param {?} r * @return {?} */ r => r.data)); if (this.chart) { this.chart.data.datasets = datasets; } this.updateColors(); } /** * @private * @param {?} newDataValues * @return {?} */ propagateDataToDatasets(newDataValues) { if (this.isMultiDataSet(newDataValues)) { if (this.datasets && newDataValues.length === this.datasets.length) { this.datasets.forEach((/** * @param {?} dataset * @param {?} i * @return {?} */ (dataset, i) => { dataset.data = newDataValues[i]; })); } else { this.datasets = newDataValues.map((/** * @param {?} data * @param {?} index * @return {?} */ (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(); } /** * @private * @param {?} data * @return {?} */ isMultiDataSet(data) { return Array.isArray(data[0]); } /** * @private * @return {?} */ 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; } } /** * @private * @return {?} */ 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.decorators = [ { type: Directive, args: [{ // tslint:disable-next-line:directive-selector selector: 'canvas[baseChart]', exportAs: 'base-chart' },] } ]; /** @nocollapse */ BaseChartDirective.ctorParameters = () => [ { type: ElementRef }, { type: ThemeService } ]; BaseChartDirective.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 }] }; if (false) { /** @type {?} */ BaseChartDirective.prototype.data; /** @type {?} */ BaseChartDirective.prototype.datasets; /** @type {?} */ BaseChartDirective.prototype.labels; /** @type {?} */ BaseChartDirective.prototype.options; /** @type {?} */ BaseChartDirective.prototype.chartType; /** @type {?} */ BaseChartDirective.prototype.colors; /** @type {?} */ BaseChartDirective.prototype.legend; /** @type {?} */ BaseChartDirective.prototype.plugins; /** @type {?} */ BaseChartDirective.prototype.chartClick; /** @type {?} */ BaseChartDirective.prototype.chartHover; /** @type {?} */ BaseChartDirective.prototype.ctx; /** @type {?} */ BaseChartDirective.prototype.chart; /** * @type {?} * @private */ BaseChartDirective.prototype.old; /** * @type {?} * @private */ BaseChartDirective.prototype.subs; /** * @type {?} * @private */ BaseChartDirective.prototype.element; /** * @type {?} * @private */ BaseChartDirective.prototype.themeService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1jaGFydC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZzItY2hhcnRzL3NyYy9saWIvYmFzZS1jaGFydC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBRUwsU0FBUyxFQUVULFVBQVUsRUFDVixZQUFZLEVBQ1osS0FBSyxFQUlMLE1BQU0sR0FFUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBRXpDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUUvQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3RDLE9BQU8sRUFDTCxLQUFLLEVBT0wsYUFBYSxFQUNkLE1BQU0sVUFBVSxDQUFDOzs7O0FBYWxCLHVCQWVDOzs7SUFkQyw4QkFBb0I7O0lBQ3BCLDhCQUFtQjs7SUFDbkIsa0NBQXdCOztJQUN4QixrQ0FBdUI7O0lBQ3ZCLHVDQUEyQjs7SUFDM0IsdUNBQThCOztJQUM5QixnQ0FBc0I7O0lBQ3RCLDBCQUFnQjs7SUFDaEIsK0JBQXFCOztJQUNyQiwwQkFBZ0I7O0lBQ2hCLGdDQUFzQjs7SUFDdEIsMEJBRUU7OztBQUdKLE1BQUssVUFBVTtJQUNiLE9BQU8sR0FBQTtJQUNQLE1BQU0sR0FBQTtJQUNOLE9BQU8sR0FBQTtFQUNSOzs7O0FBT0QsTUFBTSxPQUFPLGtCQUFrQjs7Ozs7SUE0QzdCLFlBQ1UsT0FBbUIsRUFDbkIsWUFBMEI7UUFEMUIsWUFBTyxHQUFQLE9BQU8sQ0FBWTtRQUNuQixpQkFBWSxHQUFaLFlBQVksQ0FBYztRQTFDcEIsWUFBTyxHQUFpQixFQUFFLENBQUM7UUFNMUIsZUFBVSxHQUF3RCxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3JGLGVBQVUsR0FBc0QsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUs1RixRQUFHLEdB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RSxJQUFJLENBQUMsR0FBRyxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQztZQUVyRSxVQUFVLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQy9CO1FBRUQsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTTs7Ozs7UUFBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsRUFBQyxDQUFDLE1BQU0sRUFBRTtZQUN0RyxJQUFJLENBQUMsR0FBRyxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRzs7OztZQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBQyxDQUFDO1lBRTlELFVBQVUsQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDL0I7UUFFRCxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNOzs7OztRQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUMsRUFBQyxDQUFDLE1BQU0sRUFBRTtZQUM3RyxJQUFJLENBQUMsR0FBRyxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRzs7OztZQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUMsQ0FBQztZQUVyRSxVQUFVLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQy9CO1FBRUQsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRTtZQUMzQyxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUV0QyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFFcEIsVUFBVSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUMvQjtRQUVELDBEQUEwRDtRQUMxRCxJQUFJLElBQUksQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNOzs7OztRQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFDLENBQUMsTUFBTSxFQUFFO1lBQ2hHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRzs7OztZQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBQyxDQUFDO1lBRTFELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUVwQixVQUFVLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQy9CO1FBRUQsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRTtZQUMxQyxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUVyQyxVQUFVLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQy9CO1FBRUQsSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTTs7Ozs7UUFBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLEVBQUUsSUFB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cEIsaUNBYUU7Ozs7O0lBRUYsa0NBQWtDOzs7OztJQWNoQyxxQ0FBMkI7Ozs7O0lBQzNCLDBDQUFrQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgQWZ0ZXJWaWV3SW5pdCxcclxuICBEaXJlY3RpdmUsXHJcbiAgRG9DaGVjayxcclxuICBFbGVtZW50UmVmLFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBJbnB1dCxcclxuICBPbkNoYW5nZXMsXHJcbiAgT25EZXN0cm95LFxyXG4gIE9uSW5pdCxcclxuICBPdXRwdXQsXHJcbiAgU2ltcGxlQ2hhbmdlcyxcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgZ2V0Q29sb3JzIH0gZnJvbSAnLi9nZXQtY29sb3JzJztcclxuaW1wb3J0IHsgQ29sb3IgfSBmcm9tICcuL2NvbG9yJztcclxuaW1wb3J0IHsgVGhlbWVTZXJ2aWNlIH0gZnJvbSAnLi90aGVtZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IGNsb25lRGVlcCB9IGZyb20gJ2xvZGFzaC1lcyc7XHJcbmltcG9ydCB7XHJcbiAgQ2hhcnQsXHJcbiAgQ2hhcnRDb25maWd1cmF0aW9uLFxyXG4gIENoYXJ0RGF0YVNldHMsXHJcbiAgQ2hhcnRPcHRpb25zLFxyXG4gIENoYXJ0UG9pbnQsIENoYXJ0VHlwZSxcclxuICBQbHVnaW5TZXJ2aWNlR2xvYmFsUmVnaXN0cmF0aW9uLFxyXG4gIFBsdWdpblNlcnZpY2VSZWdpc3RyYXRpb25PcHRpb25zLFxyXG4gIHBsdWdpblNlcnZpY2VcclxufSBmcm9tICdjaGFydC5qcyc7XHJcblxyXG5leHBvcnQgdHlwZSBTaW5nbGVEYXRhU2V0ID0gQXJyYXk8bnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCB8IG51bWJlcltdPiB8IENoYXJ0UG9pbnRbXTtcclxuZXhwb3J0IHR5cGUgTXVsdGlEYXRhU2V0ID0gU2luZ2xlRGF0YVNldFtdO1xyXG5leHBvcnQgdHlwZSBTaW5nbGVPck11bHRpRGF0YVNldCA9IFNpbmdsZURhdGFTZXQgfCBNdWx0aURhdGFTZXQ7XHJcblxyXG5leHBvcnQgdHlwZSBQbHVnaW5TZXJ2aWNlR2xvYmFsUmVnaXN0cmF0aW9uQW5kT3B0aW9ucyA9XHJcbiAgUGx1Z2luU2VydmljZUdsb2JhbFJlZ2lzdHJhdGlvblxyXG4gICYgUGx1Z2luU2VydmljZVJlZ2lzdHJhdGlvbk9wdGlvbnM7XHJcbmV4cG9ydCB0eXBlIFNpbmdsZUxpbmVMYWJlbCA9IHN0cmluZztcclxuZXhwb3J0IHR5cGUgTXVsdGlMaW5lTGFiZWwgPSBzdHJpbmdbXTtcclxuZXhwb3J0IHR5cGUgTGFiZWwgPSBTaW5nbGVMaW5lTGFiZWwgfCBNdWx0aUxpbmVMYWJlbDtcclxuXHJcbmludGVyZmFjZSBPbGRTdGF0ZSB7XHJcbiAgZGF0YUV4aXN0czogYm9vbGVhbjtcclxuICBkYXRhTGVuZ3RoOiBudW1iZXI7XHJcbiAgZGF0YXNldHNFeGlzdHM6IGJvb2xlYW47XHJcbiAgZGF0YXNldHNMZW5ndGg6IG51bWJlcjtcclxuICBkYXRhc2V0c0RhdGFPYmplY3RzOiBhbnlbXTtcclxuICBkYXRhc2V0c0RhdGFMZW5ndGhzOiBudW1iZXJbXTtcclxuICBjb2xvcnNFeGlzdHM6IGJvb2xlYW47XHJcbiAgY29sb3JzOiBDb2xvcltdO1xyXG4gIGxhYmVsc0V4aXN0OiBib29sZWFuO1xyXG4gIGxhYmVsczogTGFiZWxbXTtcclxuICBsZWdlbmRFeGlzdHM6IGJvb2xlYW47XHJcbiAgbGVnZW5kOiB7XHJcbiAgICBwb3NpdGlvbj86IHN0cmluZztcclxuICB9O1xyXG59XHJcblxyXG5lbnVtIFVwZGF0ZVR5cGUge1xyXG4gIERlZmF1bHQsXHJcbiAgVXBkYXRlLFxyXG4gIFJlZnJlc2hcclxufVxyXG5cclxuQERpcmVjdGl2ZSh7XHJcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOmRpcmVjdGl2ZS1zZWxlY3RvclxyXG4gIHNlbGVjdG9yOiAnY2FudmFzW2Jhc2VDaGFydF0nLFxyXG4gIGV4cG9ydEFzOiAnYmFzZS1jaGFydCdcclxufSlcclxuZXhwb3J0IGNsYXNzIEJhc2VDaGFydERpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25Jbml0LCBPbkRlc3Ryb3ksIERvQ2hlY2sge1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBkYXRhOiBTaW5nbGVPck11bHRpRGF0YVNldDtcclxuICBASW5wdXQoKSBwdWJsaWMgZGF0YXNldHM6IENoYXJ0RGF0YVNldHNbXTtcclxuICBASW5wdXQoKSBwdWJsaWMgbGFiZWxzOiBMYWJlbFtdO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBvcHRpb25zOiBDaGFydE9wdGlvbnMgPSB7fTtcclxuICBASW5wdXQoKSBwdWJsaWMgY2hhcnRUeXBlOiBDaGFydFR5cGU7XHJcbiAgQElucHV0KCkgcHVibGljIGNvbG9yczogQ29sb3JbXTtcclxuICBASW5wdXQoKSBwdWJsaWMgbGVnZW5kOiBib29sZWFuO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBwbHVnaW5zOiBQbHVnaW5TZXJ2aWNlR2xvYmFsUmVnaXN0cmF0aW9uQW5kT3B0aW9uc1tdO1xyXG5cclxuICBAT3V0cHV0KCkgcHVibGljIGNoYXJ0Q2xpY2s6IEV2ZW50RW1pdHRlcjx7IGV2ZW50PzogTW91c2VFdmVudCwgYWN0aXZlPzoge31bXSB9PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuICBAT3V0cHV0KCkgcHVibGljIGNoYXJ0SG92ZXI6IEV2ZW50RW1pdHRlcjx7IGV2ZW50OiBNb3VzZUV2ZW50LCBhY3RpdmU6IHt9W10gfT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcblxyXG4gIHB1YmxpYyBjdHg6IHN0cmluZztcclxuICBwdWJsaWMgY2hhcnQ6IENoYXJ0O1xyXG5cclxuICBwcml2YXRlIG9sZDogT2xkU3RhdGUgPSB7XHJcbiAgICBkYXRhRXhpc3RzOiBmYWxzZSxcclxuICAgIGRhdGFMZW5ndGg6IDAsXHJcbiAgICBkYXRhc2V0c0V4aXN0czogZmFsc2UsXHJcbiAgICBkYXRhc2V0c0xlbmd0aDogMCxcclxuICAgIGRhdGFzZXRzRGF0YU9iamVjdHM6IFtdLFxyXG4gICAgZGF0YXNldHNEYXRhTGVuZ3RoczogW10sXHJcbiAgICBjb2xvcnNFeGlzdHM6IGZhbHNlLFxyXG4gICAgY29sb3JzOiBbXSxcclxuICAgIGxhYmVsc0V4aXN0OiBmYWxzZSxcclxuICAgIGxhYmVsczogW10sXHJcbiAgICBsZWdlbmRFeGlzdHM6IGZhbHNlLFxyXG4gICAgbGVnZW5kOiB7fSxcclxuICB9O1xyXG5cclxuICBwcml2YXRlIHN1YnM6IFN1YnNjcmlwdGlvbltdID0gW107XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlZ2lzdGVyIGEgcGx1Z2luLlxyXG4gICAqL1xyXG4gIHB1YmxpYyBzdGF0aWMgcmVnaXN0ZXJQbHVnaW4ocGx1Z2luOiBQbHVnaW5TZXJ2aWNlR2xvYmFsUmVnaXN0cmF0aW9uQW5kT3B0aW9ucyk6IHZvaWQge1xyXG4gICAgcGx1Z2luU2VydmljZS5yZWdpc3RlcihwbHVnaW4pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHN0YXRpYyB1bnJlZ2lzdGVyUGx1Z2luKHBsdWdpbjogUGx1Z2luU2VydmljZUdsb2JhbFJlZ2lzdHJhdGlvbkFuZE9wdGlvbnMpOiB2b2lkIHtcclxuICAgIHBsdWdpblNlcnZpY2UudW5yZWdpc3RlcihwbHVnaW4pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBlbGVtZW50OiBFbGVtZW50UmVmLFxyXG4gICAgcHJpdmF0ZSB0aGVtZVNlcnZpY2U6IFRoZW1lU2VydmljZSxcclxuICApIHsgfVxyXG5cclxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmN0eCA9IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50LmdldENvbnRleHQoJzJkJyk7XHJcbiAgICB0aGlzLnJlZnJlc2goKTtcclxuICAgIHRoaXMuc3Vicy5wdXNoKHRoaXMudGhlbWVTZXJ2aWNlLmNvbG9yc2NoZW1lc09wdGlvbnMuc3Vic2NyaWJlKHIgPT4gdGhpcy50aGVtZUNoYW5nZWQocikpKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgdGhlbWVDaGFuZ2VkKG9wdGlvbnM6IHt9KTogdm9pZCB7XHJcbiAgICB0aGlzLnJlZnJlc2goKTtcclxuICB9XHJcblxyXG4gIG5nRG9DaGVjaygpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5jaGFydCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBsZXQgdXBkYXRlUmVxdWlyZWQgPSBVcGRhdGVUeXBlLkRlZmF1bHQ7XHJcbiAgICBjb25zdCB3YW50VXBkYXRlID0gKHg6IFVwZGF0ZVR5cGUpID0+IHtcclxuICAgICAgdXBkYXRlUmVxdWlyZWQgPSB4ID4gdXBkYXRlUmVxdWlyZWQgPyB4IDogdXBkYXRlUmVxdWlyZWQ7XHJcbiAgICB9O1xyXG5cclxuICAgIGlmICghIXRoaXMuZGF0YSAhPT0gdGhpcy5vbGQuZGF0YUV4aXN0cykge1xyXG4gICAgICB0aGlzLnByb3BhZ2F0ZURhdGFUb0RhdGFzZXRzKHRoaXMuZGF0YSk7XHJcblxyXG4gICAgICB0aGlzLm9sZC5kYXRhRXhpc3RzID0gISF0aGlzLmRhdGE7XHJcblxyXG4gICAgICB3YW50VXBkYXRlKFVwZGF0ZVR5cGUuVXBkYXRlKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5kYXRhICYmIHRoaXMuZGF0YS5sZW5ndGggIT09IHRoaXMub2xkLmRhdGFMZW5ndGgpIHtcclxuICAgICAgdGhpcy5vbGQuZGF0YUxlbmd0aCA9IHRoaXMuZGF0YSAmJiB0aGlzLmRhdGEubGVuZ3RoIHx8IDA7XHJcblxyXG4gICAgICB3YW50VXBkYXRlKFVwZGF0ZVR5cGUuVXBkYXRlKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoISF0aGlzLmRhdGFzZXRzICE9PSB0aGlzLm9sZC5kYXRhc2V0c0V4aXN0cykge1xyXG4gICAgICB0aGlzLm9sZC5kYXRhc2V0c0V4aXN0cyA9ICEhdGhpcy5kYXRhc2V0cztcclxuXHJcbiAgICAgIHdhbnRVcGRhdGUoVXBkYXRlVHlwZS5VcGRhdGUpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmRhdGFzZXRzICYmIHRoaXMuZGF0YXNldHMubGVuZ3RoICE9PSB0aGlzLm9sZC5kYXRhc2V0c0xlbmd0aCkge1xyXG4gICAgICB0aGlzLm9sZC5kYXRhc2V0c0xlbmd0aCA9IHRoaXMuZGF0YXNldHMgJiYgdGhpcy5kYXRhc2V0cy5sZW5ndGggfHwgMDtcclxuXHJcbiAgICAgIHdhbnRVcGRhdGUoVXBkYXRlVHlwZS5VcGRhdGUpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmRhdGFzZXRzICYmIHRoaXMuZGF0YXNldHMuZmlsdGVyKCh4LCBpKSA9PiB4LmRhdGEgIT09IHRoaXMub2xkLmRhdGFzZXRzRGF0YU9iamVjdHNbaV0pLmxlbmd0aCkge1xyXG4gICAgICB0aGlzLm9sZC5kYXRhc2V0c0RhdGFPYmplY3RzID0gdGhpcy5kYXRhc2V0cy5tYXAoeCA9PiB4LmRhdGEpO1xyXG5cclxuICAgICAgd2FudFVwZGF0ZShVcGRhdGVUeXBlLlVwZGF0ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuZGF0YXNldHMgJiYgdGhpcy5kYXRhc2V0cy5maWx0ZXIoKHgsIGkpID0+IHguZGF0YS5sZW5ndGggIT09IHRoaXMub2xkLmRhdGFzZXRzRGF0YUxlbmd0aHNbaV0pLmxlbmd0aCkge1xyXG4gICAgICB0aGlzLm9sZC5kYXRhc2V0c0RhdGFMZW5ndGhzID0gdGhpcy5kYXRhc2V0cy5tYXAoeCA9PiB4LmRhdGEubGVuZ3RoKTtcclxuXHJcbiAgICAgIHdhbnRVcGRhdGUoVXBkYXRlVHlwZS5VcGRhdGUpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghIXRoaXMuY29sb3JzICE9PSB0aGlzLm9sZC5jb2xvcn