UNPKG

ngx-bootstrap

Version:
581 lines 47.9 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /* tslint:disable:no-forward-ref max-file-line-count */ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, forwardRef, Input, Output, ViewEncapsulation } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { TimepickerActions } from './reducer/timepicker.actions'; import { TimepickerStore } from './reducer/timepicker.store'; import { getControlsValue } from './timepicker-controls.util'; import { TimepickerConfig } from './timepicker.config'; import { isValidDate, padNumber, parseTime, isInputValid, isHourInputValid, isMinuteInputValid, isSecondInputValid, isInputLimitValid } from './timepicker.utils'; /** @type {?} */ export var TIMEPICKER_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, /* tslint:disable-next-line: no-use-before-declare */ useExisting: forwardRef(function () { return TimepickerComponent; }), multi: true }; var TimepickerComponent = /** @class */ (function () { function TimepickerComponent(_config, _cd, _store, _timepickerActions) { var _this = this; this._cd = _cd; this._store = _store; this._timepickerActions = _timepickerActions; /** * emits true if value is a valid date */ this.isValid = new EventEmitter(); // min\max validation for input fields this.invalidHours = false; this.invalidMinutes = false; this.invalidSeconds = false; // control value accessor methods // tslint:disable-next-line:no-any this.onChange = Function.prototype; // tslint:disable-next-line:no-any this.onTouched = Function.prototype; Object.assign(this, _config); this.timepickerSub = _store .select(function (state) { return state.value; }) .subscribe(function (value) { // update UI values if date changed _this._renderTime(value); _this.onChange(value); _this._store.dispatch(_this._timepickerActions.updateControls(getControlsValue(_this))); }); _store .select(function (state) { return state.controls; }) .subscribe(function (controlsState) { _this.isValid.emit(isInputValid(_this.hours, _this.minutes, _this.seconds, _this.isPM())); Object.assign(_this, controlsState); _cd.markForCheck(); }); } Object.defineProperty(TimepickerComponent.prototype, "isSpinnersVisible", { /** @deprecated - please use `isEditable` instead */ get: /** * @deprecated - please use `isEditable` instead * @return {?} */ function () { return this.showSpinners && !this.readonlyInput; }, enumerable: true, configurable: true }); Object.defineProperty(TimepickerComponent.prototype, "isEditable", { get: /** * @return {?} */ function () { return !(this.readonlyInput || this.disabled); }, enumerable: true, configurable: true }); /** * @return {?} */ TimepickerComponent.prototype.resetValidation = /** * @return {?} */ function () { this.invalidHours = false; this.invalidMinutes = false; this.invalidSeconds = false; }; /** * @return {?} */ TimepickerComponent.prototype.isPM = /** * @return {?} */ function () { return this.showMeridian && this.meridian === this.meridians[1]; }; /** * @param {?} $event * @return {?} */ TimepickerComponent.prototype.prevDef = /** * @param {?} $event * @return {?} */ function ($event) { $event.preventDefault(); }; /** * @param {?} $event * @return {?} */ TimepickerComponent.prototype.wheelSign = /** * @param {?} $event * @return {?} */ function ($event) { return Math.sign($event.deltaY) * -1; }; /** * @param {?} changes * @return {?} */ TimepickerComponent.prototype.ngOnChanges = /** * @param {?} changes * @return {?} */ function (changes) { this._store.dispatch(this._timepickerActions.updateControls(getControlsValue(this))); }; /** * @param {?} step * @param {?=} source * @return {?} */ TimepickerComponent.prototype.changeHours = /** * @param {?} step * @param {?=} source * @return {?} */ function (step, source) { if (source === void 0) { source = ''; } this.resetValidation(); this._store.dispatch(this._timepickerActions.changeHours({ step: step, source: source })); }; /** * @param {?} step * @param {?=} source * @return {?} */ TimepickerComponent.prototype.changeMinutes = /** * @param {?} step * @param {?=} source * @return {?} */ function (step, source) { if (source === void 0) { source = ''; } this.resetValidation(); this._store.dispatch(this._timepickerActions.changeMinutes({ step: step, source: source })); }; /** * @param {?} step * @param {?=} source * @return {?} */ TimepickerComponent.prototype.changeSeconds = /** * @param {?} step * @param {?=} source * @return {?} */ function (step, source) { if (source === void 0) { source = ''; } this.resetValidation(); this._store.dispatch(this._timepickerActions.changeSeconds({ step: step, source: source })); }; /** * @param {?} hours * @return {?} */ TimepickerComponent.prototype.updateHours = /** * @param {?} hours * @return {?} */ function (hours) { this.resetValidation(); this.hours = hours; /** @type {?} */ var isValid = isHourInputValid(this.hours, this.isPM()) && this.isValidLimit(); if (!isValid) { this.invalidHours = true; this.isValid.emit(false); this.onChange(null); return; } this._updateTime(); }; /** * @param {?} minutes * @return {?} */ TimepickerComponent.prototype.updateMinutes = /** * @param {?} minutes * @return {?} */ function (minutes) { this.resetValidation(); this.minutes = minutes; /** @type {?} */ var isValid = isMinuteInputValid(this.minutes) && this.isValidLimit(); if (!isValid) { this.invalidMinutes = true; this.isValid.emit(false); this.onChange(null); return; } this._updateTime(); }; /** * @param {?} seconds * @return {?} */ TimepickerComponent.prototype.updateSeconds = /** * @param {?} seconds * @return {?} */ function (seconds) { this.resetValidation(); this.seconds = seconds; /** @type {?} */ var isValid = isSecondInputValid(this.seconds) && this.isValidLimit(); if (!isValid) { this.invalidSeconds = true; this.isValid.emit(false); this.onChange(null); return; } this._updateTime(); }; /** * @return {?} */ TimepickerComponent.prototype.isValidLimit = /** * @return {?} */ function () { return isInputLimitValid({ hour: this.hours, minute: this.minutes, seconds: this.seconds, isPM: this.isPM() }, this.max, this.min); }; /** * @return {?} */ TimepickerComponent.prototype._updateTime = /** * @return {?} */ function () { /** @type {?} */ var _seconds = this.showSeconds ? this.seconds : void 0; /** @type {?} */ var _minutes = this.showMinutes ? this.minutes : void 0; if (!isInputValid(this.hours, _minutes, _seconds, this.isPM())) { this.isValid.emit(false); this.onChange(null); return; } this._store.dispatch(this._timepickerActions.setTime({ hour: this.hours, minute: this.minutes, seconds: this.seconds, isPM: this.isPM() })); }; /** * @return {?} */ TimepickerComponent.prototype.toggleMeridian = /** * @return {?} */ function () { if (!this.showMeridian || !this.isEditable) { return; } /** @type {?} */ var _hoursPerDayHalf = 12; this._store.dispatch(this._timepickerActions.changeHours({ step: _hoursPerDayHalf, source: '' })); }; /** * Write a new value to the element. */ /** * Write a new value to the element. * @param {?} obj * @return {?} */ TimepickerComponent.prototype.writeValue = /** * Write a new value to the element. * @param {?} obj * @return {?} */ function (obj) { if (isValidDate(obj)) { this._store.dispatch(this._timepickerActions.writeValue(parseTime(obj))); } else if (obj == null) { this._store.dispatch(this._timepickerActions.writeValue(null)); } }; /** * Set the function to be called when the control receives a change event. */ // tslint:disable-next-line:no-any /** * Set the function to be called when the control receives a change event. * @param {?} fn * @return {?} */ // tslint:disable-next-line:no-any TimepickerComponent.prototype.registerOnChange = /** * Set the function to be called when the control receives a change event. * @param {?} fn * @return {?} */ // tslint:disable-next-line:no-any function (fn) { this.onChange = fn; }; /** * Set the function to be called when the control receives a touch event. */ /** * Set the function to be called when the control receives a touch event. * @param {?} fn * @return {?} */ TimepickerComponent.prototype.registerOnTouched = /** * Set the function to be called when the control receives a touch event. * @param {?} fn * @return {?} */ function (fn) { this.onTouched = fn; }; /** * This function is called when the control status changes to or from "disabled". * Depending on the value, it will enable or disable the appropriate DOM element. * * @param isDisabled */ /** * This function is called when the control status changes to or from "disabled". * Depending on the value, it will enable or disable the appropriate DOM element. * * @param {?} isDisabled * @return {?} */ TimepickerComponent.prototype.setDisabledState = /** * This function is called when the control status changes to or from "disabled". * Depending on the value, it will enable or disable the appropriate DOM element. * * @param {?} isDisabled * @return {?} */ function (isDisabled) { this.disabled = isDisabled; this._cd.markForCheck(); }; /** * @return {?} */ TimepickerComponent.prototype.ngOnDestroy = /** * @return {?} */ function () { this.timepickerSub.unsubscribe(); }; /** * @private * @param {?} value * @return {?} */ TimepickerComponent.prototype._renderTime = /** * @private * @param {?} value * @return {?} */ function (value) { if (!isValidDate(value)) { this.hours = ''; this.minutes = ''; this.seconds = ''; this.meridian = this.meridians[0]; return; } /** @type {?} */ var _value = parseTime(value); /** @type {?} */ var _hoursPerDayHalf = 12; /** @type {?} */ var _hours = _value.getHours(); if (this.showMeridian) { this.meridian = this.meridians[_hours >= _hoursPerDayHalf ? 1 : 0]; _hours = _hours % _hoursPerDayHalf; // should be 12 PM, not 00 PM if (_hours === 0) { _hours = _hoursPerDayHalf; } } this.hours = padNumber(_hours); this.minutes = padNumber(_value.getMinutes()); this.seconds = padNumber(_value.getUTCSeconds()); }; TimepickerComponent.decorators = [ { type: Component, args: [{ selector: 'timepicker', changeDetection: ChangeDetectionStrategy.OnPush, providers: [TIMEPICKER_CONTROL_VALUE_ACCESSOR, TimepickerStore], template: "<table>\n <tbody>\n <tr class=\"text-center\" [hidden]=\"!showSpinners\">\n <!-- increment hours button-->\n <td>\n <a class=\"btn btn-link\" [class.disabled]=\"!canIncrementHours || !isEditable\"\n (click)=\"changeHours(hourStep)\"\n ><span class=\"bs-chevron bs-chevron-up\"></span></a>\n </td>\n <!-- divider -->\n <td *ngIf=\"showMinutes\">&nbsp;&nbsp;&nbsp;</td>\n <!-- increment minutes button -->\n <td *ngIf=\"showMinutes\">\n <a class=\"btn btn-link\" [class.disabled]=\"!canIncrementMinutes || !isEditable\"\n (click)=\"changeMinutes(minuteStep)\"\n ><span class=\"bs-chevron bs-chevron-up\"></span></a>\n </td>\n <!-- divider -->\n <td *ngIf=\"showSeconds\">&nbsp;</td>\n <!-- increment seconds button -->\n <td *ngIf=\"showSeconds\">\n <a class=\"btn btn-link\" [class.disabled]=\"!canIncrementSeconds || !isEditable\"\n (click)=\"changeSeconds(secondsStep)\">\n <span class=\"bs-chevron bs-chevron-up\"></span>\n </a>\n </td>\n <!-- space between -->\n <td *ngIf=\"showMeridian\">&nbsp;&nbsp;&nbsp;</td>\n <!-- meridian placeholder-->\n <td *ngIf=\"showMeridian\"></td>\n </tr>\n <tr>\n <!-- hours -->\n <td class=\"form-group\" [class.has-error]=\"invalidHours\">\n <input type=\"text\" [class.is-invalid]=\"invalidHours\"\n class=\"form-control text-center bs-timepicker-field\"\n placeholder=\"HH\"\n maxlength=\"2\"\n [readonly]=\"readonlyInput\"\n [disabled]=\"disabled\"\n [value]=\"hours\"\n (wheel)=\"prevDef($event);changeHours(hourStep * wheelSign($event), 'wheel')\"\n (keydown.ArrowUp)=\"changeHours(hourStep, 'key')\"\n (keydown.ArrowDown)=\"changeHours(-hourStep, 'key')\"\n (change)=\"updateHours($event.target.value)\"></td>\n <!-- divider -->\n <td *ngIf=\"showMinutes\">&nbsp;:&nbsp;</td>\n <!-- minutes -->\n <td class=\"form-group\" *ngIf=\"showMinutes\" [class.has-error]=\"invalidMinutes\">\n <input type=\"text\" [class.is-invalid]=\"invalidMinutes\"\n class=\"form-control text-center bs-timepicker-field\"\n placeholder=\"MM\"\n maxlength=\"2\"\n [readonly]=\"readonlyInput\"\n [disabled]=\"disabled\"\n [value]=\"minutes\"\n (wheel)=\"prevDef($event);changeMinutes(minuteStep * wheelSign($event), 'wheel')\"\n (keydown.ArrowUp)=\"changeMinutes(minuteStep, 'key')\"\n (keydown.ArrowDown)=\"changeMinutes(-minuteStep, 'key')\"\n (change)=\"updateMinutes($event.target.value)\">\n </td>\n <!-- divider -->\n <td *ngIf=\"showSeconds\">&nbsp;:&nbsp;</td>\n <!-- seconds -->\n <td class=\"form-group\" *ngIf=\"showSeconds\" [class.has-error]=\"invalidSeconds\">\n <input type=\"text\" [class.is-invalid]=\"invalidSeconds\"\n class=\"form-control text-center bs-timepicker-field\"\n placeholder=\"SS\"\n maxlength=\"2\"\n [readonly]=\"readonlyInput\"\n [disabled]=\"disabled\"\n [value]=\"seconds\"\n (wheel)=\"prevDef($event);changeSeconds(secondsStep * wheelSign($event), 'wheel')\"\n (keydown.ArrowUp)=\"changeSeconds(secondsStep, 'key')\"\n (keydown.ArrowDown)=\"changeSeconds(-secondsStep, 'key')\"\n (change)=\"updateSeconds($event.target.value)\">\n </td>\n <!-- space between -->\n <td *ngIf=\"showMeridian\">&nbsp;&nbsp;&nbsp;</td>\n <!-- meridian -->\n <td *ngIf=\"showMeridian\">\n <button type=\"button\" class=\"btn btn-default text-center\"\n [disabled]=\"!isEditable || !canToggleMeridian\"\n [class.disabled]=\"!isEditable || !canToggleMeridian\"\n (click)=\"toggleMeridian()\"\n >{{ meridian }}\n </button>\n </td>\n </tr>\n <tr class=\"text-center\" [hidden]=\"!showSpinners\">\n <!-- decrement hours button-->\n <td>\n <a class=\"btn btn-link\" [class.disabled]=\"!canDecrementHours || !isEditable\"\n (click)=\"changeHours(-hourStep)\">\n <span class=\"bs-chevron bs-chevron-down\"></span>\n </a>\n </td>\n <!-- divider -->\n <td *ngIf=\"showMinutes\">&nbsp;&nbsp;&nbsp;</td>\n <!-- decrement minutes button-->\n <td *ngIf=\"showMinutes\">\n <a class=\"btn btn-link\" [class.disabled]=\"!canDecrementMinutes || !isEditable\"\n (click)=\"changeMinutes(-minuteStep)\">\n <span class=\"bs-chevron bs-chevron-down\"></span>\n </a>\n </td>\n <!-- divider -->\n <td *ngIf=\"showSeconds\">&nbsp;</td>\n <!-- decrement seconds button-->\n <td *ngIf=\"showSeconds\">\n <a class=\"btn btn-link\" [class.disabled]=\"!canDecrementSeconds || !isEditable\"\n (click)=\"changeSeconds(-secondsStep)\">\n <span class=\"bs-chevron bs-chevron-down\"></span>\n </a>\n </td>\n <!-- space between -->\n <td *ngIf=\"showMeridian\">&nbsp;&nbsp;&nbsp;</td>\n <!-- meridian placeholder-->\n <td *ngIf=\"showMeridian\"></td>\n </tr>\n </tbody>\n</table>\n", encapsulation: ViewEncapsulation.None, styles: ["\n .bs-chevron {\n border-style: solid;\n display: block;\n width: 9px;\n height: 9px;\n position: relative;\n border-width: 3px 0px 0 3px;\n }\n\n .bs-chevron-up {\n -webkit-transform: rotate(45deg);\n transform: rotate(45deg);\n top: 2px;\n }\n\n .bs-chevron-down {\n -webkit-transform: rotate(-135deg);\n transform: rotate(-135deg);\n top: -2px;\n }\n\n .bs-timepicker-field {\n width: 50px;\n }\n "] }] } ]; /** @nocollapse */ TimepickerComponent.ctorParameters = function () { return [ { type: TimepickerConfig }, { type: ChangeDetectorRef }, { type: TimepickerStore }, { type: TimepickerActions } ]; }; TimepickerComponent.propDecorators = { hourStep: [{ type: Input }], minuteStep: [{ type: Input }], secondsStep: [{ type: Input }], readonlyInput: [{ type: Input }], disabled: [{ type: Input }], mousewheel: [{ type: Input }], arrowkeys: [{ type: Input }], showSpinners: [{ type: Input }], showMeridian: [{ type: Input }], showMinutes: [{ type: Input }], showSeconds: [{ type: Input }], meridians: [{ type: Input }], min: [{ type: Input }], max: [{ type: Input }], isValid: [{ type: Output }] }; return TimepickerComponent; }()); export { TimepickerComponent }; if (false) { /** * hours change step * @type {?} */ TimepickerComponent.prototype.hourStep; /** * hours change step * @type {?} */ TimepickerComponent.prototype.minuteStep; /** * seconds change step * @type {?} */ TimepickerComponent.prototype.secondsStep; /** * if true hours and minutes fields will be readonly * @type {?} */ TimepickerComponent.prototype.readonlyInput; /** * if true hours and minutes fields will be disabled * @type {?} */ TimepickerComponent.prototype.disabled; /** * if true scroll inside hours and minutes inputs will change time * @type {?} */ TimepickerComponent.prototype.mousewheel; /** * if true the values of hours and minutes can be changed using the up/down arrow keys on the keyboard * @type {?} */ TimepickerComponent.prototype.arrowkeys; /** * if true spinner arrows above and below the inputs will be shown * @type {?} */ TimepickerComponent.prototype.showSpinners; /** * if true meridian button will be shown * @type {?} */ TimepickerComponent.prototype.showMeridian; /** * show minutes in timepicker * @type {?} */ TimepickerComponent.prototype.showMinutes; /** * show seconds in timepicker * @type {?} */ TimepickerComponent.prototype.showSeconds; /** * meridian labels based on locale * @type {?} */ TimepickerComponent.prototype.meridians; /** * minimum time user can select * @type {?} */ TimepickerComponent.prototype.min; /** * maximum time user can select * @type {?} */ TimepickerComponent.prototype.max; /** * emits true if value is a valid date * @type {?} */ TimepickerComponent.prototype.isValid; /** @type {?} */ TimepickerComponent.prototype.hours; /** @type {?} */ TimepickerComponent.prototype.minutes; /** @type {?} */ TimepickerComponent.prototype.seconds; /** @type {?} */ TimepickerComponent.prototype.meridian; /** @type {?} */ TimepickerComponent.prototype.invalidHours; /** @type {?} */ TimepickerComponent.prototype.invalidMinutes; /** @type {?} */ TimepickerComponent.prototype.invalidSeconds; /** @type {?} */ TimepickerComponent.prototype.canIncrementHours; /** @type {?} */ TimepickerComponent.prototype.canIncrementMinutes; /** @type {?} */ TimepickerComponent.prototype.canIncrementSeconds; /** @type {?} */ TimepickerComponent.prototype.canDecrementHours; /** @type {?} */ TimepickerComponent.prototype.canDecrementMinutes; /** @type {?} */ TimepickerComponent.prototype.canDecrementSeconds; /** @type {?} */ TimepickerComponent.prototype.canToggleMeridian; /** @type {?} */ TimepickerComponent.prototype.onChange; /** @type {?} */ TimepickerComponent.prototype.onTouched; /** @type {?} */ TimepickerComponent.prototype.timepickerSub; /** * @type {?} * @private */ TimepickerComponent.prototype._cd; /** * @type {?} * @private */ TimepickerComponent.prototype._store; /** * @type {?} * @private */ TimepickerComponent.prototype._timepickerActions; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXBpY2tlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZ3gtYm9vdHN0cmFwL3RpbWVwaWNrZXIvIiwic291cmNlcyI6WyJ0aW1lcGlja2VyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUNBLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxZQUFZLEVBQ1osVUFBVSxFQUNWLEtBQUssRUFHTCxNQUFNLEVBQ1MsaUJBQWlCLEVBQ2pDLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV6RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUNqRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDN0QsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFRdkQsT0FBTyxFQUNMLFdBQVcsRUFDWCxTQUFTLEVBQ1QsU0FBUyxFQUNULFlBQVksRUFDWixnQkFBZ0IsRUFDaEIsa0JBQWtCLEVBQ2xCLGtCQUFrQixFQUNsQixpQkFBaUIsRUFDbEIsTUFBTSxvQkFBb0IsQ0FBQzs7QUFNNUIsTUFBTSxLQUFPLGlDQUFpQyxHQUE4QjtJQUMxRSxPQUFPLEVBQUUsaUJBQWlCOztJQUUxQixXQUFXLEVBQUUsVUFBVSxDQUFDLGNBQU0sT0FBQSxtQkFBbUIsRUFBbkIsQ0FBbUIsQ0FBQztJQUNsRCxLQUFLLEVBQUUsSUFBSTtDQUNaO0FBRUQ7SUE4R0UsNkJBQ0UsT0FBeUIsRUFDakIsR0FBc0IsRUFDdEIsTUFBdUIsRUFDdkIsa0JBQXFDO1FBSi9DLGlCQTJCQztRQXpCUyxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUN0QixXQUFNLEdBQU4sTUFBTSxDQUFpQjtRQUN2Qix1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QzdCLGtEQUE2Qjs7SUFFN0IsZ0RBQTJCOztJQUMzQixrREFBNkI7O0lBQzdCLGtEQUE2Qjs7SUFFN0IsZ0RBQTJCOztJQUkzQix1Q0FBOEI7O0lBRTlCLHdDQUErQjs7SUFFL0IsNENBQTRCOzs7OztJQUkxQixrQ0FBOEI7Ozs7O0lBQzlCLHFDQUErQjs7Ozs7SUFDL0IsaURBQTZDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGU6bm8tZm9yd2FyZC1yZWYgbWF4LWZpbGUtbGluZS1jb3VudCAqL1xuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgZm9yd2FyZFJlZixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7IFRpbWVwaWNrZXJBY3Rpb25zIH0gZnJvbSAnLi9yZWR1Y2VyL3RpbWVwaWNrZXIuYWN0aW9ucyc7XG5pbXBvcnQgeyBUaW1lcGlja2VyU3RvcmUgfSBmcm9tICcuL3JlZHVjZXIvdGltZXBpY2tlci5zdG9yZSc7XG5pbXBvcnQgeyBnZXRDb250cm9sc1ZhbHVlIH0gZnJvbSAnLi90aW1lcGlja2VyLWNvbnRyb2xzLnV0aWwnO1xuaW1wb3J0IHsgVGltZXBpY2tlckNvbmZpZyB9IGZyb20gJy4vdGltZXBpY2tlci5jb25maWcnO1xuXG5pbXBvcnQge1xuICBUaW1lQ2hhbmdlU291cmNlLFxuICBUaW1lcGlja2VyQ29tcG9uZW50U3RhdGUsXG4gIFRpbWVwaWNrZXJDb250cm9sc1xufSBmcm9tICcuL3RpbWVwaWNrZXIubW9kZWxzJztcblxuaW1wb3J0IHtcbiAgaXNWYWxpZERhdGUsXG4gIHBhZE51bWJlcixcbiAgcGFyc2VUaW1lLFxuICBpc0lucHV0VmFsaWQsXG4gIGlzSG91cklucHV0VmFsaWQsXG4gIGlzTWludXRlSW5wdXRWYWxpZCxcbiAgaXNTZWNvbmRJbnB1dFZhbGlkLFxuICBpc0lucHV0TGltaXRWYWxpZFxufSBmcm9tICcuL3RpbWVwaWNrZXIudXRpbHMnO1xuXG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3JNb2RlbCB9IGZyb20gJy4vbW9kZWxzJztcblxuZXhwb3J0IGNvbnN0IFRJTUVQSUNLRVJfQ09OVFJPTF9WQUxVRV9BQ0NFU1NPUjogQ29udHJvbFZhbHVlQWNjZXNzb3JNb2RlbCA9IHtcbiAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gIC8qIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogbm8tdXNlLWJlZm9yZS1kZWNsYXJlICovXG4gIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IFRpbWVwaWNrZXJDb21wb25lbnQpLFxuICBtdWx0aTogdHJ1ZVxufTtcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndGltZXBpY2tlcicsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBwcm92aWRlcnM6IFtUSU1FUElDS0VSX0NPTlRST0xfVkFMVUVfQUNDRVNTT1IsIFRpbWVwaWNrZXJTdG9yZV0sXG4gIHRlbXBsYXRlVXJsOiAnLi90aW1lcGlja2VyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVzOiBbYFxuICAgIC5icy1jaGV2cm9uIHtcbiAgICAgIGJvcmRlci1zdHlsZTogc29saWQ7XG4gICAgICBkaXNwbGF5OiBibG9jaztcbiAgICAgIHdpZHRoOiA5cHg7XG4gICAgICBoZWlnaHQ6IDlweDtcbiAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgIGJvcmRlci13aWR0aDogM3B4IDBweCAwIDNweDtcbiAgICB9XG5cbiAgICAuYnMtY2hldnJvbi11cCB7XG4gICAgICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDQ1ZGVnKTtcbiAgICAgIHRyYW5zZm9ybTogcm90YXRlKDQ1ZGVnKTtcbiAgICAgIHRvcDogMnB4O1xuICAgIH1cblxuICAgIC5icy1jaGV2cm9uLWRvd24ge1xuICAgICAgLXdlYmtpdC10cmFuc2Zvcm06IHJvdGF0ZSgtMTM1ZGVnKTtcbiAgICAgIHRyYW5zZm9ybTogcm90YXRlKC0xMzVkZWcpO1xuICAgICAgdG9wOiAtMnB4O1xuICAgIH1cblxuICAgIC5icy10aW1lcGlja2VyLWZpZWxkIHtcbiAgICAgIHdpZHRoOiA1MHB4O1xuICAgIH1cbiAgYF0sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmVcbn0pXG5leHBvcnQgY2xhc3MgVGltZXBpY2tlckNvbXBvbmVudFxuICBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLFxuICAgIFRpbWVwaWNrZXJDb21wb25lbnRTdGF0ZSxcbiAgICBUaW1lcGlja2VyQ29udHJvbHMsXG4gICAgT25DaGFuZ2VzLFxuICAgIE9uRGVzdHJveSB7XG4gIC8qKiBob3VycyBjaGFuZ2Ugc3RlcCAqL1xuICBASW5wdXQoKSBob3VyU3RlcDogbnVtYmVyO1xuICAvKiogaG91cnMgY2hhbmdlIHN0ZXAgKi9cbiAgQElucHV0KCkgbWludXRlU3RlcDogbnVtYmVyO1xuICAvKiogc2Vjb25kcyBjaGFuZ2Ugc3RlcCAqL1xuICBASW5wdXQoKSBzZWNvbmRzU3RlcDogbnVtYmVyO1xuICAvKiogaWYgdHJ1ZSBob3VycyBhbmQgbWludXRlcyBmaWVsZHMgd2lsbCBiZSByZWFkb25seSAqL1xuICBASW5wdXQoKSByZWFkb25seUlucHV0OiBib29sZWFuO1xuICAvKiogaWYgdHJ1ZSBob3VycyBhbmQgbWludXRlcyBmaWVsZHMgd2lsbCBiZSBkaXNhYmxlZCAqL1xuICBASW5wdXQoKSBkaXNhYmxlZDogYm9vbGVhbjtcbiAgLyoqIGlmIHRydWUgc2Nyb2xsIGluc2lkZSBob3VycyBhbmQgbWludXRlcyBpbnB1dHMgd2lsbCBjaGFuZ2UgdGltZSAqL1xuICBASW5wdXQoKSBtb3VzZXdoZWVsOiBib29sZWFuO1xuICAvKiogaWYgdHJ1ZSB0aGUgdmFsdWVzIG9mIGhvdXJzIGFuZCBtaW51dGVzIGNhbiBiZSBjaGFuZ2VkIHVzaW5nIHRoZSB1cC9kb3duIGFycm93IGtleXMgb24gdGhlIGtleWJvYXJkICovXG4gIEBJbnB1dCgpIGFycm93a2V5czogYm9vbGVhbjtcbiAgLyoqIGlmIHRydWUgc3Bpbm5lciBhcnJvd3MgYWJvdmUgYW5kIGJlbG93IHRoZSBpbnB1dHMgd2lsbCBiZSBzaG93biAqL1xuICBASW5wdXQoKSBzaG93U3Bpbm5lcnM6IGJvb2xlYW47XG4gIC8qKiBpZiB0cnVlIG1lcmlkaWFuIGJ1dHRvbiB3aWxsIGJlIHNob3duICovXG4gIEBJbnB1dCgpIHNob3dNZXJpZGlhbjogYm9vbGVhbjtcbiAgLyoqIHNob3cgbWludXRlcyBpbiB0aW1lcGlja2VyICovXG4gIEBJbnB1dCgpIHNob3dNaW51dGVzOiBib29sZWFuO1xuICAvKiogc2hvdyBzZWNvbmRzIGluIHRpbWVwaWNrZXIgKi9cbiAgQElucHV0KCkgc2hvd1NlY29uZHM6IGJvb2xlYW47XG4gIC8qKiBtZXJpZGlhbiBsYWJlbHMgYmFzZWQgb24gbG9jYWxlICovXG4gIEBJbnB1dCgpIG1lcmlkaWFuczogc3RyaW5nW107XG4gIC8qKiBtaW5pbXVtIHRpbWUgdXNlciBjYW4gc2VsZWN0ICovXG4gIEBJbnB1dCgpIG1pbjogRGF0ZTtcbiAgLyoqIG1heGltdW0gdGltZSB1c2VyIGNhbiBzZWxlY3QgKi9cbiAgQElucHV0KCkgbWF4OiBEYXRlO1xuXG4gIC8qKiBlbWl0cyB0cnVlIGlmIHZhbHVlIGlzIGEgdmFsaWQgZGF0ZSAqL1xuICBAT3V0cHV0KCkgaXNWYWxpZCA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICAvLyB1aSB2YXJpYWJsZXNcbiAgaG91cnM6IHN0cmluZztcbiAgbWludXRlczogc3RyaW5nO1xuICBzZWNvbmRzOiBzdHJpbmc7XG4gIG1lcmlkaWFuOiBzdHJpbmc7XG5cbiAgLyoqIEBkZXByZWNhdGVkIC0gcGxlYXNlIHVzZSBgaXNFZGl0YWJsZWAgaW5zdGVhZCAqL1xuICBnZXQgaXNTcGlubmVyc1Zpc2libGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2hvd1NwaW5uZXJzICYmICF0aGlzLnJlYWRvbmx5SW5wdXQ7XG4gIH1cblxuICBnZXQgaXNFZGl0YWJsZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISh0aGlzLnJlYWRvbmx5SW5wdXQgfHwgdGhpcy5kaXNhYmxlZCk7XG4gIH1cblxuICAvLyBtaW5cXG1heCB2YWxpZGF0aW9uIGZvciBpbnB1dCBmaWVsZHNcbiAgaW52YWxpZEhvdXJzID0gZmFsc2U7XG4gIGludmFsaWRNaW51dGVzID0gZmFsc2U7XG4gIGludmFsaWRTZWNvbmRzID0gZmFsc2U7XG5cbiAgLy8gdGltZSBwaWNrZXIgY29udHJvbHMgc3RhdGVcbiAgY2FuSW5jcmVtZW50SG91cnM6IGJvb2xlYW47XG4gIGNhbkluY3JlbWVudE1pbnV0ZXM6IGJvb2xlYW47XG4gIGNhbkluY3JlbWVudFNlY29uZHM6IGJvb2xlYW47XG5cbiAgY2FuRGVjcmVtZW50SG91cnM6IGJvb2xlYW47XG4gIGNhbkRlY3JlbWVudE1pbnV0ZXM6IGJvb2xlYW47XG4gIGNhbkRlY3JlbWVudFNlY29uZHM6IGJvb2xlYW47XG5cbiAgY2FuVG9nZ2xlTWVyaWRpYW46IGJvb2xlYW47XG5cbiAgLy8gY29udHJvbCB2YWx1ZSBhY2Nlc3NvciBtZXRob2RzXG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgb25DaGFuZ2UgPSBGdW5jdGlvbi5wcm90b3R5cGU7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTpuby1hbnlcbiAgb25Ub3VjaGVkID0gRnVuY3Rpb24ucHJvdG90eXBlO1xuXG4gIHRpbWVwaWNrZXJTdWI6IFN1YnNjcmlwdGlvbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBfY29uZmlnOiBUaW1lcGlja2VyQ29uZmlnLFxuICAgIHByaXZhdGUgX2NkOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIF9zdG9yZTogVGltZXBpY2tlclN0b3JlLFxuICAgIHByaXZhdGUgX3RpbWVwaWNrZXJBY3Rpb25zOiBUaW1lcGlja2VyQWN0aW9uc1xuICApIHtcbiAgICBPYmplY3QuYXNzaWduKHRoaXMsIF9jb25maWcpO1xuXG4gICAgdGhpcy50aW1lcGlja2VyU3ViID0gX3N0b3JlXG4gICAgICAuc2VsZWN0KHN0YXRlID0+IHN0YXRlLnZhbHVlKVxuICAgICAgLnN1YnNjcmliZSgodmFsdWU6IERhdGUpID0+IHtcbiAgICAgICAgLy8gdXBkYXRlIFVJIHZhbHVlcyBpZiBkYXRlIGNoYW5nZWRcbiAgICAgICAgdGhpcy5fcmVuZGVyVGltZSh2YWx1ZSk7XG4gICAgICAgIHRoaXMub25DaGFuZ2UodmFsdWUpO1xuXG4gICAgICAgIHRoaXMuX3N0b3JlLmRpc3BhdGNoKFxuICAgICAgICAgIHRoaXMuX3RpbWVwaWNrZXJBY3Rpb25zLnVwZGF0ZUNvbnRyb2xzKGdldENvbnRyb2xzVmFsdWUodGhpcykpXG4gICAgICAgICk7XG4gICAgICB9KTtcblxuICAgIF9zdG9yZVxuICAgICAgLnNlbGVjdChzdGF0ZSA9PiBzdGF0ZS5jb250cm9scylcbiAgICAgIC5zdWJzY3JpYmUoKGNvbnRyb2xzU3RhdGU6IFRpbWVwaWNrZXJDb250cm9scykgPT4ge1xuICAgICAgICB0aGlzLmlzVmFsaWQuZW1pdChpc0lucHV0VmFsaWQodGhpcy5ob3VycywgdGhpcy5taW51dGVzLCB0aGlzLnNlY29uZHMsIHRoaXMuaXNQTSgpKSk7XG4gICAgICAgIE9iamVjdC5hc3NpZ24odGhpcywgY29udHJvbHNTdGF0ZSk7XG4gICAgICAgIF9jZC5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcmVzZXRWYWxpZGF0aW9uKCk6IHZvaWQge1xuICAgIHRoaXMuaW52YWxpZEhvdXJzID0gZmFsc2U7XG4gICAgdGhpcy5pbnZhbGlkTWludXRlcyA9IGZhbHNlO1xuICAgIHRoaXMuaW52YWxpZFNlY29uZHMgPSBmYWxzZTtcbiAgfVxuXG4gIGlzUE0oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2hvd01lcmlkaWFuICYmIHRoaXMubWVyaWRpYW4gPT09IHRoaXMubWVyaWRpYW5zWzFdO1xuICB9XG5cbiAgcHJldkRlZigkZXZlbnQ6IEV2ZW50KSB7XG4gICAgJGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH1cblxuICB3aGVlbFNpZ24oJGV2ZW50OiBXaGVlbEV2ZW50SW5pdCk6IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGguc2lnbigkZXZlbnQuZGVsdGFZKSAqIC0xO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIHRoaXMuX3N0b3JlLmRpc3BhdGNoKFxuICAgICAgdGhpcy5fdGltZXBpY2tlckFjdGlvbnMudXBkYXRlQ29udHJvbHMoZ2V0Q29udHJvbHNWYWx1ZSh0aGlzKSlcbiAgICApO1xuICB9XG5cbiAgY2hhbmdlSG91cnMoc3RlcDogbnVtYmVyLCBzb3VyY2U6IFRpbWVDaGFuZ2VTb3VyY2UgPSAnJyk6IHZvaWQge1xuICAgIHRoaXMucmVzZXRWYWxpZGF0aW9uKCk7XG4gICAgdGhpcy5fc3RvcmUuZGlzcGF0Y2godGhpcy5fdGltZXBpY2tlckFjdGlvbnMuY2hhbmdlSG91cnMoeyBzdGVwLCBzb3VyY2UgfSkpO1xuICB9XG5cbiAgY2hhbmdlTWludXRlcyhzdGVwOiBudW1iZXIsIHNvdXJjZTogVGltZUNoYW5nZVNvdXJjZSA9ICcnKTogdm9pZCB7XG4gICAgdGhpcy5yZXNldFZhbGlkYXRpb24oKTtcbiAgICB0aGlzLl9zdG9yZS5kaXNwYXRjaChcbiAgICAgIHRoaXMuX3RpbWVwaWNrZXJBY3Rpb25zLmNoYW5nZU1pbnV0ZXMoeyBzdGVwLCBzb3VyY2UgfSlcbiAgICApO1xuICB9XG5cbiAgY2hhbmdlU2Vjb25kcyhzdGVwOiBudW1iZXIsIHNvdXJjZTogVGltZUNoYW5nZVNvdXJjZSA9ICcnKTogdm9pZCB7XG4gICAgdGhpcy5yZXNldFZhbGlkYXRpb24oKTtcbiAgICB0aGlzLl9zdG9yZS5kaXNwYXRjaChcbiAgICAgIHRoaXMuX3RpbWVwaWNrZXJBY3Rpb25zLmNoYW5nZVNlY29uZHMoeyBzdGVwLCBzb3VyY2UgfSlcbiAgICApO1xuICB9XG5cbiAgdXBkYXRlSG91cnMoaG91cnM6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMucmVzZXRWYWxpZGF0aW9uKCk7XG4gICAgdGhpcy5ob3VycyA9IGhvdXJzO1xuXG4gICAgY29uc3QgaXNWYWxpZCA9IGlzSG91cklucHV0VmFsaWQodGhpcy5ob3VycywgdGhpcy5pc1BNKCkpICYmIHRoaXMuaXNWYWxpZExpbWl0KCk7XG5cbiAgICBpZiAoIWlzVmFsaWQpIHtcbiAgICAgIHRoaXMuaW52YWxpZEhvdXJzID0gdHJ1ZTtcbiAgICAgIHRoaXMuaXNWYWxpZC5lbWl0KGZhbHNlKTtcbiAgICAgIHRoaXMub25DaGFuZ2UobnVsbCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl91cGRhdGVUaW1lKCk7XG4gIH1cblxuICB1cGRhdGVNaW51dGVzKG1pbnV0ZXM6IHN0cmluZykge1xuICAgIHRoaXMucmVzZXRWYWxpZGF0aW9uKCk7XG4gICAgdGhpcy5taW51dGVzID0gbWludXRlcztcblxuICAgIGNvbnN0IGlzVmFsaWQgPSBpc01pbnV0ZUlucHV0VmFsaWQodGhpcy5taW51dGVzKSAmJiB0aGlzLmlzVmFsaWRMaW1pdCgpO1xuXG4gICAgaWYgKCFpc1ZhbGlkKSB7XG4gICAgICB0aGlzLmludmFsaWRNaW51dGVzID0gdHJ1ZTtcbiAgICAgIHRoaXMuaXNWYWxpZC5lbWl0KGZhbHNlKTtcbiAgICAgIHRoaXMub25DaGFuZ2UobnVsbCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl91cGRhdGVUaW1lKCk7XG4gIH1cblxuICB1cGRhdGVTZWNvbmRzKHNlY29uZHM6IHN0cmluZykge1xuICAgIHRoaXMucmVzZXRWYWxpZGF0aW9uKCk7XG4gICAgdGhpcy5zZWNvbmRzID0gc2Vjb25kcztcblxuICAgIGNvbnN0IGlzVmFsaWQgPSBpc1NlY29uZElucHV0VmFsaWQodGhpcy5zZWNvbmRzKSAmJiB0aGlzLmlzVmFsaWRMaW1pdCgpO1xuXG4gICAgaWYgKCFpc1ZhbGlkKSB7XG4gICAgICB0aGlzLmludmFsaWRTZWNvbmRzID0gdHJ1ZTtcbiAgICAgIHRoaXMuaXNWYWxpZC5lbWl0KGZhbHNlKTtcbiAgICAgIHRoaXMub25DaGFuZ2UobnVsbCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl91cGRhdGVUaW1lKCk7XG4gIH1cblxuICBpc1ZhbGlkTGltaXQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzSW5wdXRMaW1pdFZhbGlkKHtcbiAgICAgIGhvdXI6IHRoaXMuaG91cnMsXG4gICAgICBtaW51dGU6IHRoaXMubWludXRlcyxcbiAgICAgIHNlY29uZHM6IHRoaXMuc2Vjb25kcyxcbiAgICAgIGlzUE06IHRoaXMuaXNQTSgpXG4gICAgfSwgdGhpcy5tYXgsIHRoaXMubWluKTtcbiAgfVxuXG4gIF91cGRhdGVUaW1lKCkge1xuICAgIGNvbnN0IF9zZWNvbmRzID0gdGhpcy5zaG93U2Vjb25kcyA/IHRoaXMuc2Vjb25kcyA6IHZvaWQgMDtcbiAgICBjb25zdCBfbWludXRlcyA9IHRoaXMuc2hvd01pbnV0ZXMgPyB0aGlzLm1pbnV0ZXMgOiB2b2lkIDA7XG4gICAgaWYgKCFpc0lucHV0VmFsaWQodGhpcy5ob3VycywgX21pbnV0ZXMsIF9zZWNvbmRzLCB0aGlzLmlzUE0oKSkpIHtcbiAgICAgIHRoaXMuaXNWYWxpZC5lbWl0KGZhbHNlKTtcbiAgICAgIHRoaXMub25DaGFuZ2UobnVsbCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9zdG9yZS5kaXNwYXRjaChcbiAgICAgIHRoaXMuX3RpbWVwaWNrZXJBY3Rpb25zLnNldFRpbWUoe1xuICAgICAgICBob3VyOiB0aGlzLmhvdXJzLFxuICAgICAgICBtaW51dGU6IHRoaXMubWludXRlcyxcbiAgICAgICAgc2Vjb25kczogdGhpcy5zZWNvbmRzLFxuICAgICAgICBpc1BNOiB0aGlzLmlzUE0oKVxuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgdG9nZ2xlTWVyaWRpYW4oKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnNob3dNZXJpZGlhbiB8fCAhdGhpcy5pc0VkaXRhYmxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgX2hvdXJzUGVyRGF5SGFsZiA9IDEyO1xuICAgIHRoaXMuX3N0b3JlLmRpc3BhdGNoKFxuICAgICAgdGhpcy5fdGltZXBpY2tlckFjdGlvbnMuY2hhbmdlSG91cnMoe1xuICAgICAgICBzdGVwOiBfaG91cnNQZXJEYXlIYWxmLFxuICAgICAgICBzb3VyY2U6ICcnXG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogV3JpdGUgYSBuZXcgdmFsdWUgdG8gdGhlIGVsZW1lbnQuXG4gICAqL1xuICB3cml0ZVZhbHVlKG9iajogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCB8IERhdGUpOiB2b2lkIHtcbiAgICBpZiAoaXNWYWxpZERhdGUob2JqKSkge1xuICAgICAgdGhpcy5fc3RvcmUuZGlzcGF0Y2godGhpcy5fdGltZXBpY2tlckFjdGlvbnMud3JpdGVWYWx1ZShwYXJzZVRpbWUob2JqKSkpO1xuICAgIH0gZWxzZSBpZiAob2JqID09IG51bGwpIHtcbiAgICAgIHRoaXMuX3N0b3JlLmRpc3BhdGNoKHRoaXMuX3RpbWVwaWNrZXJBY3Rpb25zLndyaXRlVmFsdWUobnVsbCkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBjb250cm9sIHJlY2VpdmVzIGEgY2hhbmdlIGV2ZW50LlxuICAgKi9cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLWFueVxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiAoXzogYW55KSA9PiB7fSk6IHZvaWQge1xuICAgIHRoaXMub25DaGFuZ2UgPSBmbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgdGhlIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCB3aGVuIHRoZSBjb250cm9sIHJlY2VpdmVzIGEgdG91Y2ggZXZlbnQuXG4gICAqL1xuICByZWdpc3Rlck9uVG91Y2hlZChmbjogKCkgPT4ge30pOiB2b2lkIHtcbiAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW4gdGhlIGNvbnRyb2wgc3RhdHVzIGNoYW5nZXMgdG8gb3IgZnJvbSBcImRpc2FibGVkXCIuXG4gICAqIERlcGVuZGluZyBvbiB0aGUgdmFsdWUsIGl0IHdpbGwgZW5hYmxlIG9yIGRpc2FibGUgdGhlIGFwcHJvcHJpYXRlIERPTSBlbGVtZW50LlxuICAgKlxuICAgKiBAcGFyYW0gaXNEaXNhYmxlZFxuICAgKi9cbiAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gICAgdGhpcy5fY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnRpbWVwaWNrZXJTdWIudW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlbmRlclRpbWUodmFsdWU6IHN0cmluZyB8IERhdGUpOiB2b2lkIHtcbiAgICBpZiAoIWlzVmFsaWREYXRlKHZhbHVlKSkge1xuICAgICAgdGhpcy5ob3VycyA9ICcnO1xuICAgICAgdGhpcy5taW51dGVzID0gJyc7XG4gICAgICB0aGlzLnNlY29uZHMgPSAnJztcbiAgICAgIHRoaXMubWVyaWRpYW4gPSB0aGlzLm1lcmlkaWFuc1swXTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IF92YWx1ZSA9IHBhcnNlVGltZSh2YWx1ZSk7XG4gICAgY29uc3QgX2hvdXJzUGVyRGF5SGFsZiA9IDEyO1xuICAgIGxldCBfaG91cnMgPSBfdmFsdWUuZ2V0SG91cnMoKTtcblxuICAgIGlmICh0aGlzLnNob3dNZXJpZGlhbikge1xuICAgICAgdGhpcy5tZXJpZGlhbiA9IHRoaXMubWVyaWRpYW5zW19ob3VycyA+PSBfaG91cnNQZXJEYXlIYWxmID8gMSA6IDBdO1xuICAgICAgX2hvdXJzID0gX2hvdXJzICUgX2hvdXJzUGVyRGF5SGFsZjtcbiAgICAgIC8vIHNob3VsZCBiZSAxMiBQTSwgbm90IDAwIFBNXG4gICAgICBpZiAoX2hvdXJzID09PSAwKSB7XG4gICAgICAgIF9ob3VycyA9IF9ob3Vyc1BlckRheUhhbGY7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5ob3VycyA9IHBhZE51bWJlcihfaG91cnMpO1xuICAgIHRoaXMubWludXRlcyA9IHBhZE51bWJlcihfdmFsdWUuZ2V0TWludXRlcygpKTtcbiAgICB0aGlzLnNlY29uZHMgPSBwYWROdW1iZXIoX3ZhbHVlLmdldFVUQ1NlY29uZHMoKSk7XG4gIH1cbn1cbiJdfQ==