UNPKG

ngx-material-timepicker

Version:
263 lines 44.2 kB
import { ChangeDetectionStrategy, Component, EventEmitter, Inject, Input, Output } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { NgxMaterialTimepickerService } from '../../services/ngx-material-timepicker.service'; import { Subject } from 'rxjs'; import { TimePeriod } from '../../models/time-period.enum'; import { TimeUnit } from '../../models/time-unit.enum'; import { TimeAdapter } from '../../services/time-adapter'; import { TIME_LOCALE } from '../../tokens/time-locale.token'; import { TimepickerTimeUtils } from '../../utils/timepicker-time.utils'; import { distinctUntilChanged, map, takeUntil, tap } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "../../services/ngx-material-timepicker.service"; import * as i2 from "./timepicker-time-control/ngx-timepicker-time-control.component"; import * as i3 from "./timepicker-period-selector/ngx-timepicker-period-selector.component"; import * as i4 from "../timepicker-toggle-button/ngx-material-timepicker-toggle.component"; import * as i5 from "../../ngx-material-timepicker.component"; import * as i6 from "@angular/common"; import * as i7 from "../../directives/ngx-material-timepicker-toggle-icon.directive"; export class NgxTimepickerFieldComponent { constructor(timepickerService, locale) { this.timepickerService = timepickerService; this.locale = locale; this.minHour = 1; this.maxHour = 12; this.timeUnit = TimeUnit; this.buttonAlign = 'right'; this.timeChanged = new EventEmitter(); this._format = 12; this.unsubscribe$ = new Subject(); this.isFirstTimeChange = true; this.onChange = () => { }; } set format(value) { this._format = value === 24 ? 24 : 12; this.minHour = this._format === 12 ? 1 : 0; this.maxHour = this._format === 12 ? 12 : 23; this.hoursList = TimepickerTimeUtils.getHours(this._format); const isDynamicallyChanged = value && (this.previousFormat && this.previousFormat !== this._format); if (isDynamicallyChanged) { this.updateTime(this.timepickerTime); } this.previousFormat = this._format; } get format() { return this._format; } set min(value) { if (typeof value === 'string') { this._min = TimeAdapter.parseTime(value, { locale: this.locale, format: this.format }); return; } this._min = value; } get min() { return this._min; } set max(value) { if (typeof value === 'string') { this._max = TimeAdapter.parseTime(value, { locale: this.locale, format: this.format }); return; } this._max = value; } get max() { return this._max; } set defaultTime(val) { this._defaultTime = val; this.isDefaultTime = !!val; } get defaultTime() { return this._defaultTime; } set minutesGap(gap) { if (gap == null) { return; } gap = Math.floor(gap); this._minutesGap = gap <= 59 ? gap : 1; } get minutesGap() { return this._minutesGap; } ngOnInit() { this.initTime(this.defaultTime); this.hoursList = TimepickerTimeUtils.getHours(this._format); this.minutesList = TimepickerTimeUtils.getMinutes(); this.isTimeRangeSet = !!(this.min || this.max); this.hour$ = this.timepickerService.selectedHour.pipe(tap((clockTime) => this.selectedHour = clockTime.time), map(this.changeDefaultTimeValue.bind(this)), tap(() => this.isTimeRangeSet && this.updateAvailableMinutes())); this.minute$ = this.timepickerService.selectedMinute.pipe(map(this.changeDefaultTimeValue.bind(this)), tap(() => this.isFirstTimeChange = false)); if (this.format === 12) { this.timepickerService.selectedPeriod.pipe(distinctUntilChanged(), tap((period) => this.period = period), tap(period => this.isChangePeriodDisabled = this.isPeriodDisabled(period)), takeUntil(this.unsubscribe$)).subscribe(() => this.isTimeRangeSet && this.updateAvailableTime()); } else if (this.isTimeRangeSet) { this.updateAvailableTime(); } } writeValue(val) { if (val) { this.initTime(val); } else { this.resetTime(); } } registerOnTouched(fn) { } registerOnChange(fn) { this.onChange = fn; } setDisabledState(isDisabled) { this.disabled = isDisabled; } changeHour(hour) { this.timepickerService.hour = this.hoursList.find(h => h.time === hour); this.changeTime(); } changeMinute(minute) { this.timepickerService.minute = this.minutesList.find(m => m.time === minute); this.changeTime(); } changePeriod(period) { this.timepickerService.period = period; this.changeTime(); } onTimeSet(time) { this.updateTime(time); this.emitLocalTimeChange(time); } ngOnDestroy() { this.unsubscribe$.next(); this.unsubscribe$.complete(); } changeTime() { const time = this.timepickerService.getFullTime(this.format); this.timepickerTime = time; this.emitLocalTimeChange(time); } resetTime() { this.timepickerService.hour = { angle: 0, time: null }; this.timepickerService.minute = { angle: 0, time: null }; } emitLocalTimeChange(time) { const localTime = TimeAdapter.toLocaleTimeString(time, { format: this.format, locale: this.locale }); this.onChange(localTime); this.timeChanged.emit(localTime); } changeDefaultTimeValue(clockFaceTime) { if (!this.isDefaultTime && this.isFirstTimeChange) { return Object.assign(Object.assign({}, clockFaceTime), { time: null }); } return clockFaceTime; } updateAvailableHours() { this.hoursList = TimepickerTimeUtils.disableHours(this.hoursList, { min: this.min, max: this.max, format: this.format, period: this.period }); } updateAvailableMinutes() { this.minutesList = TimepickerTimeUtils.disableMinutes(this.minutesList, this.selectedHour, { min: this.min, max: this.max, format: this.format, period: this.period }); } updateAvailableTime() { this.updateAvailableHours(); if (this.selectedHour) { this.updateAvailableMinutes(); } } updateTime(time) { if (time) { const formattedTime = TimeAdapter.formatTime(time, { locale: this.locale, format: this.format }); this.timepickerService.setDefaultTimeIfAvailable(formattedTime, this.min, this.max, this.format); this.timepickerTime = formattedTime; } } initTime(time) { const isDefaultTimeAvailable = TimeAdapter .isTimeAvailable(time, this.min, this.max, 'minutes', null, this.format); if (!isDefaultTimeAvailable) { if (this.min) { this.updateTime(TimeAdapter.fromDateTimeToString(this.min, this.format)); return; } if (this.max) { this.updateTime(TimeAdapter.fromDateTimeToString(this.max, this.format)); return; } } this.updateTime(time); } isPeriodDisabled(period) { return TimepickerTimeUtils.disableHours(TimepickerTimeUtils.getHours(12), { min: this.min, max: this.max, format: 12, period: period === TimePeriod.AM ? TimePeriod.PM : TimePeriod.AM }).every(time => time.disabled); } } NgxTimepickerFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: NgxTimepickerFieldComponent, deps: [{ token: i1.NgxMaterialTimepickerService }, { token: TIME_LOCALE }], target: i0.ɵɵFactoryTarget.Component }); NgxTimepickerFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.17", type: NgxTimepickerFieldComponent, selector: "ngx-timepicker-field", inputs: { disabled: "disabled", toggleIcon: "toggleIcon", buttonAlign: "buttonAlign", clockTheme: "clockTheme", controlOnly: "controlOnly", cancelBtnTmpl: "cancelBtnTmpl", confirmBtnTmpl: "confirmBtnTmpl", format: "format", min: "min", max: "max", defaultTime: "defaultTime", minutesGap: "minutesGap" }, outputs: { timeChanged: "timeChanged" }, providers: [ NgxMaterialTimepickerService, { provide: NG_VALUE_ACCESSOR, useExisting: NgxTimepickerFieldComponent, multi: true } ], ngImport: i0, template: "<div class=\"ngx-timepicker\" [ngClass]=\"{'ngx-timepicker--disabled': disabled}\">\n <ngx-timepicker-time-control\n class=\"ngx-timepicker__control--first\"\n [placeholder]=\"'HH'\"\n [time]=\"(hour$ | async)?.time\"\n [min]=\"minHour\"\n [max]=\"maxHour\"\n [timeUnit]=\"timeUnit.HOUR\"\n [disabled]=\"disabled\"\n [timeList]=\"hoursList\"\n [preventTyping]=\"isTimeRangeSet\"\n (timeChanged)=\"changeHour($event)\"></ngx-timepicker-time-control>\n <span class=\"ngx-timepicker__time-colon ngx-timepicker__control--second\">:</span>\n <ngx-timepicker-time-control\n class=\"ngx-timepicker__control--third\"\n [placeholder]=\"'MM'\"\n [time]=\"(minute$ | async)?.time\"\n [min]=\"0\"\n [max]=\"59\"\n [timeUnit]=\"timeUnit.MINUTE\"\n [disabled]=\"disabled\"\n [timeList]=\"minutesList\"\n [preventTyping]=\"isTimeRangeSet\"\n [minutesGap]=\"minutesGap\"\n (timeChanged)=\"changeMinute($event)\"></ngx-timepicker-time-control>\n <ngx-timepicker-period-selector\n class=\"ngx-timepicker__control--forth\"\n [selectedPeriod]=\"period\"\n [disabled]=\"disabled || isChangePeriodDisabled\"\n (periodSelected)=\"changePeriod($event)\"\n *ngIf=\"format !== 24\"></ngx-timepicker-period-selector>\n <ngx-material-timepicker-toggle\n class=\"ngx-timepicker__toggle\"\n *ngIf=\"!controlOnly\"\n [ngClass]=\"{'ngx-timepicker__toggle--left': buttonAlign === 'left'}\"\n [for]=\"timepicker\"\n [disabled]=\"disabled\">\n <span ngxMaterialTimepickerToggleIcon>\n <!--suppress HtmlUnknownAttribute -->\n <ng-container *ngTemplateOutlet=\"toggleIcon || defaultIcon\"></ng-container>\n </span>\n </ngx-material-timepicker-toggle>\n</div>\n<ngx-material-timepicker\n [min]=\"min\"\n [max]=\"max\"\n [theme]=\"clockTheme\"\n [defaultTime]=\"timepickerTime\"\n [format]=\"format\"\n [cancelBtnTmpl]=\"cancelBtnTmpl\"\n [confirmBtnTmpl]=\"confirmBtnTmpl\"\n [minutesGap]=\"minutesGap\"\n (timeSet)=\"onTimeSet($event)\" #timepicker></ngx-material-timepicker>\n\n<ng-template #defaultIcon>\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" width=\"24px\" height=\"24px\">\n <!--suppress CheckEmptyScriptTag -->\n <path\n d=\"M 12 2 C 6.4889971 2 2 6.4889971 2 12 C 2 17.511003 6.4889971 22 12 22 C 17.511003 22 22 17.511003 22 12 C 22 6.4889971 17.511003 2 12 2 z M 12 4 C 16.430123 4 20 7.5698774 20 12 C 20 16.430123 16.430123 20 12 20 C 7.5698774 20 4 16.430123 4 12 C 4 7.5698774 7.5698774 4 12 4 z M 11 6 L 11 12.414062 L 15.292969 16.707031 L 16.707031 15.292969 L 13 11.585938 L 13 6 L 11 6 z\"/>\n </svg>\n</ng-template>\n", styles: [".ngx-timepicker{display:flex;align-items:center;height:100%;border-bottom:1px solid rgba(0,0,0,.12)}.ngx-timepicker--disabled{background:rgba(0,0,0,.07);pointer-events:none}.ngx-timepicker__time-colon{margin-left:10px}.ngx-timepicker__control--first{order:1}.ngx-timepicker__control--second{order:2}.ngx-timepicker__control--third{order:3}.ngx-timepicker__control--forth{order:4}.ngx-timepicker__toggle{order:4}.ngx-timepicker__toggle--left{order:0}\n"], components: [{ type: i2.NgxTimepickerTimeControlComponent, selector: "ngx-timepicker-time-control", inputs: ["time", "min", "max", "placeholder", "timeUnit", "disabled", "timeList", "preventTyping", "minutesGap"], outputs: ["timeChanged"] }, { type: i3.NgxTimepickerPeriodSelectorComponent, selector: "ngx-timepicker-period-selector", inputs: ["isOpened", "disabled", "selectedPeriod"], outputs: ["periodSelected"] }, { type: i4.NgxMaterialTimepickerToggleComponent, selector: "ngx-material-timepicker-toggle", inputs: ["for", "disabled"] }, { type: i5.NgxMaterialTimepickerComponent, selector: "ngx-material-timepicker", inputs: ["cancelBtnTmpl", "editableHintTmpl", "confirmBtnTmpl", "ESC", "enableKeyboardInput", "preventOverlayClick", "disableAnimation", "appendToInput", "hoursOnly", "defaultTime", "timepickerClass", "theme", "min", "max", "ngxMaterialTimepickerTheme", "format", "minutesGap"], outputs: ["timeSet", "opened", "closed", "hourSelected", "timeChanged"] }], directives: [{ type: i6.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i7.NgxMaterialTimepickerToggleIconDirective, selector: "[ngxMaterialTimepickerToggleIcon]" }, { type: i6.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "async": i6.AsyncPipe }, changeDetection: i0.ChangeDetectionStrategy.OnPush }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: NgxTimepickerFieldComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-timepicker-field', templateUrl: './ngx-timepicker-field.component.html', styleUrls: ['./ngx-timepicker-field.component.scss'], providers: [ NgxMaterialTimepickerService, { provide: NG_VALUE_ACCESSOR, useExisting: NgxTimepickerFieldComponent, multi: true } ], changeDetection: ChangeDetectionStrategy.OnPush }] }], ctorParameters: function () { return [{ type: i1.NgxMaterialTimepickerService }, { type: undefined, decorators: [{ type: Inject, args: [TIME_LOCALE] }] }]; }, propDecorators: { disabled: [{ type: Input }], toggleIcon: [{ type: Input }], buttonAlign: [{ type: Input }], clockTheme: [{ type: Input }], controlOnly: [{ type: Input }], cancelBtnTmpl: [{ type: Input }], confirmBtnTmpl: [{ type: Input }], format: [{ type: Input }], min: [{ type: Input }], max: [{ type: Input }], defaultTime: [{ type: Input }], minutesGap: [{ type: Input }], timeChanged: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LXRpbWVwaWNrZXItZmllbGQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9tYXRlcmlhbC10aW1lcGlja2VyL2NvbXBvbmVudHMvdGltZXBpY2tlci1maWVsZC9uZ3gtdGltZXBpY2tlci1maWVsZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL21hdGVyaWFsLXRpbWVwaWNrZXIvY29tcG9uZW50cy90aW1lcGlja2VyLWZpZWxkL25neC10aW1lcGlja2VyLWZpZWxkLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQXFCLE1BQU0sRUFBZSxNQUFNLGVBQWUsQ0FBQztBQUN4SSxPQUFPLEVBQXdCLGlCQUFpQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekUsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sZ0RBQWdELENBQUM7QUFDOUYsT0FBTyxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUUzQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDM0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBRXZELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDN0QsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFFeEUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7Ozs7Ozs7OztBQWdCM0UsTUFBTSxPQUFPLDJCQUEyQjtJQStHcEMsWUFBb0IsaUJB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LHVDQUF1QztvQkFDcEQsU0FBUyxFQUFFLENBQUMsdUNBQXVDLENBQUM7b0JBQ3BELFNBQVMsRUFBRTt3QkFDUCw0QkFBNEI7d0JBQzVCOzRCQUNJLE9BQU8sRUFBRSxpQkFBaUI7NEJBQzFCLFdBQVcsNkJBQTZCOzRCQUN4QyxLQUFLLEVBQUUsSUFBSTt5QkFDZDtxQkFDSjtvQkFDRCxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtpQkFDbEQ7OzBCQWlIZ0IsTUFBTTsyQkFBQyxXQUFXOzRDQTlGdEIsUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFHRixNQUFNO3NCQURULEtBQUs7Z0JBbUJGLEdBQUc7c0JBRE4sS0FBSztnQkFjRixHQUFHO3NCQUROLEtBQUs7Z0JBY0YsV0FBVztzQkFEZCxLQUFLO2dCQVdGLFVBQVU7c0JBRGIsS0FBSztnQkFhSSxXQUFXO3NCQUFwQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbmplY3QsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgT3V0cHV0LCBUZW1wbGF0ZVJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTmd4TWF0ZXJpYWxUaW1lcGlja2VyU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL25neC1tYXRlcmlhbC10aW1lcGlja2VyLnNlcnZpY2UnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQ2xvY2tGYWNlVGltZSB9IGZyb20gJy4uLy4uL21vZGVscy9jbG9jay1mYWNlLXRpbWUuaW50ZXJmYWNlJztcbmltcG9ydCB7IFRpbWVQZXJpb2QgfSBmcm9tICcuLi8uLi9tb2RlbHMvdGltZS1wZXJpb2QuZW51bSc7XG5pbXBvcnQgeyBUaW1lVW5pdCB9IGZyb20gJy4uLy4uL21vZGVscy90aW1lLXVuaXQuZW51bSc7XG5pbXBvcnQgeyBOZ3hNYXRlcmlhbFRpbWVwaWNrZXJUaGVtZSB9IGZyb20gJy4uLy4uL21vZGVscy9uZ3gtbWF0ZXJpYWwtdGltZXBpY2tlci10aGVtZS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgVGltZUFkYXB0ZXIgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy90aW1lLWFkYXB0ZXInO1xuaW1wb3J0IHsgVElNRV9MT0NBTEUgfSBmcm9tICcuLi8uLi90b2tlbnMvdGltZS1sb2NhbGUudG9rZW4nO1xuaW1wb3J0IHsgVGltZXBpY2tlclRpbWVVdGlscyB9IGZyb20gJy4uLy4uL3V0aWxzL3RpbWVwaWNrZXItdGltZS51dGlscyc7XG5pbXBvcnQgeyBEYXRlVGltZSB9IGZyb20gJ2x1eG9uJztcbmltcG9ydCB7IGRpc3RpbmN0VW50aWxDaGFuZ2VkLCBtYXAsIHRha2VVbnRpbCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ25neC10aW1lcGlja2VyLWZpZWxkJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vbmd4LXRpbWVwaWNrZXItZmllbGQuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL25neC10aW1lcGlja2VyLWZpZWxkLmNvbXBvbmVudC5zY3NzJ10sXG4gICAgcHJvdmlkZXJzOiBbXG4gICAgICAgIE5neE1hdGVyaWFsVGltZXBpY2tlclNlcnZpY2UsXG4gICAgICAgIHtcbiAgICAgICAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgICAgICAgdXNlRXhpc3Rpbmc6IE5neFRpbWVwaWNrZXJGaWVsZENvbXBvbmVudCxcbiAgICAgICAgICAgIG11bHRpOiB0cnVlXG4gICAgICAgIH1cbiAgICBdLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIE5neFRpbWVwaWNrZXJGaWVsZENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBDb250cm9sVmFsdWVBY2Nlc3NvciB7XG5cbiAgICBwZXJpb2Q6IFRpbWVQZXJpb2Q7XG4gICAgaG91ciQ6IE9ic2VydmFibGU8Q2xvY2tGYWNlVGltZT47XG4gICAgbWludXRlJDogT2JzZXJ2YWJsZTxDbG9ja0ZhY2VUaW1lPjtcblxuICAgIG1pbkhvdXIgPSAxO1xuICAgIG1heEhvdXIgPSAxMjtcblxuICAgIHRpbWVVbml0ID0gVGltZVVuaXQ7XG4gICAgdGltZXBpY2tlclRpbWU6IHN0cmluZztcblxuICAgIGhvdXJzTGlzdDogQ2xvY2tGYWNlVGltZVtdO1xuICAgIG1pbnV0ZXNMaXN0OiBDbG9ja0ZhY2VUaW1lW107XG5cbiAgICBpc1RpbWVSYW5nZVNldDogYm9vbGVhbjtcbiAgICBpc0NoYW5nZVBlcmlvZERpc2FibGVkOiBib29sZWFuO1xuXG4gICAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW47XG4gICAgQElucHV0KCkgdG9nZ2xlSWNvbjogVGVtcGxhdGVSZWY8SFRNTE9iamVjdEVsZW1lbnQ+O1xuICAgIEBJbnB1dCgpIGJ1dHRvbkFsaWduOiAncmlnaHQnIHwgJ2xlZnQnID0gJ3JpZ2h0JztcbiAgICBASW5wdXQoKSBjbG9ja1RoZW1lOiBOZ3hNYXRlcmlhbFRpbWVwaWNrZXJUaGVtZTtcbiAgICBASW5wdXQoKSBjb250cm9sT25seTogYm9vbGVhbjtcbiAgICBASW5wdXQoKSBjYW5jZWxCdG5UbXBsOiBUZW1wbGF0ZVJlZjxOb2RlPjtcbiAgICBASW5wdXQoKSBjb25maXJtQnRuVG1wbDogVGVtcGxhdGVSZWY8Tm9kZT47XG5cbiAgICBASW5wdXQoKVxuICAgIHNldCBmb3JtYXQodmFsdWU6IG51bWJlcikge1xuICAgICAgICB0aGlzLl9mb3JtYXQgPSB2YWx1ZSA9PT0gMjQgPyAyNCA6IDEyO1xuICAgICAgICB0aGlzLm1pbkhvdXIgPSB0aGlzLl9mb3JtYXQgPT09IDEyID8gMSA6IDA7XG4gICAgICAgIHRoaXMubWF4SG91ciA9IHRoaXMuX2Zvcm1hdCA9PT0gMTIgPyAxMiA6IDIzO1xuICAgICAgICB0aGlzLmhvdXJzTGlzdCA9IFRpbWVwaWNrZXJUaW1lVXRpbHMuZ2V0SG91cnModGhpcy5fZm9ybWF0KTtcbiAgICAgICAgY29uc3QgaXNEeW5hbWljYWxseUNoYW5nZWQgPSB2YWx1ZSAmJiAodGhpcy5wcmV2aW91c0Zvcm1hdCAmJiB0aGlzLnByZXZpb3VzRm9ybWF0ICE9PSB0aGlzLl9mb3JtYXQpO1xuXG4gICAgICAgIGlmIChpc0R5bmFtaWNhbGx5Q2hhbmdlZCkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVUaW1lKHRoaXMudGltZXBpY2tlclRpbWUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucHJldmlvdXNGb3JtYXQgPSB0aGlzLl9mb3JtYXQ7XG4gICAgfVxuXG4gICAgZ2V0IGZvcm1hdCgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5fZm9ybWF0O1xuICAgIH1cblxuICAgIEBJbnB1dCgpXG4gICAgc2V0IG1pbih2YWx1ZTogc3RyaW5nIHwgRGF0ZVRpbWUpIHtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRoaXMuX21pbiA9IFRpbWVBZGFwdGVyLnBhcnNlVGltZSh2YWx1ZSwge2xvY2FsZTogdGhpcy5sb2NhbGUsIGZvcm1hdDogdGhpcy5mb3JtYXR9KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9taW4gPSB2YWx1ZTtcbiAgICB9XG5cbiAgICBnZXQgbWluKCk6IHN0cmluZyB8IERhdGVUaW1lIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21pbjtcbiAgICB9XG5cbiAgICBASW5wdXQoKVxuICAgIHNldCBtYXgodmFsdWU6IHN0cmluZyB8IERhdGVUaW1lKSB7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLl9tYXggPSBUaW1lQWRhcHRlci5wYXJzZVRpbWUodmFsdWUsIHtsb2NhbGU6IHRoaXMubG9jYWxlLCBmb3JtYXQ6IHRoaXMuZm9ybWF0fSk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fbWF4ID0gdmFsdWU7XG4gICAgfVxuXG4gICAgZ2V0IG1heCgpOiBzdHJpbmcgfCBEYXRlVGltZSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXg7XG4gICAgfVxuXG4gICAgQElucHV0KClcbiAgICBzZXQgZGVmYXVsdFRpbWUodmFsOiBzdHJpbmcpIHtcbiAgICAgICAgdGhpcy5fZGVmYXVsdFRpbWUgPSB2YWw7XG4gICAgICAgIHRoaXMuaXNEZWZhdWx0VGltZSA9ICEhdmFsO1xuICAgIH1cblxuICAgIGdldCBkZWZhdWx0VGltZSgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGVmYXVsdFRpbWU7XG4gICAgfVxuXG4gICAgQElucHV0KClcbiAgICBzZXQgbWludXRlc0dhcChnYXA6IG51bWJlcikge1xuICAgICAgICBpZiAoZ2FwID09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBnYXAgPSBNYXRoLmZsb29yKGdhcCk7XG4gICAgICAgIHRoaXMuX21pbnV0ZXNHYXAgPSBnYXAgPD0gNTkgPyBnYXAgOiAxO1xuICAgIH1cblxuICAgIGdldCBtaW51dGVzR2FwKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLl9taW51dGVzR2FwO1xuICAgIH1cblxuICAgIEBPdXRwdXQoKSB0aW1lQ2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuXG4gICAgcHJpdmF0ZSBfZGVmYXVsdFRpbWU6IHN0cmluZztcbiAgICBwcml2YXRlIF9mb3JtYXQgPSAxMjtcbiAgICBwcml2YXRlIF9taW46IHN0cmluZyB8IERhdGVUaW1lO1xuICAgIHByaXZhdGUgX21heDogc3RyaW5nIHwgRGF0ZVRpbWU7XG4gICAgcHJpdmF0ZSBfbWludXRlc0dhcDogbnVtYmVyO1xuICAgIHByaXZhdGUgcHJldmlvdXNGb3JtYXQ6IG51bWJlcjtcblxuICAgIHByaXZhdGUgdW5zdWJzY3JpYmUkID0gbmV3IFN1YmplY3QoKTtcblxuICAgIHByaXZhdGUgaXNGaXJzdFRpbWVDaGFuZ2UgPSB0cnVlO1xuICAgIHByaXZhdGUgaXNEZWZhdWx0VGltZTogYm9vbGVhbjtcbiAgICBwcml2YXRlIHNlbGVjdGVkSG91cjogbnVtYmVyO1xuXG4gICAgcHJpdmF0ZSBvbkNoYW5nZTogKHZhbHVlOiBzdHJpbmcpID0+IHZvaWQgPSAoKSA9PiB7XG4gICAgfVxuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSB0aW1lcGlja2VyU2VydmljZTogTmd4TWF0ZXJpYWxUaW1lcGlja2VyU2VydmljZSxcbiAgICAgICAgICAgICAgICBASW5qZWN0KFRJTUVfTE9DQUxFKSBwcml2YXRlIGxvY2FsZTogc3RyaW5nKSB7XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKSB7XG4gICAgICAgIHRoaXMuaW5pdFRpbWUodGhpcy5kZWZhdWx0VGltZSk7XG5cbiAgICAgICAgdGhpcy5ob3Vyc0xpc3QgPSBUaW1lcGlja2VyVGltZVV0aWxzLmdldEhvdXJzKHRoaXMuX2Zvcm1hdCk7XG4gICAgICAgIHRoaXMubWludXRlc0xpc3QgPSBUaW1lcGlja2VyVGltZVV0aWxzLmdldE1pbnV0ZXMoKTtcbiAgICAgICAgdGhpcy5pc1RpbWVSYW5nZVNldCA9ICEhKHRoaXMubWluIHx8IHRoaXMubWF4KTtcblxuICAgICAgICB0aGlzLmhvdXIkID0gdGhpcy50aW1lcGlja2VyU2VydmljZS5zZWxlY3RlZEhvdXIucGlwZShcbiAgICAgICAgICAgIHRhcCgoY2xvY2tUaW1lOiBDbG9ja0ZhY2VUaW1lKSA9PiB0aGlzLnNlbGVjdGVkSG91ciA9IGNsb2NrVGltZS50aW1lKSxcbiAgICAgICAgICAgIG1hcCh0aGlzLmNoYW5nZURlZmF1bHRUaW1lVmFsdWUuYmluZCh0aGlzKSksXG4gICAgICAgICAgICB0YXAoKCkgPT4gdGhpcy5pc1RpbWVSYW5nZVNldCAmJiB0aGlzLnVwZGF0ZUF2YWlsYWJsZU1pbnV0ZXMoKSlcbiAgICAgICAgKSBhcyBPYnNlcnZhYmxlPENsb2NrRmFjZVRpbWU+O1xuICAgICAgICB0aGlzLm1pbnV0ZSQgPSB0aGlzLnRpbWVwaWNrZXJTZXJ2aWNlLnNlbGVjdGVkTWludXRlLnBpcGUoXG4gICAgICAgICAgICBtYXAodGhpcy5jaGFuZ2VEZWZhdWx0VGltZVZhbHVlLmJpbmQodGhpcykpLFxuICAgICAgICAgICAgdGFwKCgpID0+IHRoaXMuaXNGaXJzdFRpbWVDaGFuZ2UgPSBmYWxzZSlcbiAgICAgICAgKSBhcyBPYnNlcnZhYmxlPENsb2NrRmFjZVRpbWU+O1xuXG4gICAgICAgIGlmICh0aGlzLmZvcm1hdCA9PT0gMTIpIHtcbiAgICAgICAgICAgIHRoaXMudGltZXBpY2tlclNlcnZpY2Uuc2VsZWN0ZWRQZXJpb2QucGlwZShcbiAgICAgICAgICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZDxUaW1lUGVyaW9kPigpLFxuICAgICAgICAgICAgICAgIHRhcCgocGVyaW9kOiBUaW1lUGVyaW9kKSA9PiB0aGlzLnBlcmlvZCA9IHBlcmlvZCksXG4gICAgICAgICAgICAgICAgdGFwKHBlcmlvZCA9PiB0aGlzLmlzQ2hhbmdlUGVyaW9kRGlzYWJsZWQgPSB0aGlzLmlzUGVyaW9kRGlzYWJsZWQocGVyaW9kKSksXG4gICAgICAgICAgICAgICAgdGFrZVVudGlsKHRoaXMudW5zdWJzY3JpYmUkKVxuICAgICAgICAgICAgKS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5pc1RpbWVSYW5nZVNldCAmJiB0aGlzLnVwZGF0ZUF2YWlsYWJsZVRpbWUoKSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc1RpbWVSYW5nZVNldCkge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVBdmFpbGFibGVUaW1lKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICB3cml0ZVZhbHVlKHZhbDogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGlmICh2YWwpIHtcbiAgICAgICAgICAgIHRoaXMuaW5pdFRpbWUodmFsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMucmVzZXRUaW1lKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XG4gICAgfVxuXG4gICAgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KTogdm9pZCB7XG4gICAgICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcbiAgICB9XG5cbiAgICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gICAgfVxuXG4gICAgY2hhbmdlSG91cihob3VyOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgdGhpcy50aW1lcGlja2VyU2VydmljZS5ob3VyID0gdGhpcy5ob3Vyc0xpc3QuZmluZChoID0+IGgudGltZSA9PT0gaG91cik7XG4gICAgICAgIHRoaXMuY2hhbmdlVGltZSgpO1xuICAgIH1cblxuICAgIGNoYW5nZU1pbnV0ZShtaW51dGU6IG51bWJlcik6IHZvaWQge1xuICAgICAgICB0aGlzLnRpbWVwaWNrZXJTZXJ2aWNlLm1pbnV0ZSA9IHRoaXMubWludXRlc0xpc3QuZmluZChtID0+IG0udGltZSA9PT0gbWludXRlKTtcbiAgICAgICAgdGhpcy5jaGFuZ2VUaW1lKCk7XG4gICAgfVxuXG4gICAgY2hhbmdlUGVyaW9kKHBlcmlvZDogVGltZVBlcmlvZCk6IHZvaWQge1xuICAgICAgICB0aGlzLnRpbWVwaWNrZXJTZXJ2aWNlLnBlcmlvZCA9IHBlcmlvZDtcbiAgICAgICAgdGhpcy5jaGFuZ2VUaW1lKCk7XG4gICAgfVxuXG4gICAgb25UaW1lU2V0KHRpbWU6IHN0cmluZyk6IHZvaWQge1xuICAgICAgICB0aGlzLnVwZGF0ZVRpbWUodGltZSk7XG4gICAgICAgIHRoaXMuZW1pdExvY2FsVGltZUNoYW5nZSh0aW1lKTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy51bnN1YnNjcmliZSQubmV4dCgpO1xuICAgICAgICB0aGlzLnVuc3Vic2NyaWJlJC5jb21wbGV0ZSgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgY2hhbmdlVGltZSgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgdGltZSA9IHRoaXMudGltZXBpY2tlclNlcnZpY2UuZ2V0RnVsbFRpbWUodGhpcy5mb3JtYXQpO1xuICAgICAgICB0aGlzLnRpbWVwaWNrZXJUaW1lID0gdGltZTtcblxuICAgICAgICB0aGlzLmVtaXRMb2NhbFRpbWVDaGFuZ2UodGltZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSByZXNldFRpbWUoKTogdm9pZCB7XG4gICAgICAgIHRoaXMudGltZXBpY2tlclNlcnZpY2UuaG91ciA9IHthbmdsZTogMCwgdGltZTogbnVsbH07XG4gICAgICAgIHRoaXMudGltZXBpY2tlclNlcnZpY2UubWludXRlID0ge2FuZ2xlOiAwLCB0aW1lOiBudWxsfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGVtaXRMb2NhbFRpbWVDaGFuZ2UodGltZTogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGxvY2FsVGltZSA9IFRpbWVBZGFwdGVyLnRvTG9jYWxlVGltZVN0cmluZyh0aW1lLCB7Zm9ybWF0OiB0aGlzLmZvcm1hdCwgbG9jYWxlOiB0aGlzLmxvY2FsZX0pO1xuXG4gICAgICAgIHRoaXMub25DaGFuZ2UobG9jYWxUaW1lKTtcbiAgICAgICAgdGhpcy50aW1lQ2hhbmdlZC5lbWl0KGxvY2FsVGltZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjaGFuZ2VEZWZhdWx0VGltZVZhbHVlKGNsb2NrRmFjZVRpbWU6IENsb2NrRmFjZVRpbWUpOiBDbG9ja0ZhY2VUaW1lIHtcbiAgICAgICAgaWYgKCF0aGlzLmlzRGVmYXVsdFRpbWUgJiYgdGhpcy5pc0ZpcnN0VGltZUNoYW5nZSkge1xuICAgICAgICAgICAgcmV0dXJuIHsuLi5jbG9ja0ZhY2VUaW1lLCB0aW1lOiBudWxsfTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2xvY2tGYWNlVGltZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZUF2YWlsYWJsZUhvdXJzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmhvdXJzTGlzdCA9IFRpbWVwaWNrZXJUaW1lVXRpbHMuZGlzYWJsZUhvdXJzKHRoaXMuaG91cnNMaXN0LCB7XG4gICAgICAgICAgICBtaW46IHRoaXMubWluIGFzIERhdGVUaW1lLFxuICAgICAgICAgICAgbWF4OiB0aGlzLm1heCBhcyBEYXRlVGltZSxcbiAgICAgICAgICAgIGZvcm1hdDogdGhpcy5mb3JtYXQsXG4gICAgICAgICAgICBwZXJpb2Q6IHRoaXMucGVyaW9kXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlQXZhaWxhYmxlTWludXRlcygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5taW51dGVzTGlzdCA9IFRpbWVwaWNrZXJUaW1lVXRpbHMuZGlzYWJsZU1pbnV0ZXModGhpcy5taW51dGVzTGlzdCwgdGhpcy5zZWxlY3RlZEhvdXIsIHtcbiAgICAgICAgICAgIG1pbjogdGhpcy5taW4gYXMgRGF0ZVRpbWUsXG4gICAgICAgICAgICBtYXg6IHRoaXMubWF4IGFzIERhdGVUaW1lLFxuICAgICAgICAgICAgZm9ybWF0OiB0aGlzLmZvcm1hdCxcbiAgICAgICAgICAgIHBlcmlvZDogdGhpcy5wZXJpb2RcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1cGRhdGVBdmFpbGFibGVUaW1lKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnVwZGF0ZUF2YWlsYWJsZUhvdXJzKCk7XG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkSG91cikge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVBdmFpbGFibGVNaW51dGVzKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZVRpbWUodGltZTogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGlmICh0aW1lKSB7XG4gICAgICAgICAgICBjb25zdCBmb3JtYXR0ZWRUaW1lID0gVGltZUFkYXB0ZXIuZm9ybWF0VGltZSh0aW1lLCB7bG9jYWxlOiB0aGlzLmxvY2FsZSwgZm9ybWF0OiB0aGlzLmZvcm1hdH0pO1xuICAgICAgICAgICAgdGhpcy50aW1lcGlja2VyU2VydmljZS5zZXREZWZhdWx0VGltZUlmQXZhaWxhYmxlKGZvcm1hdHRlZFRpbWUsIHRoaXMubWluIGFzIERhdGVUaW1lLCB0aGlzLm1heCBhcyBEYXRlVGltZSwgdGhpcy5mb3JtYXQpO1xuICAgICAgICAgICAgdGhpcy50aW1lcGlja2VyVGltZSA9IGZvcm1hdHRlZFRpbWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGluaXRUaW1lKHRpbWUpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgaXNEZWZhdWx0VGltZUF2YWlsYWJsZSA9IFRpbWVBZGFwdGVyXG4gICAgICAgICAgICAuaXNUaW1lQXZhaWxhYmxlKHRpbWUsIHRoaXMubWluIGFzIERhdGVUaW1lLCB0aGlzLm1heCBhcyBEYXRlVGltZSwgJ21pbnV0ZXMnLCBudWxsLCB0aGlzLmZvcm1hdCk7XG4gICAgICAgIGlmICghaXNEZWZhdWx0VGltZUF2YWlsYWJsZSkge1xuICAgICAgICAgICAgaWYgKHRoaXMubWluKSB7XG4gICAgICAgICAgICAgICAgdGhpcy51cGRhdGVUaW1lKFRpbWVBZGFwdGVyLmZyb21EYXRlVGltZVRvU3RyaW5nKHRoaXMubWluIGFzIERhdGVUaW1lLCB0aGlzLmZvcm1hdCkpO1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmICh0aGlzLm1heCkge1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlVGltZShUaW1lQWRhcHRlci5mcm9tRGF0ZVRpbWVUb1N0cmluZyh0aGlzLm1heCBhcyBEYXRlVGltZSwgdGhpcy5mb3JtYXQpKTtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51cGRhdGVUaW1lKHRpbWUpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNQZXJpb2REaXNhYmxlZChwZXJpb2QpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIFRpbWVwaWNrZXJUaW1lVXRpbHMuZGlzYWJsZUhvdXJzKFRpbWVwaWNrZXJUaW1lVXRpbHMuZ2V0SG91cnMoMTIpLCB7XG4gICAgICAgICAgICBtaW46IHRoaXMubWluIGFzIERhdGVUaW1lLFxuICAgICAgICAgICAgbWF4OiB0aGlzLm1heCBhcyBEYXRlVGltZSxcbiAgICAgICAgICAgIGZvcm1hdDogMTIsXG4gICAgICAgICAgICBwZXJpb2Q6IHBlcmlvZCA9PT0gVGltZVBlcmlvZC5BTSA/IFRpbWVQZXJpb2QuUE0gOiBUaW1lUGVyaW9kLkFNXG4gICAgICAgIH0pLmV2ZXJ5KHRpbWUgPT4gdGltZS5kaXNhYmxlZCk7XG4gICAgfVxuXG59XG4iLCI8ZGl2IGNsYXNzPVwibmd4LXRpbWVwaWNrZXJcIiBbbmdDbGFzc109XCJ7J25neC10aW1lcGlja2VyLS1kaXNhYmxlZCc6IGRpc2FibGVkfVwiPlxuICAgIDxuZ3gtdGltZXBpY2tlci10aW1lLWNvbnRyb2xcbiAgICAgICAgY2xhc3M9XCJuZ3gtdGltZXBpY2tlcl9fY29udHJvbC0tZmlyc3RcIlxuICAgICAgICBbcGxhY2Vob2xkZXJdPVwiJ0hIJ1wiXG4gICAgICAgIFt0aW1lXT1cIihob3VyJCB8IGFzeW5jKT8udGltZVwiXG4gICAgICAgIFttaW5dPVwibWluSG91clwiXG4gICAgICAgIFttYXhdPVwibWF4SG91clwiXG4gICAgICAgIFt0aW1lVW5pdF09XCJ0aW1lVW5pdC5IT1VSXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgW3RpbWVMaXN0XT1cImhvdXJzTGlzdFwiXG4gICAgICAgIFtwcmV2ZW50VHlwaW5nXT1cImlzVGltZVJhbmdlU2V0XCJcbiAgICAgICAgKHRpbWVDaGFuZ2VkKT1cImNoYW5nZUhvdXIoJGV2ZW50KVwiPjwvbmd4LXRpbWVwaWNrZXItdGltZS1jb250cm9sPlxuICAgIDxzcGFuIGNsYXNzPVwibmd4LXRpbWVwaWNrZXJfX3RpbWUtY29sb24gbmd4LXRpbWVwaWNrZXJfX2NvbnRyb2wtLXNlY29uZFwiPjo8L3NwYW4+XG4gICAgPG5neC10aW1lcGlja2VyLXRpbWUtY29udHJvbFxuICAgICAgICBjbGFzcz1cIm5neC10aW1lcGlja2VyX19jb250cm9sLS10aGlyZFwiXG4gICAgICAgIFtwbGFjZWhvbGRlcl09XCInTU0nXCJcbiAgICAgICAgW3RpbWVdPVwiKG1pbnV0ZSQgfCBhc3luYyk/LnRpbWVcIlxuICAgICAgICBbbWluXT1cIjBcIlxuICAgICAgICBbbWF4XT1cIjU5XCJcbiAgICAgICAgW3RpbWVVbml0XT1cInRpbWVVbml0Lk1JTlVURVwiXG4gICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXG4gICAgICAgIFt0aW1lTGlzdF09XCJtaW51dGVzTGlzdFwiXG4gICAgICAgIFtwcmV2ZW50VHlwaW5nXT1cImlzVGltZVJhbmdlU2V0XCJcbiAgICAgICAgW21pbnV0ZXNHYXBdPVwibWludXRlc0dhcFwiXG4gICAgICAgICh0aW1lQ2hhbmdlZCk9XCJjaGFuZ2VNaW51dGUoJGV2ZW50KVwiPjwvbmd4LXRpbWVwaWNrZXItdGltZS1jb250cm9sPlxuICAgIDxuZ3gtdGltZXBpY2tlci1wZXJpb2Qtc2VsZWN0b3JcbiAgICAgICAgY2xhc3M9XCJuZ3gtdGltZXBpY2tlcl9fY29udHJvbC0tZm9ydGhcIlxuICAgICAgICBbc2VsZWN0ZWRQZXJpb2RdPVwicGVyaW9kXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkIHx8IGlzQ2hhbmdlUGVyaW9kRGlzYWJsZWRcIlxuICAgICAgICAocGVyaW9kU2VsZWN0ZWQpPVwiY2hhbmdlUGVyaW9kKCRldmVudClcIlxuICAgICAgICAqbmdJZj1cImZvcm1hdCAhPT0gMjRcIj48L25neC10aW1lcGlja2VyLXBlcmlvZC1zZWxlY3Rvcj5cbiAgICA8bmd4LW1hdGVyaWFsLXRpbWVwaWNrZXItdG9nZ2xlXG4gICAgICAgIGNsYXNzPVwibmd4LXRpbWVwaWNrZXJfX3RvZ2dsZVwiXG4gICAgICAgICpuZ0lmPVwiIWNvbnRyb2xPbmx5XCJcbiAgICAgICAgW25nQ2xhc3NdPVwieyduZ3gtdGltZXBpY2tlcl9fdG9nZ2xlLS1sZWZ0JzogYnV0dG9uQWxpZ24gPT09ICdsZWZ0J31cIlxuICAgICAgICBbZm9yXT1cInRpbWVwaWNrZXJcIlxuICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIj5cbiAgICAgICAgPHNwYW4gbmd4TWF0ZXJpYWxUaW1lcGlja2VyVG9nZ2xlSWNvbj5cbiAgICAgICAgICAgIDwhLS1zdXBwcmVzcyBIdG1sVW5rbm93bkF0dHJpYnV0ZSAtLT5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0b2dnbGVJY29uIHx8IGRlZmF1bHRJY29uXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvc3Bhbj5cbiAgICA8L25neC1tYXRlcmlhbC10aW1lcGlja2VyLXRvZ2dsZT5cbjwvZGl2PlxuPG5neC1tYXRlcmlhbC10aW1lcGlja2VyXG4gICAgW21pbl09XCJtaW5cIlxuICAgIFttYXhdPVwibWF4XCJcbiAgICBbdGhlbWVdPVwiY2xvY2tUaGVtZVwiXG4gICAgW2RlZmF1bHRUaW1lXT1cInRpbWVwaWNrZXJUaW1lXCJcbiAgICBbZm9ybWF0XT1cImZvcm1hdFwiXG4gICAgW2NhbmNlbEJ0blRtcGxdPVwiY2FuY2VsQnRuVG1wbFwiXG4gICAgW2NvbmZpcm1CdG5UbXBsXT1cImNvbmZpcm1CdG5UbXBsXCJcbiAgICBbbWludXRlc0dhcF09XCJtaW51dGVzR2FwXCJcbiAgICAodGltZVNldCk9XCJvblRpbWVTZXQoJGV2ZW50KVwiICN0aW1lcGlja2VyPjwvbmd4LW1hdGVyaWFsLXRpbWVwaWNrZXI+XG5cbjxuZy10ZW1wbGF0ZSAjZGVmYXVsdEljb24+XG4gICAgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgdmlld0JveD1cIjAgMCAyNCAyNFwiIHdpZHRoPVwiMjRweFwiIGhlaWdodD1cIjI0cHhcIj5cbiAgICAgICAgPCEtLXN1cHByZXNzIENoZWNrRW1wdHlTY3JpcHRUYWcgLS0+XG4gICAgICAgIDxwYXRoXG4gICAgICAgICAgICBkPVwiTSAxMiAyIEMgNi40ODg5OTcxIDIgMiA2LjQ4ODk5NzEgMiAxMiBDIDIgMTcuNTExMDAzICAgICAgICAgICAgICAgICAgIDYuNDg4OTk3MSAyMiAxMiAyMiBDIDE3LjUxMTAwMyAyMiAyMiAxNy41MTEwMDMgMjIgMTIgQyAyMiA2LjQ4ODk5NzEgMTcuNTExMDAzIDIgMTIgMiB6IE0gMTIgNCBDIDE2LjQzMDEyMyA0IDIwIDcuNTY5ODc3NCAyMCAxMiBDIDIwIDE2LjQzMDEyMyAxNi40MzAxMjMgMjAgMTIgMjAgQyA3LjU2OTg3NzQgMjAgNCAxNi40MzAxMjMgNCAxMiBDIDQgNy41Njk4Nzc0IDcuNTY5ODc3NCA0IDEyIDQgeiBNIDExIDYgTCAxMSAxMi40MTQwNjIgTCAxNS4yOTI5NjkgMTYuNzA3MDMxIEwgMTYuNzA3MDMxIDE1LjI5Mjk2OSBMIDEzIDExLjU4NTkzOCBMIDEzIDYgTCAxMSA2IHpcIi8+XG4gICAgPC9zdmc+XG48L25nLXRlbXBsYXRlPlxuIl19