UNPKG

fundamental-ngx

Version:

SAP Fiori Fundamentals, implemented in Angular

628 lines 50.6 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, ElementRef, EventEmitter, forwardRef, HostListener, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { Subject } from 'rxjs'; import { TimeComponent } from '../time/time.component'; import { DateTimeFormatParser } from './format/datetime-parser'; /** * The datetime picker component is an opinionated composition of the fd-popover, * fd-calendar and fd-time components to accomplish the UI pattern for picking a date and time. */ export class DatetimePickerComponent { /** * @hidden * @param {?} elRef * @param {?} dateTimeAdapter */ constructor(elRef, dateTimeAdapter) { this.elRef = elRef; this.dateTimeAdapter = dateTimeAdapter; /** * Placeholder for the inner input element. */ this.placeholder = 'mm/dd/yyyy, hh:mm:ss am'; /** * Whether the component should be in compact mode. */ this.compact = false; /** * The placement of the popover. It can be one of: top, top-start, top-end, bottom, * bottom-start, bottom-end, right, right-start, right-end, left, left-start, left-end. */ this.placement = 'bottom-start'; /** * Whether the time component should be meridian (am/pm). */ this.meridian = true; /** * Whether the time component shows spinners for changing the time. */ this.spinners = true; /** * Whether the time component shows seconds. */ this.displaySeconds = true; /** * Whether to perform visual validation on the picker input. */ this.validate = true; /** * Current selected date. Two-way binding is supported. */ this.date = new Date(); /** * Whether the popover is open. Two-way binding is supported. */ this.isOpen = false; /** * The disableFunction for the calendar. */ this.startingDayOfWeek = 0; /** * Aria label for the datetime picker input. */ this.datetimeInputLabel = 'Datetime input'; /** * Aria label for the button to show/hide the calendar. */ this.displayDatetimeToggleLabel = 'Display calendar toggle'; /** * Whether a null input is considered valid. */ this.allowNull = true; /** * Event emitted when the date changes. This can be a time or day change. */ this.dateChange = new EventEmitter(); /** * Event emitted when the day changes from the calendar. */ this.calendarChange = new EventEmitter(); /** * Event emitted when the time changes from the time component. */ this.timeChange = new EventEmitter(); /** * Event emitted when popover closes. */ this.onClose = new EventEmitter(); /** * @hidden Date of the input field. Internal use. * For programmatic selection, use two-way binding on the date input. */ this.inputFieldDate = null; /** * @hidden The Time object which interacts with the inner Time component. Internal use. */ this.isInvalidDateInput = false; /** * @hidden Observable used internally. */ this.dateFromInput = new Subject(); /** * @hidden The Time object which interacts with the inner Time component. Internal use. */ this.time = { hour: 0, minute: 0, second: 0 }; /** * @hidden The CalendarDay object which interacts with the inner Calendar component. Internal use. */ this.selectedDay = { date: null }; this.disableFunction = (/** * @param {?} d * @return {?} */ function (d) { return false; }); /** * The blockFunction for the calendar. */ this.blockFunction = (/** * @param {?} d * @return {?} */ function (d) { return false; }); this.disableRangeStartFunction = (/** * @param {?} d * @return {?} */ function (d) { return false; }); this.disableRangeEndFunction = (/** * @param {?} d * @return {?} */ function (d) { return false; }); this.blockRangeStartFunction = (/** * @param {?} d * @return {?} */ function (d) { return false; }); this.blockRangeEndFunction = (/** * @param {?} d * @return {?} */ function (d) { return false; }); /** * @hidden */ this.onChange = (/** * @return {?} */ () => { }); /** * @hidden */ this.onTouched = (/** * @return {?} */ () => { }); } /** * Toggles the popover. * @return {?} */ togglePopover() { this.onTouched(this.selectedDay.date); if (this.isOpen) { this.closePopover(); } else { this.openPopover(); } } /** * Opens the popover. * @param {?=} inputFieldDate * @return {?} */ openPopover(inputFieldDate) { if (!this.isOpen && !this.disabled) { this.onTouched(this.selectedDay.date); this.isOpen = true; if (inputFieldDate !== null && inputFieldDate !== '' && !this.isInvalidDateInput) { this.inputValueChange(this.date); } } } /** * Closes the popover * @return {?} */ closePopover() { if (this.isOpen) { this.onClose.emit(this.date); this.isOpen = false; } } /** * @param {?} d * @return {?} */ updatePickerInputHandler(d) { if (d.selectedDay && d.selectedDay.date) { d.selectedDay.date.setHours(this.date.getHours()); d.selectedDay.date.setMinutes(this.date.getMinutes()); d.selectedDay.date.setSeconds(this.date.getSeconds()); d.selectedDay.date.setMilliseconds(this.date.getMilliseconds()); /** @type {?} */ const previous = this.date.getTime(); this.selectedDay = d.selectedDay; this.date = d.selectedDay.date; this.inputFieldDate = this.dateTimeAdapter.format(this.date); this.time = { hour: this.date.getHours(), minute: this.date.getMinutes(), second: this.date.getSeconds() }; if (this.date.getTime() !== previous) { this.calendarChange.emit(this.date); this.dateChange.emit(this.date); this.onChange(this.date); } } else if (d === '') { this.selectedDay.date = null; this.selectedDay.selected = null; this.time.second = null; this.time.minute = null; this.time.hour = null; this.timeComponent.displayedHour = null; this.timeComponent.period = 'am'; this.timeComponent.oldPeriod = 'am'; this.calendarChange.emit(null); this.timeChange.emit(null); this.dateChange.emit(null); this.onChange(this.selectedDay.date); } } /** * @hidden * @param {?} e * @return {?} */ isInvalidDateInputHandler(e) { this.isInvalidDateInput = e; } /** * @hidden * @param {?} e * @return {?} */ inputValueChange(e) { /** @type {?} */ let temp; if (typeof e === 'string') { temp = this.dateTimeAdapter.parse(e); } else { temp = new Date(e); } /* Need to check if current locale toDateString contains AM or PM. If the current locale has it and it is absent from the user's input, the meridian should be considered invalid */ /** @type {?} */ const localeMeridian = new Date().toLocaleTimeString().slice(-2); /** @type {?} */ let meridianValid = true; if ((localeMeridian === 'AM' || localeMeridian === 'PM') && (typeof e === 'string' && e.slice(-2) !== 'AM' && e.slice(-2) !== 'PM')) { meridianValid = false; } if (meridianValid && temp && temp.toLocaleDateString() !== 'Invalid Date') { /** @type {?} */ const newValue = { hour: temp.getHours(), minute: temp.getMinutes(), second: temp.getSeconds() }; if (newValue.hour !== this.time.hour || newValue.minute !== this.time.minute || newValue.second !== this.time.second) { this.time = newValue; this.setTime(true); } this.dateFromInput.next(temp.toLocaleDateString()); } else if (e === '' && this.allowNull) { this.isInvalidDateInput = false; this.dateFromInput.next(''); } else { this.isInvalidDateInput = true; } } /** * @hidden * @return {?} */ onEscapeKeydownHandler() { this.closePopover(); } /** * @hidden * @param {?} event * @return {?} */ onGlobalClick(event) { if (!this.elRef.nativeElement.contains(event.target)) { this.closePopover(); } } /** * @hidden * @return {?} */ ngOnInit() { if (this.date && this.inputFieldDate !== null) { this.selectedDay.date = this.date; this.time = { hour: this.date.getHours(), minute: this.date.getMinutes(), second: this.date.getSeconds() }; } if (this.dateFromInput) { this.dateFromInputSubscription = this.dateFromInput.subscribe((/** * @param {?} date * @return {?} */ date => { this.updatePickerInputHandler(date); })); } } /** * @hidden * @return {?} */ ngOnDestroy() { if (this.dateFromInputSubscription) { this.dateFromInputSubscription.unsubscribe(); } } /** * @hidden * @param {?} fn * @return {?} */ registerOnChange(fn) { this.onChange = fn; } /** * @hidden * @param {?} fn * @return {?} */ registerOnTouched(fn) { this.onTouched = fn; } /** * @hidden * @param {?} isDisabled * @return {?} */ setDisabledState(isDisabled) { this.disabled = isDisabled; } /** * @hidden * @param {?} selected * @return {?} */ writeValue(selected) { if (!selected) { return; } this.selectedDay.date = selected; this.time = { hour: selected.getHours(), minute: selected.getMinutes(), second: selected.getSeconds() }; this.date = this.selectedDay.date; this.setTime(); } /** * @hidden * @param {?=} fireEvents * @return {?} */ setTime(fireEvents = false) { this.date.setHours(this.time.hour); this.date.setMinutes(this.time.minute); this.date.setSeconds(this.time.second); this.inputFieldDate = this.dateTimeAdapter.format(this.date); if (fireEvents) { this.timeChange.emit(this.date); this.dateChange.emit(this.date); this.onChange(this.date); } } /** * @hidden * @return {?} */ focusArrowLeft() { this.elRef.nativeElement.querySelector('#arrowLeft').focus(); } } DatetimePickerComponent.decorators = [ { type: Component, args: [{ selector: 'fd-datetime-picker', template: "<div class=\"fd-datetime\">\n <fd-popover [(isOpen)]=\"isOpen\"\n [closeOnOutsideClick]=\"false\"\n [closeOnEscapeKey]=\"false\"\n [triggers]=\"[]\"\n [disabled]=\"disabled\"\n [placement]=\"placement\">\n <fd-popover-control>\n <div class=\"fd-input-group fd-input-group--after\"\n [ngClass]=\"{'fd-input-group--compact' : compact}\">\n <input type=\"text\"\n [attr.aria-label]=\"datetimeInputLabel\"\n [(ngModel)]=\"inputFieldDate\"\n [placeholder]=\"placeholder\"\n (keyup.enter)=\"inputValueChange(inputFieldDate)\"\n (blur)=\"inputValueChange(inputFieldDate)\"\n (click)=\"openPopover(inputFieldDate)\"\n [ngClass]=\"{ 'fd-input--compact': compact, 'is-invalid': isInvalidDateInput && validate }\"\n [disabled]=\"disabled\">\n <span class=\"fd-input-group__addon fd-input-group__addon--after fd-input-group__addon--button\">\n <button class=\"fd-popover__control fd-button--icon fd-button--light sap-icon--date-time\"\n (click)=\"togglePopover()\" [attr.aria-label]=\"displayDatetimeToggleLabel\"\n [attr.aria-expanded]=\"isOpen\" type=\"button\" [disabled]=\"disabled\"></button>\n </span>\n </div>\n </fd-popover-control>\n <fd-popover-body\n [attr.aria-expanded]=\"isOpen\"\n [attr.aria-hidden]=\"!isOpen\"\n [style.display]=\"'block'\">\n <div class=\"fd-datetime__container\">\n <fd-calendar calType=\"single\"\n (closeCalendar)=\"closePopover()\"\n [disableFunction]=\"disableFunction ? disableFunction : null\"\n [blockFunction]=\"blockFunction ? blockFunction : null\"\n [disableRangeStartFunction]=\"disableRangeStartFunction ? disableRangeStartFunction : null\"\n [disableRangeEndFunction]=\"disableRangeEndFunction ? disableRangeEndFunction : null\"\n [blockRangeStartFunction]=\"blockRangeStartFunction ? blockRangeStartFunction : null\"\n [blockRangeEndFunction]=\"blockRangeEndFunction ? blockRangeEndFunction : null\"\n [(selectedDay)]=\"selectedDay\"\n (isInvalidDateInput)=\"isInvalidDateInputHandler($event)\"\n [dateFromDatePicker]=\"dateFromInput\"\n [allowFocusEscape]=\"true\"\n [startingDayOfWeek]=\"startingDayOfWeek\"></fd-calendar>\n <div class=\"fd-datetime__separator\"></div>\n <fd-time [disabled]=\"disabled\"\n [meridian]=\"meridian\"\n [(ngModel)]=\"time\"\n (ngModelChange)=\"setTime(true)\"\n [spinners]=\"spinners\"\n [displaySeconds]=\"displaySeconds\"\n (focusArrowLeft)=\"focusArrowLeft()\"></fd-time>\n </div>\n </fd-popover-body>\n </fd-popover>\n</div>\n", host: { '(blur)': 'onTouched()', '[class.fd-datetime-host]': 'true' }, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/** * @return {?} */ () => DatetimePickerComponent)), multi: true } ], encapsulation: ViewEncapsulation.None, styles: [".fd-datetime-host{display:inline-block;width:230px}.fd-datetime-host .fd-datetime{display:block}.fd-datetime-host .fd-datetime__container{display:flex;align-items:center;margin:0 16px}.fd-datetime-host .fd-datetime__separator{background-color:#d3d3d3;width:1px;margin:42px 28px;-ms-grid-row-align:stretch;align-self:stretch}.fd-datetime-host .fd-datetime fd-popover{display:block}.fd-datetime-host .fd-datetime fd-time{width:auto}"] }] } ]; /** @nocollapse */ DatetimePickerComponent.ctorParameters = () => [ { type: ElementRef }, { type: DateTimeFormatParser } ]; DatetimePickerComponent.propDecorators = { timeComponent: [{ type: ViewChild, args: [TimeComponent,] }], placeholder: [{ type: Input }], compact: [{ type: Input }], placement: [{ type: Input }], meridian: [{ type: Input }], disabled: [{ type: Input }], spinners: [{ type: Input }], displaySeconds: [{ type: Input }], validate: [{ type: Input }], date: [{ type: Input }], isOpen: [{ type: Input }], startingDayOfWeek: [{ type: Input }], datetimeInputLabel: [{ type: Input }], displayDatetimeToggleLabel: [{ type: Input }], allowNull: [{ type: Input }], dateChange: [{ type: Output }], calendarChange: [{ type: Output }], timeChange: [{ type: Output }], onClose: [{ type: Output }], disableFunction: [{ type: Input }], blockFunction: [{ type: Input }], disableRangeStartFunction: [{ type: Input }], disableRangeEndFunction: [{ type: Input }], blockRangeStartFunction: [{ type: Input }], blockRangeEndFunction: [{ type: Input }], onEscapeKeydownHandler: [{ type: HostListener, args: ['document:keydown.escape', [],] }], onGlobalClick: [{ type: HostListener, args: ['document:click', ['$event'],] }] }; if (false) { /** * @hidden Reference to the inner time component. * @type {?} */ DatetimePickerComponent.prototype.timeComponent; /** * Placeholder for the inner input element. * @type {?} */ DatetimePickerComponent.prototype.placeholder; /** * Whether the component should be in compact mode. * @type {?} */ DatetimePickerComponent.prototype.compact; /** * The placement of the popover. It can be one of: top, top-start, top-end, bottom, * bottom-start, bottom-end, right, right-start, right-end, left, left-start, left-end. * @type {?} */ DatetimePickerComponent.prototype.placement; /** * Whether the time component should be meridian (am/pm). * @type {?} */ DatetimePickerComponent.prototype.meridian; /** * Whether the component is disabled. * @type {?} */ DatetimePickerComponent.prototype.disabled; /** * Whether the time component shows spinners for changing the time. * @type {?} */ DatetimePickerComponent.prototype.spinners; /** * Whether the time component shows seconds. * @type {?} */ DatetimePickerComponent.prototype.displaySeconds; /** * Whether to perform visual validation on the picker input. * @type {?} */ DatetimePickerComponent.prototype.validate; /** * Current selected date. Two-way binding is supported. * @type {?} */ DatetimePickerComponent.prototype.date; /** * Whether the popover is open. Two-way binding is supported. * @type {?} */ DatetimePickerComponent.prototype.isOpen; /** * The disableFunction for the calendar. * @type {?} */ DatetimePickerComponent.prototype.startingDayOfWeek; /** * Aria label for the datetime picker input. * @type {?} */ DatetimePickerComponent.prototype.datetimeInputLabel; /** * Aria label for the button to show/hide the calendar. * @type {?} */ DatetimePickerComponent.prototype.displayDatetimeToggleLabel; /** * Whether a null input is considered valid. * @type {?} */ DatetimePickerComponent.prototype.allowNull; /** * Event emitted when the date changes. This can be a time or day change. * @type {?} */ DatetimePickerComponent.prototype.dateChange; /** * Event emitted when the day changes from the calendar. * @type {?} */ DatetimePickerComponent.prototype.calendarChange; /** * Event emitted when the time changes from the time component. * @type {?} */ DatetimePickerComponent.prototype.timeChange; /** * Event emitted when popover closes. * @type {?} */ DatetimePickerComponent.prototype.onClose; /** * @hidden Date of the input field. Internal use. * For programmatic selection, use two-way binding on the date input. * @type {?} */ DatetimePickerComponent.prototype.inputFieldDate; /** * @hidden The Time object which interacts with the inner Time component. Internal use. * @type {?} */ DatetimePickerComponent.prototype.isInvalidDateInput; /** * @hidden Observable used internally. * @type {?} */ DatetimePickerComponent.prototype.dateFromInput; /** * @hidden The Time object which interacts with the inner Time component. Internal use. * @type {?} */ DatetimePickerComponent.prototype.time; /** * @hidden The CalendarDay object which interacts with the inner Calendar component. Internal use. * @type {?} */ DatetimePickerComponent.prototype.selectedDay; /** * Subscription of the dateFromInput. * @type {?} * @private */ DatetimePickerComponent.prototype.dateFromInputSubscription; /** @type {?} */ DatetimePickerComponent.prototype.disableFunction; /** * The blockFunction for the calendar. * @type {?} */ DatetimePickerComponent.prototype.blockFunction; /** @type {?} */ DatetimePickerComponent.prototype.disableRangeStartFunction; /** @type {?} */ DatetimePickerComponent.prototype.disableRangeEndFunction; /** @type {?} */ DatetimePickerComponent.prototype.blockRangeStartFunction; /** @type {?} */ DatetimePickerComponent.prototype.blockRangeEndFunction; /** * @hidden * @type {?} */ DatetimePickerComponent.prototype.onChange; /** * @hidden * @type {?} */ DatetimePickerComponent.prototype.onTouched; /** * @type {?} * @private */ DatetimePickerComponent.prototype.elRef; /** * @type {?} * @private */ DatetimePickerComponent.prototype.dateTimeAdapter; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXRpbWUtcGlja2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2Z1bmRhbWVudGFsLW5neC8iLCJzb3VyY2VzIjpbImxpYi9kYXRldGltZS1waWNrZXIvZGF0ZXRpbWUtcGlja2VyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUNILFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixZQUFZLEVBQ1osS0FBSyxFQUdMLE1BQU0sRUFDTixTQUFTLEVBQ1QsaUJBQWlCLEVBQ3BCLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RSxPQUFPLEVBQUUsT0FBTyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUU3QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFdkQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7Ozs7O0FBdUJoRSxNQUFNLE9BQU8sdUJBQXVCOzs7Ozs7SUE4UWhDLFlBQW9CLEtBQWlCLEVBQ2pCLGVBQXFDO1FBRHJDLFVBQUssR0FBTCxLQUFLLENBQVk7UUFDakIsb0JBQWUsR0FBZixlQUFlLENBQXNCOzs7O1FBdlF6RCxnQkFBVyxHQUFXLHlCQUF5QixDQUFDOzs7O1FBSWhELFlBQU8sR0FBWSxLQUFLLENBQUM7Ozs7O1FBS3pCLGNBQVMsR0FBYyxjQUFjLENBQUM7Ozs7UUFJdEMsYUFBUSxHQUFZLElBQUksQ0FBQzs7OztRQVF6QixhQUFRLEdBQVksSUFBSSxDQUFDOzs7O1FBSXpCLG1CQUFjLEdBQVksSUFBSSxDQUFDOzs7O1FBSS9CLGFBQVEsR0FBWSxJQUFJLENBQUM7Ozs7UUFJekIsU0FBSSxHQUFTLElBQUksSUFBSSxFQUFFLENBQUM7Ozs7UUFJeEIsV0FBTSxHQUFZLEtBQUssQ0FBQzs7OztRQUl4QixzQkFBaUIsR0FBVyxDQUFDLENB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TCxLQUFLO2dDQUlMLEtBQUs7aUNBSUwsS0FBSzt5Q0FJTCxLQUFLO3dCQUlMLEtBQUs7eUJBSUwsTUFBTTs2QkFJTixNQUFNO3lCQUlOLE1BQU07c0JBSU4sTUFBTTs4QkEwQk4sS0FBSzs0QkFNTCxLQUFLO3dDQUlMLEtBQUs7c0NBSUwsS0FBSztzQ0FJTCxLQUFLO29DQUlMLEtBQUs7cUNBZ0hMLFlBQVksU0FBQyx5QkFBeUIsRUFBRSxFQUFFOzRCQU0xQyxZQUFZLFNBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxRQUFRLENBQUM7Ozs7Ozs7SUEvTzFDLGdEQUM2Qjs7Ozs7SUFHN0IsOENBQ2dEOzs7OztJQUdoRCwwQ0FDeUI7Ozs7OztJQUl6Qiw0Q0FDc0M7Ozs7O0lBR3RDLDJDQUN5Qjs7Ozs7SUFHekIsMkNBQ2tCOzs7OztJQUdsQiwyQ0FDeUI7Ozs7O0lBR3pCLGlEQUMrQjs7Ozs7SUFHL0IsMkNBQ3lCOzs7OztJQUd6Qix1Q0FDd0I7Ozs7O0lBR3hCLHlDQUN3Qjs7Ozs7SUFHeEIsb0RBQzhCOzs7OztJQUc5QixxREFDOEM7Ozs7O0lBRzlDLDZEQUMrRDs7Ozs7SUFHL0QsNENBQzBCOzs7OztJQUcxQiw2Q0FDbUU7Ozs7O0lBR25FLGlEQUN1RTs7Ozs7SUFHdkUsNkNBQ21FOzs7OztJQUduRSwwQ0FDZ0U7Ozs7OztJQU1oRSxpREFBc0I7Ozs7O0lBR3RCLHFEQUFvQzs7Ozs7SUFHcEMsZ0RBQStDOzs7OztJQUcvQyx1Q0FBcUQ7Ozs7O0lBR3JELDhDQUVFOzs7Ozs7SUFHRiw0REFBZ0Q7O0lBRWhELGtEQUdFOzs7OztJQUdGLGdEQUdFOztJQUNGLDREQUdFOztJQUNGLDBEQUdFOztJQUNGLDBEQUdFOztJQUNGLHdEQUdFOzs7OztJQUdGLDJDQUF5Qjs7Ozs7SUFHekIsNENBQTBCOzs7OztJQXlJZCx3Q0FBeUI7Ozs7O0lBQ3pCLGtEQUE2QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgQ29tcG9uZW50LFxuICAgIEVsZW1lbnRSZWYsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIGZvcndhcmRSZWYsIEhvc3RCaW5kaW5nLFxuICAgIEhvc3RMaXN0ZW5lcixcbiAgICBJbnB1dCxcbiAgICBPbkRlc3Ryb3ksXG4gICAgT25Jbml0LFxuICAgIE91dHB1dCxcbiAgICBWaWV3Q2hpbGQsXG4gICAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDYWxlbmRhckRheSB9IGZyb20gJy4uL2NhbGVuZGFyL2NhbGVuZGFyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFRpbWVPYmplY3QgfSBmcm9tICcuLi90aW1lL3RpbWUtb2JqZWN0JztcbmltcG9ydCB7IFRpbWVDb21wb25lbnQgfSBmcm9tICcuLi90aW1lL3RpbWUuY29tcG9uZW50JztcbmltcG9ydCB7IFBsYWNlbWVudCB9IGZyb20gJ3BvcHBlci5qcyc7XG5pbXBvcnQgeyBEYXRlVGltZUZvcm1hdFBhcnNlciB9IGZyb20gJy4vZm9ybWF0L2RhdGV0aW1lLXBhcnNlcic7XG5cbi8qKlxuICogVGhlIGRhdGV0aW1lIHBpY2tlciBjb21wb25lbnQgaXMgYW4gb3BpbmlvbmF0ZWQgY29tcG9zaXRpb24gb2YgdGhlIGZkLXBvcG92ZXIsXG4gKiBmZC1jYWxlbmRhciBhbmQgZmQtdGltZSBjb21wb25lbnRzIHRvIGFjY29tcGxpc2ggdGhlIFVJIHBhdHRlcm4gZm9yIHBpY2tpbmcgYSBkYXRlIGFuZCB0aW1lLlxuICovXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2ZkLWRhdGV0aW1lLXBpY2tlcicsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2RhdGV0aW1lLXBpY2tlci5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vZGF0ZXRpbWUtcGlja2VyLmNvbXBvbmVudC5zY3NzJ10sXG4gICAgaG9zdDoge1xuICAgICAgICAnKGJsdXIpJzogJ29uVG91Y2hlZCgpJyxcbiAgICAgICAgJ1tjbGFzcy5mZC1kYXRldGltZS1ob3N0XSc6ICd0cnVlJ1xuICAgIH0sXG4gICAgcHJvdmlkZXJzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gRGF0ZXRpbWVQaWNrZXJDb21wb25lbnQpLFxuICAgICAgICAgICAgbXVsdGk6IHRydWVcbiAgICAgICAgfVxuICAgIF0sXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZVxufSlcbmV4cG9ydCBjbGFzcyBEYXRldGltZVBpY2tlckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBDb250cm9sVmFsdWVBY2Nlc3NvciB7XG5cbiAgICAvKiogQGhpZGRlbiBSZWZlcmVuY2UgdG8gdGhlIGlubmVyIHRpbWUgY29tcG9uZW50LiAqL1xuICAgIEBWaWV3Q2hpbGQoVGltZUNvbXBvbmVudClcbiAgICB0aW1lQ29tcG9uZW50OiBUaW1lQ29tcG9uZW50O1xuXG4gICAgLyoqIFBsYWNlaG9sZGVyIGZvciB0aGUgaW5uZXIgaW5wdXQgZWxlbWVudC4gKi9cbiAgICBASW5wdXQoKVxuICAgIHBsYWNlaG9sZGVyOiBzdHJpbmcgPSAnbW0vZGQveXl5eSwgaGg6bW06c3MgYW0nO1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIGNvbXBvbmVudCBzaG91bGQgYmUgaW4gY29tcGFjdCBtb2RlLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgY29tcGFjdDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgLyoqIFRoZSBwbGFjZW1lbnQgb2YgdGhlIHBvcG92ZXIuIEl0IGNhbiBiZSBvbmUgb2Y6IHRvcCwgdG9wLXN0YXJ0LCB0b3AtZW5kLCBib3R0b20sXG4gICAgICogIGJvdHRvbS1zdGFydCwgYm90dG9tLWVuZCwgcmlnaHQsIHJpZ2h0LXN0YXJ0LCByaWdodC1lbmQsIGxlZnQsIGxlZnQtc3RhcnQsIGxlZnQtZW5kLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgcGxhY2VtZW50OiBQbGFjZW1lbnQgPSAnYm90dG9tLXN0YXJ0JztcblxuICAgIC8qKiBXaGV0aGVyIHRoZSB0aW1lIGNvbXBvbmVudCBzaG91bGQgYmUgbWVyaWRpYW4gKGFtL3BtKS4gKi9cbiAgICBASW5wdXQoKVxuICAgIG1lcmlkaWFuOiBib29sZWFuID0gdHJ1ZTtcblxuICAgIC8qKiBXaGV0aGVyIHRoZSBjb21wb25lbnQgaXMgZGlzYWJsZWQuICovXG4gICAgQElucHV0KClcbiAgICBkaXNhYmxlZDogYm9vbGVhbjtcblxuICAgIC8qKiBXaGV0aGVyIHRoZSB0aW1lIGNvbXBvbmVudCBzaG93cyBzcGlubmVycyBmb3IgY2hhbmdpbmcgdGhlIHRpbWUuICovXG4gICAgQElucHV0KClcbiAgICBzcGlubmVyczogYm9vbGVhbiA9IHRydWU7XG5cbiAgICAvKiogV2hldGhlciB0aGUgdGltZSBjb21wb25lbnQgc2hvd3Mgc2Vjb25kcy4gKi9cbiAgICBASW5wdXQoKVxuICAgIGRpc3BsYXlTZWNvbmRzOiBib29sZWFuID0gdHJ1ZTtcblxuICAgIC8qKiBXaGV0aGVyIHRvIHBlcmZvcm0gdmlzdWFsIHZhbGlkYXRpb24gb24gdGhlIHBpY2tlciBpbnB1dC4gKi9cbiAgICBASW5wdXQoKVxuICAgIHZhbGlkYXRlOiBib29sZWFuID0gdHJ1ZTtcblxuICAgIC8qKiBDdXJyZW50IHNlbGVjdGVkIGRhdGUuIFR3by13YXkgYmluZGluZyBpcyBzdXBwb3J0ZWQuICovXG4gICAgQElucHV0KClcbiAgICBkYXRlOiBEYXRlID0gbmV3IERhdGUoKTtcblxuICAgIC8qKiBXaGV0aGVyIHRoZSBwb3BvdmVyIGlzIG9wZW4uIFR3by13YXkgYmluZGluZyBpcyBzdXBwb3J0ZWQuICovXG4gICAgQElucHV0KClcbiAgICBpc09wZW46IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKiBUaGUgZGlzYWJsZUZ1bmN0aW9uIGZvciB0aGUgY2FsZW5kYXIuICovXG4gICAgQElucHV0KClcbiAgICBzdGFydGluZ0RheU9mV2VlazogbnVtYmVyID0gMDtcblxuICAgIC8qKiBBcmlhIGxhYmVsIGZvciB0aGUgZGF0ZXRpbWUgcGlja2VyIGlucHV0LiAqL1xuICAgIEBJbnB1dCgpXG4gICAgZGF0ZXRpbWVJbnB1dExhYmVsOiBzdHJpbmcgPSAnRGF0ZXRpbWUgaW5wdXQnO1xuXG4gICAgLyoqIEFyaWEgbGFiZWwgZm9yIHRoZSBidXR0b24gdG8gc2hvdy9oaWRlIHRoZSBjYWxlbmRhci4gKi9cbiAgICBASW5wdXQoKVxuICAgIGRpc3BsYXlEYXRldGltZVRvZ2dsZUxhYmVsOiBzdHJpbmcgPSAnRGlzcGxheSBjYWxlbmRhciB0b2dnbGUnO1xuXG4gICAgLyoqIFdoZXRoZXIgYSBudWxsIGlucHV0IGlzIGNvbnNpZGVyZWQgdmFsaWQuICovXG4gICAgQElucHV0KClcbiAgICBhbGxvd051bGw6IGJvb2xlYW4gPSB0cnVlO1xuXG4gICAgLyoqIEV2ZW50IGVtaXR0ZWQgd2hlbiB0aGUgZGF0ZSBjaGFuZ2VzLiBUaGlzIGNhbiBiZSBhIHRpbWUgb3IgZGF5IGNoYW5nZS4gKi9cbiAgICBAT3V0cHV0KClcbiAgICByZWFkb25seSBkYXRlQ2hhbmdlOiBFdmVudEVtaXR0ZXI8RGF0ZT4gPSBuZXcgRXZlbnRFbWl0dGVyPERhdGU+KCk7XG5cbiAgICAvKiogRXZlbnQgZW1pdHRlZCB3aGVuIHRoZSBkYXkgY2hhbmdlcyBmcm9tIHRoZSBjYWxlbmRhci4gKi9cbiAgICBAT3V0cHV0KClcbiAgICByZWFkb25seSBjYWxlbmRhckNoYW5nZTogRXZlbnRFbWl0dGVyPERhdGU+ID0gbmV3IEV2ZW50RW1pdHRlcjxEYXRlPigpO1xuXG4gICAgLyoqIEV2ZW50IGVtaXR0ZWQgd2hlbiB0aGUgdGltZSBjaGFuZ2VzIGZyb20gdGhlIHRpbWUgY29tcG9uZW50LiAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHJlYWRvbmx5IHRpbWVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxEYXRlPiA9IG5ldyBFdmVudEVtaXR0ZXI8RGF0ZT4oKTtcblxuICAgIC8qKiBFdmVudCBlbWl0dGVkIHdoZW4gcG9wb3ZlciBjbG9zZXMuICovXG4gICAgQE91dHB1dCgpXG4gICAgcmVhZG9ubHkgb25DbG9zZTogRXZlbnRFbWl0dGVyPERhdGU+ID0gbmV3IEV2ZW50RW1pdHRlcjxEYXRlPigpO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlbiBEYXRlIG9mIHRoZSBpbnB1dCBmaWVsZC4gSW50ZXJuYWwgdXNlLlxuICAgICAqIEZvciBwcm9ncmFtbWF0aWMgc2VsZWN0aW9uLCB1c2UgdHdvLXdheSBiaW5kaW5nIG9uIHRoZSBkYXRlIGlucHV0LlxuICAgICAqL1xuICAgIGlucHV0RmllbGREYXRlID0gbnVsbDtcblxuICAgIC8qKiBAaGlkZGVuIFRoZSBUaW1lIG9iamVjdCB3aGljaCBpbnRlcmFjdHMgd2l0aCB0aGUgaW5uZXIgVGltZSBjb21wb25lbnQuIEludGVybmFsIHVzZS4gKi9cbiAgICBpc0ludmFsaWREYXRlSW5wdXQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKiBAaGlkZGVuIE9ic2VydmFibGUgdXNlZCBpbnRlcm5hbGx5LiAqL1xuICAgIGRhdGVGcm9tSW5wdXQ6IFN1YmplY3Q8c3RyaW5nPiA9IG5ldyBTdWJqZWN0KCk7XG5cbiAgICAvKiogQGhpZGRlbiBUaGUgVGltZSBvYmplY3Qgd2hpY2ggaW50ZXJhY3RzIHdpdGggdGhlIGlubmVyIFRpbWUgY29tcG9uZW50LiBJbnRlcm5hbCB1c2UuICovXG4gICAgdGltZTogVGltZU9iamVjdCA9IHsgaG91cjogMCwgbWludXRlOiAwLCBzZWNvbmQ6IDAgfTtcblxuICAgIC8qKiBAaGlkZGVuIFRoZSBDYWxlbmRhckRheSBvYmplY3Qgd2hpY2ggaW50ZXJhY3RzIHdpdGggdGhlIGlubmVyIENhbGVuZGFyIGNvbXBvbmVudC4gSW50ZXJuYWwgdXNlLiAqL1xuICAgIHNlbGVjdGVkRGF5OiBDYWxlbmRhckRheSA9IHtcbiAgICAgICAgZGF0ZTogbnVsbFxuICAgIH07XG5cbiAgICAvKiogU3Vic2NyaXB0aW9uIG9mIHRoZSBkYXRlRnJvbUlucHV0LiAqL1xuICAgIHByaXZhdGUgZGF0ZUZyb21JbnB1dFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuXG4gICAgQElucHV0KClcbiAgICBkaXNhYmxlRnVuY3Rpb24gPSBmdW5jdGlvbihkKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgLyoqIFRoZSBibG9ja0Z1bmN0aW9uIGZvciB0aGUgY2FsZW5kYXIuICovXG4gICAgQElucHV0KClcbiAgICBibG9ja0Z1bmN0aW9uID0gZnVuY3Rpb24oZCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICBASW5wdXQoKVxuICAgIGRpc2FibGVSYW5nZVN0YXJ0RnVuY3Rpb24gPSBmdW5jdGlvbihkKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIEBJbnB1dCgpXG4gICAgZGlzYWJsZVJhbmdlRW5kRnVuY3Rpb24gPSBmdW5jdGlvbihkKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIEBJbnB1dCgpXG4gICAgYmxvY2tSYW5nZVN0YXJ0RnVuY3Rpb24gPSBmdW5jdGlvbihkKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIEBJbnB1dCgpXG4gICAgYmxvY2tSYW5nZUVuZEZ1bmN0aW9uID0gZnVuY3Rpb24oZCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgb25DaGFuZ2U6IGFueSA9ICgpID0+IHt9O1xuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBvblRvdWNoZWQ6IGFueSA9ICgpID0+IHt9O1xuXG4gICAgLyoqIFRvZ2dsZXMgdGhlIHBvcG92ZXIuICovXG4gICAgdG9nZ2xlUG9wb3ZlcigpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5vblRvdWNoZWQodGhpcy5zZWxlY3RlZERheS5kYXRlKTtcbiAgICAgICAgaWYgKHRoaXMuaXNPcGVuKSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlUG9wb3ZlcigpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5vcGVuUG9wb3ZlcigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIE9wZW5zIHRoZSBwb3BvdmVyLiAqL1xuICAgIG9wZW5Qb3BvdmVyKGlucHV0RmllbGREYXRlPzogc3RyaW5nKTogdm9pZCB7XG4gICAgICAgIGlmICghdGhpcy5pc09wZW4gJiYgIXRoaXMuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMub25Ub3VjaGVkKHRoaXMuc2VsZWN0ZWREYXkuZGF0ZSk7XG4gICAgICAgICAgICB0aGlzLmlzT3BlbiA9IHRydWU7XG4gICAgICAgICAgICBpZiAoaW5wdXRGaWVsZERhdGUgIT09IG51bGwgJiYgaW5wdXRGaWVsZERhdGUgIT09ICcnICYmICF0aGlzLmlzSW52YWxpZERhdGVJbnB1dCkge1xuICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRWYWx1ZUNoYW5nZSh0aGlzLmRhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIENsb3NlcyB0aGUgcG9wb3ZlciAqL1xuICAgIGNsb3NlUG9wb3ZlcigpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuaXNPcGVuKSB7XG4gICAgICAgICAgICB0aGlzLm9uQ2xvc2UuZW1pdCh0aGlzLmRhdGUpO1xuICAgICAgICAgICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHVwZGF0ZVBpY2tlcklucHV0SGFuZGxlcihkKTogdm9pZCB7XG4gICAgICAgIGlmIChkLnNlbGVjdGVkRGF5ICYmIGQuc2VsZWN0ZWREYXkuZGF0ZSkge1xuICAgICAgICAgICAgZC5zZWxlY3RlZERheS5kYXRlLnNldEhvdXJzKHRoaXMuZGF0ZS5nZXRIb3VycygpKTtcbiAgICAgICAgICAgIGQuc2VsZWN0ZWREYXkuZGF0ZS5zZXRNaW51dGVzKHRoaXMuZGF0ZS5nZXRNaW51dGVzKCkpO1xuICAgICAgICAgICAgZC5zZWxlY3RlZERheS5kYXRlLnNldFNlY29uZHModGhpcy5kYXRlLmdldFNlY29uZHMoKSk7XG4gICAgICAgICAgICBkLnNlbGVjdGVkRGF5LmRhdGUuc2V0TWlsbGlzZWNvbmRzKHRoaXMuZGF0ZS5nZXRNaWxsaXNlY29uZHMoKSk7XG4gICAgICAgICAgICBjb25zdCBwcmV2aW91cyA9IHRoaXMuZGF0ZS5nZXRUaW1lKCk7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkRGF5ID0gZC5zZWxlY3RlZERheTtcbiAgICAgICAgICAgIHRoaXMuZGF0ZSA9IGQuc2VsZWN0ZWREYXkuZGF0ZTtcbiAgICAgICAgICAgIHRoaXMuaW5wdXRGaWVsZERhdGUgPSB0aGlzLmRhdGVUaW1lQWRhcHRlci5mb3JtYXQodGhpcy5kYXRlKTtcbiAgICAgICAgICAgIHRoaXMudGltZSA9IHtob3VyOiB0aGlzLmRhdGUuZ2V0SG91cnMoKSwgbWludXRlOiB0aGlzLmRhdGUuZ2V0TWludXRlcygpLCBzZWNvbmQ6IHRoaXMuZGF0ZS5nZXRTZWNvbmRzKCl9O1xuICAgICAgICAgICAgaWYgKHRoaXMuZGF0ZS5nZXRUaW1lKCkgIT09IHByZXZpb3VzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jYWxlbmRhckNoYW5nZS5lbWl0KHRoaXMuZGF0ZSk7XG4gICAgICAgICAgICAgICAgdGhpcy5kYXRlQ2hhbmdlLmVtaXQodGhpcy5kYXRlKTtcbiAgICAgICAgICAgICAgICB0aGlzLm9uQ2hhbmdlKHRoaXMuZGF0ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoZCA9PT0gJycpIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWREYXkuZGF0ZSA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkRGF5LnNlbGVjdGVkID0gbnVsbDtcbiAgICAgICAgICAgIHRoaXMudGltZS5zZWNvbmQgPSBudWxsO1xuICAgICAgICAgICAgdGhpcy50aW1lLm1pbnV0ZSA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnRpbWUuaG91ciA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnRpbWVDb21wb25lbnQuZGlzcGxheWVkSG91ciA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLnRpbWVDb21wb25lbnQucGVyaW9kID0gJ2FtJztcbiAgICAgICAgICAgIHRoaXMudGltZUNvbXBvbmVudC5vbGRQZXJpb2QgPSAnYW0nO1xuICAgICAgICAgICAgdGhpcy5jYWxlbmRhckNoYW5nZS5lbWl0KG51bGwpO1xuICAgICAgICAgICAgdGhpcy50aW1lQ2hhbmdlLmVtaXQobnVsbCk7XG4gICAgICAgICAgICB0aGlzLmRhdGVDaGFuZ2UuZW1pdChudWxsKTtcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2UodGhpcy5zZWxlY3RlZERheS5kYXRlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgaXNJbnZhbGlkRGF0ZUlucHV0SGFuZGxlcihlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuaXNJbnZhbGlkRGF0ZUlucHV0ID0gZTtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIGlucHV0VmFsdWVDaGFuZ2UoZSk6IHZvaWQge1xuICAgICAgICBsZXQgdGVtcDtcbiAgICAgICAgaWYgKHR5cGVvZiBlID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgdGVtcCA9IHRoaXMuZGF0ZVRpbWVBZGFwdGVyLnBhcnNlKGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGVtcCA9IG5ldyBEYXRlKGUpO1xuICAgICAgICB9XG4gICAgICAgIC8qXG4gICAgICAgICBOZWVkIHRvIGNoZWNrIGlmIGN1cnJlbnQgbG9jYWxlIHRvRGF0ZVN0cmluZyBjb250YWlucyBBTSBvciBQTS4gSWYgdGhlIGN1cnJlbnQgbG9jYWxlIGhhcyBpdCBhbmQgaXQgaXMgYWJzZW50XG4gICAgICAgICBmcm9tIHRoZSB1c2VyJ3MgaW5wdXQsIHRoZSBtZXJpZGlhbiBzaG91bGQgYmUgY29uc2lkZXJlZCBpbnZhbGlkXG4gICAgICAgICAqL1xuICAgICAgICBjb25zdCBsb2NhbGVNZXJpZGlhbiA9IG5ldyBEYXRlKCkudG9Mb2NhbGVUaW1lU3RyaW5nKCkuc2xpY2UoLTIpO1xuICAgICAgICBsZXQgbWVyaWRpYW5WYWxpZCA9IHRydWU7XG4gICAgICAgIGlmICgobG9jYWxlTWVyaWRpYW4gPT09ICdBTScgfHwgbG9jYWxlTWVyaWRpYW4gPT09ICdQTScpICYmXG4gICAgICAgICAgICAodHlwZW9mIGUgPT09ICdzdHJpbmcnICYmIGUuc2xpY2UoLTIpICE9PSAnQU0nICYmIGUuc2xpY2UoLTIpICE9PSAnUE0nKSkge1xuICAgICAgICAgICAgbWVyaWRpYW5WYWxpZCA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG1lcmlkaWFuVmFsaWQgJiYgdGVtcCAmJiB0ZW1wLnRvTG9jYWxlRGF0ZVN0cmluZygpICE9PSAnSW52YWxpZCBEYXRlJykge1xuICAgICAgICAgICAgY29uc3QgbmV3VmFsdWUgPSB7aG91cjogdGVtcC5nZXRIb3VycygpLCBtaW51dGU6IHRlbXAuZ2V0TWludXRlcygpLCBzZWNvbmQ6IHRlbXAuZ2V0U2Vjb25kcygpfTtcbiAgICAgICAgICAgIGlmIChuZXdWYWx1ZS5ob3VyICE9PSB0aGlzLnRpbWUuaG91ciB8fCBuZXdWYWx1ZS5taW51dGUgIT09IHRoaXMudGltZS5taW51dGUgfHwgbmV3VmFsdWUuc2Vjb25kICE9PSB0aGlzLnRpbWUuc2Vjb25kKSB7XG4gICAgICAgICAgICAgICAgdGhpcy50aW1lID0gbmV3VmFsdWU7XG4gICAgICAgICAgICAgICAgdGhpcy5zZXRUaW1lKHRydWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5kYXRlRnJvbUlucHV0Lm5leHQodGVtcC50b0xvY2FsZURhdGVTdHJpbmcoKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoZSA9PT0gJycgJiYgdGhpcy5hbGxvd051bGwpIHtcbiAgICAgICAgICAgIHRoaXMuaXNJbnZhbGlkRGF0ZUlucHV0ID0gZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmRhdGVGcm9tSW5wdXQubmV4dCgnJyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmlzSW52YWxpZERhdGVJbnB1dCA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmtleWRvd24uZXNjYXBlJywgW10pXG4gICAgb25Fc2NhcGVLZXlkb3duSGFuZGxlcigpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5jbG9zZVBvcG92ZXIoKTtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQnXSlcbiAgICBwdWJsaWMgb25HbG9iYWxDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuZWxSZWYubmF0aXZlRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQpKSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlUG9wb3ZlcigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuZGF0ZSAmJiB0aGlzLmlucHV0RmllbGREYXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkRGF5LmRhdGUgPSB0aGlzLmRhdGU7XG4gICAgICAgICAgICB0aGlzLnRpbWUgPSB7aG91cjogdGhpcy5kYXRlLmdldEhvdXJzKCksIG1pbnV0ZTogdGhpcy5kYXRlLmdldE1pbnV0ZXMoKSwgc2Vjb25kOiB0aGlzLmRhdGUuZ2V0U2Vjb25kcygpfTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5kYXRlRnJvbUlucHV0KSB7XG4gICAgICAgICAgICB0aGlzLmRhdGVGcm9tSW5wdXRTdWJzY3JpcHRpb24gPSB0aGlzLmRhdGVGcm9tSW5wdXQuc3Vic2NyaWJlKGRhdGUgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMudXBkYXRlUGlja2VySW5wdXRIYW5kbGVyKGRhdGUpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5kYXRlRnJvbUlucHV0U3Vic2NyaXB0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLmRhdGVGcm9tSW5wdXRTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBlbFJlZjogRWxlbWVudFJlZixcbiAgICAgICAgICAgICAgICBwcml2YXRlIGRhdGVUaW1lQWRhcHRlcjogRGF0ZVRpbWVGb3JtYXRQYXJzZXJcbiAgICApIHt9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIHJlZ2lzdGVyT25DaGFuZ2UoZm46IChzZWxlY3RlZDogYW55KSA9PiB7dm9pZH0pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5vbkNoYW5nZSA9IGZuO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgcmVnaXN0ZXJPblRvdWNoZWQoZm46IGFueSk6IHZvaWQge1xuICAgICAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgc2V0RGlzYWJsZWRTdGF0ZShpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZGlzYWJsZWQgPSBpc0Rpc2FibGVkO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgd3JpdGVWYWx1ZShzZWxlY3RlZDogRGF0ZSk6IHZvaWQge1xuICAgICAgICBpZiAoIXNlbGVjdGVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zZWxlY3RlZERheS5kYXRlID0gc2VsZWN0ZWQ7XG4gICAgICAgIHRoaXMudGltZSA9IHtob3VyOiBzZWxlY3RlZC5nZXRIb3VycygpLCBtaW51dGU6IHNlbGVjdGVkLmdldE1pbnV0ZXMoKSwgc2Vjb25kOiBzZWxlY3RlZC5nZXRTZWNvbmRzKCl9XG4gICAgICAgIHRoaXMuZGF0ZSA9IHRoaXMuc2VsZWN0ZWREYXkuZGF0ZTtcbiAgICAgICAgdGhpcy5zZXRUaW1lKCk7XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBzZXRUaW1lKGZpcmVFdmVudHMgPSBmYWxzZSk6IHZvaWQge1xuICAgICAgICB0aGlzLmRhdGUuc2V0SG91cnModGhpcy50aW1lLmhvdXIpO1xuI