ngx-beautiful-charts
Version:
A library to create charts in Angular
354 lines • 34.3 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Component, Input, ElementRef } from '@angular/core';
import { colorSchemes } from '../../constants/color-schemes';
import { TimelineChartService } from './timeline-chart.service';
import { GlobalParametersService } from '../../global/global-parameters.service';
var TimelineChartComponent = /** @class */ (function () {
function TimelineChartComponent(timelineChartService, globalParametersService, currentElement) {
this.timelineChartService = timelineChartService;
this.globalParametersService = globalParametersService;
this.currentElement = currentElement;
this.colorScheme = 'colorful';
this.customColorScheme = [];
this.xPadding = 60;
this.yPadding = this.xPadding / 2;
this.timeData = [];
}
/**
* @return {?}
*/
TimelineChartComponent.prototype.computeBarDimensions = /**
* @return {?}
*/
function () {
this.barWidth = this.timelineChartService.rectHeight * .05;
this.barStartY = this.yPadding + this.timelineChartService.rectHeight / 2 - this.barWidth / 2;
this.barEndY = this.yPadding + this.timelineChartService.rectHeight / 2 + this.barWidth / 2;
};
/**
* @return {?}
*/
TimelineChartComponent.prototype.setColors = /**
* @return {?}
*/
function () {
var e_1, _a;
/** @type {?} */
var cnt = 0;
try {
for (var _b = tslib_1.__values(this.data), _c = _b.next(); !_c.done; _c = _b.next()) {
var oneTimeData = _c.value;
if (!oneTimeData.color) {
if (this.customColorScheme.length > 0) {
oneTimeData.color = this.customColorScheme[cnt % this.customColorScheme.length];
}
else {
oneTimeData.color = colorSchemes[this.colorScheme][cnt % 10];
}
cnt++;
}
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_1) throw e_1.error; }
}
};
/**
* @return {?}
*/
TimelineChartComponent.prototype.setDimensions = /**
* @return {?}
*/
function () {
if (this.width && !this.height)
this.height = this.width / 2;
else if (!this.width && this.height)
this.width = this.height * 2;
else if (!this.width && !this.height) {
/** @type {?} */
var host = this.currentElement.nativeElement;
if (host.parentNode != null) {
/** @type {?} */
var dims = host.parentNode.getBoundingClientRect();
this.width = dims.width;
this.height = dims.width / 2;
}
}
// console.log('---set dimensions---');
// console.log('width: ' + this.width);
// console.log('height: ' + this.height);
// console.log('--------------------');
};
/**
* @param {?} text
* @param {?} width
* @return {?}
*/
TimelineChartComponent.prototype.textWrap = /**
* @param {?} text
* @param {?} width
* @return {?}
*/
function (text, width) {
/** @type {?} */
var noOfCharactersPerLine = width / 10;
/** @type {?} */
var newLineStr = '\n';
/** @type {?} */
var done = false;
/** @type {?} */
var res = [];
do {
/** @type {?} */
var found = false;
for (var i = noOfCharactersPerLine - 1; i >= 0; i--) {
if ((text.charAt(i) === ' ')) {
res.push([text.slice(0, i), newLineStr].join(''));
text = text.slice(i + 1);
found = true;
break;
}
}
if (!found) {
res.push([text.slice(0, noOfCharactersPerLine), newLineStr].join(''));
text = text.slice(noOfCharactersPerLine);
}
if (text.length < noOfCharactersPerLine)
done = true;
} while (!done);
res.push(text);
return res;
};
/**
* @return {?}
*/
TimelineChartComponent.prototype.computeTimeData = /**
* @return {?}
*/
function () {
var e_2, _a;
// const distanceBetweenTimeBubbles = this.width * .8 / (this.data.length - 1);
/** @type {?} */
var minTime = Math.min.apply(Math, tslib_1.__spread(this.data.map((/**
* @param {?} timeData
* @return {?}
*/
function (timeData) { return timeData.time; }))));
/** @type {?} */
var maxTime = Math.max.apply(Math, tslib_1.__spread(this.data.map((/**
* @param {?} timeData
* @return {?}
*/
function (timeData) { return timeData.time; }))));
/** @type {?} */
var perTimeWidth = this.timelineChartService.rectWidth * .8 / (maxTime - minTime);
this.data.sort((/**
* @param {?} a
* @param {?} b
* @return {?}
*/
function (a, b) { return a.time < b.time ? -1 : a.time > b.time ? 1 : 0; }));
/** @type {?} */
var diffs = [];
for (var i = 1; i < this.data.length; i++) {
diffs.push(this.data[i].time - this.data[i - 1].time);
}
/** @type {?} */
var minDiff = Math.min.apply(Math, tslib_1.__spread(diffs));
this.timeBubbleRadius = Math.min(minDiff * perTimeWidth * .4);
/** @type {?} */
var maxRadius = this.timelineChartService.rectWidth * .8 / (this.data.length - 1) * .25;
/** @type {?} */
var minRadius = this.timelineChartService.rectWidth * .8 * .04;
// console.log('max: ' + maxRadius);
// console.log('min: ' + minRadius);
if (this.timeBubbleRadius > maxRadius)
this.timeBubbleRadius = maxRadius;
if (this.timeBubbleRadius < minRadius)
this.timeBubbleRadius = minRadius;
this.textBlockHeight = this.timelineChartService.rectHeight * 2 / 16;
this.timeData = [];
/** @type {?} */
var cnt = 0;
/** @type {?} */
var up = 1;
try {
for (var _b = tslib_1.__values(this.data), _c = _b.next(); !_c.done; _c = _b.next()) {
var oneTimeData = _c.value;
/** @type {?} */
var color = oneTimeData.color;
/** @type {?} */
var x = (oneTimeData.time - minTime) * perTimeWidth;
/** @type {?} */
var timeBubble = {
centre: {
x: x,
y: this.barStartY + this.barWidth / 2
},
text: oneTimeData.displayTime ? oneTimeData.displayTime : oneTimeData.time
// oneTimeData.displayTime ?
// this.textWrap(oneTimeData.displayTime, this.timeBubbleRadius * 2) :
// [oneTimeData.time]
};
/** @type {?} */
var start = {
x: x,
y: (up === 1) ? this.barStartY : this.barEndY
};
/** @type {?} */
var end = {
x: x,
y: (up === 1) ? this.barStartY - this.timelineChartService.rectHeight / 4 : this.barEndY + this.timelineChartService.rectHeight / 4
};
/** @type {?} */
var line = 'M ' + start.x + ' ' + start.y + ' ' + end.x + ' ' + end.y;
/** @type {?} */
var textBlock = {
position: {
x: x,
y: (up === 1) ?
this.barStartY - this.timelineChartService.rectHeight * 7 / 16 :
this.barEndY + this.timelineChartService.rectHeight * 4 / 16
},
text: this.textWrap(oneTimeData.text, this.timeBubbleRadius * 4)
};
this.timeData.push({
timeBubble: timeBubble,
line: line,
textBlock: textBlock,
color: color
});
up = up * -1;
cnt++;
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
}
finally { if (e_2) throw e_2.error; }
}
};
/**
* @return {?}
*/
TimelineChartComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.componentID = this.globalParametersService.addNewComponent();
this.computeBarDimensions();
this.setColors();
this.timelineChartService.setValues({
componentID: this.componentID,
width: this.width,
height: this.height,
xPadding: this.xPadding,
yPadding: this.yPadding
});
/** @type {?} */
var transX = this.xPadding + this.timelineChartService.rectWidth * .1;
this.gTranslate = 'translate(' + transX + 'px, ' + this.yPadding + 'px)';
this.computeBarDimensions();
this.computeTimeData();
};
/**
* @return {?}
*/
TimelineChartComponent.prototype.ngOnChanges = /**
* @return {?}
*/
function () {
this.computeBarDimensions();
this.setColors();
this.timelineChartService.setValues({
componentID: this.componentID,
width: this.width,
height: this.height,
xPadding: this.xPadding,
yPadding: this.yPadding
});
/** @type {?} */
var transX = this.xPadding + this.timelineChartService.rectWidth * .1;
this.gTranslate = 'translate(' + transX + 'px, ' + this.yPadding + 'px)';
this.computeBarDimensions();
this.computeTimeData();
};
TimelineChartComponent.decorators = [
{ type: Component, args: [{
selector: 'ngx-timeline-chart',
template: "<svg [attr.width]=\"width\" [attr.height]=\"height\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n <g [ngStyle]=\"{'transform': gTranslate}\">\n <rect x=\"0\" \n [attr.y]=\"barStartY\" \n [attr.width]=\"timelineChartService.rectWidth * .8\" \n [attr.height]=\"barWidth\" \n fill=\"grey\" />\n\n <g *ngFor=\"let timeDataInst of timeData\">\n <circle class=\"time-bubble\" [attr.cx]=\"timeDataInst.timeBubble.centre.x\" \n [attr.cy]=\"timeDataInst.timeBubble.centre.y\" \n [attr.r]=\"timeBubbleRadius\" [attr.fill]=\"timeDataInst.color\">\n </circle>\n\n <text class=\"time-bubble-text\" [attr.x]=\"timeDataInst.timeBubble.centre.x\"\n [attr.y]=\"timeDataInst.timeBubble.centre.y\"\n text-anchor=\"middle\" dominant-baseline=\"middle\">\n {{ timeDataInst.timeBubble.text }}\n <!-- <tspan *ngFor=\"let line of timeDataInst.timeBubble.text\" \n [attr.x]=\"timeDataInst.timeBubble.centre.x\"\n [attr.dx]=\"0\"\n [attr.dy]=\"14\">\n {{ line }}\n </tspan> -->\n </text>\n \n <path class=\"line-path\"\n [attr.d]=\"timeDataInst.line\" fill=\"none\" [attr.stroke]=\"timeDataInst.color\" />\n\n <text class=\"time-block-text\" [attr.x]=\"timeDataInst.textBlock.position.x\"\n [attr.y]=\"timeDataInst.textBlock.position.y\"\n [attr.height]=\"textBlockHeight\"\n text-anchor=\"middle\" dominant-baseline=\"middle\">\n <tspan *ngFor=\"let line of timeDataInst.textBlock.text\" \n [attr.x]=\"timeDataInst.textBlock.position.x\"\n [attr.dx]=\"0\"\n [attr.dy]=\"14\">\n {{ line }}\n </tspan>\n </text>\n\n </g>\n </g>\n</svg>\n\n",
providers: [TimelineChartService],
styles: [".time-bubble-text{font-size:12px}"]
}] }
];
/** @nocollapse */
TimelineChartComponent.ctorParameters = function () { return [
{ type: TimelineChartService },
{ type: GlobalParametersService },
{ type: ElementRef }
]; };
TimelineChartComponent.propDecorators = {
data: [{ type: Input }],
width: [{ type: Input }],
height: [{ type: Input }],
colorScheme: [{ type: Input }],
customColorScheme: [{ type: Input }]
};
return TimelineChartComponent;
}());
export { TimelineChartComponent };
if (false) {
/** @type {?} */
TimelineChartComponent.prototype.data;
/** @type {?} */
TimelineChartComponent.prototype.width;
/** @type {?} */
TimelineChartComponent.prototype.height;
/** @type {?} */
TimelineChartComponent.prototype.colorScheme;
/** @type {?} */
TimelineChartComponent.prototype.customColorScheme;
/** @type {?} */
TimelineChartComponent.prototype.componentID;
/** @type {?} */
TimelineChartComponent.prototype.xPadding;
/** @type {?} */
TimelineChartComponent.prototype.yPadding;
/** @type {?} */
TimelineChartComponent.prototype.gTranslate;
/** @type {?} */
TimelineChartComponent.prototype.barWidth;
/** @type {?} */
TimelineChartComponent.prototype.barStartY;
/** @type {?} */
TimelineChartComponent.prototype.barEndY;
/** @type {?} */
TimelineChartComponent.prototype.timeBubbleRadius;
/** @type {?} */
TimelineChartComponent.prototype.textBlockHeight;
/** @type {?} */
TimelineChartComponent.prototype.timeData;
/** @type {?} */
TimelineChartComponent.prototype.timelineChartService;
/**
* @type {?}
* @private
*/
TimelineChartComponent.prototype.globalParametersService;
/**
* @type {?}
* @private
*/
TimelineChartComponent.prototype.currentElement;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZWxpbmUtY2hhcnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LWJlYXV0aWZ1bC1jaGFydHMvIiwic291cmNlcyI6WyJsaWIvdGltZWxpbmUtY2hhcnQvdGltZWxpbmUtY2hhcnQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxLQUFLLEVBQWEsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUVqRjtJQWdLRSxnQ0FBbUIsb0JBQTBDLEVBQ3pDLHVCQUFnRCxFQUNoRCxjQUEwQjtRQUYzQix5QkFBb0IsR0FBcEIsb0JBQW9CLENBQXNCO1FBQ3pDLDRCQUF1QixHQUF2Qix1QkFBdUIsQ0FBeUI7UUFDaEQsbUJBQWMsR0FBZCxjQUFjLENBQVk7UUF2SnJDLGdCQUFXLEdBQUcsVUFBVSxDQUFDO1FBQ3pCLHNCQUFpQixHQUFhLEVBQUUsQ0FBQztRQUkxQyxhQUFRLEdBQUcsRUFBRSxDQUFDO1FBQ2QsYUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO1FBUzdCLGFBQVEsR0FBRyxFQUFFLENBQUM7SUF5SWQsQ0FBQzs7OztJQXJJRCxxREFBb0I7OztJQUFwQjtRQUNFLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFVBQVUsR0FBRyxHQUFHLENBQUM7UUFDM0QsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO1FBQzlGLElBQUks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REFBOEM7b0JBRTlDLFNBQVMsRUFBRSxDQUFDLG9CQUFvQixDQUFDOztpQkFDbEM7Ozs7Z0JBUlEsb0JBQW9CO2dCQUNwQix1QkFBdUI7Z0JBSGMsVUFBVTs7O3VCQWFyRCxLQUFLO3dCQUNMLEtBQUs7eUJBQ0wsS0FBSzs4QkFDTCxLQUFLO29DQUNMLEtBQUs7O0lBeUxSLDZCQUFDO0NBQUEsQUFyTUQsSUFxTUM7U0EvTFksc0JBQXNCOzs7SUFFakMsc0NBQW1COztJQUNuQix1Q0FBdUI7O0lBQ3ZCLHdDQUF3Qjs7SUFDeEIsNkNBQWtDOztJQUNsQyxtREFBMEM7O0lBRzFDLDZDQUFZOztJQUNaLDBDQUFjOztJQUNkLDBDQUE2Qjs7SUFDN0IsNENBQW1COztJQUVuQiwwQ0FBaUI7O0lBQ2pCLDJDQUFrQjs7SUFDbEIseUNBQWdCOztJQUVoQixrREFBeUI7O0lBQ3pCLGlEQUF3Qjs7SUFDeEIsMENBQWM7O0lBc0lGLHNEQUFpRDs7Ozs7SUFDakQseURBQXdEOzs7OztJQUN4RCxnREFBa0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQsIE9uQ2hhbmdlcywgRWxlbWVudFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgY29sb3JTY2hlbWVzIH0gZnJvbSAnLi4vLi4vY29uc3RhbnRzL2NvbG9yLXNjaGVtZXMnO1xuaW1wb3J0IHsgVGltZWxpbmVDaGFydFNlcnZpY2UgfSBmcm9tICcuL3RpbWVsaW5lLWNoYXJ0LnNlcnZpY2UnO1xuaW1wb3J0IHsgR2xvYmFsUGFyYW1ldGVyc1NlcnZpY2UgfSBmcm9tICcuLi8uLi9nbG9iYWwvZ2xvYmFsLXBhcmFtZXRlcnMuc2VydmljZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC10aW1lbGluZS1jaGFydCcsXG4gIHRlbXBsYXRlVXJsOiAnLi90aW1lbGluZS1jaGFydC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3RpbWVsaW5lLWNoYXJ0LmNvbXBvbmVudC5zY3NzJ10sXG4gIHByb3ZpZGVyczogW1RpbWVsaW5lQ2hhcnRTZXJ2aWNlXVxufSlcbmV4cG9ydCBjbGFzcyBUaW1lbGluZUNoYXJ0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuXG4gIEBJbnB1dCgpIGRhdGE6IGFueTtcbiAgQElucHV0KCkgd2lkdGg6IG51bWJlcjtcbiAgQElucHV0KCkgaGVpZ2h0OiBudW1iZXI7XG4gIEBJbnB1dCgpIGNvbG9yU2NoZW1lID0gJ2NvbG9yZnVsJztcbiAgQElucHV0KCkgY3VzdG9tQ29sb3JTY2hlbWU6IHN0cmluZ1tdID0gW107XG5cblxuICBjb21wb25lbnRJRDtcbiAgeFBhZGRpbmcgPSA2MDtcbiAgeVBhZGRpbmcgPSB0aGlzLnhQYWRkaW5nIC8gMjtcbiAgZ1RyYW5zbGF0ZTogc3RyaW5nO1xuXG4gIGJhcldpZHRoOiBudW1iZXI7XG4gIGJhclN0YXJ0WTogbnVtYmVyO1xuICBiYXJFbmRZOiBudW1iZXI7XG5cbiAgdGltZUJ1YmJsZVJhZGl1czogbnVtYmVyO1xuICB0ZXh0QmxvY2tIZWlnaHQ6IG51bWJlcjtcbiAgdGltZURhdGEgPSBbXTtcblxuXG5cbiAgY29tcHV0ZUJhckRpbWVuc2lvbnMoKSB7XG4gICAgdGhpcy5iYXJXaWR0aCA9IHRoaXMudGltZWxpbmVDaGFydFNlcnZpY2UucmVjdEhlaWdodCAqIC4wNTtcbiAgICB0aGlzLmJhclN0YXJ0WSA9IHRoaXMueVBhZGRpbmcgKyB0aGlzLnRpbWVsaW5lQ2hhcnRTZXJ2aWNlLnJlY3RIZWlnaHQgLyAyIC0gdGhpcy5iYXJXaWR0aCAvIDI7XG4gICAgdGhpcy5iYXJFbmRZID0gdGhpcy55UGFkZGluZyArIHRoaXMudGltZWxpbmVDaGFydFNlcnZpY2UucmVjdEhlaWdodCAvIDIgKyB0aGlzLmJhcldpZHRoIC8gMjtcbiAgfVxuXG4gIHNldENvbG9ycygpIHtcbiAgICBsZXQgY250ID0gMDtcbiAgICBmb3IgKGNvbnN0IG9uZVRpbWVEYXRhIG9mIHRoaXMuZGF0YSkge1xuICAgICAgaWYgKCFvbmVUaW1lRGF0YS5jb2xvcikge1xuICAgICAgICBpZiAodGhpcy5jdXN0b21Db2xvclNjaGVtZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgb25lVGltZURhdGEuY29sb3IgPSB0aGlzLmN1c3RvbUNvbG9yU2NoZW1lW2NudCAlIHRoaXMuY3VzdG9tQ29sb3JTY2hlbWUubGVuZ3RoXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvbmVUaW1lRGF0YS5jb2xvciA9IGNvbG9yU2NoZW1lc1t0aGlzLmNvbG9yU2NoZW1lXVtjbnQgJSAxMF07XG4gICAgICAgIH1cbiAgICAgICAgY250Kys7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc2V0RGltZW5zaW9ucygpIHtcbiAgICBpZiAodGhpcy53aWR0aCAmJiAhdGhpcy5oZWlnaHQpIHRoaXMuaGVpZ2h0ID0gdGhpcy53aWR0aCAvIDI7XG4gICAgZWxzZSBpZiAoIXRoaXMud2lkdGggJiYgdGhpcy5oZWlnaHQpIHRoaXMud2lkdGggPSB0aGlzLmhlaWdodCAqIDI7XG4gICAgZWxzZSBpZiAoIXRoaXMud2lkdGggJiYgIXRoaXMuaGVpZ2h0KSB7XG4gICAgICBjb25zdCBob3N0ID0gdGhpcy5jdXJyZW50RWxlbWVudC5uYXRpdmVFbGVtZW50O1xuICAgICAgaWYgKGhvc3QucGFyZW50Tm9kZSAhPSBudWxsKSB7XG4gICAgICAgIGNvbnN0IGRpbXMgPSBob3N0LnBhcmVudE5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHRoaXMud2lkdGggPSBkaW1zLndpZHRoO1xuICAgICAgICB0aGlzLmhlaWdodCA9IGRpbXMud2lkdGggLyAyO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBjb25zb2xlLmxvZygnLS0tc2V0IGRpbWVuc2lvbnMtLS0nKTtcbiAgICAvLyBjb25zb2xlLmxvZygnd2lkdGg6ICcgKyB0aGlzLndpZHRoKTtcbiAgICAvLyBjb25zb2xlLmxvZygnaGVpZ2h0OiAnICsgdGhpcy5oZWlnaHQpO1xuICAgIC8vIGNvbnNvbGUubG9nKCctLS0tLS0tLS0tLS0tLS0tLS0tLScpO1xuICB9XG5cbiAgdGV4dFdyYXAodGV4dCwgd2lkdGgpIHtcbiAgICBjb25zdCBub09mQ2hhcmFjdGVyc1BlckxpbmUgPSB3aWR0aCAvIDEwO1xuICAgIGNvbnN0IG5ld0xpbmVTdHIgPSAnXFxuJztcbiAgICBsZXQgZG9uZSA9IGZhbHNlO1xuICAgIGNvbnN0IHJlcyA9IFtdO1xuICAgIGRvIHtcbiAgICAgIGxldCBmb3VuZCA9IGZhbHNlO1xuICAgICAgZm9yIChsZXQgaSA9IG5vT2ZDaGFyYWN0ZXJzUGVyTGluZSAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgaWYgKCh0ZXh0LmNoYXJBdChpKSAgPT09ICcgJykpIHtcbiAgICAgICAgICAgICAgcmVzLnB1c2goW3RleHQuc2xpY2UoMCwgaSksIG5ld0xpbmVTdHJdLmpvaW4oJycpKTtcbiAgICAgICAgICAgICAgdGV4dCA9IHRleHQuc2xpY2UoaSArIDEpO1xuICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghZm91bmQpIHtcbiAgICAgICAgICByZXMucHVzaChbdGV4dC5zbGljZSgwLCBub09mQ2hhcmFjdGVyc1BlckxpbmUpLCBuZXdMaW5lU3RyXS5qb2luKCcnKSk7XG4gICAgICAgICAgdGV4dCA9IHRleHQuc2xpY2Uobm9PZkNoYXJhY3RlcnNQZXJMaW5lKTtcbiAgICAgIH1cbiAgICAgIGlmICh0ZXh0Lmxlbmd0aCA8IG5vT2ZDaGFyYWN0ZXJzUGVyTGluZSkgZG9uZSA9IHRydWU7XG4gICAgfSB3aGlsZSAoIWRvbmUpO1xuICAgIHJlcy5wdXNoKHRleHQpO1xuICAgIHJldHVybiByZXM7XG4gIH1cblxuICBjb21wdXRlVGltZURhdGEoKSB7XG4gICAgLy8gY29uc3QgZGlzdGFuY2VCZXR3ZWVuVGltZUJ1YmJsZXMgPSB0aGlzLndpZHRoICogLjggLyAodGhpcy5kYXRhLmxlbmd0aCAtIDEpO1xuICAgIGNvbnN0IG1pblRpbWUgPSBNYXRoLm1pbiguLi50aGlzLmRhdGEubWFwKHRpbWVEYXRhID0+IHRpbWVEYXRhLnRpbWUpKTtcbiAgICBjb25zdCBtYXhUaW1lID0gTWF0aC5tYXgoLi4udGhpcy5kYXRhLm1hcCh0aW1lRGF0YSA9PiB0aW1lRGF0YS50aW1lKSk7XG4gICAgY29uc3QgcGVyVGltZVdpZHRoID0gdGhpcy50aW1lbGluZUNoYXJ0U2VydmljZS5yZWN0V2lkdGggKiAuOCAvIChtYXhUaW1lIC0gbWluVGltZSk7XG4gICAgdGhpcy5kYXRhLnNvcnQoKGEsIGIpID0+IGEudGltZSA8IGIudGltZSA/IC0xIDogYS50aW1lID4gYi50aW1lID8gMSA6IDApO1xuICAgIGNvbnN0IGRpZmZzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCB0aGlzLmRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGRpZmZzLnB1c2godGhpcy5kYXRhW2ldLnRpbWUgLSB0aGlzLmRhdGFbaSAtIDFdLnRpbWUpO1xuICAgIH1cbiAgICBjb25zdCBtaW5EaWZmID0gTWF0aC5taW4oLi4uZGlmZnMpO1xuICAgIHRoaXMudGltZUJ1YmJsZVJhZGl1cyA9IE1hdGgubWluKG1pbkRpZmYgKiBwZXJUaW1lV2lkdGggKiAuNCk7XG4gICAgY29uc3QgbWF4UmFkaXVzID0gdGhpcy50aW1lbGluZUNoYXJ0U2VydmljZS5yZWN0V2lkdGggKiAuOCAvICh0aGlzLmRhdGEubGVuZ3RoIC0gMSkgKiAuMjU7XG4gICAgY29uc3QgbWluUmFkaXVzID0gdGhpcy50aW1lbGluZUNoYXJ0U2VydmljZS5yZWN0V2lkdGggKiAuOCAqIC4wNDtcblxuICAgIC8vIGNvbnNvbGUubG9nKCdtYXg6ICcgKyBtYXhSYWRpdXMpO1xuICAgIC8vIGNvbnNvbGUubG9nKCdtaW46ICcgKyBtaW5SYWRpdXMpO1xuXG5cbiAgICBpZiAodGhpcy50aW1lQnViYmxlUmFkaXVzID4gbWF4UmFkaXVzKSB0aGlzLnRpbWVCdWJibGVSYWRpdXMgPSBtYXhSYWRpdXM7XG4gICAgaWYgKHRoaXMudGltZUJ1YmJsZVJhZGl1cyA8IG1pblJhZGl1cykgdGhpcy50aW1lQnViYmxlUmFkaXVzID0gbWluUmFkaXVzO1xuICAgIHRoaXMudGV4dEJsb2NrSGVpZ2h0ID0gdGhpcy50aW1lbGluZUNoYXJ0U2VydmljZS5yZWN0SGVpZ2h0ICogMiAvIDE2O1xuICAgIHRoaXMudGltZURhdGEgPSBbXTtcbiAgICBsZXQgY250ID0gMDtcbiAgICBsZXQgdXAgPSAxO1xuICAgIGZvciAoY29uc3Qgb25lVGltZURhdGEgb2YgdGhpcy5kYXRhKSB7XG4gICAgICBjb25zdCBjb2xvciA9IG9uZVRpbWVEYXRhLmNvbG9yO1xuICAgICAgY29uc3QgeCA9IChvbmVUaW1lRGF0YS50aW1lIC0gbWluVGltZSkgKiBwZXJUaW1lV2lkdGg7XG4gICAgICBjb25zdCB0aW1lQnViYmxlID0ge1xuICAgICAgICBjZW50cmU6IHtcbiAgICAgICAgICB4LFxuICAgICAgICAgIHk6IHRoaXMuYmFyU3RhcnRZICsgdGhpcy5iYXJXaWR0aCAvIDJcbiAgICAgICAgfSxcbiAgICAgICAgdGV4dDogb25lVGltZURhdGEuZGlzcGxheVRpbWUgPyBvbmVUaW1lRGF0YS5kaXNwbGF5VGltZSA6IG9uZVRpbWVEYXRhLnRpbWVcbiAgICAgICAgLy8gb25lVGltZURhdGEuZGlzcGxheVRpbWUgP1xuICAgICAgICAvLyB0aGlzLnRleHRXcmFwKG9uZVRpbWVEYXRhLmRpc3BsYXlUaW1lLCB0aGlzLnRpbWVCdWJibGVSYWRpdXMgKiAyKSA6XG4gICAgICAgIC8vIFtvbmVUaW1lRGF0YS50aW1lXVxuICAgICAgfTtcbiAgICAgIGNvbnN0IHN0YXJ0ID0ge1xuICAgICAgICB4LFxuICAgICAgICB5OiAodXAgPT09IDEpID8gdGhpcy5iYXJTdGFydFkgOiB0aGlzLmJhckVuZFlcbiAgICAgIH07XG4gICAgICBjb25zdCBlbmQgPSB7XG4gICAgICAgIHgsXG4gICAgICAgIHk6ICh1cCA9PT0gMSkgPyB0aGlzLmJhclN0YXJ0WSAtIHRoaXMudGltZWxpbmVDaGFydFNlcnZpY2UucmVjdEhlaWdodCAvIDQgOiB0aGlzLmJhckVuZFkgKyB0aGlzLnRpbWVsaW5lQ2hhcnRTZXJ2aWNlLnJlY3RIZWlnaHQgLyA0XG4gICAgICB9O1xuICAgICAgY29uc3QgbGluZSA9ICdNICcgKyBzdGFydC54ICsgJyAnICsgc3RhcnQueSArICcgJyArIGVuZC54ICsgJyAnICsgZW5kLnk7XG5cbiAgICAgIGNvbnN0IHRleHRCbG9jayA9IHtcbiAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICB4LFxuICAgICAgICAgIHk6ICh1cCA9PT0gMSkgP1xuICAgICAgICAgIHRoaXMuYmFyU3RhcnRZIC0gdGhpcy50aW1lbGluZUNoYXJ0U2VydmljZS5yZWN0SGVpZ2h0ICogNyAvIDE2IDpcbiAgICAgICAgICB0aGlzLmJhckVuZFkgKyB0aGlzLnRpbWVsaW5lQ2hhcnRTZXJ2aWNlLnJlY3RIZWlnaHQgKiA0IC8gMTZcbiAgICAgICAgfSxcbiAgICAgICAgdGV4dDogdGhpcy50ZXh0V3JhcChvbmVUaW1lRGF0YS50ZXh0LCB0aGlzLnRpbWVCdWJibGVSYWRpdXMgKiA0KVxuICAgICAgfTtcbiAgICAgIHRoaXMudGltZURhdGEucHVzaCh7XG4gICAgICAgIHRpbWVCdWJibGUsXG4gICAgICAgIGxpbmUsXG4gICAgICAgIHRleHRCbG9jayxcbiAgICAgICAgY29sb3JcbiAgICAgIH0pO1xuICAgICAgdXAgPSB1cCAqIC0xO1xuICAgICAgY250Kys7XG4gICAgfVxuICB9XG5cbiAgY29uc3RydWN0b3IocHVibGljIHRpbWVsaW5lQ2hhcnRTZXJ2aWNlOiBUaW1lbGluZUNoYXJ0U2VydmljZSxcbiAgICAgICAgICAgICAgcHJpdmF0ZSBnbG9iYWxQYXJhbWV0ZXJzU2VydmljZTogR2xvYmFsUGFyYW1ldGVyc1NlcnZpY2UsXG4gICAgICAgICAgICAgIHByaXZhdGUgY3VycmVudEVsZW1lbnQ6IEVsZW1lbnRSZWYpIHtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuY29tcG9uZW50SUQgPSB0aGlzLmdsb2JhbFBhcmFtZXRlcnNTZXJ2aWNlLmFkZE5ld0NvbXBvbmVudCgpO1xuICAgIHRoaXMuY29tcHV0ZUJhckRpbWVuc2lvbnMoKTtcbiAgICB0aGlzLnNldENvbG9ycygpO1xuICAgIHRoaXMudGltZWxpbmVDaGFydFNlcnZpY2Uuc2V0VmFsdWVzKHtcbiAgICAgIGNvbXBvbmVudElEOiB0aGlzLmNvbXBvbmVudElELFxuICAgICAgd2lkdGg6IHRoaXMud2lkdGgsXG4gICAgICBoZWlnaHQ6IHRoaXMuaGVpZ2h0LFxuICAgICAgeFBhZGRpbmc6IHRoaXMueFBhZGRpbmcsXG4gICAgICB5UGFkZGluZzogdGhpcy55UGFkZGluZ1xuICAgIH0pO1xuICAgIGNvbnN0IHRyYW5zWCA9IHRoaXMueFBhZGRpbmcgKyB0aGlzLnRpbWVsaW5lQ2hhcnRTZXJ2aWNlLnJlY3RXaWR0aCAqIC4xO1xuICAgIHRoaXMuZ1RyYW5zbGF0ZSA9ICd0cmFuc2xhdGUoJyArIHRyYW5zWCArICdweCwgJyArIHRoaXMueVBhZGRpbmcgKyAncHgpJztcbiAgICB0aGlzLmNvbXB1dGVCYXJEaW1lbnNpb25zKCk7XG4gICAgdGhpcy5jb21wdXRlVGltZURhdGEoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCkge1xuICAgIHRoaXMuY29tcHV0ZUJhckRpbWVuc2lvbnMoKTtcbiAgICB0aGlzLnNldENvbG9ycygpO1xuICAgIHRoaXMudGltZWxpbmVDaGFydFNlcnZpY2Uuc2V0VmFsdWVzKHtcbiAgICAgIGNvbXBvbmVudElEOiB0aGlzLmNvbXBvbmVudElELFxuICAgICAgd2lkdGg6IHRoaXMud2lkdGgsXG4gICAgICBoZWlnaHQ6IHRoaXMuaGVpZ2h0LFxuICAgICAgeFBhZGRpbmc6IHRoaXMueFBhZGRpbmcsXG4gICAgICB5UGFkZGluZzogdGhpcy55UGFkZGluZ1xuICAgIH0pO1xuICAgIGNvbnN0IHRyYW5zWCA9IHRoaXMueFBhZGRpbmcgKyB0aGlzLnRpbWVsaW5lQ2hhcnRTZXJ2aWNlLnJlY3RXaWR0aCAqIC4xO1xuICAgIHRoaXMuZ1RyYW5zbGF0ZSA9ICd0cmFuc2xhdGUoJyArIHRyYW5zWCArICdweCwgJyArIHRoaXMueVBhZGRpbmcgKyAncHgpJztcbiAgICB0aGlzLmNvbXB1dGVCYXJEaW1lbnNpb25zKCk7XG4gICAgdGhpcy5jb21wdXRlVGltZURhdGEoKTtcbiAgfVxufVxuIl19