UNPKG

truly-ui

Version:

Web Components for Desktop Applications.

170 lines (168 loc) 34.6 kB
/* MIT License Copyright (c) 2019 Temainfo Software Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import { Input, Component, Output, EventEmitter } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "../i18n/i18n.service"; import * as i2 from "@angular/common"; import * as i3 from "../icons/icons"; import * as i4 from "../loader/loader"; import * as i5 from "../tooltip/directives/tooltip.directive"; import * as i6 from "../calendar/pipes/holiday"; export class TlTimeAvailablePicker { constructor(change, i18nService) { this.change = change; this.i18nService = i18nService; this.availableTimes = []; this.color = 'basic'; this.loading = false; this.maxHeight = '180px'; this.width = '260px'; this.dateValue = new Date(); this.value = []; this.holidays = []; this.changeSelect = new EventEmitter(); this.filterTimes = []; this.selectedTime = []; this.notFoundMessage = this.i18nService.getLocale().TimeAvailablePicker.notFound; } ngAfterViewInit() { this.handleValueChange(); } setUpData() { this.resetArrays(); this.availableTimes.forEach((value) => { this.filterTimes.push({ range: value, selected: false }); }); } resetArrays() { this.filterTimes = []; this.selectedTime = []; } handleValueChange() { if (this.value.length > 0) { this.value.forEach((date) => { const dateFilter = this.getDateOnFilter(date); if (dateFilter >= 0) { this.filterTimes[dateFilter].selected = true; } }); this.updateTime(); } } getDateOnFilter(date) { return this.filterTimes.findIndex((item) => (new Date(item.range.start).getTime() === new Date(date.start).getTime()) && (new Date(item.range.end).getTime() === new Date(date.end).getTime())); } getSelectedArray() { return this.filterTimes.filter((item) => item.selected); } deselectAll() { this.filterTimes.forEach((item) => item.selected = false); } findSelected() { return this.filterTimes.findIndex((item) => item.selected); } handleDeselect(time) { this.deselectAll(); time.selected = true; this.updateTime(); } setSelectedTime(time, index) { const readySelected = this.findSelected(); if ((index === 0 || index === this.filterTimes.length - 1) && !(readySelected >= 0)) { this.handleDeselect(time); return; } if ((this.filterTimes[this.getFirstIndex(index)].selected || this.filterTimes[this.getLastIndex(index)].selected) && this.getSelectedArray().length > 1) { this.handleDeselect(time); return; } if (readySelected < 0) { time.selected = !time.selected; this.updateTime(); return; } time.selected = !time.selected; this.selectMany(readySelected, index); } getFirstIndex(index) { return index === 0 ? index : index - 1; } getLastIndex(index) { return index === this.filterTimes.length - 1 ? index : index + 1; } selectMany(readySelected, index) { this.filterTimes.forEach((value, index2, array) => { if (index2 > readySelected && index2 <= index) { value.selected = true; } if (index2 < readySelected && index2 >= index) { value.selected = true; } }); this.updateTime(); } updateTime() { this.selectedTime = []; const allSelected = this.filterTimes.filter((value) => value.selected); if (allSelected.length > 0) { this.selectedTime[0] = allSelected[0]; if (allSelected.length > 1) { this.selectedTime[1] = allSelected[allSelected.length - 1]; } } this.changeSelect.emit(this.getSelectedArray().map((item) => item.range)); this.change.detectChanges(); } ngOnChanges(changes) { if (changes['availableTimes']) { this.setUpData(); } if (changes['value']) { this.handleValueChange(); } } } /** @nocollapse */ TlTimeAvailablePicker.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TlTimeAvailablePicker, deps: [{ token: i0.ChangeDetectorRef }, { token: i1.I18nService }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ TlTimeAvailablePicker.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: TlTimeAvailablePicker, selector: "tl-time-available-picker", inputs: { availableTimes: "availableTimes", color: "color", loading: "loading", maxHeight: "maxHeight", width: "width", dateValue: "dateValue", value: "value", holidays: "holidays" }, outputs: { changeSelect: "changeSelect" }, usesOnChanges: true, ngImport: i0, template: "<div [class]=\"'ui-time-available-picker ' + color\" [style.width]=\"width\">\n <div class=\"ui-time-header\">\n <ng-container *ngIf=\"dateValue | holiday:holidays as dayArray\">\n <div class=\"ui-date-selected\" [class.holiday]=\"dayArray?.length > 0\" [tooltip]=\"{text: dayArray[0]?.description, placement: 'top-center'}\">\n <span class=\"ui-day\">{{ dateValue | date:'dd' }}</span>\n <span class=\"ui-day-week\">{{ dateValue | date:'EEEE' }}</span>\n <span class=\"ui-day-holiday\" *ngIf=\"dayArray?.length > 0\">{{ dayArray[0]?.description }}</span>\n </div>\n </ng-container>\n <div class=\"ui-time-selected\">\n <span *ngIf=\"selectedTime.length > 1\">{{ selectedTime[0]?.range.start | date: 'HH:mm' }} - {{ selectedTime[1]?.range.end | date: 'HH:mm' }}</span>\n <span *ngIf=\"selectedTime.length === 1\">{{ selectedTime[0]?.range.start | date: 'HH:mm' }} - {{ selectedTime[0]?.range.end | date: 'HH:mm' }}</span>\n </div>\n </div>\n\n <div class=\"ui-container\" *ngIf=\"loading || filterTimes.length === 0\" [style.minHeight]=\"maxHeight\">\n <div *ngIf=\"loading\" class=\"ui-loader-wrapper\">\n <div class=\"ui-loader\">\n <tl-loader></tl-loader>\n </div>\n </div>\n\n <div *ngIf=\"!filterTimes || filterTimes.length === 0 && !loading\" class=\"ui-empty-data\">\n <tl-icon [lib]=\"'ion'\" [style]=\"'md'\">sad</tl-icon>\n <span>{{ notFoundMessage }}</span>\n </div>\n </div>\n\n <div *ngIf=\"filterTimes.length > 0 && !loading\" class=\"ui-time-content\" [style.maxHeight]=\"maxHeight\">\n <div *ngFor=\"let item of filterTimes; let i = index\" class=\"ui-time-item\">\n <div (keydown.enter)=\"setSelectedTime(item, i)\"\n class=\"ui-range-wrapper\"\n (click)=\"setSelectedTime(item, i)\"\n [ngClass]=\"{ 'ui-selected': item.selected }\"\n tabindex=\"-1\">\n <span class=\"item-range\">{{ item.range.start | date: 'HH:mm' }}</span>\n </div>\n </div>\n </div>\n</div>\n", styles: ["*{box-sizing:border-box}.ui-time-available-picker{-webkit-user-select:none;user-select:none;display:flex;flex-direction:column;width:300px;border-radius:7px;box-sizing:border-box}.ui-time-available-picker>.ui-time-header{height:70px;width:100%;display:flex;justify-content:space-between;align-items:center;border-top-left-radius:7px;border-top-right-radius:7px}.ui-time-available-picker>.ui-time-header>.ui-date-selected{display:flex;flex-direction:column;align-items:center;line-height:20px;justify-content:center;width:90px}.ui-time-available-picker>.ui-time-header>.ui-date-selected>.ui-day{font-size:2em;font-weight:700;line-height:20px}.ui-time-available-picker>.ui-time-header>.ui-date-selected>.ui-day-week{font-size:.9em;font-variant:all-petite-caps;font-weight:700;line-height:10px}.ui-time-available-picker>.ui-time-header>.ui-date-selected>.ui-day-holiday{font-size:.8em;font-variant:all-petite-caps;font-weight:700;line-height:10px}.ui-time-available-picker>.ui-time-header>.ui-time-selected{width:170px;display:flex;justify-content:space-around}.ui-time-available-picker>.ui-time-header>.ui-time-selected span{font-size:1.3em;padding:5px 15px;border-radius:3px}.ui-time-available-picker>.ui-time-content{display:grid;grid-template-rows:repeat(auto-fill,30px);grid-template-columns:auto auto auto auto;grid-auto-flow:row;grid-gap:4px;position:relative;padding:4px;overflow-y:auto;overflow-x:hidden}.ui-time-available-picker>.ui-time-content::-webkit-scrollbar{border-radius:5px;width:5px}.ui-time-available-picker>.ui-time-content>.ui-time-item{display:flex;align-items:center;justify-content:center;font-size:1em;font-family:Segoe UI,Lato,\"sans-serif\",Arial;height:100%;box-sizing:border-box}.ui-time-available-picker>.ui-time-content>.ui-time-item .ui-range-wrapper{display:flex;padding:0 5px;transition:background .15s ease-in-out;border-radius:3px;cursor:pointer;flex-flow:column;align-items:center;place-content:center;width:100%;height:100%;outline:none;border:1px solid transparent;box-sizing:border-box}.ui-time-available-picker>.ui-time-footer{height:50px;border-bottom-left-radius:7px;border-bottom-right-radius:7px;display:flex;justify-content:space-around;align-items:center}.ui-empty-data{display:flex;justify-content:center;align-items:center;height:180px;flex-direction:column;line-height:30px}.ui-empty-data tl-icon{font-size:4em}.ui-empty-data span{font-family:Segoe UI,Lato,\"sans-serif\",Arial;font-weight:600}.ui-container{position:relative;width:100%}.ui-loader-wrapper{width:100%;height:100%;display:flex;position:absolute;align-items:center;place-content:center}.ui-loader-wrapper>.ui-loader{width:50px;height:50px}@keyframes shadow-drop-bottom{0%{box-shadow:0 0 #0000}to{box-shadow:0 12px 20px -12px #00000059}}@keyframes play18{0%{background-position:0px 0px}to{background-position:-18432px 0px}}\n"], dependencies: [{ kind: "directive", type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.TlIcons, selector: "tl-icon", inputs: ["icon", "lib", "style", "size", "animation", "color", "align"] }, { kind: "component", type: i4.TlLoader, selector: "tl-loader", inputs: ["color", "strokeWidth"] }, { kind: "directive", type: i5.TooltipDirective, selector: "[tooltip]", inputs: ["tooltip"] }, { kind: "pipe", type: i2.DatePipe, name: "date" }, { kind: "pipe", type: i6.TlHolidayPipe, name: "holiday" }] }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: TlTimeAvailablePicker, decorators: [{ type: Component, args: [{ selector: 'tl-time-available-picker', template: "<div [class]=\"'ui-time-available-picker ' + color\" [style.width]=\"width\">\n <div class=\"ui-time-header\">\n <ng-container *ngIf=\"dateValue | holiday:holidays as dayArray\">\n <div class=\"ui-date-selected\" [class.holiday]=\"dayArray?.length > 0\" [tooltip]=\"{text: dayArray[0]?.description, placement: 'top-center'}\">\n <span class=\"ui-day\">{{ dateValue | date:'dd' }}</span>\n <span class=\"ui-day-week\">{{ dateValue | date:'EEEE' }}</span>\n <span class=\"ui-day-holiday\" *ngIf=\"dayArray?.length > 0\">{{ dayArray[0]?.description }}</span>\n </div>\n </ng-container>\n <div class=\"ui-time-selected\">\n <span *ngIf=\"selectedTime.length > 1\">{{ selectedTime[0]?.range.start | date: 'HH:mm' }} - {{ selectedTime[1]?.range.end | date: 'HH:mm' }}</span>\n <span *ngIf=\"selectedTime.length === 1\">{{ selectedTime[0]?.range.start | date: 'HH:mm' }} - {{ selectedTime[0]?.range.end | date: 'HH:mm' }}</span>\n </div>\n </div>\n\n <div class=\"ui-container\" *ngIf=\"loading || filterTimes.length === 0\" [style.minHeight]=\"maxHeight\">\n <div *ngIf=\"loading\" class=\"ui-loader-wrapper\">\n <div class=\"ui-loader\">\n <tl-loader></tl-loader>\n </div>\n </div>\n\n <div *ngIf=\"!filterTimes || filterTimes.length === 0 && !loading\" class=\"ui-empty-data\">\n <tl-icon [lib]=\"'ion'\" [style]=\"'md'\">sad</tl-icon>\n <span>{{ notFoundMessage }}</span>\n </div>\n </div>\n\n <div *ngIf=\"filterTimes.length > 0 && !loading\" class=\"ui-time-content\" [style.maxHeight]=\"maxHeight\">\n <div *ngFor=\"let item of filterTimes; let i = index\" class=\"ui-time-item\">\n <div (keydown.enter)=\"setSelectedTime(item, i)\"\n class=\"ui-range-wrapper\"\n (click)=\"setSelectedTime(item, i)\"\n [ngClass]=\"{ 'ui-selected': item.selected }\"\n tabindex=\"-1\">\n <span class=\"item-range\">{{ item.range.start | date: 'HH:mm' }}</span>\n </div>\n </div>\n </div>\n</div>\n", styles: ["*{box-sizing:border-box}.ui-time-available-picker{-webkit-user-select:none;user-select:none;display:flex;flex-direction:column;width:300px;border-radius:7px;box-sizing:border-box}.ui-time-available-picker>.ui-time-header{height:70px;width:100%;display:flex;justify-content:space-between;align-items:center;border-top-left-radius:7px;border-top-right-radius:7px}.ui-time-available-picker>.ui-time-header>.ui-date-selected{display:flex;flex-direction:column;align-items:center;line-height:20px;justify-content:center;width:90px}.ui-time-available-picker>.ui-time-header>.ui-date-selected>.ui-day{font-size:2em;font-weight:700;line-height:20px}.ui-time-available-picker>.ui-time-header>.ui-date-selected>.ui-day-week{font-size:.9em;font-variant:all-petite-caps;font-weight:700;line-height:10px}.ui-time-available-picker>.ui-time-header>.ui-date-selected>.ui-day-holiday{font-size:.8em;font-variant:all-petite-caps;font-weight:700;line-height:10px}.ui-time-available-picker>.ui-time-header>.ui-time-selected{width:170px;display:flex;justify-content:space-around}.ui-time-available-picker>.ui-time-header>.ui-time-selected span{font-size:1.3em;padding:5px 15px;border-radius:3px}.ui-time-available-picker>.ui-time-content{display:grid;grid-template-rows:repeat(auto-fill,30px);grid-template-columns:auto auto auto auto;grid-auto-flow:row;grid-gap:4px;position:relative;padding:4px;overflow-y:auto;overflow-x:hidden}.ui-time-available-picker>.ui-time-content::-webkit-scrollbar{border-radius:5px;width:5px}.ui-time-available-picker>.ui-time-content>.ui-time-item{display:flex;align-items:center;justify-content:center;font-size:1em;font-family:Segoe UI,Lato,\"sans-serif\",Arial;height:100%;box-sizing:border-box}.ui-time-available-picker>.ui-time-content>.ui-time-item .ui-range-wrapper{display:flex;padding:0 5px;transition:background .15s ease-in-out;border-radius:3px;cursor:pointer;flex-flow:column;align-items:center;place-content:center;width:100%;height:100%;outline:none;border:1px solid transparent;box-sizing:border-box}.ui-time-available-picker>.ui-time-footer{height:50px;border-bottom-left-radius:7px;border-bottom-right-radius:7px;display:flex;justify-content:space-around;align-items:center}.ui-empty-data{display:flex;justify-content:center;align-items:center;height:180px;flex-direction:column;line-height:30px}.ui-empty-data tl-icon{font-size:4em}.ui-empty-data span{font-family:Segoe UI,Lato,\"sans-serif\",Arial;font-weight:600}.ui-container{position:relative;width:100%}.ui-loader-wrapper{width:100%;height:100%;display:flex;position:absolute;align-items:center;place-content:center}.ui-loader-wrapper>.ui-loader{width:50px;height:50px}@keyframes shadow-drop-bottom{0%{box-shadow:0 0 #0000}to{box-shadow:0 12px 20px -12px #00000059}}@keyframes play18{0%{background-position:0px 0px}to{background-position:-18432px 0px}}\n"] }] }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i1.I18nService }]; }, propDecorators: { availableTimes: [{ type: Input }], color: [{ type: Input }], loading: [{ type: Input }], maxHeight: [{ type: Input }], width: [{ type: Input }], dateValue: [{ type: Input }], value: [{ type: Input }], holidays: [{ type: Input }], changeSelect: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZS1hdmFpbGFibGUtcGlja2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvdHJ1bHktdWkvc3JjL2NvbXBvbmVudHMvdGltZS1hdmFpbGFibGUtcGlja2VyL3RpbWUtYXZhaWxhYmxlLXBpY2tlci50cyIsIi4uLy4uLy4uLy4uL3Byb2plY3RzL3RydWx5LXVpL3NyYy9jb21wb25lbnRzL3RpbWUtYXZhaWxhYmxlLXBpY2tlci90aW1lLWF2YWlsYWJsZS1waWNrZXIuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FvQkc7QUFDSCxPQUFPLEVBQ0wsS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQWlCLFlBQVksRUFFdEQsTUFBTSxlQUFlLENBQUM7Ozs7Ozs7O0FBbUJ2QixNQUFNLE9BQU8scUJBQXFCO0lBMEJoQyxZQUFxQixNQUF5QixFQUFVLFdBQXdCO1FBQTNELFdBQU0sR0FBTixNQUFNLENBQW1CO1FBQVUsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUF4QnZFLG1CQUFjLEdBQXFCLEVBQUUsQ0FBQztRQUV0QyxVQUFLLEdBQUcsT0FBTyxDQUFDO1FBRWhCLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFFaEIsY0FBUyxHQUFHLE9BQU8sQ0FBQztRQUVwQixVQUFLLEdBQUcsT0FBTyxDQUFDO1FBRWhCLGNBQVMsR0FBUyxJQUFJLElBQUksRUFBRSxDQUFDO1FBRTdCLFVBQUssR0FBcUIsRUFBRSxDQUFDO1FBRTdCLGFBQVEsR0FBMkIsRUFBRSxDQUFDO1FBRXJDLGlCQUFZLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFFeEQsZ0JBQVcsR0FBc0IsRUFBRSxDQUFDO1FBRXBDLGlCQUFZLEdBQXNCLEVBQUUsQ0FBQztRQUVyQyxvQkFBZSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxFQUFFLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDO0lBRUMsQ0FBQztJQUVyRixlQUFlO1FBQ2IsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVPLFNBQVM7UUFDZixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUUsQ0FBRSxLQUFLLEVBQUcsRUFBRTtZQUN2QyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBRSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxDQUFFLENBQUM7UUFDN0QsQ0FBQyxDQUFFLENBQUM7SUFDTixDQUFDO0lBRU8sV0FBVztRQUNqQixJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztJQUN6QixDQUFDO0lBRU8saUJBQWlCO1FBQ3ZCLElBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFHO1lBQzNCLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFFLENBQUUsSUFBZSxFQUFHLEVBQUU7Z0JBQ3hDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQzlDLElBQUssVUFBVSxJQUFJLENBQUMsRUFBRTtvQkFDcEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUMsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDO2lCQUM5QztZQUNILENBQUMsQ0FBRSxDQUFDO1lBQ0osSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1NBQ25CO0lBQ0gsQ0FBQztJQUVPLGVBQWUsQ0FBRSxJQUFlO1FBQ3RDLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUUsQ0FBRSxJQUFnQixFQUFHLEVBQUUsQ0FDeEQsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sRUFBRSxLQUFLLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUMzRSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLEtBQUssSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQ3BFLENBQUM7SUFDSixDQUFDO0lBRU8sZ0JBQWdCO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUUsQ0FBRSxJQUFnQixFQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFFLENBQUM7SUFDMUUsQ0FBQztJQUVPLFdBQVc7UUFDakIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUUsQ0FBRSxJQUFnQixFQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBRSxDQUFDO0lBQzVFLENBQUM7SUFFTyxZQUFZO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUUsQ0FBRSxJQUFnQixFQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFFLENBQUM7SUFDN0UsQ0FBQztJQUVPLGNBQWMsQ0FBRSxJQUFnQjtRQUN0QyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFDckIsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3BCLENBQUM7SUFFRCxlQUFlLENBQUUsSUFBZ0IsRUFBRSxLQUFhO1FBQzlDLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUMxQyxJQUFLLENBQUUsS0FBSyxLQUFLLENBQUMsSUFBSSxLQUFLLEtBQUssSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFFLElBQUksQ0FBQyxDQUFDLGFBQWEsSUFBSSxDQUFDLENBQUMsRUFBRztZQUN2RixJQUFJLENBQUMsY0FBYyxDQUFFLElBQUksQ0FBRSxDQUFDO1lBQzVCLE9BQU87U0FDUjtRQUNELElBQUssQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFFLElBQUksQ0FBQyxhQUFhLENBQUUsS0FBSyxDQUFFLENBQUUsQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLFdBQVcsQ0FBRSxJQUFJLENBQUMsWUFBWSxDQUFFLEtBQUssQ0FBRSxDQUFFLENBQUMsUUFBUSxDQUFFO2VBQ3RILElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUc7WUFDeEMsSUFBSSxDQUFDLGNBQWMsQ0FBRSxJQUFJLENBQUUsQ0FBQztZQUM1QixPQUFPO1NBQ1I7UUFDRCxJQUFLLGFBQWEsR0FBRyxDQUFDLEVBQUc7WUFDdkIsSUFBSSxDQUFDLFFBQVEsR0FBRyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUM7WUFDL0IsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ2xCLE9BQU87U0FDUjtRQUNELElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBQy9CLElBQUksQ0FBQyxVQUFVLENBQUUsYUFBYSxFQUFFLEtBQUssQ0FBRSxDQUFDO0lBRTFDLENBQUM7SUFFTyxhQUFhLENBQUUsS0FBSztRQUMxQixPQUFPLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRU8sWUFBWSxDQUFFLEtBQUs7UUFDekIsT0FBTyxLQUFLLEtBQUssSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDbkUsQ0FBQztJQUVPLFVBQVUsQ0FBRSxhQUFxQixFQUFFLEtBQWE7UUFDdEQsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUUsQ0FBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRyxFQUFFO1lBQ25ELElBQUssTUFBTSxHQUFHLGFBQWEsSUFBSSxNQUFNLElBQUksS0FBSyxFQUFHO2dCQUMvQyxLQUFLLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQzthQUN2QjtZQUNELElBQUssTUFBTSxHQUFHLGFBQWEsSUFBSSxNQUFNLElBQUksS0FBSyxFQUFHO2dCQUMvQyxLQUFLLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQzthQUN2QjtRQUNILENBQUMsQ0FBRSxDQUFDO1FBQ0osSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3BCLENBQUM7SUFFTyxVQUFVO1FBQ2hCLElBQUksQ0FBQyxZQUFZLEdBQUcsRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFFLENBQUUsS0FBSyxFQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFFLENBQUM7UUFDM0UsSUFBSyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRztZQUM1QixJQUFJLENBQUMsWUFBWSxDQUFFLENBQUMsQ0FBRSxHQUFHLFdBQVcsQ0FBRSxDQUFDLENBQUUsQ0FBQztZQUMxQyxJQUFLLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFHO2dCQUM1QixJQUFJLENBQUMsWUFBWSxDQUFFLENBQUMsQ0FBRSxHQUFHLFdBQVcsQ0FBRSxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBRSxDQUFDO2FBQ2hFO1NBQ0Y7UUFDRCxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBRSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBRSxDQUFDO1FBQzVFLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLENBQUM7SUFDOUIsQ0FBQztJQUVELFdBQVcsQ0FBQyxPQUFzQjtRQUNoQyxJQUFJLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFO1lBQzdCLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztTQUNsQjtRQUNELElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFO1lBQ3BCLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1NBQzFCO0lBQ0gsQ0FBQzs7c0lBOUlVLHFCQUFxQjswSEFBckIscUJBQXFCLHdUQzNDbEMsZ2dFQXdDQTs0RkRHYSxxQkFBcUI7a0JBTGpDLFNBQVM7K0JBQ0UsMEJBQTBCO2tJQU0zQixjQUFjO3NCQUF0QixLQUFLO2dCQUVHLEtBQUs7c0JBQWIsS0FBSztnQkFFRyxPQUFPO3NCQUFmLEtBQUs7Z0JBRUcsU0FBUztzQkFBakIsS0FBSztnQkFFRyxLQUFLO3NCQUFiLEtBQUs7Z0JBRUcsU0FBUztzQkFBakIsS0FBSztnQkFFRyxLQUFLO3NCQUFiLEtBQUs7Z0JBRUcsUUFBUTtzQkFBaEIsS0FBSztnQkFFSSxZQUFZO3NCQUFyQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiBNSVQgTGljZW5zZVxuXG4gQ29weXJpZ2h0IChjKSAyMDE5IFRlbWFpbmZvIFNvZnR3YXJlXG5cbiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4gb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbFxuIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHNcbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4gY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGxcbiBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1JcbiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4gTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRVxuIFNPRlRXQVJFLlxuICovXG5pbXBvcnQge1xuICBJbnB1dCwgQ29tcG9uZW50LCBPdXRwdXQsIEFmdGVyVmlld0luaXQsIEV2ZW50RW1pdHRlciwgQ2hhbmdlRGV0ZWN0b3JSZWYsIFNpbXBsZUNoYW5nZXMsXG4gIE9uQ2hhbmdlc1xufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEkxOG5TZXJ2aWNlIH0gZnJvbSAnLi4vaTE4bi9pMThuLnNlcnZpY2UnO1xuaW1wb3J0IHtDYWxlbmRhckhvbGlkYXl9IGZyb20gJy4uL2NhbGVuZGFyL2ludGVyZmFjZXMvY2FsZW5kYXItaG9saWRheS5pbnRlcmZhY2UnO1xuXG5leHBvcnQgaW50ZXJmYWNlIEZpbHRlclRpbWUge1xuICByYW5nZTogRGF0ZVJhbmdlO1xuICBzZWxlY3RlZDogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBEYXRlUmFuZ2Uge1xuICBzdGFydDogRGF0ZTtcbiAgZW5kOiBEYXRlO1xufVxuXG5AQ29tcG9uZW50KCB7XG4gIHNlbGVjdG9yOiAndGwtdGltZS1hdmFpbGFibGUtcGlja2VyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3RpbWUtYXZhaWxhYmxlLXBpY2tlci5odG1sJyxcbiAgc3R5bGVVcmxzOiBbICcuL3RpbWUtYXZhaWxhYmxlLXBpY2tlci5zY3NzJyBdLFxufSApXG5leHBvcnQgY2xhc3MgVGxUaW1lQXZhaWxhYmxlUGlja2VyIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzIHtcblxuICBASW5wdXQoKSBhdmFpbGFibGVUaW1lczogQXJyYXk8RGF0ZVJhbmdlPiA9IFtdO1xuXG4gIEBJbnB1dCgpIGNvbG9yID0gJ2Jhc2ljJztcblxuICBASW5wdXQoKSBsb2FkaW5nID0gZmFsc2U7XG5cbiAgQElucHV0KCkgbWF4SGVpZ2h0ID0gJzE4MHB4JztcblxuICBASW5wdXQoKSB3aWR0aCA9ICcyNjBweCc7XG5cbiAgQElucHV0KCkgZGF0ZVZhbHVlOiBEYXRlID0gbmV3IERhdGUoKTtcblxuICBASW5wdXQoKSB2YWx1ZTogQXJyYXk8RGF0ZVJhbmdlPiA9IFtdO1xuXG4gIEBJbnB1dCgpIGhvbGlkYXlzOiBBcnJheTxDYWxlbmRhckhvbGlkYXk+ID0gW107XG5cbiAgQE91dHB1dCgpIGNoYW5nZVNlbGVjdDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgcHVibGljIGZpbHRlclRpbWVzOiBBcnJheTxGaWx0ZXJUaW1lPiA9IFtdO1xuXG4gIHB1YmxpYyBzZWxlY3RlZFRpbWU6IEFycmF5PEZpbHRlclRpbWU+ID0gW107XG5cbiAgcHVibGljIG5vdEZvdW5kTWVzc2FnZSA9IHRoaXMuaTE4blNlcnZpY2UuZ2V0TG9jYWxlKCkuVGltZUF2YWlsYWJsZVBpY2tlci5ub3RGb3VuZDtcblxuICBjb25zdHJ1Y3RvciggcHJpdmF0ZSBjaGFuZ2U6IENoYW5nZURldGVjdG9yUmVmLCBwcml2YXRlIGkxOG5TZXJ2aWNlOiBJMThuU2VydmljZSApIHt9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMuaGFuZGxlVmFsdWVDaGFuZ2UoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0VXBEYXRhKCkge1xuICAgIHRoaXMucmVzZXRBcnJheXMoKTtcbiAgICB0aGlzLmF2YWlsYWJsZVRpbWVzLmZvckVhY2goICggdmFsdWUgKSA9PiB7XG4gICAgICB0aGlzLmZpbHRlclRpbWVzLnB1c2goIHsgcmFuZ2U6IHZhbHVlLCBzZWxlY3RlZDogZmFsc2UgfSApO1xuICAgIH0gKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzZXRBcnJheXMoKSB7XG4gICAgdGhpcy5maWx0ZXJUaW1lcyA9IFtdO1xuICAgIHRoaXMuc2VsZWN0ZWRUaW1lID0gW107XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZVZhbHVlQ2hhbmdlKCkge1xuICAgIGlmICggdGhpcy52YWx1ZS5sZW5ndGggPiAwICkge1xuICAgICAgdGhpcy52YWx1ZS5mb3JFYWNoKCAoIGRhdGU6IERhdGVSYW5nZSApID0+IHtcbiAgICAgICAgY29uc3QgZGF0ZUZpbHRlciA9IHRoaXMuZ2V0RGF0ZU9uRmlsdGVyKGRhdGUpO1xuICAgICAgICBpZiAoIGRhdGVGaWx0ZXIgPj0gMCkge1xuICAgICAgICAgIHRoaXMuZmlsdGVyVGltZXNbZGF0ZUZpbHRlcl0uc2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9ICk7XG4gICAgICB0aGlzLnVwZGF0ZVRpbWUoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldERhdGVPbkZpbHRlciggZGF0ZTogRGF0ZVJhbmdlICkge1xuICAgIHJldHVybiB0aGlzLmZpbHRlclRpbWVzLmZpbmRJbmRleCggKCBpdGVtOiBGaWx0ZXJUaW1lICkgPT5cbiAgICAgIChuZXcgRGF0ZShpdGVtLnJhbmdlLnN0YXJ0KS5nZXRUaW1lKCkgPT09IG5ldyBEYXRlKGRhdGUuc3RhcnQpLmdldFRpbWUoKSkgJiZcbiAgICAobmV3IERhdGUoaXRlbS5yYW5nZS5lbmQpLmdldFRpbWUoKSA9PT0gbmV3IERhdGUoZGF0ZS5lbmQpLmdldFRpbWUoKSlcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRTZWxlY3RlZEFycmF5KCkge1xuICAgIHJldHVybiB0aGlzLmZpbHRlclRpbWVzLmZpbHRlciggKCBpdGVtOiBGaWx0ZXJUaW1lICkgPT4gaXRlbS5zZWxlY3RlZCApO1xuICB9XG5cbiAgcHJpdmF0ZSBkZXNlbGVjdEFsbCgpIHtcbiAgICB0aGlzLmZpbHRlclRpbWVzLmZvckVhY2goICggaXRlbTogRmlsdGVyVGltZSApID0+IGl0ZW0uc2VsZWN0ZWQgPSBmYWxzZSApO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kU2VsZWN0ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmlsdGVyVGltZXMuZmluZEluZGV4KCAoIGl0ZW06IEZpbHRlclRpbWUgKSA9PiBpdGVtLnNlbGVjdGVkICk7XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZURlc2VsZWN0KCB0aW1lOiBGaWx0ZXJUaW1lICkge1xuICAgIHRoaXMuZGVzZWxlY3RBbGwoKTtcbiAgICB0aW1lLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICB0aGlzLnVwZGF0ZVRpbWUoKTtcbiAgfVxuXG4gIHNldFNlbGVjdGVkVGltZSggdGltZTogRmlsdGVyVGltZSwgaW5kZXg6IG51bWJlciApIHtcbiAgICBjb25zdCByZWFkeVNlbGVjdGVkID0gdGhpcy5maW5kU2VsZWN0ZWQoKTtcbiAgICBpZiAoICggaW5kZXggPT09IDAgfHwgaW5kZXggPT09IHRoaXMuZmlsdGVyVGltZXMubGVuZ3RoIC0gMSApICYmICEocmVhZHlTZWxlY3RlZCA+PSAwKSApIHtcbiAgICAgIHRoaXMuaGFuZGxlRGVzZWxlY3QoIHRpbWUgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCAodGhpcy5maWx0ZXJUaW1lc1sgdGhpcy5nZXRGaXJzdEluZGV4KCBpbmRleCApIF0uc2VsZWN0ZWQgfHwgdGhpcy5maWx0ZXJUaW1lc1sgdGhpcy5nZXRMYXN0SW5kZXgoIGluZGV4ICkgXS5zZWxlY3RlZCApXG4gICAgICAmJiB0aGlzLmdldFNlbGVjdGVkQXJyYXkoKS5sZW5ndGggPiAxICkge1xuICAgICAgdGhpcy5oYW5kbGVEZXNlbGVjdCggdGltZSApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIHJlYWR5U2VsZWN0ZWQgPCAwICkge1xuICAgICAgdGltZS5zZWxlY3RlZCA9ICF0aW1lLnNlbGVjdGVkO1xuICAgICAgdGhpcy51cGRhdGVUaW1lKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRpbWUuc2VsZWN0ZWQgPSAhdGltZS5zZWxlY3RlZDtcbiAgICB0aGlzLnNlbGVjdE1hbnkoIHJlYWR5U2VsZWN0ZWQsIGluZGV4ICk7XG5cbiAgfVxuXG4gIHByaXZhdGUgZ2V0Rmlyc3RJbmRleCggaW5kZXggKSB7XG4gICAgcmV0dXJuIGluZGV4ID09PSAwID8gaW5kZXggOiBpbmRleCAtIDE7XG4gIH1cblxuICBwcml2YXRlIGdldExhc3RJbmRleCggaW5kZXggKSB7XG4gICAgcmV0dXJuIGluZGV4ID09PSB0aGlzLmZpbHRlclRpbWVzLmxlbmd0aCAtIDEgPyBpbmRleCA6IGluZGV4ICsgMTtcbiAgfVxuXG4gIHByaXZhdGUgc2VsZWN0TWFueSggcmVhZHlTZWxlY3RlZDogbnVtYmVyLCBpbmRleDogbnVtYmVyICkge1xuICAgIHRoaXMuZmlsdGVyVGltZXMuZm9yRWFjaCggKCB2YWx1ZSwgaW5kZXgyLCBhcnJheSApID0+IHtcbiAgICAgIGlmICggaW5kZXgyID4gcmVhZHlTZWxlY3RlZCAmJiBpbmRleDIgPD0gaW5kZXggKSB7XG4gICAgICAgIHZhbHVlLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmICggaW5kZXgyIDwgcmVhZHlTZWxlY3RlZCAmJiBpbmRleDIgPj0gaW5kZXggKSB7XG4gICAgICAgIHZhbHVlLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICB9ICk7XG4gICAgdGhpcy51cGRhdGVUaW1lKCk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVRpbWUoKSB7XG4gICAgdGhpcy5zZWxlY3RlZFRpbWUgPSBbXTtcbiAgICBjb25zdCBhbGxTZWxlY3RlZCA9IHRoaXMuZmlsdGVyVGltZXMuZmlsdGVyKCAoIHZhbHVlICkgPT4gdmFsdWUuc2VsZWN0ZWQgKTtcbiAgICBpZiAoIGFsbFNlbGVjdGVkLmxlbmd0aCA+IDAgKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkVGltZVsgMCBdID0gYWxsU2VsZWN0ZWRbIDAgXTtcbiAgICAgIGlmICggYWxsU2VsZWN0ZWQubGVuZ3RoID4gMSApIHtcbiAgICAgICAgdGhpcy5zZWxlY3RlZFRpbWVbIDEgXSA9IGFsbFNlbGVjdGVkWyBhbGxTZWxlY3RlZC5sZW5ndGggLSAxIF07XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuY2hhbmdlU2VsZWN0LmVtaXQoIHRoaXMuZ2V0U2VsZWN0ZWRBcnJheSgpLm1hcCgoaXRlbSkgPT4gaXRlbS5yYW5nZSkgKTtcbiAgICB0aGlzLmNoYW5nZS5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgaWYgKGNoYW5nZXNbJ2F2YWlsYWJsZVRpbWVzJ10pIHtcbiAgICAgIHRoaXMuc2V0VXBEYXRhKCk7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VzWyd2YWx1ZSddKSB7XG4gICAgICB0aGlzLmhhbmRsZVZhbHVlQ2hhbmdlKCk7XG4gICAgfVxuICB9XG5cbn1cbiIsIjxkaXYgW2NsYXNzXT1cIid1aS10aW1lLWF2YWlsYWJsZS1waWNrZXIgJyArIGNvbG9yXCIgW3N0eWxlLndpZHRoXT1cIndpZHRoXCI+XG4gIDxkaXYgY2xhc3M9XCJ1aS10aW1lLWhlYWRlclwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJkYXRlVmFsdWUgfCBob2xpZGF5OmhvbGlkYXlzIGFzIGRheUFycmF5XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwidWktZGF0ZS1zZWxlY3RlZFwiIFtjbGFzcy5ob2xpZGF5XT1cImRheUFycmF5Py5sZW5ndGggPiAwXCIgW3Rvb2x0aXBdPVwie3RleHQ6IGRheUFycmF5WzBdPy5kZXNjcmlwdGlvbiwgcGxhY2VtZW50OiAndG9wLWNlbnRlcid9XCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwidWktZGF5XCI+e3sgZGF0ZVZhbHVlIHwgZGF0ZTonZGQnIH19PC9zcGFuPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInVpLWRheS13ZWVrXCI+e3sgZGF0ZVZhbHVlIHwgZGF0ZTonRUVFRScgfX08L3NwYW4+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwidWktZGF5LWhvbGlkYXlcIiAqbmdJZj1cImRheUFycmF5Py5sZW5ndGggPiAwXCI+e3sgZGF5QXJyYXlbMF0/LmRlc2NyaXB0aW9uIH19PC9zcGFuPlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPGRpdiBjbGFzcz1cInVpLXRpbWUtc2VsZWN0ZWRcIj5cbiAgICAgIDxzcGFuICpuZ0lmPVwic2VsZWN0ZWRUaW1lLmxlbmd0aCA+IDFcIj57eyBzZWxlY3RlZFRpbWVbMF0/LnJhbmdlLnN0YXJ0IHwgZGF0ZTogJ0hIOm1tJyB9fSAtIHt7IHNlbGVjdGVkVGltZVsxXT8ucmFuZ2UuZW5kIHwgZGF0ZTogJ0hIOm1tJyB9fTwvc3Bhbj5cbiAgICAgIDxzcGFuICpuZ0lmPVwic2VsZWN0ZWRUaW1lLmxlbmd0aCA9PT0gMVwiPnt7IHNlbGVjdGVkVGltZVswXT8ucmFuZ2Uuc3RhcnQgfCBkYXRlOiAnSEg6bW0nIH19IC0ge3sgc2VsZWN0ZWRUaW1lWzBdPy5yYW5nZS5lbmQgfCBkYXRlOiAnSEg6bW0nIH19PC9zcGFuPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8ZGl2IGNsYXNzPVwidWktY29udGFpbmVyXCIgKm5nSWY9XCJsb2FkaW5nIHx8IGZpbHRlclRpbWVzLmxlbmd0aCA9PT0gMFwiIFtzdHlsZS5taW5IZWlnaHRdPVwibWF4SGVpZ2h0XCI+XG4gICAgPGRpdiAqbmdJZj1cImxvYWRpbmdcIiBjbGFzcz1cInVpLWxvYWRlci13cmFwcGVyXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwidWktbG9hZGVyXCI+XG4gICAgICAgIDx0bC1sb2FkZXI+PC90bC1sb2FkZXI+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgKm5nSWY9XCIhZmlsdGVyVGltZXMgfHwgZmlsdGVyVGltZXMubGVuZ3RoID09PSAwICYmICFsb2FkaW5nXCIgY2xhc3M9XCJ1aS1lbXB0eS1kYXRhXCI+XG4gICAgICA8dGwtaWNvbiBbbGliXT1cIidpb24nXCIgW3N0eWxlXT1cIidtZCdcIj5zYWQ8L3RsLWljb24+XG4gICAgICA8c3Bhbj57eyBub3RGb3VuZE1lc3NhZ2UgfX08L3NwYW4+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDxkaXYgKm5nSWY9XCJmaWx0ZXJUaW1lcy5sZW5ndGggPiAwICYmICFsb2FkaW5nXCIgY2xhc3M9XCJ1aS10aW1lLWNvbnRlbnRcIiBbc3R5bGUubWF4SGVpZ2h0XT1cIm1heEhlaWdodFwiPlxuICAgIDxkaXYgKm5nRm9yPVwibGV0IGl0ZW0gb2YgZmlsdGVyVGltZXM7IGxldCBpID0gaW5kZXhcIiBjbGFzcz1cInVpLXRpbWUtaXRlbVwiPlxuICAgICAgPGRpdiAgKGtleWRvd24uZW50ZXIpPVwic2V0U2VsZWN0ZWRUaW1lKGl0ZW0sIGkpXCJcbiAgICAgICAgICAgIGNsYXNzPVwidWktcmFuZ2Utd3JhcHBlclwiXG4gICAgICAgICAgICAoY2xpY2spPVwic2V0U2VsZWN0ZWRUaW1lKGl0ZW0sIGkpXCJcbiAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgJ3VpLXNlbGVjdGVkJzogaXRlbS5zZWxlY3RlZCB9XCJcbiAgICAgICAgICAgIHRhYmluZGV4PVwiLTFcIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJpdGVtLXJhbmdlXCI+e3sgaXRlbS5yYW5nZS5zdGFydCB8IGRhdGU6ICdISDptbScgfX08L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==