@flxng/circle-timer
Version:
Circle Timer (countdown) component for Angular.
300 lines • 24.3 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/circle-timer.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, EventEmitter, Input, NgZone, Output } from '@angular/core';
import { Subject, timer } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
var CircleTimerComponent = /** @class */ (function () {
function CircleTimerComponent(ngZone) {
this.ngZone = ngZone;
// only to set initial state (ngOnInit)
this.duration = 0; // milliseconds
// milliseconds
this.color = '#1cbbf8';
this.onComplete = new EventEmitter();
this.destroy$ = new Subject();
this.startTime = 0;
this.timeLeft = 0;
this.ticking = false;
this.completed = false;
this.formattedTimeLeft = '';
this.fullDasharray = 283;
this.dasharray = this.fullDasharray + " " + this.fullDasharray;
}
/**
* @return {?}
*/
CircleTimerComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
this.init(this.startDate);
};
/**
* @return {?}
*/
CircleTimerComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.destroy$.next();
this.destroy$.complete();
};
/**
* @param {?=} startDate
* @return {?}
*/
CircleTimerComponent.prototype.init = /**
* @param {?=} startDate
* @return {?}
*/
function (startDate) {
this.setTimeLeft(startDate);
this.formatTimeLeft();
this.setDasharray();
if (this.timeLeft === 0) {
this.completed = true;
}
};
/**
* @param {?=} startDate
* @return {?}
*/
CircleTimerComponent.prototype.setTimeLeft = /**
* @param {?=} startDate
* @return {?}
*/
function (startDate) {
this.ticking = false;
this.completed = false;
this.destroy$.next();
if (!startDate) {
this.timeLeft = this.duration;
return 0;
}
/** @type {?} */
var startTime = new Date((/** @type {?} */ (startDate))).getTime();
/** @type {?} */
var endTime = startTime + this.duration;
/** @type {?} */
var timeLeftRaw = endTime - Date.now();
if (timeLeftRaw <= 0) {
this.timeLeft = 0;
return 0;
}
/** @type {?} */
var timeLeftSeconds = timeLeftRaw / 1000;
this.timeLeft = Math.floor(timeLeftSeconds) * 1000;
return timeLeftSeconds % 1;
};
/**
* @param {?=} startDate
* @param {?=} delayMs
* @param {?=} replaying
* @return {?}
*/
CircleTimerComponent.prototype.start = /**
* @param {?=} startDate
* @param {?=} delayMs
* @param {?=} replaying
* @return {?}
*/
function (startDate, delayMs, replaying) {
var _this = this;
if (delayMs === void 0) { delayMs = 0; }
if (replaying === void 0) { replaying = false; }
if (this.ticking) {
console.log('Cannot start: timer already running.');
return;
}
/** @type {?} */
var decimalPortion = this.setTimeLeft(startDate);
/** @type {?} */
var startDelayMs = delayMs + decimalPortion * 1000;
this.formatTimeLeft();
this.setDasharray();
if (this.timeLeft === 0) {
this.completed = true;
console.log('Cannot start: timer already completed.');
return;
}
timer(startDelayMs, 1000)
.pipe(takeUntil(this.destroy$))
.subscribe((/**
* @param {?} e
* @return {?}
*/
function (e) {
_this.ticking = true;
_this.timeLeft -= 1000;
if (_this.timeLeft <= 0) {
_this.timeLeft = 0;
_this.ticking = false;
_this.completed = true;
_this.onComplete.emit(replaying);
_this.destroy$.next();
}
_this.formatTimeLeft();
_this.setDasharray();
}));
};
/**
* @param {?=} startDate
* @return {?}
*/
CircleTimerComponent.prototype.replay = /**
* @param {?=} startDate
* @return {?}
*/
function (startDate) {
this.start(startDate, 1200, true);
};
/**
* @return {?}
*/
CircleTimerComponent.prototype.pause = /**
* @return {?}
*/
function () { };
/**
* @return {?}
*/
CircleTimerComponent.prototype.continue = /**
* @return {?}
*/
function () { };
/**
* @return {?}
*/
CircleTimerComponent.prototype.complete = /**
* @return {?}
*/
function () {
this.timeLeft = 0;
this.ticking = false;
this.completed = true;
this.destroy$.next();
this.formatTimeLeft();
this.setDasharray();
};
/**
* @return {?}
*/
CircleTimerComponent.prototype.isTicking = /**
* @return {?}
*/
function () {
return this.ticking;
};
/**
* @return {?}
*/
CircleTimerComponent.prototype.isCompleted = /**
* @return {?}
*/
function () {
return this.completed;
};
/**
* @return {?}
*/
CircleTimerComponent.prototype.formatTimeLeft = /**
* @return {?}
*/
function () {
if (this.timeLeft <= 0) {
this.timeLeft = 0;
}
/** @type {?} */
var daysLeft = Math.floor(this.timeLeft / (1000 * 60 * 60 * 24));
/** @type {?} */
var hoursLeft = Math.floor((this.timeLeft % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
/** @type {?} */
var minutesLeft = Math.floor((this.timeLeft % (1000 * 60 * 60)) / (1000 * 60));
/** @type {?} */
var secondsLeft = Math.floor((this.timeLeft % (1000 * 60)) / 1000);
/** @type {?} */
var formattedDays = daysLeft < 10 ? "0" + daysLeft : "" + daysLeft;
/** @type {?} */
var formattedHours = hoursLeft < 10 ? "0" + hoursLeft : "" + hoursLeft;
/** @type {?} */
var formattedMinutes = minutesLeft < 10 ? "0" + minutesLeft : "" + minutesLeft;
/** @type {?} */
var formattedSeconds = secondsLeft < 10 ? "0" + secondsLeft : "" + secondsLeft;
this.formattedTimeLeft = formattedMinutes + ":" + formattedSeconds;
if (formattedHours !== '00' || formattedDays !== '00') {
this.formattedTimeLeft = formattedHours + ":" + this.formattedTimeLeft;
}
if (formattedDays !== '00') {
this.formattedTimeLeft = formattedDays + ":" + this.formattedTimeLeft;
}
};
/**
* @return {?}
*/
CircleTimerComponent.prototype.setDasharray = /**
* @return {?}
*/
function () {
/** @type {?} */
var rawFraction = this.timeLeft / this.duration;
/** @type {?} */
var fraction = rawFraction - (1 / this.duration) * (1 - rawFraction);
/** @type {?} */
var remaining = Math.round(fraction * this.fullDasharray);
this.dasharray = remaining + " " + this.fullDasharray;
};
CircleTimerComponent.decorators = [
{ type: Component, args: [{
selector: 'flx-circle-timer',
template: "<div class=\"base-timer\">\r\n <svg class=\"base-timer-svg\"\r\n viewBox=\"0 0 100 100\"\r\n xmlns=\"http://www.w3.org/2000/svg\">\r\n <g class=\"base-timer-circle\">\r\n <circle [ngClass]=\"completed ? 'base-timer-completed' : 'base-timer-stroke'\"\r\n cx=\"50\"\r\n cy=\"50\"\r\n r=\"45\" />\r\n <path [attr.stroke-dasharray]=\"dasharray\"\r\n [style.stroke]=\"color\"\r\n id=\"remaining-time-stroke\"\r\n d=\" M 50, 50\r\n m -45, 0\r\n a 45,45 0 1,0 90,0\r\n a 45,45 0 1,0 -90,0\">\r\n </path>\r\n </g>\r\n </svg>\r\n <span class=\"time\">\r\n <!-- <img *ngIf=\"completed\"\r\n src=\"../../../assets/image/check.svg\"\r\n alt=\"\">\r\n <span *ngIf=\"!completed\">{{formattedTimeLeft}}</span> -->\r\n <span>{{formattedTimeLeft}}</span>\r\n </span>\r\n</div>",
styles: [":host .base-timer{position:relative;height:200px;width:200px}:host .base-timer-circle{fill:none;stroke:none}:host .base-timer-stroke{stroke-width:1px;stroke:grey}:host .base-timer-completed{stroke-width:1px;stroke:grey}:host .base-timer .time{position:absolute;width:200px;height:200px;top:0;display:-webkit-box;display:flex;-webkit-box-align:center;align-items:center;-webkit-box-pack:center;justify-content:center;font-size:26px}:host .base-timer .time img{height:80px}:host .base-timer #remaining-time-stroke{stroke-width:2px;-webkit-transform:rotate(90deg);transform:rotate(90deg);-webkit-transform-origin:center;transform-origin:center;-webkit-transition:1s linear;transition:1s linear;stroke:#1cbbf8}:host .base-timer .base-timer-svg{-webkit-transform:scaleX(-1);transform:scaleX(-1)}"]
}] }
];
/** @nocollapse */
CircleTimerComponent.ctorParameters = function () { return [
{ type: NgZone }
]; };
CircleTimerComponent.propDecorators = {
startDate: [{ type: Input }],
duration: [{ type: Input }],
color: [{ type: Input }],
onComplete: [{ type: Output }]
};
return CircleTimerComponent;
}());
export { CircleTimerComponent };
if (false) {
/** @type {?} */
CircleTimerComponent.prototype.startDate;
/** @type {?} */
CircleTimerComponent.prototype.duration;
/** @type {?} */
CircleTimerComponent.prototype.color;
/** @type {?} */
CircleTimerComponent.prototype.onComplete;
/** @type {?} */
CircleTimerComponent.prototype.destroy$;
/** @type {?} */
CircleTimerComponent.prototype.startTime;
/** @type {?} */
CircleTimerComponent.prototype.timeLeft;
/** @type {?} */
CircleTimerComponent.prototype.ticking;
/** @type {?} */
CircleTimerComponent.prototype.completed;
/** @type {?} */
CircleTimerComponent.prototype.formattedTimeLeft;
/** @type {?} */
CircleTimerComponent.prototype.fullDasharray;
/** @type {?} */
CircleTimerComponent.prototype.dasharray;
/**
* @type {?}
* @protected
*/
CircleTimerComponent.prototype.ngZone;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2lyY2xlLXRpbWVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BmbHhuZy9jaXJjbGUtdGltZXIvIiwic291cmNlcyI6WyJsaWIvY2lyY2xlLXRpbWVyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQXFCLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNsRyxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0QyxPQUFPLEVBQVMsU0FBUyxFQUFhLE1BQU0sZ0JBQWdCLENBQUM7QUFJN0Q7SUF1QkUsOEJBQXNCLE1BQWM7UUFBZCxXQUFNLEdBQU4sTUFBTSxDQUFROztRQWhCM0IsYUFBUSxHQUFHLENBQUMsQ0FBQyxDQUFDLGVBQWU7O1FBQzdCLFVBQUssR0FBRyxTQUFTLENBQUM7UUFFakIsZUFBVSxHQUFHLElBQUksWUFBWSxFQUFXLENBQUM7UUFFbkQsYUFBUSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFFL0IsY0FBUyxHQUFHLENBQUMsQ0FBQztRQUNkLGFBQVEsR0FBRyxDQUFDLENBQUM7UUFDYixZQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ2hCLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFDbEIsc0JBQWlCLEdBQUcsRUFBRSxDQUFDO1FBRWQsa0JBQWEsR0FBRyxHQUFHLENBQUM7UUFDN0IsY0FBUyxHQUFNLElBQUksQ0FBQyxhQUFhLFNBQUksSUFBSSxDQUFDLGFBQWUsQ0FBQztJQUVuQixDQUFDOzs7O0lBRXhDLHVDQUFROzs7SUFBUjtRQUNFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzVCLENBQUM7Ozs7SUFFRCwwQ0FBVzs7O0lBQVg7UUFDRSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3JCLElBQUks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S0FBSyxJQUFJLEVBQUU7WUFDMUIsSUFBSSxDQUFDLGlCQUFpQixHQUFNLGFBQWEsTUFBRyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQztTQUN2RTtJQUNILENBQUM7Ozs7SUFFRCwyQ0FBWTs7O0lBQVo7O1lBQ1EsV0FBVyxHQUFHLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVE7O1lBQzNDLFFBQVEsR0FBRyxXQUFXLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQzs7WUFDaEUsU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7UUFFM0QsSUFBSSxDQUFDLFNBQVMsR0FBTSxTQUFTLFNBQUksSUFBSSxDQUFDLGFBQWUsQ0FBQztJQUN4RCxDQUFDOztnQkFqS0YsU0FBUyxTQUFDO29CQUNULFFBQVEsRUFBRSxrQkFBa0I7b0JBQzVCLHM3QkFBNEM7O2lCQUU3Qzs7OztnQkFWd0MsTUFBTTs7OzRCQVk1QyxLQUFLOzJCQUNMLEtBQUs7d0JBQ0wsS0FBSzs2QkFFTCxNQUFNOztJQXdKVCwyQkFBQztDQUFBLEFBbEtELElBa0tDO1NBN0pZLG9CQUFvQjs7O0lBQy9CLHlDQUE0Qjs7SUFDNUIsd0NBQXNCOztJQUN0QixxQ0FBMkI7O0lBRTNCLDBDQUFtRDs7SUFFbkQsd0NBQStCOztJQUUvQix5Q0FBYzs7SUFDZCx3Q0FBYTs7SUFDYix1Q0FBZ0I7O0lBQ2hCLHlDQUFrQjs7SUFDbEIsaURBQXVCOztJQUV2Qiw2Q0FBNkI7O0lBQzdCLHlDQUEwRDs7Ozs7SUFFOUMsc0NBQXdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBOZ1pvbmUsIE9uRGVzdHJveSwgT25Jbml0LCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YmplY3QsIHRpbWVyIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkZWxheSwgdGFrZVVudGlsLCB0YWtlV2hpbGUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmV4cG9ydCB0eXBlIFN0YXJ0RGF0ZSA9IERhdGUgfCBzdHJpbmcgfCBudW1iZXI7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2ZseC1jaXJjbGUtdGltZXInLFxuICB0ZW1wbGF0ZVVybDogJy4vY2lyY2xlLXRpbWVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vY2lyY2xlLXRpbWVyLmNvbXBvbmVudC5zY3NzJ10sXG59KVxuZXhwb3J0IGNsYXNzIENpcmNsZVRpbWVyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBASW5wdXQoKSBzdGFydERhdGU/OiBzdHJpbmc7IC8vIG9ubHkgdG8gc2V0IGluaXRpYWwgc3RhdGUgKG5nT25Jbml0KVxuICBASW5wdXQoKSBkdXJhdGlvbiA9IDA7IC8vIG1pbGxpc2Vjb25kc1xuICBASW5wdXQoKSBjb2xvciA9ICcjMWNiYmY4JztcblxuICBAT3V0cHV0KCkgb25Db21wbGV0ZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgc3RhcnRUaW1lID0gMDtcbiAgdGltZUxlZnQgPSAwO1xuICB0aWNraW5nID0gZmFsc2U7XG4gIGNvbXBsZXRlZCA9IGZhbHNlO1xuICBmb3JtYXR0ZWRUaW1lTGVmdCA9ICcnO1xuXG4gIHJlYWRvbmx5IGZ1bGxEYXNoYXJyYXkgPSAyODM7XG4gIGRhc2hhcnJheSA9IGAke3RoaXMuZnVsbERhc2hhcnJheX0gJHt0aGlzLmZ1bGxEYXNoYXJyYXl9YDtcblxuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgbmdab25lOiBOZ1pvbmUpIHt9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5pbml0KHRoaXMuc3RhcnREYXRlKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgfVxuXG4gIGluaXQoc3RhcnREYXRlPzogU3RhcnREYXRlKTogdm9pZCB7XG4gICAgdGhpcy5zZXRUaW1lTGVmdChzdGFydERhdGUpO1xuICAgIHRoaXMuZm9ybWF0VGltZUxlZnQoKTtcbiAgICB0aGlzLnNldERhc2hhcnJheSgpO1xuXG4gICAgaWYgKHRoaXMudGltZUxlZnQgPT09IDApIHtcbiAgICAgIHRoaXMuY29tcGxldGVkID0gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICBzZXRUaW1lTGVmdChzdGFydERhdGU/OiBTdGFydERhdGUpOiBudW1iZXIge1xuICAgIHRoaXMudGlja2luZyA9IGZhbHNlO1xuICAgIHRoaXMuY29tcGxldGVkID0gZmFsc2U7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG5cbiAgICBpZiAoIXN0YXJ0RGF0ZSkge1xuICAgICAgdGhpcy50aW1lTGVmdCA9IHRoaXMuZHVyYXRpb247XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBjb25zdCBzdGFydFRpbWUgPSBuZXcgRGF0ZSg8c3RyaW5nPnN0YXJ0RGF0ZSkuZ2V0VGltZSgpO1xuICAgIGNvbnN0IGVuZFRpbWUgPSBzdGFydFRpbWUgKyB0aGlzLmR1cmF0aW9uO1xuICAgIGNvbnN0IHRpbWVMZWZ0UmF3ID0gZW5kVGltZSAtIERhdGUubm93KCk7XG4gICAgaWYgKHRpbWVMZWZ0UmF3IDw9IDApIHtcbiAgICAgIHRoaXMudGltZUxlZnQgPSAwO1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgY29uc3QgdGltZUxlZnRTZWNvbmRzID0gdGltZUxlZnRSYXcgLyAxMDAwO1xuXG4gICAgdGhpcy50aW1lTGVmdCA9IE1hdGguZmxvb3IodGltZUxlZnRTZWNvbmRzKSAqIDEwMDA7XG4gICAgcmV0dXJuIHRpbWVMZWZ0U2Vjb25kcyAlIDE7XG4gIH1cblxuICBzdGFydChzdGFydERhdGU/OiBTdGFydERhdGUsIGRlbGF5TXMgPSAwLCByZXBsYXlpbmcgPSBmYWxzZSk6IHZvaWQge1xuICAgIGlmICh0aGlzLnRpY2tpbmcpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdDYW5ub3Qgc3RhcnQ6IHRpbWVyIGFscmVhZHkgcnVubmluZy4nKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBkZWNpbWFsUG9ydGlvbiA9IHRoaXMuc2V0VGltZUxlZnQoc3RhcnREYXRlKTtcbiAgICBjb25zdCBzdGFydERlbGF5TXMgPSBkZWxheU1zICsgZGVjaW1hbFBvcnRpb24gKiAxMDAwO1xuICAgIHRoaXMuZm9ybWF0VGltZUxlZnQoKTtcbiAgICB0aGlzLnNldERhc2hhcnJheSgpO1xuXG4gICAgaWYgKHRoaXMudGltZUxlZnQgPT09IDApIHtcbiAgICAgIHRoaXMuY29tcGxldGVkID0gdHJ1ZTtcbiAgICAgIGNvbnNvbGUubG9nKCdDYW5ub3Qgc3RhcnQ6IHRpbWVyIGFscmVhZHkgY29tcGxldGVkLicpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRpbWVyKHN0YXJ0RGVsYXlNcywgMTAwMClcbiAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgIC5zdWJzY3JpYmUoKGUpID0+IHtcbiAgICAgICAgdGhpcy50aWNraW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy50aW1lTGVmdCAtPSAxMDAwO1xuICAgICAgICBpZiAodGhpcy50aW1lTGVmdCA8PSAwKSB7XG4gICAgICAgICAgdGhpcy50aW1lTGVmdCA9IDA7XG4gICAgICAgICAgdGhpcy50aWNraW5nID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5jb21wbGV0ZWQgPSB0cnVlO1xuICAgICAgICAgIHRoaXMub25Db21wbGV0ZS5lbWl0KHJlcGxheWluZyk7XG4gICAgICAgICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZvcm1hdFRpbWVMZWZ0KCk7XG4gICAgICAgIHRoaXMuc2V0RGFzaGFycmF5KCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHJlcGxheShzdGFydERhdGU/OiBTdGFydERhdGUpOiB2b2lkIHtcbiAgICB0aGlzLnN0YXJ0KHN0YXJ0RGF0ZSwgMTIwMCwgdHJ1ZSk7XG4gIH1cblxuICBwYXVzZSgpOiB2b2lkIHt9XG5cbiAgY29udGludWUoKTogdm9pZCB7fVxuXG4gIGNvbXBsZXRlKCk6IHZvaWQge1xuICAgIHRoaXMudGltZUxlZnQgPSAwO1xuICAgIHRoaXMudGlja2luZyA9IGZhbHNlO1xuICAgIHRoaXMuY29tcGxldGVkID0gdHJ1ZTtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcblxuICAgIHRoaXMuZm9ybWF0VGltZUxlZnQoKTtcbiAgICB0aGlzLnNldERhc2hhcnJheSgpO1xuICB9XG5cbiAgaXNUaWNraW5nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnRpY2tpbmc7XG4gIH1cblxuICBpc0NvbXBsZXRlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jb21wbGV0ZWQ7XG4gIH1cblxuICBmb3JtYXRUaW1lTGVmdCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy50aW1lTGVmdCA8PSAwKSB7XG4gICAgICB0aGlzLnRpbWVMZWZ0ID0gMDtcbiAgICB9XG5cbiAgICBjb25zdCBkYXlzTGVmdCA9IE1hdGguZmxvb3IodGhpcy50aW1lTGVmdCAvICgxMDAwICogNjAgKiA2MCAqIDI0KSk7XG4gICAgY29uc3QgaG91cnNMZWZ0ID0gTWF0aC5mbG9vcigodGhpcy50aW1lTGVmdCAlICgxMDAwICogNjAgKiA2MCAqIDI0KSkgLyAoMTAwMCAqIDYwICogNjApKTtcbiAgICBjb25zdCBtaW51dGVzTGVmdCA9IE1hdGguZmxvb3IoKHRoaXMudGltZUxlZnQgJSAoMTAwMCAqIDYwICogNjApKSAvICgxMDAwICogNjApKTtcbiAgICBjb25zdCBzZWNvbmRzTGVmdCA9IE1hdGguZmxvb3IoKHRoaXMudGltZUxlZnQgJSAoMTAwMCAqIDYwKSkgLyAxMDAwKTtcblxuICAgIGNvbnN0IGZvcm1hdHRlZERheXMgPSBkYXlzTGVmdCA8IDEwID8gYDAke2RheXNMZWZ0fWAgOiBgJHtkYXlzTGVmdH1gO1xuICAgIGNvbnN0IGZvcm1hdHRlZEhvdXJzID0gaG91cnNMZWZ0IDwgMTAgPyBgMCR7aG91cnNMZWZ0fWAgOiBgJHtob3Vyc0xlZnR9YDtcbiAgICBjb25zdCBmb3JtYXR0ZWRNaW51dGVzID0gbWludXRlc0xlZnQgPCAxMCA/IGAwJHttaW51dGVzTGVmdH1gIDogYCR7bWludXRlc0xlZnR9YDtcbiAgICBjb25zdCBmb3JtYXR0ZWRTZWNvbmRzID0gc2Vjb25kc0xlZnQgPCAxMCA/IGAwJHtzZWNvbmRzTGVmdH1gIDogYCR7c2Vjb25kc0xlZnR9YDtcblxuICAgIHRoaXMuZm9ybWF0dGVkVGltZUxlZnQgPSBgJHtmb3JtYXR0ZWRNaW51dGVzfToke2Zvcm1hdHRlZFNlY29uZHN9YDtcblxuICAgIGlmIChmb3JtYXR0ZWRIb3VycyAhPT0gJzAwJyB8fCBmb3JtYXR0ZWREYXlzICE9PSAnMDAnKSB7XG4gICAgICB0aGlzLmZvcm1hdHRlZFRpbWVMZWZ0ID0gYCR7Zm9ybWF0dGVkSG91cnN9OmAgKyB0aGlzLmZvcm1hdHRlZFRpbWVMZWZ0O1xuICAgIH1cblxuICAgIGlmIChmb3JtYXR0ZWREYXlzICE9PSAnMDAnKSB7XG4gICAgICB0aGlzLmZvcm1hdHRlZFRpbWVMZWZ0ID0gYCR7Zm9ybWF0dGVkRGF5c306YCArIHRoaXMuZm9ybWF0dGVkVGltZUxlZnQ7XG4gICAgfVxuICB9XG5cbiAgc2V0RGFzaGFycmF5KCk6IHZvaWQge1xuICAgIGNvbnN0IHJhd0ZyYWN0aW9uID0gdGhpcy50aW1lTGVmdCAvIHRoaXMuZHVyYXRpb247XG4gICAgY29uc3QgZnJhY3Rpb24gPSByYXdGcmFjdGlvbiAtICgxIC8gdGhpcy5kdXJhdGlvbikgKiAoMSAtIHJhd0ZyYWN0aW9uKTtcbiAgICBjb25zdCByZW1haW5pbmcgPSBNYXRoLnJvdW5kKGZyYWN0aW9uICogdGhpcy5mdWxsRGFzaGFycmF5KTtcblxuICAgIHRoaXMuZGFzaGFycmF5ID0gYCR7cmVtYWluaW5nfSAke3RoaXMuZnVsbERhc2hhcnJheX1gO1xuICB9XG59XG4iXX0=