vix-ui
Version:
324 lines • 28.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
import { Component, Input } from '@angular/core';
export class VixGraphComponent {
constructor() {
this.title = '';
this.subtitle = '';
this.xAxis = (/** @type {?} */ ({})); // can define anything for x-axis. E.g. instead of numeric x-axis, category 0, category 1, ...
this.yAxis = (/** @type {?} */ ({}));
this.data = []; // format: data => [data1, data2], where data1 => [1, 2, ...]
this.graphType = ''; // current supported: line, bar, scatter, pie
this.customOptions = (/** @type {?} */ ({})); // any other options that are supported by e-charts
this.labelFormatter = '';
this.tooltipFormatter = '';
this.currentData = (/** @type {?} */ ({}));
this.isLoading = false;
this.isGraphExists = false;
}
/**
* @return {?}
*/
ngDoCheck() {
if (JSON.stringify(this.currentData).toLowerCase() !== JSON.stringify(this.options).toLowerCase()) {
this.isLoading = true;
this.currentData = Object.assign({}, this.options);
}
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
this.isLoading = true;
this.initializeGraph();
}
/**
* @return {?}
*/
ngOnInit() {
this.isLoading = true;
this.currentData = Object.assign({}, this.options);
this.initializeGraph();
}
/**
* @return {?}
*/
initializeGraph() {
this.isGraphExists = false;
// Variable definitions
if (this.graphType === '' || (this.data.length <= 0)) {
return;
}
/** @type {?} */
const tempGraphType = this.graphType;
// Define some common options
this.options = {
title: {
text: this.title,
subtext: this.subtitle,
},
width: this.width,
height: this.height,
animationEasing: 'exponentialOut',
grid: {
top: '10%',
containLabel: true,
},
tooltip: {
trigger: 'item',
formatter: '{b}: {c} ({d}%)'
}
};
if (this.tooltipFormatter.length > 0) {
this.options.tooltip.formatter = this.tooltipFormatter;
}
this.configLineAxis(this.xAxis, this.yAxis, tempGraphType); // config the axis
this.configLegend(tempGraphType, this.data);
this.configSeries(tempGraphType, this.data); // config the data
// Custom options - this will override any existing fields, if they coincide.
if (!this.isEmptyObject(this.customOptions)) {
Object.assign(this.options, this.customOptions);
}
// console.log(this.options)
this.isGraphExists = true;
}
/**
* @param {?} xAxis
* @param {?} yAxis
* @param {?} graphType
* @return {?}
*/
configLineAxis(xAxis, yAxis, graphType) {
if (graphType !== 'line') {
return;
}
// Xaxis and Yaxis definitions
this.options.xAxis = {};
this.options.yAxis = {};
if (!this.isEmptyObject(xAxis)) {
this.options.xAxis = {
type: xAxis.type,
data: xAxis.data,
nameGap: 30,
silent: true,
splitLine: {
show: false,
},
boundaryGap: false,
animationDelay: function (idx) {
return idx * 10;
}
};
}
if (!this.isEmptyObject(yAxis)) {
this.options.yAxis = {
type: yAxis.type,
data: yAxis.data,
nameGap: 30,
silent: true,
splitLine: {
show: false,
},
boundaryGap: false,
animationDelay: function (idx) {
return idx * 10;
}
};
}
this.options.axisPointer = {
show: true,
type: this.graphType,
snap: true,
};
this.options.tooltip = {
trigger: 'axis',
};
}
/**
* @param {?} graphType
* @param {?} data
* @return {?}
*/
configLegend(graphType, data) {
/** @type {?} */
const legend = {
padding: [30, 0, 0, 0],
type: 'scroll',
orient: 'horizontal',
bottom: 0,
data: []
};
switch (graphType) {
case 'line':
data.forEach(function (tempData) {
if (tempData.name) {
legend.data.push(tempData.name);
}
else {
legend.data.push('');
}
});
break;
case 'pie':
// For more flexibility - the data can be in an array, or just an object
// This is because one pie chart can only take one data set
if (Array.isArray(data)) {
data.forEach(function (tempData) {
tempData.data.forEach(function (point) {
legend.data.push(point.name);
});
});
}
else {
data.data.forEach(function (point) {
legend.data.push(point.name);
});
}
break;
default:
break;
}
this.options.legend = legend;
}
/**
* @param {?} graphType
* @param {?} data
* @return {?}
*/
configSeries(graphType, data) {
/** @type {?} */
const series = [];
/** @type {?} */
const seriesTemplate = this.retrieveSeriesTemplate(graphType);
// Insert the data
switch (graphType) {
case 'line':
// Processing the data into options format (series parameter)
data.forEach(function (value) {
/** @type {?} */
const dataOpts = (/** @type {?} */ ({}));
// dataOpts.name = value.name;
Object.keys(value).forEach(key => {
dataOpts[key] = value[key];
});
series.push(dataOpts);
});
break;
case 'pie':
if (Array.isArray(data)) {
series.push({
data: data[0].data
});
}
else {
series.push({
data: data.data
});
}
break;
default:
series.push({
data: data[0].data
});
break;
}
series.forEach(function (subSeries) {
Object.assign(subSeries, seriesTemplate);
});
this.options.series = series;
}
/**
* @param {?} graphType
* @return {?}
*/
retrieveSeriesTemplate(graphType) {
/** @type {?} */
let seriesTemplate = {};
switch (graphType) {
case 'line':
break;
case 'pie':
/** @type {?} */
const label = this.labelFormatter.length > 0 ? this.labelFormatter : '{b}: {c} ({d}%)';
seriesTemplate = {
label: {
formatter: label
}
};
break;
}
Object.assign(seriesTemplate, { type: graphType });
return seriesTemplate;
}
/**
* @param {?} obj
* @return {?}
*/
isEmptyObject(obj) {
for (const name in obj) {
if (name) {
return false;
}
}
return true;
}
}
VixGraphComponent.decorators = [
{ type: Component, args: [{
selector: 'vix-graph',
template: "<div *ngIf=\"isGraphExists\" echarts [options]=\"options\"\nclass=\"demo-echarts\">\n</div>\n",
styles: [""]
}] }
];
VixGraphComponent.ctorParameters = () => [];
VixGraphComponent.propDecorators = {
title: [{ type: Input }],
subtitle: [{ type: Input }],
xAxis: [{ type: Input }],
yAxis: [{ type: Input }],
data: [{ type: Input }],
graphType: [{ type: Input }],
customOptions: [{ type: Input }],
width: [{ type: Input }],
height: [{ type: Input }],
labelFormatter: [{ type: Input }],
tooltipFormatter: [{ type: Input }]
};
if (false) {
/** @type {?} */
VixGraphComponent.prototype.title;
/** @type {?} */
VixGraphComponent.prototype.subtitle;
/** @type {?} */
VixGraphComponent.prototype.xAxis;
/** @type {?} */
VixGraphComponent.prototype.yAxis;
/** @type {?} */
VixGraphComponent.prototype.data;
/** @type {?} */
VixGraphComponent.prototype.graphType;
/** @type {?} */
VixGraphComponent.prototype.customOptions;
/** @type {?} */
VixGraphComponent.prototype.width;
/** @type {?} */
VixGraphComponent.prototype.height;
/** @type {?} */
VixGraphComponent.prototype.labelFormatter;
/** @type {?} */
VixGraphComponent.prototype.tooltipFormatter;
/** @type {?} */
VixGraphComponent.prototype.options;
/** @type {?} */
VixGraphComponent.prototype.currentData;
/** @type {?} */
VixGraphComponent.prototype.iterableDiffer;
/** @type {?} */
VixGraphComponent.prototype.isLoading;
/** @type {?} */
VixGraphComponent.prototype.isGraphExists;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JhcGguY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vdml4LXVpLyIsInNvdXJjZXMiOlsidml4LWdyYXBoL2dyYXBoLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBbUIsS0FBSyxFQUE0QixNQUFNLGVBQWUsQ0FBQztBQU81RixNQUFNO0lBbUJGO1FBakJTLFVBQUssR0FBRyxFQUFFLENBQUM7UUFDWCxhQUFRLEdBQUcsRUFBRSxDQUFDO1FBQ2QsVUFBSyxHQUFHLG1CQUFLLEVBQUUsRUFBQSxDQUFDLENBQUMsOEZBQThGO1FBQy9HLFVBQUssR0FBRyxtQkFBSyxFQUFFLEVBQUEsQ0FBQztRQUNoQixTQUFJLEdBQUcsRUFBRSxDQUFDLENBQUMsNkRBQTZEO1FBQ3hFLGNBQVMsR0FBRyxFQUFFLENBQUMsQ0FBQyw2Q0FBNkM7UUFDN0Qsa0JBQWEsR0FBRyxtQkFBSyxFQUFFLEVBQUEsQ0FBQyxDQUFDLG1EQUFtRDtRQUc1RSxtQkFBYyxHQUFHLEVBQUUsQ0FBQztRQUNwQixxQkFBZ0IsR0FBRyxFQUFFLENBQUM7UUFFL0IsZ0JBQVcsR0FBRyxtQkFBSyxFQUFFLEVBQUEsQ0FBQztRQUV0QixjQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ2xCLGtCQUFhLEdBQUcsS0FBSyxDQUFDO0lBR3RCLENBQUM7Ozs7SUFFRCxTQUFTO1FBQ0wsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxXQUFXLEVBQUUsS0FBSyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRTtZQUMvRixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztZQUN0QixJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUN0RDtJQUNMLENB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dXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRG9DaGVjaywgT25Jbml0LCBJbnB1dCwgU2ltcGxlQ2hhbmdlcywgT25DaGFuZ2VzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3ZpeC1ncmFwaCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9ncmFwaC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2dyYXBoLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgVml4R3JhcGhDb21wb25lbnQgaW1wbGVtZW50cyBEb0NoZWNrLCBPbkluaXQsIE9uQ2hhbmdlcyB7XG5cbiAgICBASW5wdXQoKSB0aXRsZSA9ICcnO1xuICAgIEBJbnB1dCgpIHN1YnRpdGxlID0gJyc7XG4gICAgQElucHV0KCkgeEF4aXMgPSA8YW55Pnt9OyAvLyBjYW4gZGVmaW5lIGFueXRoaW5nIGZvciB4LWF4aXMuIEUuZy4gaW5zdGVhZCBvZiBudW1lcmljIHgtYXhpcywgY2F0ZWdvcnkgMCwgY2F0ZWdvcnkgMSwgLi4uXG4gICAgQElucHV0KCkgeUF4aXMgPSA8YW55Pnt9O1xuICAgIEBJbnB1dCgpIGRhdGEgPSBbXTsgLy8gZm9ybWF0OiBkYXRhID0+IFtkYXRhMSwgZGF0YTJdLCB3aGVyZSBkYXRhMSA9PiBbMSwgMiwgLi4uXVxuICAgIEBJbnB1dCgpIGdyYXBoVHlwZSA9ICcnOyAvLyBjdXJyZW50IHN1cHBvcnRlZDogbGluZSwgYmFyLCBzY2F0dGVyLCBwaWVcbiAgICBASW5wdXQoKSBjdXN0b21PcHRpb25zID0gPGFueT57fTsgLy8gYW55IG90aGVyIG9wdGlvbnMgdGhhdCBhcmUgc3VwcG9ydGVkIGJ5IGUtY2hhcnRzXG4gICAgQElucHV0KCkgd2lkdGg6IGFueTtcbiAgICBASW5wdXQoKSBoZWlnaHQ6IGFueTtcbiAgICBASW5wdXQoKSBsYWJlbEZvcm1hdHRlciA9ICcnO1xuICAgIEBJbnB1dCgpIHRvb2x0aXBGb3JtYXR0ZXIgPSAnJztcbiAgICBvcHRpb25zOiBhbnk7XG4gICAgY3VycmVudERhdGEgPSA8YW55Pnt9O1xuICAgIGl0ZXJhYmxlRGlmZmVyOiBhbnk7XG4gICAgaXNMb2FkaW5nID0gZmFsc2U7XG4gICAgaXNHcmFwaEV4aXN0cyA9IGZhbHNlO1xuXG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgfVxuXG4gICAgbmdEb0NoZWNrKCkge1xuICAgICAgICBpZiAoSlNPTi5zdHJpbmdpZnkodGhpcy5jdXJyZW50RGF0YSkudG9Mb3dlckNhc2UoKSAhPT0gSlNPTi5zdHJpbmdpZnkodGhpcy5vcHRpb25zKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgICAgICB0aGlzLmlzTG9hZGluZyA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnREYXRhID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5vcHRpb25zKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSB0cnVlO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVHcmFwaCgpO1xuICAgIH1cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLmlzTG9hZGluZyA9IHRydWU7XG4gICAgICAgIHRoaXMuY3VycmVudERhdGEgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLm9wdGlvbnMpO1xuICAgICAgICB0aGlzLmluaXRpYWxpemVHcmFwaCgpO1xuICAgIH1cblxuICAgIGluaXRpYWxpemVHcmFwaCgpIHtcbiAgICAgIHRoaXMuaXNHcmFwaEV4aXN0cyA9IGZhbHNlO1xuICAgICAgLy8gVmFyaWFibGUgZGVmaW5pdGlvbnNcbiAgICAgIGlmICh0aGlzLmdyYXBoVHlwZSA9PT0gJycgfHwgKHRoaXMuZGF0YS5sZW5ndGggPD0gMCkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBjb25zdCB0ZW1wR3JhcGhUeXBlID0gdGhpcy5ncmFwaFR5cGU7XG5cbiAgICAgIC8vIERlZmluZSBzb21lIGNvbW1vbiBvcHRpb25zXG4gICAgICB0aGlzLm9wdGlvbnMgPSB7XG4gICAgICAgICAgdGl0bGU6IHtcbiAgICAgICAgICAgIHRleHQ6IHRoaXMudGl0bGUsXG4gICAgICAgICAgICBzdWJ0ZXh0OiB0aGlzLnN1YnRpdGxlLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgd2lkdGg6IHRoaXMud2lkdGgsXG4gICAgICAgICAgaGVpZ2h0OiB0aGlzLmhlaWdodCxcbiAgICAgICAgICBhbmltYXRpb25FYXNpbmc6ICdleHBvbmVudGlhbE91dCcsXG4gICAgICAgICAgZ3JpZDoge1xuICAgICAgICAgICAgdG9wOiAnMTAlJyxcbiAgICAgICAgICAgIGNvbnRhaW5MYWJlbDogdHJ1ZSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHRvb2x0aXA6IHtcbiAgICAgICAgICAgICAgdHJpZ2dlcjogJ2l0ZW0nLFxuICAgICAgICAgICAgICBmb3JtYXR0ZXI6ICd7Yn06IHtjfSAoe2R9JSknXG4gICAgICAgICAgfVxuICAgICAgfTtcbiAgICAgIGlmICh0aGlzLnRvb2x0aXBGb3JtYXR0ZXIubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHRoaXMub3B0aW9ucy50b29sdGlwLmZvcm1hdHRlciA9IHRoaXMudG9vbHRpcEZvcm1hdHRlcjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5jb25maWdMaW5lQXhpcyh0aGlzLnhBeGlzLCB0aGlzLnlBeGlzLCB0ZW1wR3JhcGhUeXBlKTsgLy8gY29uZmlnIHRoZSBheGlzXG4gICAgICB0aGlzLmNvbmZpZ0xlZ2VuZCh0ZW1wR3JhcGhUeXBlLCB0aGlzLmRhdGEpO1xuICAgICAgdGhpcy5jb25maWdTZXJpZXModGVtcEdyYXBoVHlwZSwgdGhpcy5kYXRhKTsgLy8gY29uZmlnIHRoZSBkYXRhXG5cbiAgICAgIC8vIEN1c3RvbSBvcHRpb25zIC0gdGhpcyB3aWxsIG92ZXJyaWRlIGFueSBleGlzdGluZyBmaWVsZHMsIGlmIHRoZXkgY29pbmNpZGUuXG4gICAgICBpZiAoIXRoaXMuaXNFbXB0eU9iamVjdCh0aGlzLmN1c3RvbU9wdGlvbnMpKSB7XG4gICAgICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLm9wdGlvbnMsIHRoaXMuY3VzdG9tT3B0aW9ucyk7XG4gICAgICB9XG4gICAgICAvLyBjb25zb2xlLmxvZyh0aGlzLm9wdGlvbnMpXG4gICAgICB0aGlzLmlzR3JhcGhFeGlzdHMgPSB0cnVlO1xuICAgIH1cblxuICAgIGNvbmZpZ0xpbmVBeGlzKHhBeGlzLCB5QXhpcywgZ3JhcGhUeXBlKSB7XG4gICAgICAgIGlmIChncmFwaFR5cGUgIT09ICdsaW5lJykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIFhheGlzIGFuZCBZYXhpcyBkZWZpbml0aW9uc1xuICAgICAgICB0aGlzLm9wdGlvbnMueEF4aXMgPSB7fTtcbiAgICAgICAgdGhpcy5vcHRpb25zLnlBeGlzID0ge307XG4gICAgICAgIGlmICghdGhpcy5pc0VtcHR5T2JqZWN0KHhBeGlzKSkge1xuICAgICAgICAgICAgdGhpcy5vcHRpb25zLnhBeGlzID0ge1xuICAgICAgICAgICAgICAgIHR5cGU6IHhBeGlzLnR5cGUsXG4gICAgICAgICAgICAgICAgZGF0YTogeEF4aXMuZGF0YSxcbiAgICAgICAgICAgICAgICBuYW1lR2FwOiAzMCxcbiAgICAgICAgICAgICAgICBzaWxlbnQ6IHRydWUsXG4gICAgICAgICAgICAgICAgc3BsaXRMaW5lOiB7XG4gICAgICAgICAgICAgICAgICAgIHNob3c6IGZhbHNlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgYm91bmRhcnlHYXA6IGZhbHNlLFxuICAgICAgICAgICAgICAgIGFuaW1hdGlvbkRlbGF5OiBmdW5jdGlvbiAoaWR4KSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpZHggKiAxMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLmlzRW1wdHlPYmplY3QoeUF4aXMpKSB7XG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMueUF4aXMgPSB7XG4gICAgICAgICAgICAgICAgdHlwZTogeUF4aXMudHlwZSxcbiAgICAgICAgICAgICAgICBkYXRhOiB5QXhpcy5kYXRhLFxuICAgICAgICAgICAgICAgIG5hbWVHYXA6IDMwLFxuICAgICAgICAgICAgICAgIHNpbGVudDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzcGxpdExpbmU6IHtcbiAgICAgICAgICAgICAgICAgICAgc2hvdzogZmFsc2UsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBib3VuZGFyeUdhcDogZmFsc2UsXG4gICAgICAgICAgICAgICAgYW5pbWF0aW9uRGVsYXk6IGZ1bmN0aW9uIChpZHgpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGlkeCAqIDEwO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm9wdGlvbnMuYXhpc1BvaW50ZXIgPSB7XG4gICAgICAgICAgc2hvdzogdHJ1ZSxcbiAgICAgICAgICB0eXBlOiB0aGlzLmdyYXBoVHlwZSxcbiAgICAgICAgICBzbmFwOiB0cnVlLFxuICAgICAgICB9O1xuXG4gICAgICAgIHRoaXMub3B0aW9ucy50b29sdGlwID0ge1xuICAgICAgICAgICAgdHJpZ2dlcjogJ2F4aXMnLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIGNvbmZpZ0xlZ2VuZChncmFwaFR5cGUsIGRhdGEpIHtcbiAgICAgICAgY29uc3QgbGVnZW5kID0ge1xuICAgICAgICAgICAgcGFkZGluZzogWzMwLCAwLCAwLCAwXSxcbiAgICAgICAgICAgIHR5cGU6ICdzY3JvbGwnLFxuICAgICAgICAgICAgb3JpZW50OiAnaG9yaXpvbnRhbCcsXG4gICAgICAgICAgICBib3R0b206IDAsXG4gICAgICAgICAgICBkYXRhOiBbXVxuICAgICAgICB9O1xuXG4gICAgICAgIHN3aXRjaCAoZ3JhcGhUeXBlKSB7XG4gICAgICAgICAgICBjYXNlICdsaW5lJzpcbiAgICAgICAgICAgICAgICBkYXRhLmZvckVhY2goZnVuY3Rpb24odGVtcERhdGEpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXBEYXRhLm5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZC5kYXRhLnB1c2godGVtcERhdGEubmFtZSk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZWdlbmQuZGF0YS5wdXNoKCcnKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncGllJzpcbiAgICAgICAgICAgICAgICAvLyBGb3IgbW9yZSBmbGV4aWJpbGl0eSAtIHRoZSBkYXRhIGNhbiBiZSBpbiBhbiBhcnJheSwgb3IganVzdCBhbiBvYmplY3RcbiAgICAgICAgICAgICAgICAvLyBUaGlzIGlzIGJlY2F1c2Ugb25lIHBpZSBjaGFydCBjYW4gb25seSB0YWtlIG9uZSBkYXRhIHNldFxuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIGRhdGEuZm9yRWFjaChmdW5jdGlvbih0ZW1wRGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGVtcERhdGEuZGF0YS5mb3JFYWNoKGZ1bmN0aW9uKHBvaW50KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLmRhdGEucHVzaChwb2ludC5uYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBkYXRhLmRhdGEuZm9yRWFjaChmdW5jdGlvbihwb2ludCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGVnZW5kLmRhdGEucHVzaChwb2ludC5uYW1lKTtcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3B0aW9ucy5sZWdlbmQgPSBsZWdlbmQ7XG4gICAgfVxuXG4gICAgY29uZmlnU2VyaWVzKGdyYXBoVHlwZSwgZGF0YSkge1xuICAgICAgICAgY29uc3Qgc2VyaWVzID0gW107XG4gICAgICAgICBjb25zdCBzZXJpZXNUZW1wbGF0ZSA9IHRoaXMucmV0cmlldmVTZXJpZXNUZW1wbGF0ZShncmFwaFR5cGUpO1xuXG4gICAgICAgICAvLyBJbnNlcnQgdGhlIGRhdGFcbiAgICAgICAgIHN3aXRjaCAoZ3JhcGhUeXBlKSB7XG4gICAgICAgICAgICBjYXNlICdsaW5lJzpcbiAgICAgICAgICAgICAgICAvLyBQcm9jZXNzaW5nIHRoZSBkYXRhIGludG8gb3B0aW9ucyBmb3JtYXQgKHNlcmllcyBwYXJhbWV0ZXIpXG4gICAgICAgICAgICAgICAgZGF0YS5mb3JFYWNoKGZ1bmN0aW9uICh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBkYXRhT3B0cyA9IDxhbnk+e307XG4gICAgICAgICAgICAgICAgICAgIC8vIGRhdGFPcHRzLm5hbWUgPSB2YWx1ZS5uYW1lO1xuICAgICAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyh2YWx1ZSkuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YU9wdHNba2V5XSA9IHZhbHVlW2tleV07XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICBzZXJpZXMucHVzaChkYXRhT3B0cyk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlICdwaWUnOlxuICAgICAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlcmllcy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGE6IGRhdGFbMF0uZGF0YVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzZXJpZXMucHVzaCh7XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhOiBkYXRhLmRhdGFcbiAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgc2VyaWVzLnB1c2goe1xuICAgICAgICAgICAgICAgICAgZGF0YTogZGF0YVswXS5kYXRhXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgIH1cbiAgICAgICAgIHNlcmllcy5mb3JFYWNoKGZ1bmN0aW9uKHN1YlNlcmllcykge1xuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihzdWJTZXJpZXMsIHNlcmllc1RlbXBsYXRlKTtcbiAgICAgICAgIH0pO1xuXG4gICAgICAgICB0aGlzLm9wdGlvbnMuc2VyaWVzID0gc2VyaWVzO1xuICAgIH1cblxuICAgIHJldHJpZXZlU2VyaWVzVGVtcGxhdGUoZ3JhcGhUeXBlKSB7XG4gICAgICAgIGxldCBzZXJpZXNUZW1wbGF0ZSA9IHt9O1xuICAgICAgICBzd2l0Y2ggKGdyYXBoVHlwZSkge1xuICAgICAgICAgICAgY2FzZSAnbGluZSc6XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAncGllJzpcbiAgICAgICAgICAgICAgY29uc3QgbGFiZWwgPSB0aGlzLmxhYmVsRm9ybWF0dGVyLmxlbmd0aCA+IDAgPyB0aGlzLmxhYmVsRm9ybWF0dGVyIDogJ3tifToge2N9ICh7ZH0lKSc7XG4gICAgICAgICAgICAgIHNlcmllc1RlbXBsYXRlID0ge1xuICAgICAgICAgICAgICAgICAgbGFiZWw6IHtcbiAgICAgICAgICAgICAgICAgICAgICBmb3JtYXR0ZXI6IGxhYmVsXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIE9iamVjdC5hc3NpZ24oc2VyaWVzVGVtcGxhdGUsIHt0eXBlOiBncmFwaFR5cGV9KTtcbiAgICAgICAgcmV0dXJuIHNlcmllc1RlbXBsYXRlO1xuICAgIH1cblxuICAgIGlzRW1wdHlPYmplY3Qob2JqKSB7XG4gICAgICAgIGZvciAoY29uc3QgbmFtZSBpbiBvYmopIHtcbiAgICAgICAgICAgIGlmIChuYW1lKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbn1cbiJdfQ==