@material-extra/timepicker
Version:
Material timepicker component
283 lines • 37.1 kB
JavaScript
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { DOWN_ARROW } from '@angular/cdk/keycodes';
import { DecimalPipe } from '@angular/common';
import { Directive, EventEmitter, forwardRef, HostBinding, HostListener, Input, Optional, Output } from '@angular/core';
import { NG_VALIDATORS, NG_VALUE_ACCESSOR, Validators } from '@angular/forms';
import { MAT_INPUT_VALUE_ACCESSOR } from '@angular/material/input';
import { Subscription } from 'rxjs';
import { Duration } from './timepicker.model';
import { TimepickerUtil } from './timepicker.util';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/material/form-field";
export const MATE_TIMEPICKER_VALUE_ACCESSOR = {
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => MateTimepickerInputDirective),
multi: true
};
export const MATE_TIMEPICKER_VALIDATORS = {
provide: NG_VALIDATORS,
useExisting: forwardRef(() => MateTimepickerInputDirective),
multi: true
};
export class MateTimepickerInputEvent {
constructor(target, targetElement) {
this.target = target;
this.targetElement = targetElement;
this.value = this.target.value;
}
}
export class MateTimepickerInputDirective {
constructor(_decimalPipe, _elementRef, _formField) {
this._decimalPipe = _decimalPipe;
this._elementRef = _elementRef;
this._formField = _formField;
this._value = Duration.zero();
this._timepickerSubscription = Subscription.EMPTY;
/** Whether the last value set on the input was valid. */
this._lastValueValid = true;
this._disabledChange = new EventEmitter();
this._valueChange = new EventEmitter();
this.maxLength = 8;
this.timeChange = new EventEmitter();
this.timeInput = new EventEmitter();
this._onTouched = () => {
};
this._validatorOnChange = () => {
};
this._cvaOnChange = () => {
};
this._formatValidator = (control) => {
return this._lastValueValid ? null : {
matTimepickerFormat: {
text: this._elementRef.nativeElement.value,
actual: this.value
}
};
};
this._validator = Validators.compose([this._formatValidator]);
}
set mateTimepicker(value) {
if (!value) {
return;
}
this._timepicker = value;
this._timepicker._registerInput(this);
this._timepickerSubscription.unsubscribe();
this._timepickerSubscription = this._timepicker._selectedChanged.subscribe((selected) => {
this.value = selected;
this._cvaOnChange(selected);
this._onTouched();
this.timeInput.emit(new MateTimepickerInputEvent(this, this._elementRef.nativeElement));
this.timeChange.emit(new MateTimepickerInputEvent(this, this._elementRef.nativeElement));
});
}
get value() {
return this._value;
}
set value(value) {
const lastValueValid = this._lastValueValid;
this._lastValueValid = true;
const oldDate = this.value;
value = this._convertValue(value);
this._value = value;
this._formatValue(value);
if (!this.sameTime(oldDate, value)) {
this._valueChange.emit(value);
}
if (!lastValueValid) {
this._validatorOnChange();
}
}
get disabled() {
return !!this._disabled;
}
set disabled(value) {
const newValue = coerceBooleanProperty(value);
const element = this._elementRef.nativeElement;
if (this._disabled !== newValue) {
this._disabled = newValue;
this._disabledChange.emit(newValue);
}
if (newValue && element.blur) {
element.blur();
}
}
set defaultValue(value) {
this._defaultValue = this._convertValue(value);
}
get defaultValue() {
return this._defaultValue;
}
_validateRegex() {
if (this._timepicker.second) {
return /^(\d|[0-1]\d|2[0-3]):(\d|[0-5]\d):(\d|[0-5]\d)$/;
}
else {
return /^(\d|[0-1]\d|2[0-3]):(\d|[0-5]\d)$/;
}
}
ngOnDestroy() {
this._valueChange.complete();
this._disabledChange.complete();
}
_onKeydown(event) {
const isAltDownArrow = event.altKey && event.code === 'ArrowDown' || event['keyCode'] === DOWN_ARROW;
if (this._timepicker && isAltDownArrow && !this._elementRef.nativeElement.readOnly) {
this._timepicker.open();
event.preventDefault();
}
}
_emitChange(value) {
this._value = value;
this._cvaOnChange(value);
this._valueChange.emit(value);
this.timeInput.emit(new MateTimepickerInputEvent(this, this._elementRef.nativeElement));
}
_onInput(value) {
const lastValueValid = this._lastValueValid;
if (this._timepicker.repair || value == null || value.length === 0 ||
this._validateRegex().test(value)) {
this._lastValueValid = true;
const time = this._convertValue(value);
if (!this.sameTime(this._value, time))
this._emitChange(time);
else if (time == null || !lastValueValid)
this._validatorOnChange();
}
else {
this._lastValueValid = false;
this._emitChange(null);
if (lastValueValid)
this._validatorOnChange();
}
}
_onChange() {
this.timeChange.emit(new MateTimepickerInputEvent(this, this._elementRef.nativeElement));
}
_onBlur() {
// Reformat the input only if we have a valid value.
if (this._timepicker.repair || this._lastValueValid) {
this._formatValue(this.value);
}
this._onTouched();
}
_getThemePalette() {
return this._formField ? this._formField.color : undefined;
}
reformatValue() {
this._formatValue(this.value);
}
sameTime(v1, v2) {
return TimepickerUtil.isEqualsDeep(v1, v2) || v1 != null && v2 != null && typeof v1.equals === 'function' && v1.equals(v2);
}
_convertValue(value) {
if (value && !(value instanceof Duration)) {
if (typeof value === 'string') {
return Duration.fromString(value);
}
else if (typeof value === 'number') {
return Duration.fromMillis(value);
}
else if (value instanceof Date) {
return Duration.fromDate(value);
}
else {
return null;
}
}
return value;
}
_formatValue(value) {
let timeValue = '';
if (value instanceof Duration) {
timeValue = `${this._decimalPipe.transform(value.hour, '2.0')}:${this._decimalPipe.transform(value.minute, '2.0')}`;
if (this._timepicker.second) {
timeValue = typeof value.second === 'number' ?
`${timeValue}:${this._decimalPipe.transform(value.second, '2.0')}` : '';
}
}
this._elementRef.nativeElement.value = timeValue;
}
getPopupConnectionElementRef() {
return this.getConnectedOverlayOrigin();
}
getConnectedOverlayOrigin() {
return this._formField ? this._formField.getConnectedOverlayOrigin() : this._elementRef;
}
registerOnChange(fn) {
this._cvaOnChange = fn;
}
registerOnTouched(fn) {
this._onTouched = fn;
}
registerOnValidatorChange(fn) {
this._validatorOnChange = fn;
}
validate(control) {
return this._validator ? this._validator(control) : null;
}
writeValue(obj) {
this.value = obj;
}
}
MateTimepickerInputDirective.ɵfac = function MateTimepickerInputDirective_Factory(t) { return new (t || MateTimepickerInputDirective)(i0.ɵɵdirectiveInject(i1.DecimalPipe), i0.ɵɵdirectiveInject(i0.ElementRef), i0.ɵɵdirectiveInject(i2.MatFormField, 8)); };
MateTimepickerInputDirective.ɵdir = i0.ɵɵdefineDirective({ type: MateTimepickerInputDirective, selectors: [["input", "mateTimepicker", ""]], hostVars: 4, hostBindings: function MateTimepickerInputDirective_HostBindings(rf, ctx) { if (rf & 1) {
i0.ɵɵlistener("keydown", function MateTimepickerInputDirective_keydown_HostBindingHandler($event) { return ctx._onKeydown($event); })("input", function MateTimepickerInputDirective_input_HostBindingHandler($event) { return ctx._onInput($event.target.value); })("change", function MateTimepickerInputDirective_change_HostBindingHandler() { return ctx._onChange(); })("blur", function MateTimepickerInputDirective_blur_HostBindingHandler() { return ctx._onBlur(); });
} if (rf & 2) {
i0.ɵɵhostProperty("disabled", ctx.disabled)("maxLength", ctx.maxLength);
i0.ɵɵattribute("aria-haspopup", ctx._timepicker ? "dialog" : null)("aria-owns", (ctx._timepicker == null ? null : ctx._timepicker.opened) && ctx._timepicker.id || null);
} }, inputs: { mateTimepicker: "mateTimepicker", value: "value", disabled: "disabled", defaultValue: "defaultValue" }, outputs: { timeChange: "timeChange", timeInput: "timeInput" }, exportAs: ["mateDatepickerInput"], features: [i0.ɵɵProvidersFeature([
DecimalPipe,
MATE_TIMEPICKER_VALUE_ACCESSOR,
MATE_TIMEPICKER_VALIDATORS,
{ provide: MAT_INPUT_VALUE_ACCESSOR, useExisting: MateTimepickerInputDirective }
])] });
/*@__PURE__*/ (function () { i0.ɵsetClassMetadata(MateTimepickerInputDirective, [{
type: Directive,
args: [{
selector: 'input[mateTimepicker]',
providers: [
DecimalPipe,
MATE_TIMEPICKER_VALUE_ACCESSOR,
MATE_TIMEPICKER_VALIDATORS,
{ provide: MAT_INPUT_VALUE_ACCESSOR, useExisting: MateTimepickerInputDirective }
],
host: {
'[attr.aria-haspopup]': '_timepicker ? "dialog" : null',
'[attr.aria-owns]': '(_timepicker?.opened && _timepicker.id) || null',
'[disabled]': 'disabled'
},
exportAs: 'mateDatepickerInput'
}]
}], function () { return [{ type: i1.DecimalPipe }, { type: i0.ElementRef }, { type: i2.MatFormField, decorators: [{
type: Optional
}] }]; }, { maxLength: [{
type: HostBinding,
args: ['maxLength']
}], mateTimepicker: [{
type: Input
}], value: [{
type: Input
}], disabled: [{
type: Input
}], defaultValue: [{
type: Input
}], timeChange: [{
type: Output
}], timeInput: [{
type: Output
}], _onKeydown: [{
type: HostListener,
args: ['keydown', ['$event']]
}], _onInput: [{
type: HostListener,
args: ['input', ['$event.target.value']]
}], _onChange: [{
type: HostListener,
args: ['change']
}], _onBlur: [{
type: HostListener,
args: ['blur']
}] }); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXBpY2tlci1pbnB1dC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiRDovRG9jdW1lbnRzL0xpYnJhcnkvQW5ndWxhci9tYXRlcmlhbC1leHRlbmQvcHJvamVjdHMvbWF0ZXJpYWwvdGltZXBpY2tlci9zcmMvIiwic291cmNlcyI6WyJsaWIvdGltZXBpY2tlci1pbnB1dC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDNUQsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQ2pELE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUM1QyxPQUFPLEVBQ0gsU0FBUyxFQUVULFlBQVksRUFDWixVQUFVLEVBQ1YsV0FBVyxFQUNYLFlBQVksRUFDWixLQUFLLEVBRUwsUUFBUSxFQUNSLE1BQU0sRUFDVCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBR0gsYUFBYSxFQUNiLGlCQUFpQixFQUlqQixVQUFVLEVBQ2IsTUFBTSxnQkFBZ0IsQ0FBQztBQUd4QixPQUFPLEVBQUMsd0JBQXdCLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQztBQUNqRSxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBRWxDLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQztBQUM1QyxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sbUJBQW1CLENBQUM7Ozs7QUFHakQsTUFBTSxDQUFDLE1BQU0sOEJBQThCLEdBQVE7SUFDL0MsT0FBTyxFQUFFLGlCQUFpQjtJQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLDRCQUE0QixDQUFDO0lBQzNELEtBQUssRUFBRSxJQUFJO0NBQ2QsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLDBCQUEwQixHQUFRO0lBQzNDLE9BQU8sRUFBRSxhQUFhO0lBQ3RCLFdB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bUJBQUMsU0FBUyxFQUFFLENBQUMsUUFBUSxDQUFDO1lBa0JuQyxRQUFRO2tCQURQLFlBQVk7bUJBQUMsT0FBTyxFQUFFLENBQUMscUJBQXFCLENBQUM7WUFxQjlDLFNBQVM7a0JBRFIsWUFBWTttQkFBQyxRQUFRO1lBTXRCLE9BQU87a0JBRE4sWUFBWTttQkFBQyxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtjb2VyY2VCb29sZWFuUHJvcGVydHl9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2VyY2lvbic7XHJcbmltcG9ydCB7RE9XTl9BUlJPV30gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcclxuaW1wb3J0IHtEZWNpbWFsUGlwZX0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcclxuaW1wb3J0IHtcclxuICAgIERpcmVjdGl2ZSxcclxuICAgIEVsZW1lbnRSZWYsXHJcbiAgICBFdmVudEVtaXR0ZXIsXHJcbiAgICBmb3J3YXJkUmVmLFxyXG4gICAgSG9zdEJpbmRpbmcsXHJcbiAgICBIb3N0TGlzdGVuZXIsXHJcbiAgICBJbnB1dCxcclxuICAgIE9uRGVzdHJveSxcclxuICAgIE9wdGlvbmFsLFxyXG4gICAgT3V0cHV0XHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgICBBYnN0cmFjdENvbnRyb2wsXHJcbiAgICBDb250cm9sVmFsdWVBY2Nlc3NvcixcclxuICAgIE5HX1ZBTElEQVRPUlMsXHJcbiAgICBOR19WQUxVRV9BQ0NFU1NPUixcclxuICAgIFZhbGlkYXRpb25FcnJvcnMsXHJcbiAgICBWYWxpZGF0b3IsXHJcbiAgICBWYWxpZGF0b3JGbixcclxuICAgIFZhbGlkYXRvcnNcclxufSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XHJcbmltcG9ydCB7VGhlbWVQYWxldHRlfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jb3JlJztcclxuaW1wb3J0IHtNYXRGb3JtRmllbGR9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xyXG5pbXBvcnQge01BVF9JTlBVVF9WQUxVRV9BQ0NFU1NPUn0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaW5wdXQnO1xyXG5pbXBvcnQge1N1YnNjcmlwdGlvbn0gZnJvbSAncnhqcyc7XHJcblxyXG5pbXBvcnQge0R1cmF0aW9ufSBmcm9tICcuL3RpbWVwaWNrZXIubW9kZWwnO1xyXG5pbXBvcnQge1RpbWVwaWNrZXJVdGlsfSBmcm9tICcuL3RpbWVwaWNrZXIudXRpbCc7XHJcbmltcG9ydCB7TWF0ZVRpbWVwaWNrZXJDb21wb25lbnR9IGZyb20gJy4vdGltZXBpY2tlci90aW1lcGlja2VyLmNvbXBvbmVudCc7XHJcblxyXG5leHBvcnQgY29uc3QgTUFURV9USU1FUElDS0VSX1ZBTFVFX0FDQ0VTU09SOiBhbnkgPSB7XHJcbiAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcclxuICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE1hdGVUaW1lcGlja2VySW5wdXREaXJlY3RpdmUpLFxyXG4gICAgbXVsdGk6IHRydWVcclxufTtcclxuXHJcbmV4cG9ydCBjb25zdCBNQVRFX1RJTUVQSUNLRVJfVkFMSURBVE9SUzogYW55ID0ge1xyXG4gICAgcHJvdmlkZTogTkdfVkFMSURBVE9SUyxcclxuICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE1hdGVUaW1lcGlja2VySW5wdXREaXJlY3RpdmUpLFxyXG4gICAgbXVsdGk6IHRydWVcclxufTtcclxuXHJcbmV4cG9ydCBjbGFzcyBNYXRlVGltZXBpY2tlcklucHV0RXZlbnQge1xyXG4gICAgdmFsdWU6IER1cmF0aW9uO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIHB1YmxpYyB0YXJnZXQ6IE1hdGVUaW1lcGlja2VySW5wdXREaXJlY3RpdmUsXHJcbiAgICAgICAgcHVibGljIHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XHJcbiAgICAgICAgdGhpcy52YWx1ZSA9IHRoaXMudGFyZ2V0LnZhbHVlO1xyXG4gICAgfVxyXG59XHJcblxyXG5ARGlyZWN0aXZlKHtcclxuICAgIHNlbGVjdG9yOiAnaW5wdXRbbWF0ZVRpbWVwaWNrZXJdJyxcclxuICAgIHByb3ZpZGVyczogW1xyXG4gICAgICAgIERlY2ltYWxQaXBlLFxyXG4gICAgICAgIE1BVEVfVElNRVBJQ0tFUl9WQUxVRV9BQ0NFU1NPUixcclxuICAgICAgICBNQVRFX1RJTUVQSUNLRVJfVkFMSURBVE9SUyxcclxuICAgICAgICB7cHJvdmlkZTogTUFUX0lOUFVUX1ZBTFVFX0FDQ0VTU09SLCB1c2VFeGlzdGluZzogTWF0ZVRpbWVwaWNrZXJJbnB1dERpcmVjdGl2ZX1cclxuICAgIF0sXHJcbiAgICBob3N0OiB7XHJcbiAgICAgICAgJ1thdHRyLmFyaWEtaGFzcG9wdXBdJzogJ190aW1lcGlja2VyID8gXCJkaWFsb2dcIiA6IG51bGwnLFxyXG4gICAgICAgICdbYXR0ci5hcmlhLW93bnNdJzogJyhfdGltZXBpY2tlcj8ub3BlbmVkICYmIF90aW1lcGlja2VyLmlkKSB8fCBudWxsJyxcclxuICAgICAgICAnW2Rpc2FibGVkXSc6ICdkaXNhYmxlZCdcclxuICAgIH0sXHJcbiAgICBleHBvcnRBczogJ21hdGVEYXRlcGlja2VySW5wdXQnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBNYXRlVGltZXBpY2tlcklucHV0RGlyZWN0aXZlIGltcGxlbWVudHMgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE9uRGVzdHJveSwgVmFsaWRhdG9yIHtcclxuICAgIHByaXZhdGUgX3ZhbHVlOiBEdXJhdGlvbiB8IG51bGwgPSBEdXJhdGlvbi56ZXJvKCk7XHJcbiAgICBwcml2YXRlIF9kaXNhYmxlZDogYm9vbGVhbjtcclxuICAgIHByaXZhdGUgX2RlZmF1bHRWYWx1ZTogRHVyYXRpb247XHJcbiAgICBwcml2YXRlIF90aW1lcGlja2VyU3Vic2NyaXB0aW9uID0gU3Vic2NyaXB0aW9uLkVNUFRZO1xyXG4gICAgcHJpdmF0ZSBfdmFsaWRhdG9yOiBWYWxpZGF0b3JGbiB8IG51bGw7XHJcblxyXG4gICAgLyoqIFdoZXRoZXIgdGhlIGxhc3QgdmFsdWUgc2V0IG9uIHRoZSBpbnB1dCB3YXMgdmFsaWQuICovXHJcbiAgICBwcml2YXRlIF9sYXN0VmFsdWVWYWxpZCA9IHRydWU7XHJcblxyXG4gICAgcHVibGljIF90aW1lcGlja2VyOiBNYXRlVGltZXBpY2tlckNvbXBvbmVudDtcclxuICAgIHB1YmxpYyBfZGlzYWJsZWRDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XHJcbiAgICBwdWJsaWMgX3ZhbHVlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxEdXJhdGlvbiB8IG51bGw+KCk7XHJcblxyXG4gICAgQEhvc3RCaW5kaW5nKCdtYXhMZW5ndGgnKVxyXG4gICAgcHVibGljIG1heExlbmd0aCA9IDg7XHJcblxyXG4gICAgQElucHV0KClcclxuICAgIHNldCBtYXRlVGltZXBpY2tlcih2YWx1ZTogTWF0ZVRpbWVwaWNrZXJDb21wb25lbnQpIHtcclxuICAgICAgICBpZiAoIXZhbHVlKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3RpbWVwaWNrZXIgPSB2YWx1ZTtcclxuICAgICAgICB0aGlzLl90aW1lcGlja2VyLl9yZWdpc3RlcklucHV0KHRoaXMpO1xyXG4gICAgICAgIHRoaXMuX3RpbWVwaWNrZXJTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuXHJcbiAgICAgICAgdGhpcy5fdGltZXBpY2tlclN1YnNjcmlwdGlvbiA9IHRoaXMuX3RpbWVwaWNrZXIuX3NlbGVjdGVkQ2hhbmdlZC5zdWJzY3JpYmUoKHNlbGVjdGVkOiBEdXJhdGlvbikgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnZhbHVlID0gc2VsZWN0ZWQ7XHJcbiAgICAgICAgICAgIHRoaXMuX2N2YU9uQ2hhbmdlKHNlbGVjdGVkKTtcclxuICAgICAgICAgICAgdGhpcy5fb25Ub3VjaGVkKCk7XHJcbiAgICAgICAgICAgIHRoaXMudGltZUlucHV0LmVtaXQobmV3IE1hdGVUaW1lcGlja2VySW5wdXRFdmVudCh0aGlzLCB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpKTtcclxuICAgICAgICAgICAgdGhpcy50aW1lQ2hhbmdlLmVtaXQobmV3IE1hdGVUaW1lcGlja2VySW5wdXRFdmVudCh0aGlzLCB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBASW5wdXQoKVxyXG4gICAgZ2V0IHZhbHVlKCk6IER1cmF0aW9uIHwgbnVsbCB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIHNldCB2YWx1ZSh2YWx1ZTogRHVyYXRpb24gfCBudWxsKSB7XHJcbiAgICAgICAgY29uc3QgbGFzdFZhbHVlVmFsaWQgPSB0aGlzLl9sYXN0VmFsdWVWYWxpZDtcclxuICAgICAgICB0aGlzLl9sYXN0VmFsdWVWYWxpZCA9IHRydWU7XHJcbiAgICAgICAgY29uc3Qgb2xkRGF0ZSA9IHRoaXMudmFsdWU7XHJcbiAgICAgICAgdmFsdWUgPSB0aGlzLl9jb252ZXJ0VmFsdWUodmFsdWUpO1xyXG4gICAgICAgIHRoaXMuX3ZhbHVlID0gdmFsdWU7XHJcbiAgICAgICAgdGhpcy5fZm9ybWF0VmFsdWUodmFsdWUpO1xyXG5cclxuICAgICAgICBpZiAoIXRoaXMuc2FtZVRpbWUob2xkRGF0ZSwgdmFsdWUpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3ZhbHVlQ2hhbmdlLmVtaXQodmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWxhc3RWYWx1ZVZhbGlkKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRvck9uQ2hhbmdlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIEBJbnB1dCgpXHJcbiAgICBnZXQgZGlzYWJsZWQoKTogYm9vbGVhbiB7XHJcbiAgICAgICAgcmV0dXJuICEhdGhpcy5fZGlzYWJsZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0IGRpc2FibGVkKHZhbHVlOiBib29sZWFuKSB7XHJcbiAgICAgICAgY29uc3QgbmV3VmFsdWUgPSBjb2VyY2VCb29sZWFuUHJvcGVydHkodmFsdWUpO1xyXG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLl9kaXNhYmxlZCAhPT0gbmV3VmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fZGlzYWJsZWQgPSBuZXdWYWx1ZTtcclxuICAgICAgICAgICAgdGhpcy5fZGlzYWJsZWRDaGFuZ2UuZW1pdChuZXdWYWx1ZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAobmV3VmFsdWUgJiYgZWxlbWVudC5ibHVyKSB7XHJcbiAgICAgICAgICAgIGVsZW1lbnQuYmx1cigpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBASW5wdXQoKVxyXG4gICAgcHVibGljIHNldCBkZWZhdWx0VmFsdWUodmFsdWU6IER1cmF0aW9uKSB7XHJcbiAgICAgICAgdGhpcy5fZGVmYXVsdFZhbHVlID0gdGhpcy5fY29udmVydFZhbHVlKHZhbHVlKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgZ2V0IGRlZmF1bHRWYWx1ZSgpOiBEdXJhdGlvbiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2RlZmF1bHRWYWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICBAT3V0cHV0KClcclxuICAgIHJlYWRvbmx5IHRpbWVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxNYXRlVGltZXBpY2tlcklucHV0RXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxNYXRlVGltZXBpY2tlcklucHV0RXZlbnQ+KCk7XHJcblxyXG4gICAgQE91dHB1dCgpXHJcbiAgICByZWFkb25seSB0aW1lSW5wdXQ6IEV2ZW50RW1pdHRlcjxNYXRlVGltZXBpY2tlcklucHV0RXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxNYXRlVGltZXBpY2tlcklucHV0RXZlbnQ+KCk7XHJcblxyXG4gICAgcHJpdmF0ZSBfb25Ub3VjaGVkID0gKCkgPT4ge1xyXG4gICAgfTtcclxuXHJcbiAgICBwcml2YXRlIF92YWxpZGF0b3JPbkNoYW5nZSA9ICgpID0+IHtcclxuICAgIH07XHJcblxyXG4gICAgcHJpdmF0ZSBfY3ZhT25DaGFuZ2U6ICh2YWx1ZTogYW55KSA9PiB2b2lkID0gKCkgPT4ge1xyXG4gICAgfTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBwcml2YXRlIF9kZWNpbWFsUGlwZTogRGVjaW1hbFBpcGUsXHJcbiAgICAgICAgcHJpdmF0ZSBfZWxlbWVudFJlZjogRWxlbWVudFJlZjxIVE1MSW5wdXRFbGVtZW50PixcclxuICAgICAgICBAT3B0aW9uYWwoKSBwcml2YXRlIF9mb3JtRmllbGQ6IE1hdEZvcm1GaWVsZFxyXG4gICAgKSB7XHJcbiAgICAgICAgdGhpcy5fdmFsaWRhdG9yID0gVmFsaWRhdG9ycy5jb21wb3NlKFt0aGlzLl9mb3JtYXRWYWxpZGF0b3JdKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9mb3JtYXRWYWxpZGF0b3I6IFZhbGlkYXRvckZuID0gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBudWxsID0+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbGFzdFZhbHVlVmFsaWQgPyBudWxsIDoge1xyXG4gICAgICAgICAgICBtYXRUaW1lcGlja2VyRm9ybWF0OiB7XHJcbiAgICAgICAgICAgICAgICB0ZXh0OiB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQudmFsdWUsXHJcbiAgICAgICAgICAgICAgICBhY3R1YWw6IHRoaXMudmFsdWVcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICB9O1xyXG5cclxuICAgIHByaXZhdGUgX3ZhbGlkYXRlUmVnZXgoKTogUmVnRXhwIHtcclxuICAgICAgICBpZiAodGhpcy5fdGltZXBpY2tlci5zZWNvbmQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIC9eKFxcZHxbMC0xXVxcZHwyWzAtM10pOihcXGR8WzAtNV1cXGQpOihcXGR8WzAtNV1cXGQpJC87XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIC9eKFxcZHxbMC0xXVxcZHwyWzAtM10pOihcXGR8WzAtNV1cXGQpJC87XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIG5nT25EZXN0cm95KCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuX3ZhbHVlQ2hhbmdlLmNvbXBsZXRlKCk7XHJcbiAgICAgICAgdGhpcy5fZGlzYWJsZWRDaGFuZ2UuY29tcGxldGUoKTtcclxuICAgIH1cclxuXHJcbiAgICBASG9zdExpc3RlbmVyKCdrZXlkb3duJywgWyckZXZlbnQnXSlcclxuICAgIF9vbktleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcclxuICAgICAgICBjb25zdCBpc0FsdERvd25BcnJvdyA9IGV2ZW50LmFsdEtleSAmJiBldmVudC5jb2RlID09PSAnQXJyb3dEb3duJyB8fCBldmVudFsna2V5Q29kZSddID09PSBET1dOX0FSUk9XO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5fdGltZXBpY2tlciAmJiBpc0FsdERvd25BcnJvdyAmJiAhdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnJlYWRPbmx5KSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3RpbWVwaWNrZXIub3BlbigpO1xyXG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBfZW1pdENoYW5nZSh2YWx1ZTogRHVyYXRpb24gfCBudWxsKSB7XHJcbiAgICAgICAgdGhpcy5fdmFsdWUgPSB2YWx1ZTtcclxuICAgICAgICB0aGlzLl9jdmFPbkNoYW5nZSh2YWx1ZSk7XHJcbiAgICAgICAgdGhpcy5fdmFsdWVDaGFuZ2UuZW1pdCh2YWx1ZSk7XHJcbiAgICAgICAgdGhpcy50aW1lSW5wdXQuZW1pdChuZXcgTWF0ZVRpbWVwaWNrZXJJbnB1dEV2ZW50KHRoaXMsIHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudCkpO1xyXG4gICAgfVxyXG5cclxuICAgIEBIb3N0TGlzdGVuZXIoJ2lucHV0JywgWyckZXZlbnQudGFyZ2V0LnZhbHVlJ10pXHJcbiAgICBfb25JbnB1dCh2YWx1ZTogc3RyaW5nKSB7XHJcbiAgICAgICAgY29uc3QgbGFzdFZhbHVlVmFsaWQgPSB0aGlzLl9sYXN0VmFsdWVWYWxpZDtcclxuICAgICAgICBpZiAodGhpcy5fdGltZXBpY2tlci5yZXBhaXIgfHwgdmFsdWUgPT0gbnVsbCB8fCB2YWx1ZS5sZW5ndGggPT09IDAgfHxcclxuICAgICAgICAgICAgdGhpcy5fdmFsaWRhdGVSZWdleCgpLnRlc3QodmFsdWUpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xhc3RWYWx1ZVZhbGlkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHRpbWUgPSB0aGlzLl9jb252ZXJ0VmFsdWUodmFsdWUpO1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuc2FtZVRpbWUodGhpcy5fdmFsdWUsIHRpbWUpKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5fZW1pdENoYW5nZSh0aW1lKTtcclxuICAgICAgICAgICAgZWxzZSBpZiAodGltZSA9PSBudWxsIHx8ICFsYXN0VmFsdWVWYWxpZClcclxuICAgICAgICAgICAgICAgIHRoaXMuX3ZhbGlkYXRvck9uQ2hhbmdlKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5fbGFzdFZhbHVlVmFsaWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5fZW1pdENoYW5nZShudWxsKTtcclxuICAgICAgICAgICAgaWYgKGxhc3RWYWx1ZVZhbGlkKVxyXG4gICAgICAgICAgICAgICAgdGhpcy5fdmFsaWRhdG9yT25DaGFuZ2UoKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgQEhvc3RMaXN0ZW5lcignY2hhbmdlJylcclxuICAgIF9vbkNoYW5nZSgpIHtcclxuICAgICAgICB0aGlzLnRpbWVDaGFuZ2UuZW1pdChuZXcgTWF0ZVRpbWVwaWNrZXJJbnB1dEV2ZW50KHRoaXMsIHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudCkpO1xyXG4gICAgfVxyXG5cclxuICAgIEBIb3N0TGlzdGVuZXIoJ2JsdXInKVxyXG4gICAgX29uQmx1cigpIHtcclxuICAgICAgICAvLyBSZWZvcm1hdCB0aGUgaW5wdXQgb25seSBpZiB3ZSBoYXZlIGEgdmFsaWQgdmFsdWUuXHJcbiAgICAgICAgaWYgKHRoaXMuX3RpbWVwaWNrZXIucmVwYWlyIHx8IHRoaXMuX2xhc3RWYWx1ZVZhbGlkKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2Zvcm1hdFZhbHVlKHRoaXMudmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLl9vblRvdWNoZWQoKTtcclxuICAgIH1cclxuXHJcbiAgICBfZ2V0VGhlbWVQYWxldHRlKCk6IFRoZW1lUGFsZXR0ZSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2Zvcm1GaWVsZCA/IHRoaXMuX2Zvcm1GaWVsZC5jb2xvciA6IHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICByZWZvcm1hdFZhbHVlKCkge1xyXG4gICAgICAgIHRoaXMuX2Zvcm1hdFZhbHVlKHRoaXMudmFsdWUpO1xyXG4gICAgfVxyXG5cclxuICAgIHNhbWVUaW1lKHYxOiBEdXJhdGlvbiB8IG51bGwsIHYyOiBEdXJhdGlvbiB8IG51bGwpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gVGltZXBpY2tlclV0aWwuaXNFcXVhbHNEZWVwKHYxLCB2MikgfHwgdjEgIT0gbnVsbCAmJiB2MiAhPSBudWxsICYmIHR5cGVvZiB2MS5lcXVhbHMgPT09ICdmdW5jdGlvbicgJiYgdjEuZXF1YWxzKHYyKTtcclxuICAgIH1cclxuXHJcbiAgICBfY29udmVydFZhbHVlKHZhbHVlOiBhbnkpOiBEdXJhdGlvbiB8IG51bGwge1xyXG4gICAgICAgIGlmICh2YWx1ZSAmJiAhKHZhbHVlIGluc3RhbmNlb2YgRHVyYXRpb24pKSB7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gRHVyYXRpb24uZnJvbVN0cmluZyh2YWx1ZSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIER1cmF0aW9uLmZyb21NaWxsaXModmFsdWUpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIER1cmF0aW9uLmZyb21EYXRlKHZhbHVlKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB2YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIF9mb3JtYXRWYWx1ZSh2YWx1ZTogRHVyYXRpb24gfCBudWxsKSB7XHJcbiAgICAgICAgbGV0IHRpbWVWYWx1ZSA9ICcnO1xyXG4gICAgICAgIGlmICh2YWx1ZSBpbnN0YW5jZW9mIER1cmF0aW9uKSB7XHJcbiAgICAgICAgICAgIHRpbWVWYWx1ZSA9IGAke3RoaXMuX2RlY2ltYWxQaXBlLnRyYW5zZm9ybSh2YWx1ZS5ob3VyLCAnMi4wJyl9OiR7dGhpcy5fZGVjaW1hbFBpcGUudHJhbnNmb3JtKHZhbHVlLm1pbnV0ZSwgJzIuMCcpfWA7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl90aW1lcGlja2VyLnNlY29uZCkge1xyXG4gICAgICAgICAgICAgICAgdGltZVZhbHVlID0gdHlwZW9mIHZhbHVlLnNlY29uZCA9PT0gJ251bWJlcicgP1xyXG4gICAgICAgICAgICAgICAgICAgIGAke3RpbWVWYWx1ZX06JHt0aGlzLl9kZWNpbWFsUGlwZS50cmFuc2Zvcm0odmFsdWUuc2Vjb25kLCAnMi4wJyl9YCA6ICcnO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC52YWx1ZSA9IHRpbWVWYWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRQb3B1cENvbm5lY3Rpb25FbGVtZW50UmVmKCk6IEVsZW1lbnRSZWYge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmdldENvbm5lY3RlZE92ZXJsYXlPcmlnaW4oKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRDb25uZWN0ZWRPdmVybGF5T3JpZ2luKCk6IEVsZW1lbnRSZWYge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9mb3JtRmllbGQgPyB0aGlzLl9mb3JtRmllbGQuZ2V0Q29ubmVjdGVkT3ZlcmxheU9yaWdpbigpIDogdGhpcy5fZWxlbWVudFJlZjtcclxuICAgIH1cclxuXHJcbiAgICByZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLl9jdmFPbkNoYW5nZSA9IGZuO1xyXG4gICAgfVxyXG5cclxuICAgIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLl9vblRvdWNoZWQgPSBmbjtcclxuICAgIH1cclxuXHJcbiAgICByZWdpc3Rlck9uVmFsaWRhdG9yQ2hhbmdlKGZuOiAoKSA9PiB2b2lkKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5fdmFsaWRhdG9yT25DaGFuZ2UgPSBmbjtcclxuICAgIH1cclxuXHJcbiAgICB2YWxpZGF0ZShjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgbnVsbCB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3ZhbGlkYXRvciA/IHRoaXMuX3ZhbGlkYXRvcihjb250cm9sKSA6IG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgd3JpdGVWYWx1ZShvYmo6IGFueSk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMudmFsdWUgPSBvYmo7XHJcbiAgICB9XHJcbn1cclxuIl19