@flxng/circle-timer
Version:
Circle Timer (countdown) component for Angular.
253 lines • 22.7 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';
export class CircleTimerComponent {
/**
* @param {?} ngZone
*/
constructor(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 {?}
*/
ngOnInit() {
this.init(this.startDate);
}
/**
* @return {?}
*/
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
/**
* @param {?=} startDate
* @return {?}
*/
init(startDate) {
this.setTimeLeft(startDate);
this.formatTimeLeft();
this.setDasharray();
if (this.timeLeft === 0) {
this.completed = true;
}
}
/**
* @param {?=} startDate
* @return {?}
*/
setTimeLeft(startDate) {
this.ticking = false;
this.completed = false;
this.destroy$.next();
if (!startDate) {
this.timeLeft = this.duration;
return 0;
}
/** @type {?} */
const startTime = new Date((/** @type {?} */ (startDate))).getTime();
/** @type {?} */
const endTime = startTime + this.duration;
/** @type {?} */
const timeLeftRaw = endTime - Date.now();
if (timeLeftRaw <= 0) {
this.timeLeft = 0;
return 0;
}
/** @type {?} */
const timeLeftSeconds = timeLeftRaw / 1000;
this.timeLeft = Math.floor(timeLeftSeconds) * 1000;
return timeLeftSeconds % 1;
}
/**
* @param {?=} startDate
* @param {?=} delayMs
* @param {?=} replaying
* @return {?}
*/
start(startDate, delayMs = 0, replaying = false) {
if (this.ticking) {
console.log('Cannot start: timer already running.');
return;
}
/** @type {?} */
const decimalPortion = this.setTimeLeft(startDate);
/** @type {?} */
const 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 {?}
*/
(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 {?}
*/
replay(startDate) {
this.start(startDate, 1200, true);
}
/**
* @return {?}
*/
pause() { }
/**
* @return {?}
*/
continue() { }
/**
* @return {?}
*/
complete() {
this.timeLeft = 0;
this.ticking = false;
this.completed = true;
this.destroy$.next();
this.formatTimeLeft();
this.setDasharray();
}
/**
* @return {?}
*/
isTicking() {
return this.ticking;
}
/**
* @return {?}
*/
isCompleted() {
return this.completed;
}
/**
* @return {?}
*/
formatTimeLeft() {
if (this.timeLeft <= 0) {
this.timeLeft = 0;
}
/** @type {?} */
const daysLeft = Math.floor(this.timeLeft / (1000 * 60 * 60 * 24));
/** @type {?} */
const hoursLeft = Math.floor((this.timeLeft % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
/** @type {?} */
const minutesLeft = Math.floor((this.timeLeft % (1000 * 60 * 60)) / (1000 * 60));
/** @type {?} */
const secondsLeft = Math.floor((this.timeLeft % (1000 * 60)) / 1000);
/** @type {?} */
const formattedDays = daysLeft < 10 ? `0${daysLeft}` : `${daysLeft}`;
/** @type {?} */
const formattedHours = hoursLeft < 10 ? `0${hoursLeft}` : `${hoursLeft}`;
/** @type {?} */
const formattedMinutes = minutesLeft < 10 ? `0${minutesLeft}` : `${minutesLeft}`;
/** @type {?} */
const 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 {?}
*/
setDasharray() {
/** @type {?} */
const rawFraction = this.timeLeft / this.duration;
/** @type {?} */
const fraction = rawFraction - (1 / this.duration) * (1 - rawFraction);
/** @type {?} */
const 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 = () => [
{ type: NgZone }
];
CircleTimerComponent.propDecorators = {
startDate: [{ type: Input }],
duration: [{ type: Input }],
color: [{ type: Input }],
onComplete: [{ type: Output }]
};
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2lyY2xlLXRpbWVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BmbHhuZy9jaXJjbGUtdGltZXIvIiwic291cmNlcyI6WyJsaWIvY2lyY2xlLXRpbWVyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQXFCLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNsRyxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0QyxPQUFPLEVBQVMsU0FBUyxFQUFhLE1BQU0sZ0JBQWdCLENBQUM7QUFTN0QsTUFBTSxPQUFPLG9CQUFvQjs7OztJQWtCL0IsWUFBc0IsTUFBYztRQUFkLFdBQU0sR0FBTixNQUFNLENBQVE7O1FBaEIzQixhQUFRLEdBQUcsQ0FBQyxDQUFDLENBQUMsZUFBZTs7UUFDN0IsVUFBSyxHQUFHLFNBQVMsQ0FBQztRQUVqQixlQUFVLEdBQUcsSUFBSSxZQUFZLEVBQVcsQ0FBQztRQUVuRCxhQUFRLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUUvQixjQUFTLEdBQUcsQ0FBQyxDQUFDO1FBQ2QsYUFBUSxHQUFHLENBQUMsQ0FBQztRQUNiLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDaEIsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUNsQixzQkFBaUIsR0FBRyxFQUFFLENBQUM7UUFFZCxrQkFBYSxHQUFHLEdBQUcsQ0FBQztRQUM3QixjQUFTLEdBQUcsR0FBRyxJQUFJLENBQUMsYUFBYSxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUVuQixDQUFDOzs7O0lBRXhDLFFBQVE7UUFDTixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUM1QixDQUFDOzs7O0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENB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YUFBYSxHQUFHLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDO1NBQ3ZFO0lBQ0gsQ0FBQzs7OztJQUVELFlBQVk7O2NBQ0osV0FBVyxHQUFHLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLFFBQVE7O2NBQzNDLFFBQVEsR0FBRyxXQUFXLEdBQUcsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLFdBQVcsQ0FBQzs7Y0FDaEUsU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUM7UUFFM0QsSUFBSSxDQUFDLFNBQVMsR0FBRyxHQUFHLFNBQVMsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDeEQsQ0FBQzs7O1lBaktGLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsa0JBQWtCO2dCQUM1QixzN0JBQTRDOzthQUU3Qzs7OztZQVZ3QyxNQUFNOzs7d0JBWTVDLEtBQUs7dUJBQ0wsS0FBSztvQkFDTCxLQUFLO3lCQUVMLE1BQU07Ozs7SUFKUCx5Q0FBNEI7O0lBQzVCLHdDQUFzQjs7SUFDdEIscUNBQTJCOztJQUUzQiwwQ0FBbUQ7O0lBRW5ELHdDQUErQjs7SUFFL0IseUNBQWM7O0lBQ2Qsd0NBQWE7O0lBQ2IsdUNBQWdCOztJQUNoQix5Q0FBa0I7O0lBQ2xCLGlEQUF1Qjs7SUFFdkIsNkNBQTZCOztJQUM3Qix5Q0FBMEQ7Ozs7O0lBRTlDLHNDQUF3QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgTmdab25lLCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTdWJqZWN0LCB0aW1lciB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVsYXksIHRha2VVbnRpbCwgdGFrZVdoaWxlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5leHBvcnQgdHlwZSBTdGFydERhdGUgPSBEYXRlIHwgc3RyaW5nIHwgbnVtYmVyO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdmbHgtY2lyY2xlLXRpbWVyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NpcmNsZS10aW1lci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NpcmNsZS10aW1lci5jb21wb25lbnQuc2NzcyddLFxufSlcbmV4cG9ydCBjbGFzcyBDaXJjbGVUaW1lckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgQElucHV0KCkgc3RhcnREYXRlPzogc3RyaW5nOyAvLyBvbmx5IHRvIHNldCBpbml0aWFsIHN0YXRlIChuZ09uSW5pdClcbiAgQElucHV0KCkgZHVyYXRpb24gPSAwOyAvLyBtaWxsaXNlY29uZHNcbiAgQElucHV0KCkgY29sb3IgPSAnIzFjYmJmOCc7XG5cbiAgQE91dHB1dCgpIG9uQ29tcGxldGUgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG5cbiAgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIHN0YXJ0VGltZSA9IDA7XG4gIHRpbWVMZWZ0ID0gMDtcbiAgdGlja2luZyA9IGZhbHNlO1xuICBjb21wbGV0ZWQgPSBmYWxzZTtcbiAgZm9ybWF0dGVkVGltZUxlZnQgPSAnJztcblxuICByZWFkb25seSBmdWxsRGFzaGFycmF5ID0gMjgzO1xuICBkYXNoYXJyYXkgPSBgJHt0aGlzLmZ1bGxEYXNoYXJyYXl9ICR7dGhpcy5mdWxsRGFzaGFycmF5fWA7XG5cbiAgY29uc3RydWN0b3IocHJvdGVjdGVkIG5nWm9uZTogTmdab25lKSB7fVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuaW5pdCh0aGlzLnN0YXJ0RGF0ZSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBpbml0KHN0YXJ0RGF0ZT86IFN0YXJ0RGF0ZSk6IHZvaWQge1xuICAgIHRoaXMuc2V0VGltZUxlZnQoc3RhcnREYXRlKTtcbiAgICB0aGlzLmZvcm1hdFRpbWVMZWZ0KCk7XG4gICAgdGhpcy5zZXREYXNoYXJyYXkoKTtcblxuICAgIGlmICh0aGlzLnRpbWVMZWZ0ID09PSAwKSB7XG4gICAgICB0aGlzLmNvbXBsZXRlZCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgc2V0VGltZUxlZnQoc3RhcnREYXRlPzogU3RhcnREYXRlKTogbnVtYmVyIHtcbiAgICB0aGlzLnRpY2tpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmNvbXBsZXRlZCA9IGZhbHNlO1xuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuXG4gICAgaWYgKCFzdGFydERhdGUpIHtcbiAgICAgIHRoaXMudGltZUxlZnQgPSB0aGlzLmR1cmF0aW9uO1xuICAgICAgcmV0dXJuIDA7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhcnRUaW1lID0gbmV3IERhdGUoPHN0cmluZz5zdGFydERhdGUpLmdldFRpbWUoKTtcbiAgICBjb25zdCBlbmRUaW1lID0gc3RhcnRUaW1lICsgdGhpcy5kdXJhdGlvbjtcbiAgICBjb25zdCB0aW1lTGVmdFJhdyA9IGVuZFRpbWUgLSBEYXRlLm5vdygpO1xuICAgIGlmICh0aW1lTGVmdFJhdyA8PSAwKSB7XG4gICAgICB0aGlzLnRpbWVMZWZ0ID0gMDtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cblxuICAgIGNvbnN0IHRpbWVMZWZ0U2Vjb25kcyA9IHRpbWVMZWZ0UmF3IC8gMTAwMDtcblxuICAgIHRoaXMudGltZUxlZnQgPSBNYXRoLmZsb29yKHRpbWVMZWZ0U2Vjb25kcykgKiAxMDAwO1xuICAgIHJldHVybiB0aW1lTGVmdFNlY29uZHMgJSAxO1xuICB9XG5cbiAgc3RhcnQoc3RhcnREYXRlPzogU3RhcnREYXRlLCBkZWxheU1zID0gMCwgcmVwbGF5aW5nID0gZmFsc2UpOiB2b2lkIHtcbiAgICBpZiAodGhpcy50aWNraW5nKSB7XG4gICAgICBjb25zb2xlLmxvZygnQ2Fubm90IHN0YXJ0OiB0aW1lciBhbHJlYWR5IHJ1bm5pbmcuJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZGVjaW1hbFBvcnRpb24gPSB0aGlzLnNldFRpbWVMZWZ0KHN0YXJ0RGF0ZSk7XG4gICAgY29uc3Qgc3RhcnREZWxheU1zID0gZGVsYXlNcyArIGRlY2ltYWxQb3J0aW9uICogMTAwMDtcbiAgICB0aGlzLmZvcm1hdFRpbWVMZWZ0KCk7XG4gICAgdGhpcy5zZXREYXNoYXJyYXkoKTtcblxuICAgIGlmICh0aGlzLnRpbWVMZWZ0ID09PSAwKSB7XG4gICAgICB0aGlzLmNvbXBsZXRlZCA9IHRydWU7XG4gICAgICBjb25zb2xlLmxvZygnQ2Fubm90IHN0YXJ0OiB0aW1lciBhbHJlYWR5IGNvbXBsZXRlZC4nKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aW1lcihzdGFydERlbGF5TXMsIDEwMDApXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAuc3Vic2NyaWJlKChlKSA9PiB7XG4gICAgICAgIHRoaXMudGlja2luZyA9IHRydWU7XG4gICAgICAgIHRoaXMudGltZUxlZnQgLT0gMTAwMDtcbiAgICAgICAgaWYgKHRoaXMudGltZUxlZnQgPD0gMCkge1xuICAgICAgICAgIHRoaXMudGltZUxlZnQgPSAwO1xuICAgICAgICAgIHRoaXMudGlja2luZyA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMuY29tcGxldGVkID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLm9uQ29tcGxldGUuZW1pdChyZXBsYXlpbmcpO1xuICAgICAgICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5mb3JtYXRUaW1lTGVmdCgpO1xuICAgICAgICB0aGlzLnNldERhc2hhcnJheSgpO1xuICAgICAgfSk7XG4gIH1cblxuICByZXBsYXkoc3RhcnREYXRlPzogU3RhcnREYXRlKTogdm9pZCB7XG4gICAgdGhpcy5zdGFydChzdGFydERhdGUsIDEyMDAsIHRydWUpO1xuICB9XG5cbiAgcGF1c2UoKTogdm9pZCB7fVxuXG4gIGNvbnRpbnVlKCk6IHZvaWQge31cblxuICBjb21wbGV0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLnRpbWVMZWZ0ID0gMDtcbiAgICB0aGlzLnRpY2tpbmcgPSBmYWxzZTtcbiAgICB0aGlzLmNvbXBsZXRlZCA9IHRydWU7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG5cbiAgICB0aGlzLmZvcm1hdFRpbWVMZWZ0KCk7XG4gICAgdGhpcy5zZXREYXNoYXJyYXkoKTtcbiAgfVxuXG4gIGlzVGlja2luZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy50aWNraW5nO1xuICB9XG5cbiAgaXNDb21wbGV0ZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY29tcGxldGVkO1xuICB9XG5cbiAgZm9ybWF0VGltZUxlZnQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMudGltZUxlZnQgPD0gMCkge1xuICAgICAgdGhpcy50aW1lTGVmdCA9IDA7XG4gICAgfVxuXG4gICAgY29uc3QgZGF5c0xlZnQgPSBNYXRoLmZsb29yKHRoaXMudGltZUxlZnQgLyAoMTAwMCAqIDYwICogNjAgKiAyNCkpO1xuICAgIGNvbnN0IGhvdXJzTGVmdCA9IE1hdGguZmxvb3IoKHRoaXMudGltZUxlZnQgJSAoMTAwMCAqIDYwICogNjAgKiAyNCkpIC8gKDEwMDAgKiA2MCAqIDYwKSk7XG4gICAgY29uc3QgbWludXRlc0xlZnQgPSBNYXRoLmZsb29yKCh0aGlzLnRpbWVMZWZ0ICUgKDEwMDAgKiA2MCAqIDYwKSkgLyAoMTAwMCAqIDYwKSk7XG4gICAgY29uc3Qgc2Vjb25kc0xlZnQgPSBNYXRoLmZsb29yKCh0aGlzLnRpbWVMZWZ0ICUgKDEwMDAgKiA2MCkpIC8gMTAwMCk7XG5cbiAgICBjb25zdCBmb3JtYXR0ZWREYXlzID0gZGF5c0xlZnQgPCAxMCA/IGAwJHtkYXlzTGVmdH1gIDogYCR7ZGF5c0xlZnR9YDtcbiAgICBjb25zdCBmb3JtYXR0ZWRIb3VycyA9IGhvdXJzTGVmdCA8IDEwID8gYDAke2hvdXJzTGVmdH1gIDogYCR7aG91cnNMZWZ0fWA7XG4gICAgY29uc3QgZm9ybWF0dGVkTWludXRlcyA9IG1pbnV0ZXNMZWZ0IDwgMTAgPyBgMCR7bWludXRlc0xlZnR9YCA6IGAke21pbnV0ZXNMZWZ0fWA7XG4gICAgY29uc3QgZm9ybWF0dGVkU2Vjb25kcyA9IHNlY29uZHNMZWZ0IDwgMTAgPyBgMCR7c2Vjb25kc0xlZnR9YCA6IGAke3NlY29uZHNMZWZ0fWA7XG5cbiAgICB0aGlzLmZvcm1hdHRlZFRpbWVMZWZ0ID0gYCR7Zm9ybWF0dGVkTWludXRlc306JHtmb3JtYXR0ZWRTZWNvbmRzfWA7XG5cbiAgICBpZiAoZm9ybWF0dGVkSG91cnMgIT09ICcwMCcgfHwgZm9ybWF0dGVkRGF5cyAhPT0gJzAwJykge1xuICAgICAgdGhpcy5mb3JtYXR0ZWRUaW1lTGVmdCA9IGAke2Zvcm1hdHRlZEhvdXJzfTpgICsgdGhpcy5mb3JtYXR0ZWRUaW1lTGVmdDtcbiAgICB9XG5cbiAgICBpZiAoZm9ybWF0dGVkRGF5cyAhPT0gJzAwJykge1xuICAgICAgdGhpcy5mb3JtYXR0ZWRUaW1lTGVmdCA9IGAke2Zvcm1hdHRlZERheXN9OmAgKyB0aGlzLmZvcm1hdHRlZFRpbWVMZWZ0O1xuICAgIH1cbiAgfVxuXG4gIHNldERhc2hhcnJheSgpOiB2b2lkIHtcbiAgICBjb25zdCByYXdGcmFjdGlvbiA9IHRoaXMudGltZUxlZnQgLyB0aGlzLmR1cmF0aW9uO1xuICAgIGNvbnN0IGZyYWN0aW9uID0gcmF3RnJhY3Rpb24gLSAoMSAvIHRoaXMuZHVyYXRpb24pICogKDEgLSByYXdGcmFjdGlvbik7XG4gICAgY29uc3QgcmVtYWluaW5nID0gTWF0aC5yb3VuZChmcmFjdGlvbiAqIHRoaXMuZnVsbERhc2hhcnJheSk7XG5cbiAgICB0aGlzLmRhc2hhcnJheSA9IGAke3JlbWFpbmluZ30gJHt0aGlzLmZ1bGxEYXNoYXJyYXl9YDtcbiAgfVxufVxuIl19