ngx-beautiful-charts
Version:
A library to create charts in Angular
311 lines • 33.4 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, Input, ElementRef } from '@angular/core';
import { colorSchemes } from '../../constants/color-schemes';
import { GlobalParametersService } from '../../global/global-parameters.service';
import { DonutChartService } from './donut-chart.service';
export class DonutChartComponent {
/**
* @param {?} donutChartService
* @param {?} globalParametersService
* @param {?} currentElement
*/
constructor(donutChartService, globalParametersService, currentElement) {
this.donutChartService = donutChartService;
this.globalParametersService = globalParametersService;
this.currentElement = currentElement;
this.colorScheme = 'colorful';
this.customColorScheme = [];
this.xPadding = 60;
this.yPadding = this.xPadding / 2;
this.donutWidthPerc = 0.4;
this.donutSlicesInit = 0;
}
/**
* @param {?} donutCompletion
* @return {?}
*/
generateDonutSlices(donutCompletion) {
if (this.donutSlicesInit === 0)
this.donutSlices = [];
/** @type {?} */
let sum = 0;
for (const val of this.data) {
sum = sum + val.value;
}
/** @type {?} */
let rotation = 0;
/** @type {?} */
let cnt = 0;
for (const val of this.data) {
// console.log(val);
/** @type {?} */
const perc = val.value / sum * donutCompletion;
/** @type {?} */
const angle = 360 * perc;
/** @type {?} */
const angleRad = angle * Math.PI / 180;
/** @type {?} */
const largeArc = (angle > 180) ? 1 : 0;
/** @type {?} */
const path = 'M 0 ' + -this.donutInnerRadius + ' 0 ' + -this.donutRadius
+ ' A ' + this.donutRadius + ' ' + this.donutRadius
+ ' 0 ' + largeArc + ' 1' + this.donutRadius * Math.sin(angleRad) + ' '
+ -this.donutRadius * Math.cos(angleRad)
+ ' L ' + this.donutInnerRadius * Math.sin(angleRad) + ' '
+ -this.donutInnerRadius * Math.cos(angleRad) + ' A '
+ this.donutInnerRadius + ' ' + this.donutInnerRadius
+ ' 0 ' + largeArc + ' 0 0 ' + -this.donutInnerRadius + ' z';
/** @type {?} */
const hoverPath = 'M 0 ' + -this.hoverDonutInnerRadius + ' 0 ' + -this.hoverDonutRadius
+ ' A ' + this.hoverDonutRadius + ' ' + this.hoverDonutRadius
+ ' 0 ' + largeArc + ' 1' + this.hoverDonutRadius * Math.sin(angleRad) + ' '
+ -this.hoverDonutRadius * Math.cos(angleRad)
+ ' L ' + this.hoverDonutInnerRadius * Math.sin(angleRad) + ' '
+ -this.hoverDonutInnerRadius * Math.cos(angleRad) + ' A '
+ this.hoverDonutInnerRadius + ' ' + this.hoverDonutInnerRadius
+ ' 0 ' + largeArc + ' 0 0 ' + -this.hoverDonutInnerRadius + ' z';
/** @type {?} */
const donutSlice = {
perc,
name: val.name,
color: val.color,
hoverD: hoverPath,
rotation: 'rotate(' + rotation + 'deg)',
d: path,
hover: false
};
// console.log(hoverPath);
// console.log(donutSlice);
if (this.donutSlicesInit === 0)
this.donutSlices.push(donutSlice);
else
this.donutSlices[cnt] = donutSlice;
// this.donutSlices.push(donutSlice);
rotation += angle;
cnt++;
}
}
/**
* @return {?}
*/
setDimensions() {
if (this.width)
this.height = this.width * .6 - this.xPadding;
else {
/** @type {?} */
const host = this.currentElement.nativeElement;
if (host.parentNode != null) {
/** @type {?} */
const dims = host.parentNode.getBoundingClientRect();
this.width = dims.width;
this.height = this.width * .6 - this.xPadding;
}
}
// console.log('---set dimensions---');
// console.log('width: ' + this.width);
// console.log('height: ' + this.height);
// console.log('--------------------');
}
/**
* @return {?}
*/
setColors() {
/** @type {?} */
let cnt = 0;
for (const slice of this.data) {
if (!slice.color) {
if (this.customColorScheme.length > 0) {
slice.color = this.customColorScheme[cnt % this.customColorScheme.length];
}
else {
slice.color = colorSchemes[this.colorScheme][cnt % 10];
}
cnt++;
}
}
}
/**
* @return {?}
*/
ngOnInit() {
this.data = JSON.parse(JSON.stringify(this.data));
this.componentID = this.globalParametersService.addNewComponent();
this.setDimensions();
this.data.sort((/**
* @param {?} a
* @param {?} b
* @return {?}
*/
(a, b) => a.value > b.value ? -1 : a.value < b.value ? 1 : 0));
this.setColors();
this.donutChartService.setValues({
componentID: this.componentID,
width: this.width,
height: this.height,
xPadding: this.xPadding,
yPadding: this.yPadding,
data: this.data
});
// console.log('x: ' + this.x);
this.donutRadius = this.donutChartService.donutRadius;
this.donutInnerRadius = (1 - this.donutWidthPerc) * this.donutChartService.donutRadius;
this.hoverDonutRadius = this.donutChartService.donutRadius * 1.05;
this.hoverDonutInnerRadius = this.donutInnerRadius;
// this.generateDonutSlices();
/** @type {?} */
let donutCompletion = 0;
/** @type {?} */
const intervalID = setInterval((/**
* @return {?}
*/
() => {
this.generateDonutSlices(donutCompletion);
this.donutSlicesInit = 1;
donutCompletion = donutCompletion + 0.01;
donutCompletion = Math.round(donutCompletion * 100) / 100;
if (donutCompletion > 1)
clearInterval(intervalID);
}), 5);
// console.log(this.hoverDonutRadius);
this.cX = this.xPadding + this.donutRadius;
this.cY = this.yPadding + this.donutRadius;
/** @type {?} */
const translateX = this.xPadding + this.donutRadius;
/** @type {?} */
const translateY = this.yPadding + this.donutRadius;
this.gTranslate = 'translate(' + translateX + 'px, ' + translateY + 'px)';
/** @type {?} */
const hoverTranslateXY = this.donutRadius * 0.08;
this.hoverTranslate = 'translate(' + hoverTranslateXY + 'px, ' + -hoverTranslateXY + 'px)';
}
/**
* @return {?}
*/
ngOnChanges() {
this.data = JSON.parse(JSON.stringify(this.data));
this.setDimensions();
this.data.sort((/**
* @param {?} a
* @param {?} b
* @return {?}
*/
(a, b) => a.value > b.value ? -1 : a.value < b.value ? 1 : 0));
this.setColors();
this.donutChartService.setValues({
componentID: this.componentID,
width: this.width,
height: this.height,
xPadding: this.xPadding,
yPadding: this.yPadding,
data: this.data
});
// console.log('x: ' + this.x);
this.donutRadius = this.donutChartService.donutRadius;
this.donutInnerRadius = (1 - this.donutWidthPerc) * this.donutChartService.donutRadius;
this.hoverDonutRadius = this.donutChartService.donutRadius * 1.05;
this.hoverDonutInnerRadius = this.donutInnerRadius;
/** @type {?} */
let donutCompletion = 0;
/** @type {?} */
const intervalID = setInterval((/**
* @return {?}
*/
() => {
this.generateDonutSlices(donutCompletion);
this.donutSlicesInit = 1;
donutCompletion = donutCompletion + 0.01;
donutCompletion = Math.round(donutCompletion * 100) / 100;
if (donutCompletion > 1)
clearInterval(intervalID);
}), 5);
// console.log(this.hoverDonutRadius);
this.cX = this.xPadding + this.donutRadius;
this.cY = this.yPadding + this.donutRadius;
/** @type {?} */
const translateX = this.xPadding + this.donutRadius;
/** @type {?} */
const translateY = this.yPadding + this.donutRadius;
this.gTranslate = 'translate(' + translateX + 'px, ' + translateY + 'px)';
/** @type {?} */
const hoverTranslateXY = this.donutRadius * 0.08;
this.hoverTranslate = 'translate(' + hoverTranslateXY + 'px, ' + -hoverTranslateXY + 'px)';
}
}
DonutChartComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-donut-chart',
template: "<svg [attr.width]=\"width\" [attr.height]=\"height\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n\n <g ngx-donut-chart-base />\n <g *ngFor=\"let donutSlice of donutSlices\">\n <g [ngStyle]=\"{'transform': gTranslate}\">\n <path class=\"donut-slice\" (mouseover)=\"donutSlice.hover=true\" (mouseout)=\"donutSlice.hover=false\"\n [ngStyle]=\"{'opacity': donutSlice.hover ? 0.7 : 1.0, 'transform': donutSlice.rotation}\"\n [attr.d]=\"donutSlice.hover ? donutSlice.hoverD : donutSlice.d\" [attr.fill]=\"donutSlice.color\" />\n <text class=\"donut-text\" [ngStyle]=\"{'display': donutSlice.hover ? 'block' : 'none'}\" \n x=\"0\" y=\"0\" class=\"small\"\n text-anchor=\"middle\" dominant-baseline=\"middle\">\n <tspan x=\"0\" dy=\"0em\">{{ donutSlice.name }}</tspan>\n <tspan x=\"0\" dy=\"1.2em\">{{ donutSlice.perc * 100 | number: '1.0-2' }}%</tspan>\n </text>\n </g>\n </g>\n\n</svg>",
providers: [DonutChartService],
styles: [".donut-slice{transition:.3s ease-in}"]
}] }
];
/** @nocollapse */
DonutChartComponent.ctorParameters = () => [
{ type: DonutChartService },
{ type: GlobalParametersService },
{ type: ElementRef }
];
DonutChartComponent.propDecorators = {
data: [{ type: Input }],
width: [{ type: Input }],
colorScheme: [{ type: Input }],
customColorScheme: [{ type: Input }]
};
if (false) {
/** @type {?} */
DonutChartComponent.prototype.data;
/** @type {?} */
DonutChartComponent.prototype.width;
/** @type {?} */
DonutChartComponent.prototype.colorScheme;
/** @type {?} */
DonutChartComponent.prototype.customColorScheme;
/** @type {?} */
DonutChartComponent.prototype.componentID;
/** @type {?} */
DonutChartComponent.prototype.xPadding;
/** @type {?} */
DonutChartComponent.prototype.yPadding;
/** @type {?} */
DonutChartComponent.prototype.height;
/** @type {?} */
DonutChartComponent.prototype.donutWidthPerc;
/** @type {?} */
DonutChartComponent.prototype.donutSlices;
/** @type {?} */
DonutChartComponent.prototype.donutRadius;
/** @type {?} */
DonutChartComponent.prototype.donutInnerRadius;
/** @type {?} */
DonutChartComponent.prototype.hoverDonutRadius;
/** @type {?} */
DonutChartComponent.prototype.hoverDonutInnerRadius;
/** @type {?} */
DonutChartComponent.prototype.cX;
/** @type {?} */
DonutChartComponent.prototype.cY;
/** @type {?} */
DonutChartComponent.prototype.gTranslate;
/** @type {?} */
DonutChartComponent.prototype.hoverTranslate;
/** @type {?} */
DonutChartComponent.prototype.hoverShift;
/** @type {?} */
DonutChartComponent.prototype.donutSlicesInit;
/** @type {?} */
DonutChartComponent.prototype.donutChartService;
/**
* @type {?}
* @private
*/
DonutChartComponent.prototype.globalParametersService;
/**
* @type {?}
* @private
*/
DonutChartComponent.prototype.currentElement;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9udXQtY2hhcnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LWJlYXV0aWZ1bC1jaGFydHMvIiwic291cmNlcyI6WyJsaWIvZG9udXQtY2hhcnQvZG9udXQtY2hhcnQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFxQixLQUFLLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUNqRixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQVExRCxNQUFNLE9BQU8sbUJBQW1COzs7Ozs7SUF3QjlCLFlBQW1CLGlCQUFvQyxFQUNuQyx1QkFBZ0QsRUFDaEQsY0FBMEI7UUFGM0Isc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFtQjtRQUNuQyw0QkFBdUIsR0FBdkIsdUJBQXVCLENBQXlCO1FBQ2hELG1CQUFjLEdBQWQsY0FBYyxDQUFZO1FBdEJyQyxnQkFBVyxHQUFHLFVBQVUsQ0FBQztRQUN6QixzQkFBaUIsR0FBYSxFQUFFLENBQUM7UUFHMUMsYUFBUSxHQUFHLEVBQUUsQ0FBQztRQUNkLGFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQztRQUU3QixtQkFBYyxHQUFHLEdBQUcsQ0FBQztRQVdyQixvQkFBZSxHQUFHLENBQUMsQ0FBQztJQUtwQixDQUFDOzs7OztJQUVELG1CQUFtQixDQUFDLGVBQWU7UUFDakMsSUFBSSxJQUFJLENBQUMsZUFBZSxLQUFLLENBQUM7WUFBRSxJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsQ0FBQzs7WUFFbEQsR0FBRyxHQUFHLENBQUM7UUFDWCxLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUU7WUFDM0IsR0FBRyxHQUFH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QUFHLE1BQU0sR0FBRyxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQztJQUM3RixDQUFDOzs7WUEzTUYsU0FBUyxTQUFDO2dCQUNULFFBQVEsRUFBRSxpQkFBaUI7Z0JBQzNCLG04QkFBMkM7Z0JBRTNDLFNBQVMsRUFBRSxDQUFDLGlCQUFpQixDQUFDOzthQUMvQjs7OztZQVBRLGlCQUFpQjtZQURqQix1QkFBdUI7WUFGYyxVQUFVOzs7bUJBYXJELEtBQUs7b0JBQ0wsS0FBSzswQkFDTCxLQUFLO2dDQUNMLEtBQUs7Ozs7SUFITixtQ0FBK0Q7O0lBQy9ELG9DQUF1Qjs7SUFDdkIsMENBQWtDOztJQUNsQyxnREFBMEM7O0lBRTFDLDBDQUFZOztJQUNaLHVDQUFjOztJQUNkLHVDQUE2Qjs7SUFDN0IscUNBQWU7O0lBQ2YsNkNBQXFCOztJQUNyQiwwQ0FBaUI7O0lBQ2pCLDBDQUFvQjs7SUFDcEIsK0NBQXlCOztJQUN6QiwrQ0FBeUI7O0lBQ3pCLG9EQUE4Qjs7SUFDOUIsaUNBQVc7O0lBQ1gsaUNBQVc7O0lBQ1gseUNBQW1COztJQUNuQiw2Q0FBdUI7O0lBQ3ZCLHlDQUFtQjs7SUFDbkIsOENBQW9COztJQUVSLGdEQUEyQzs7Ozs7SUFDM0Msc0RBQXdEOzs7OztJQUN4RCw2Q0FBa0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgT25DaGFuZ2VzLCBJbnB1dCwgRWxlbWVudFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgY29sb3JTY2hlbWVzIH0gZnJvbSAnLi4vLi4vY29uc3RhbnRzL2NvbG9yLXNjaGVtZXMnO1xuaW1wb3J0IHsgR2xvYmFsUGFyYW1ldGVyc1NlcnZpY2UgfSBmcm9tICcuLi8uLi9nbG9iYWwvZ2xvYmFsLXBhcmFtZXRlcnMuc2VydmljZSc7XG5pbXBvcnQgeyBEb251dENoYXJ0U2VydmljZSB9IGZyb20gJy4vZG9udXQtY2hhcnQuc2VydmljZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1kb251dC1jaGFydCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9kb251dC1jaGFydC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2RvbnV0LWNoYXJ0LmNvbXBvbmVudC5zY3NzJ10sXG4gIHByb3ZpZGVyczogW0RvbnV0Q2hhcnRTZXJ2aWNlXVxufSlcbmV4cG9ydCBjbGFzcyBEb251dENoYXJ0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuXG4gIEBJbnB1dCgpIGRhdGE6IFt7bmFtZTogc3RyaW5nLCBjb2xvcjogc3RyaW5nLCB2YWx1ZTogbnVtYmVyIH1dO1xuICBASW5wdXQoKSB3aWR0aDogbnVtYmVyO1xuICBASW5wdXQoKSBjb2xvclNjaGVtZSA9ICdjb2xvcmZ1bCc7XG4gIEBJbnB1dCgpIGN1c3RvbUNvbG9yU2NoZW1lOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGNvbXBvbmVudElEO1xuICB4UGFkZGluZyA9IDYwO1xuICB5UGFkZGluZyA9IHRoaXMueFBhZGRpbmcgLyAyO1xuICBoZWlnaHQ6IG51bWJlcjtcbiAgZG9udXRXaWR0aFBlcmMgPSAwLjQ7XG4gIGRvbnV0U2xpY2VzOiBhbnk7XG4gIGRvbnV0UmFkaXVzOiBudW1iZXI7XG4gIGRvbnV0SW5uZXJSYWRpdXM6IG51bWJlcjtcbiAgaG92ZXJEb251dFJhZGl1czogbnVtYmVyO1xuICBob3ZlckRvbnV0SW5uZXJSYWRpdXM6IG51bWJlcjtcbiAgY1g6IG51bWJlcjtcbiAgY1k6IG51bWJlcjtcbiAgZ1RyYW5zbGF0ZTogc3RyaW5nO1xuICBob3ZlclRyYW5zbGF0ZTogc3RyaW5nO1xuICBob3ZlclNoaWZ0OiBudW1iZXI7XG4gIGRvbnV0U2xpY2VzSW5pdCA9IDA7XG5cbiAgY29uc3RydWN0b3IocHVibGljIGRvbnV0Q2hhcnRTZXJ2aWNlOiBEb251dENoYXJ0U2VydmljZSxcbiAgICAgICAgICAgICAgcHJpdmF0ZSBnbG9iYWxQYXJhbWV0ZXJzU2VydmljZTogR2xvYmFsUGFyYW1ldGVyc1NlcnZpY2UsXG4gICAgICAgICAgICAgIHByaXZhdGUgY3VycmVudEVsZW1lbnQ6IEVsZW1lbnRSZWYpIHtcbiAgfVxuXG4gIGdlbmVyYXRlRG9udXRTbGljZXMoZG9udXRDb21wbGV0aW9uKSB7XG4gICAgaWYgKHRoaXMuZG9udXRTbGljZXNJbml0ID09PSAwKSB0aGlzLmRvbnV0U2xpY2VzID0gW107XG5cbiAgICBsZXQgc3VtID0gMDtcbiAgICBmb3IgKGNvbnN0IHZhbCBvZiB0aGlzLmRhdGEpIHtcbiAgICAgIHN1bSA9IHN1bSArIHZhbC52YWx1ZTtcbiAgICB9XG4gICAgbGV0IHJvdGF0aW9uID0gMDtcblxuICAgIGxldCBjbnQgPSAwO1xuXG4gICAgZm9yIChjb25zdCB2YWwgb2YgdGhpcy5kYXRhKSB7XG5cbiAgICAgIC8vIGNvbnNvbGUubG9nKHZhbCk7XG4gICAgICBjb25zdCBwZXJjID0gdmFsLnZhbHVlIC8gc3VtICogZG9udXRDb21wbGV0aW9uO1xuICAgICAgY29uc3QgYW5nbGUgPSAzNjAgKiBwZXJjO1xuICAgICAgY29uc3QgYW5nbGVSYWQgPSBhbmdsZSAqIE1hdGguUEkgLyAxODA7XG4gICAgICBjb25zdCBsYXJnZUFyYyA9IChhbmdsZSA+IDE4MCkgPyAxIDogMDtcblxuICAgICAgY29uc3QgcGF0aCA9ICdNIDAgJyArIC10aGlzLmRvbnV0SW5uZXJSYWRpdXMgKyAnIDAgJyArIC10aGlzLmRvbnV0UmFkaXVzXG4gICAgICArICcgQSAnICsgdGhpcy5kb251dFJhZGl1cyArICcgJyArIHRoaXMuZG9udXRSYWRpdXNcbiAgICAgICsgJyAwICcgKyBsYXJnZUFyYyArICcgMScgKyB0aGlzLmRvbnV0UmFkaXVzICogTWF0aC5zaW4oYW5nbGVSYWQpICsgJyAnXG4gICAgICArIC10aGlzLmRvbnV0UmFkaXVzICogTWF0aC5jb3MoYW5nbGVSYWQpXG4gICAgICArICcgTCAnICsgdGhpcy5kb251dElubmVyUmFkaXVzICogTWF0aC5zaW4oYW5nbGVSYWQpICsgJyAnXG4gICAgICArIC10aGlzLmRvbnV0SW5uZXJSYWRpdXMgKiBNYXRoLmNvcyhhbmdsZVJhZCkgKyAnIEEgJ1xuICAgICAgKyB0aGlzLmRvbnV0SW5uZXJSYWRpdXMgKyAnICcgKyB0aGlzLmRvbnV0SW5uZXJSYWRpdXNcbiAgICAgICsgJyAwICcgKyBsYXJnZUFyYyArICcgMCAwICcgKyAtdGhpcy5kb251dElubmVyUmFkaXVzICsgJyB6JztcblxuICAgICAgY29uc3QgaG92ZXJQYXRoID0gJ00gMCAnICsgLXRoaXMuaG92ZXJEb251dElubmVyUmFkaXVzICsgJyAwICcgKyAtdGhpcy5ob3ZlckRvbnV0UmFkaXVzXG4gICAgICArICcgQSAnICsgdGhpcy5ob3ZlckRvbnV0UmFkaXVzICsgJyAnICsgdGhpcy5ob3ZlckRvbnV0UmFkaXVzXG4gICAgICArICcgMCAnICsgbGFyZ2VBcmMgKyAnIDEnICsgdGhpcy5ob3ZlckRvbnV0UmFkaXVzICogTWF0aC5zaW4oYW5nbGVSYWQpICsgJyAnXG4gICAgICArIC10aGlzLmhvdmVyRG9udXRSYWRpdXMgKiBNYXRoLmNvcyhhbmdsZVJhZClcbiAgICAgICsgJyBMICcgKyB0aGlzLmhvdmVyRG9udXRJbm5lclJhZGl1cyAqIE1hdGguc2luKGFuZ2xlUmFkKSArICcgJ1xuICAgICAgKyAtdGhpcy5ob3ZlckRvbnV0SW5uZXJSYWRpdXMgKiBNYXRoLmNvcyhhbmdsZVJhZCkgKyAnIEEgJ1xuICAgICAgKyB0aGlzLmhvdmVyRG9udXRJbm5lclJhZGl1cyArICcgJyArIHRoaXMuaG92ZXJEb251dElubmVyUmFkaXVzXG4gICAgICArICcgMCAnICsgbGFyZ2VBcmMgKyAnIDAgMCAnICsgLXRoaXMuaG92ZXJEb251dElubmVyUmFkaXVzICsgJyB6JztcblxuXG4gICAgICBjb25zdCBkb251dFNsaWNlID0ge1xuICAgICAgICBwZXJjLFxuICAgICAgICBuYW1lOiB2YWwubmFtZSxcbiAgICAgICAgY29sb3I6IHZhbC5jb2xvcixcbiAgICAgICAgaG92ZXJEOiBob3ZlclBhdGgsXG4gICAgICAgIHJvdGF0aW9uOiAncm90YXRlKCcgKyByb3RhdGlvbiArICdkZWcpJyxcbiAgICAgICAgZDogcGF0aCxcbiAgICAgICAgaG92ZXI6IGZhbHNlXG4gICAgICB9O1xuXG4gICAgICAvLyBjb25zb2xlLmxvZyhob3ZlclBhdGgpO1xuICAgICAgLy8gY29uc29sZS5sb2coZG9udXRTbGljZSk7XG4gICAgICBpZiAoIHRoaXMuZG9udXRTbGljZXNJbml0ID09PSAwICkgdGhpcy5kb251dFNsaWNlcy5wdXNoKGRvbnV0U2xpY2UpO1xuICAgICAgZWxzZSB0aGlzLmRvbnV0U2xpY2VzW2NudF0gPSBkb251dFNsaWNlO1xuXG4gICAgICAvLyB0aGlzLmRvbnV0U2xpY2VzLnB1c2goZG9udXRTbGljZSk7XG4gICAgICByb3RhdGlvbiArPSBhbmdsZTtcbiAgICAgIGNudCArKztcbiAgICB9XG4gIH1cblxuICBzZXREaW1lbnNpb25zKCkge1xuICAgIGlmICh0aGlzLndpZHRoKSB0aGlzLmhlaWdodCA9IHRoaXMud2lkdGggKiAuNiAtIHRoaXMueFBhZGRpbmc7XG4gICAgZWxzZSB7XG4gICAgICBjb25zdCBob3N0ID0gdGhpcy5jdXJyZW50RWxlbWVudC5uYXRpdmVFbGVtZW50O1xuICAgICAgaWYgKGhvc3QucGFyZW50Tm9kZSAhPSBudWxsKSB7XG4gICAgICAgIGNvbnN0IGRpbXMgPSBob3N0LnBhcmVudE5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHRoaXMud2lkdGggPSBkaW1zLndpZHRoO1xuICAgICAgICB0aGlzLmhlaWdodCA9IHRoaXMud2lkdGggKiAuNiAtIHRoaXMueFBhZGRpbmc7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIGNvbnNvbGUubG9nKCctLS1zZXQgZGltZW5zaW9ucy0tLScpO1xuICAgIC8vIGNvbnNvbGUubG9nKCd3aWR0aDogJyArIHRoaXMud2lkdGgpO1xuICAgIC8vIGNvbnNvbGUubG9nKCdoZWlnaHQ6ICcgKyB0aGlzLmhlaWdodCk7XG4gICAgLy8gY29uc29sZS5sb2coJy0tLS0tLS0tLS0tLS0tLS0tLS0tJyk7XG4gIH1cblxuICBzZXRDb2xvcnMoKSB7XG4gICAgbGV0IGNudCA9IDA7XG4gICAgZm9yIChjb25zdCBzbGljZSBvZiB0aGlzLmRhdGEpIHtcbiAgICAgIGlmICghc2xpY2UuY29sb3IpIHtcbiAgICAgICAgaWYgKHRoaXMuY3VzdG9tQ29sb3JTY2hlbWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHNsaWNlLmNvbG9yID0gdGhpcy5jdXN0b21Db2xvclNjaGVtZVtjbnQgJSB0aGlzLmN1c3RvbUNvbG9yU2NoZW1lLmxlbmd0aF07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc2xpY2UuY29sb3IgPSBjb2xvclNjaGVtZXNbdGhpcy5jb2xvclNjaGVtZV1bY250ICUgMTBdO1xuICAgICAgICB9XG4gICAgICAgIGNudCsrO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuZGF0YSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5kYXRhKSk7XG4gICAgdGhpcy5jb21wb25lbnRJRCA9IHRoaXMuZ2xvYmFsUGFyYW1ldGVyc1NlcnZpY2UuYWRkTmV3Q29tcG9uZW50KCk7XG4gICAgdGhpcy5zZXREaW1lbnNpb25zKCk7XG4gICAgdGhpcy5kYXRhLnNvcnQoKGEsIGIpID0+IGEudmFsdWUgPiBiLnZhbHVlID8gLTEgOiBhLnZhbHVlIDwgYi52YWx1ZSA/IDEgOiAwKTtcbiAgICB0aGlzLnNldENvbG9ycygpO1xuICAgIHRoaXMuZG9udXRDaGFydFNlcnZpY2Uuc2V0VmFsdWVzKHtcbiAgICAgIGNvbXBvbmVudElEOiB0aGlzLmNvbXBvbmVudElELFxuICAgICAgd2lkdGg6IHRoaXMud2lkdGgsXG4gICAgICBoZWlnaHQ6IHRoaXMuaGVpZ2h0LFxuICAgICAgeFBhZGRpbmc6IHRoaXMueFBhZGRpbmcsXG4gICAgICB5UGFkZGluZzogdGhpcy55UGFkZGluZyxcbiAgICAgIGRhdGE6IHRoaXMuZGF0YVxuICAgIH0pO1xuICAgIC8vIGNvbnNvbGUubG9nKCd4OiAnICsgdGhpcy54KTtcbiAgICB0aGlzLmRvbnV0UmFkaXVzID0gdGhpcy5kb251dENoYXJ0U2VydmljZS5kb251dFJhZGl1cztcbiAgICB0aGlzLmRvbnV0SW5uZXJSYWRpdXMgPSAoMSAtIHRoaXMuZG9udXRXaWR0aFBlcmMpICogdGhpcy5kb251dENoYXJ0U2VydmljZS5kb251dFJhZGl1cztcbiAgICB0aGlzLmhvdmVyRG9udXRSYWRpdXMgPSB0aGlzLmRvbnV0Q2hhcnRTZXJ2aWNlLmRvbnV0UmFkaXVzICogMS4wNTtcbiAgICB0aGlzLmhvdmVyRG9udXRJbm5lclJhZGl1cyA9IHRoaXMuZG9udXRJbm5lclJhZGl1cztcblxuICAgIC8vIHRoaXMuZ2VuZXJhdGVEb251dFNsaWNlcygpO1xuXG4gICAgbGV0IGRvbnV0Q29tcGxldGlvbiA9IDA7XG5cbiAgICBjb25zdCBpbnRlcnZhbElEID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgdGhpcy5nZW5lcmF0ZURvbnV0U2xpY2VzKGRvbnV0Q29tcGxldGlvbik7XG4gICAgICB0aGlzLmRvbnV0U2xpY2VzSW5pdCA9IDE7XG4gICAgICBkb251dENvbXBsZXRpb24gPSBkb251dENvbXBsZXRpb24gKyAwLjAxO1xuICAgICAgZG9udXRDb21wbGV0aW9uID0gTWF0aC5yb3VuZChkb251dENvbXBsZXRpb24gKiAxMDApIC8gMTAwO1xuICAgICAgaWYgKGRvbnV0Q29tcGxldGlvbiA+IDEpIGNsZWFySW50ZXJ2YWwoaW50ZXJ2YWxJRCk7XG4gICAgfSwgNSk7XG5cbiAgICAvLyBjb25zb2xlLmxvZyh0aGlzLmhvdmVyRG9udXRSYWRpdXMpO1xuICAgIHRoaXMuY1ggPSB0aGlzLnhQYWRkaW5nICsgdGhpcy5kb251dFJhZGl1cztcbiAgICB0aGlzLmNZID0gdGhpcy55UGFkZGluZyArIHRoaXMuZG9udXRSYWRpdXM7XG4gICAgY29uc3QgdHJhbnNsYXRlWCA9IHRoaXMueFBhZGRpbmcgKyB0aGlzLmRvbnV0UmFkaXVzO1xuICAgIGNvbnN0IHRyYW5zbGF0ZVkgPSB0aGlzLnlQYWRkaW5nICsgdGhpcy5kb251dFJhZGl1cztcbiAgICB0aGlzLmdUcmFuc2xhdGUgPSAndHJhbnNsYXRlKCcgKyB0cmFuc2xhdGVYICsgJ3B4LCAnICsgdHJhbnNsYXRlWSArICdweCknO1xuICAgIGNvbnN0IGhvdmVyVHJhbnNsYXRlWFkgPSB0aGlzLmRvbnV0UmFkaXVzICogMC4wODtcbiAgICB0aGlzLmhvdmVyVHJhbnNsYXRlID0gJ3RyYW5zbGF0ZSgnICsgaG92ZXJUcmFuc2xhdGVYWSArICdweCwgJyArIC1ob3ZlclRyYW5zbGF0ZVhZICsgJ3B4KSc7XG4gIH1cblxuICBuZ09uQ2hhbmdlcygpIHtcbiAgICB0aGlzLmRhdGEgPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHRoaXMuZGF0YSkpO1xuICAgIHRoaXMuc2V0RGltZW5zaW9ucygpO1xuICAgIHRoaXMuZGF0YS5zb3J0KChhLCBiKSA9PiBhLnZhbHVlID4gYi52YWx1ZSA/IC0xIDogYS52YWx1ZSA8IGIudmFsdWUgPyAxIDogMCk7XG4gICAgdGhpcy5zZXRDb2xvcnMoKTtcbiAgICB0aGlzLmRvbnV0Q2hhcnRTZXJ2aWNlLnNldFZhbHVlcyh7XG4gICAgICBjb21wb25lbnRJRDogdGhpcy5jb21wb25lbnRJRCxcbiAgICAgIHdpZHRoOiB0aGlzLndpZHRoLFxuICAgICAgaGVpZ2h0OiB0aGlzLmhlaWdodCxcbiAgICAgIHhQYWRkaW5nOiB0aGlzLnhQYWRkaW5nLFxuICAgICAgeVBhZGRpbmc6IHRoaXMueVBhZGRpbmcsXG4gICAgICBkYXRhOiB0aGlzLmRhdGFcbiAgICB9KTtcbiAgICAvLyBjb25zb2xlLmxvZygneDogJyArIHRoaXMueCk7XG5cbiAgICB0aGlzLmRvbnV0UmFkaXVzID0gdGhpcy5kb251dENoYXJ0U2VydmljZS5kb251dFJhZGl1cztcbiAgICB0aGlzLmRvbnV0SW5uZXJSYWRpdXMgPSAoMSAtIHRoaXMuZG9udXRXaWR0aFBlcmMpICogdGhpcy5kb251dENoYXJ0U2VydmljZS5kb251dFJhZGl1cztcbiAgICB0aGlzLmhvdmVyRG9udXRSYWRpdXMgPSB0aGlzLmRvbnV0Q2hhcnRTZXJ2aWNlLmRvbnV0UmFkaXVzICogMS4wNTtcbiAgICB0aGlzLmhvdmVyRG9udXRJbm5lclJhZGl1cyA9IHRoaXMuZG9udXRJbm5lclJhZGl1cztcblxuICAgIGxldCBkb251dENvbXBsZXRpb24gPSAwO1xuICAgIGNvbnN0IGludGVydmFsSUQgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XG4gICAgICB0aGlzLmdlbmVyYXRlRG9udXRTbGljZXMoZG9udXRDb21wbGV0aW9uKTtcbiAgICAgIHRoaXMuZG9udXRTbGljZXNJbml0ID0gMTtcbiAgICAgIGRvbnV0Q29tcGxldGlvbiA9IGRvbnV0Q29tcGxldGlvbiArIDAuMDE7XG4gICAgICBkb251dENvbXBsZXRpb24gPSBNYXRoLnJvdW5kKGRvbnV0Q29tcGxldGlvbiAqIDEwMCkgLyAxMDA7XG4gICAgICBpZiAoZG9udXRDb21wbGV0aW9uID4gMSkgY2xlYXJJbnRlcnZhbChpbnRlcnZhbElEKTtcbiAgICB9LCA1KTtcblxuICAgIC8vIGNvbnNvbGUubG9nKHRoaXMuaG92ZXJEb251dFJhZGl1cyk7XG4gICAgdGhpcy5jWCA9IHRoaXMueFBhZGRpbmcgKyB0aGlzLmRvbnV0UmFkaXVzO1xuICAgIHRoaXMuY1kgPSB0aGlzLnlQYWRkaW5nICsgdGhpcy5kb251dFJhZGl1cztcbiAgICBjb25zdCB0cmFuc2xhdGVYID0gdGhpcy54UGFkZGluZyArIHRoaXMuZG9udXRSYWRpdXM7XG4gICAgY29uc3QgdHJhbnNsYXRlWSA9IHRoaXMueVBhZGRpbmcgKyB0aGlzLmRvbnV0UmFkaXVzO1xuICAgIHRoaXMuZ1RyYW5zbGF0ZSA9ICd0cmFuc2xhdGUoJyArIHRyYW5zbGF0ZVggKyAncHgsICcgKyB0cmFuc2xhdGVZICsgJ3B4KSc7XG4gICAgY29uc3QgaG92ZXJUcmFuc2xhdGVYWSA9IHRoaXMuZG9udXRSYWRpdXMgKiAwLjA4O1xuICAgIHRoaXMuaG92ZXJUcmFuc2xhdGUgPSAndHJhbnNsYXRlKCcgKyBob3ZlclRyYW5zbGF0ZVhZICsgJ3B4LCAnICsgLWhvdmVyVHJhbnNsYXRlWFkgKyAncHgpJztcbiAgfVxuXG59XG4iXX0=