UNPKG

@matheo/datepicker

Version:

Angular material date+time picker

305 lines 50.7 kB
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Inject, Input, Optional, Output, ViewEncapsulation, } from '@angular/core'; import { MAT_DATE_FORMATS } from '@angular/material/core'; import { DateAdapter, } from '@matheo/datepicker/core'; import { createMissingDateImplError } from './datepicker-errors'; import * as i0 from "@angular/core"; import * as i1 from "@matheo/datepicker/core"; import * as i2 from "@angular/common"; export const CLOCK_RADIUS = 50; export const CLOCK_INNER_RADIUS = 27.5; export const CLOCK_OUTER_RADIUS = 41.25; export const CLOCK_TICK_RADIUS = 7.0833; /** * A clock that is used as part of the datepicker. * @docs-private */ export class MatClockView { constructor(_changeDetectorRef, _element, _dateAdapter, _dateFormats) { this._changeDetectorRef = _changeDetectorRef; this._element = _element; this._dateAdapter = _dateAdapter; this._dateFormats = _dateFormats; this.clockStep = 1; this.twelveHour = false; this.currentViewChange = new EventEmitter(); /** Emits when a new date is selected. */ this.selectedChange = new EventEmitter(); /** Emits when any date is selected. */ this._userSelection = new EventEmitter(); // Hours and Minutes representing the clock view. this._hours = []; this._minutes = []; if (!this._dateAdapter) { throw createMissingDateImplError('DateAdapter'); } if (!this._dateFormats) { throw createMissingDateImplError('MAT_DATE_FORMATS'); } this.mouseMoveListener = (event) => { this._handleMousemove(event); }; this.mouseUpListener = () => { this._handleMouseup(); }; } /** * The time to display in this clock view. (the rest is ignored) */ get activeDate() { return this._activeDate; } set activeDate(value) { const oldActiveDate = this._activeDate; const validDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value)) || this._dateAdapter.today(); this._activeDate = this._dateAdapter.clampDate(validDate, this.minDate, this.maxDate); if (oldActiveDate && this._dateAdapter.compareDate(oldActiveDate, this._activeDate)) { this._init(); } } // The currently selected date. get selected() { return this._selected; } set selected(value) { this._selected = this._getValidDateOrNull(this._dateAdapter.deserialize(value)); } /** The minimum selectable date. */ get minDate() { return this._minDate; } set minDate(value) { this._minDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value)); } /** The maximum selectable date. */ get maxDate() { return this._maxDate; } set maxDate(value) { this._maxDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value)); } updateSize() { const { offsetWidth, offsetHeight } = this._element.nativeElement; this._size = (offsetWidth < offsetHeight ? offsetWidth : offsetHeight) * 0.9; this._changeDetectorRef.detectChanges(); } get inHourView() { return this.currentView === 'hour'; } get _hand() { this._selectedHour = this._dateAdapter.getHours(this.activeDate); this._selectedMinute = this._dateAdapter.getMinutes(this.activeDate); let radius = CLOCK_OUTER_RADIUS; let deg = 0; if (this.inHourView) { const outer = this.twelveHour || this._selectedHour >= 0 && this._selectedHour < 12; radius = outer ? CLOCK_OUTER_RADIUS : CLOCK_INNER_RADIUS; deg = Math.round(this._selectedHour * (360 / (24 / 2))); } else { deg = Math.round(this._selectedMinute * (360 / 60)); } return { transform: `rotate(${deg}deg)`, height: `${radius}%`, 'margin-top': `${50 - radius}%`, transition: this._draggingMouse ? 'none' : 'all 300ms ease', }; } ngAfterViewInit() { this.updateSize(); } ngAfterContentInit() { this._init(); } // Handles mousedown events on the clock body. _handleMousedown(event) { this._draggingMouse = true; document.addEventListener('mousemove', this.mouseMoveListener); document.addEventListener('touchmove', this.mouseMoveListener); document.addEventListener('mouseup', this.mouseUpListener); document.addEventListener('touchend', this.mouseUpListener); this.setTime(event); } _handleMousemove(event) { event.preventDefault(); this.setTime(event); } _handleMouseup() { this._draggingMouse = false; document.removeEventListener('mousemove', this.mouseMoveListener); document.removeEventListener('touchmove', this.mouseMoveListener); document.removeEventListener('mouseup', this.mouseUpListener); document.removeEventListener('touchend', this.mouseUpListener); if (this.dateFilter && !this.dateFilter(this.activeDate, this.currentView)) { return; } if (this.inHourView) { // we refresh the valid minutes this.currentViewChange.emit('minute'); this.selectedChange.emit(this.activeDate); this._init(); } else { this._userSelection.emit({ value: this.activeDate, event }); } } // Initializes this clock view. _init() { this._hours.length = 0; this._minutes.length = 0; const hourNames = this._dateAdapter.getHourNames(); const minuteNames = this._dateAdapter.getMinuteNames(); if (this.twelveHour) { this._anteMeridian = this._dateAdapter.getHours(this.activeDate) < 12; for (let i = 0; i < hourNames.length / 2; i++) { const radian = (i / 6) * Math.PI; const radius = CLOCK_OUTER_RADIUS; const date = this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), this._dateAdapter.getMonth(this.activeDate), this._dateAdapter.getDate(this.activeDate), this._anteMeridian ? i : i + 12, 0, 0, 0); this._hours.push({ value: this._anteMeridian ? i : i + 12, displayValue: i === 0 ? hourNames[12] : hourNames[i], enabled: !this.dateFilter || this.dateFilter(date, 'hour'), cssClasses: this.dateClass ? this.dateClass(date, 'hour') : undefined, top: CLOCK_RADIUS - Math.cos(radian) * radius - CLOCK_TICK_RADIUS, left: CLOCK_RADIUS + Math.sin(radian) * radius - CLOCK_TICK_RADIUS, }); } } else { for (let i = 0; i < hourNames.length; i++) { const radian = (i / 6) * Math.PI; const outer = i > 0 && i < 13; const radius = outer ? CLOCK_OUTER_RADIUS : CLOCK_INNER_RADIUS; const hour = i % 12 ? i : (i === 0 ? 12 : 0); const date = this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), this._dateAdapter.getMonth(this.activeDate), this._dateAdapter.getDate(this.activeDate), hour, 0, 0, 0); this._hours.push({ value: hour, displayValue: hourNames[hour], enabled: !this.dateFilter || this.dateFilter(date, 'hour'), cssClasses: this.dateClass ? this.dateClass(date, 'hour') : undefined, top: CLOCK_RADIUS - Math.cos(radian) * radius - CLOCK_TICK_RADIUS, left: CLOCK_RADIUS + Math.sin(radian) * radius - CLOCK_TICK_RADIUS, fontSize: i > 0 && i < 13 ? '' : '80%', }); } } for (let i = 0; i < minuteNames.length; i += 5) { const radian = (i / 30) * Math.PI; const date = this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), this._dateAdapter.getMonth(this.activeDate), this._dateAdapter.getDate(this.activeDate), this._dateAdapter.getHours(this.activeDate), i, 0, 0); this._minutes.push({ value: i, displayValue: i === 0 ? '00' : minuteNames[i], enabled: !this.dateFilter || this.dateFilter(date, 'minute'), cssClasses: this.dateClass ? this.dateClass(date, 'minute') : undefined, top: CLOCK_RADIUS - Math.cos(radian) * CLOCK_OUTER_RADIUS - CLOCK_TICK_RADIUS, left: CLOCK_RADIUS + Math.sin(radian) * CLOCK_OUTER_RADIUS - CLOCK_TICK_RADIUS, }); } this._changeDetectorRef.markForCheck(); } // Set Time setTime(event) { const trigger = this._element.nativeElement; const triggerRect = trigger.getBoundingClientRect(); const width = trigger.offsetWidth; const height = trigger.offsetHeight; const pageX = event.pageX !== undefined ? event.pageX : event.touches[0].pageX; const pageY = event.pageY !== undefined ? event.pageY : event.touches[0].pageY; const x = width / 2 - (pageX - triggerRect.left - window.pageXOffset); const y = height / 2 - (pageY - triggerRect.top - window.pageYOffset); const unit = Math.PI / (this.inHourView ? 6 : this.clockStep ? 30 / this.clockStep : 30); const z = Math.sqrt(x * x + y * y); const avg = (width * (CLOCK_OUTER_RADIUS / 100) + width * (CLOCK_INNER_RADIUS / 100)) / 2; const outer = this.inHourView && z > avg - 16 /* button radius */; let radian = Math.atan2(-x, y); if (radian < 0) { radian = Math.PI * 2 + radian; } let value = Math.round(radian / unit); let date = this._dateAdapter.clone(this.activeDate); if (this.inHourView) { if (value === 12) { value = 0; } value = this.twelveHour ? (this._anteMeridian ? value : value + 12) : (outer ? value : value + 12); date = this._dateAdapter.setHours(date, value); } else { if (this.clockStep) { value *= this.clockStep; } if (value === 60) { value = 0; } date = this._dateAdapter.setMinutes(date, value); } // validate if the resulting value is disabled and do not take action if (this.dateFilter && !this.dateFilter(date, this.currentView)) { return; } // we don't want to re-render the clock this._activeDate = date; this.selectedChange.emit(this.activeDate); } _focusActiveCell() { } /** * @param obj The object to check. * @returns The given object if it is both a date instance and valid, otherwise null. */ _getValidDateOrNull(obj) { return this._dateAdapter.isDateInstance(obj) && this._dateAdapter.isValid(obj) ? obj : null; } } /** @nocollapse */ /** @nocollapse */ MatClockView.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: MatClockView, deps: [{ token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: i1.DateAdapter, optional: true }, { token: MAT_DATE_FORMATS, optional: true }], target: i0.ɵɵFactoryTarget.Component }); /** @nocollapse */ /** @nocollapse */ MatClockView.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.0.3", type: MatClockView, selector: "mat-clock-view", inputs: { activeDate: "activeDate", selected: "selected", minDate: "minDate", maxDate: "maxDate", dateFilter: "dateFilter", dateClass: "dateClass", clockStep: "clockStep", twelveHour: "twelveHour", currentView: "currentView" }, outputs: { currentViewChange: "currentViewChange", selectedChange: "selectedChange", _userSelection: "_userSelection" }, host: { attributes: { "role": "clock" }, listeners: { "mousedown": "_handleMousedown($event)", "window:resize": "updateSize()" } }, exportAs: ["matClockView"], ngImport: i0, template: "<div class=\"mat-clock\" [style.width.px]=\"_size\" [style.height.px]=\"_size\">\n <div class=\"mat-clock-center\"></div>\n <div class=\"mat-clock-hand\" [ngStyle]=\"_hand\"></div>\n\n <div class=\"mat-clock-hours\" [class.active]=\"inHourView\">\n <div *ngFor=\"let item of _hours\"\n class=\"mat-clock-cell\"\n [ngClass]=\"item.cssClasses\"\n [class.mat-clock-cell-selected]=\"_selectedHour == item.value\"\n [class.mat-clock-cell-disabled]=\"!item.enabled\"\n [style.top.%]=\"item.top\"\n [style.left.%]=\"item.left\"\n [style.fontSize]=\"item.fontSize\">\n {{ item.displayValue }}\n </div>\n </div>\n\n <div class=\"mat-clock-minutes\" [class.active]=\"!inHourView\">\n <div *ngFor=\"let item of _minutes\"\n class=\"mat-clock-cell\"\n [ngClass]=\"item.cssClasses\"\n [class.mat-clock-cell-selected]=\"_selectedMinute == item.value\"\n [class.mat-clock-cell-disabled]=\"!item.enabled\"\n [style.top.%]=\"item.top\"\n [style.left.%]=\"item.left\">\n {{ item.displayValue }}\n </div>\n </div>\n</div>\n", directives: [{ type: i2.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.0.3", ngImport: i0, type: MatClockView, decorators: [{ type: Component, args: [{ selector: 'mat-clock-view', exportAs: 'matClockView', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: { role: 'clock', '(mousedown)': '_handleMousedown($event)' }, preserveWhitespaces: false, template: "<div class=\"mat-clock\" [style.width.px]=\"_size\" [style.height.px]=\"_size\">\n <div class=\"mat-clock-center\"></div>\n <div class=\"mat-clock-hand\" [ngStyle]=\"_hand\"></div>\n\n <div class=\"mat-clock-hours\" [class.active]=\"inHourView\">\n <div *ngFor=\"let item of _hours\"\n class=\"mat-clock-cell\"\n [ngClass]=\"item.cssClasses\"\n [class.mat-clock-cell-selected]=\"_selectedHour == item.value\"\n [class.mat-clock-cell-disabled]=\"!item.enabled\"\n [style.top.%]=\"item.top\"\n [style.left.%]=\"item.left\"\n [style.fontSize]=\"item.fontSize\">\n {{ item.displayValue }}\n </div>\n </div>\n\n <div class=\"mat-clock-minutes\" [class.active]=\"!inHourView\">\n <div *ngFor=\"let item of _minutes\"\n class=\"mat-clock-cell\"\n [ngClass]=\"item.cssClasses\"\n [class.mat-clock-cell-selected]=\"_selectedMinute == item.value\"\n [class.mat-clock-cell-disabled]=\"!item.enabled\"\n [style.top.%]=\"item.top\"\n [style.left.%]=\"item.left\">\n {{ item.displayValue }}\n </div>\n </div>\n</div>\n" }] }], ctorParameters: function () { return [{ type: i0.ChangeDetectorRef }, { type: i0.ElementRef }, { type: i1.DateAdapter, decorators: [{ type: Optional }] }, { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MAT_DATE_FORMATS] }] }]; }, propDecorators: { activeDate: [{ type: Input }], selected: [{ type: Input }], minDate: [{ type: Input }], maxDate: [{ type: Input }], dateFilter: [{ type: Input }], dateClass: [{ type: Input }], clockStep: [{ type: Input }], twelveHour: [{ type: Input }], currentView: [{ type: Input }], currentViewChange: [{ type: Output }], selectedChange: [{ type: Output }], _userSelection: [{ type: Output }], updateSize: [{ type: HostListener, args: ['window:resize'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvY2stdmlldy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2xpYnMvZGF0ZXBpY2tlci9zcmMvbGliL2Nsb2NrLXZpZXcudHMiLCIuLi8uLi8uLi8uLi8uLi9saWJzL2RhdGVwaWNrZXIvc3JjL2xpYi9jbG9jay12aWV3Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUdMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osWUFBWSxFQUNaLE1BQU0sRUFDTixLQUFLLEVBQ0wsUUFBUSxFQUNSLE1BQU0sRUFDTixpQkFBaUIsR0FDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFDeEQsT0FBTyxFQUNMLFdBQVcsR0FFWixNQUFNLHlCQUF5QixDQUFDO0FBRWpDLE9BQU8sRUFBQywwQkFBMEIsRUFBQyxNQUFNLHFCQUFxQixDQUFDOzs7O0FBRy9ELE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxFQUFFLENBQUM7QUFDL0IsTUFBTSxDQUFDLE1BQU0sa0JBQWtCLEdBQUcsSUFBSSxDQUFDO0FBQ3ZDLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLEtBQUssQ0FBQztBQUN4QyxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLENBQUM7QUFJeEM7OztHQUdHO0FBYUgsTUFBTSxPQUFPLFlBQVk7SUFtSXZCLFlBQ1Usa0JBQXFDLEVBQ3JDLFFBQW9CLEVBQ1QsWUFBNEIsRUFHdkMsWUFBNEI7UUFMNUIsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUFtQjtRQUNyQyxhQUFRLEdBQVIsUUFBUSxDQUFZO1FBQ1QsaUJBQVksR0FBWixZQUFZLENBQWdCO1FBR3ZDLGlCQUFZLEdBQVosWUFBWSxDQUFnQjtRQW5FN0IsY0FBUyxHQUFXLENBQUMsQ0FBQztRQUV0QixlQUFVLEdBQVksS0FB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c0JBRFYsS0FBSztnQkFZRyxVQUFVO3NCQUFsQixLQUFLO2dCQUdHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBRUcsU0FBUztzQkFBakIsS0FBSztnQkFFRyxVQUFVO3NCQUFsQixLQUFLO2dCQUVHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUksaUJBQWlCO3NCQUExQixNQUFNO2dCQUlFLGNBQWM7c0JBRHRCLE1BQU07Z0JBSVksY0FBYztzQkFBaEMsTUFBTTtnQkFHUCxVQUFVO3NCQURULFlBQVk7dUJBQUMsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyQ29udGVudEluaXQsXG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RMaXN0ZW5lcixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgT3B0aW9uYWwsXG4gIE91dHB1dCxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtNQVRfREFURV9GT1JNQVRTfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9jb3JlJztcbmltcG9ydCB7XG4gIERhdGVBZGFwdGVyLFxuICBNYXREYXRlRm9ybWF0cyxcbn0gZnJvbSAnQG1hdGhlby9kYXRlcGlja2VyL2NvcmUnO1xuaW1wb3J0IHtNYXRDYWxlbmRhckNlbGxDbGFzc0Z1bmN0aW9uLCBNYXRDYWxlbmRhclVzZXJFdmVudH0gZnJvbSAnLi9jYWxlbmRhci1ib2R5JztcbmltcG9ydCB7Y3JlYXRlTWlzc2luZ0RhdGVJbXBsRXJyb3J9IGZyb20gJy4vZGF0ZXBpY2tlci1lcnJvcnMnO1xuaW1wb3J0IHtEYXRlRmlsdGVyRm59IGZyb20gJy4vZGF0ZXBpY2tlci1pbnB1dC1iYXNlJztcblxuZXhwb3J0IGNvbnN0IENMT0NLX1JBRElVUyA9IDUwO1xuZXhwb3J0IGNvbnN0IENMT0NLX0lOTkVSX1JBRElVUyA9IDI3LjU7XG5leHBvcnQgY29uc3QgQ0xPQ0tfT1VURVJfUkFESVVTID0gNDEuMjU7XG5leHBvcnQgY29uc3QgQ0xPQ0tfVElDS19SQURJVVMgPSA3LjA4MzM7XG5cbmV4cG9ydCB0eXBlIENsb2NrVmlldyA9ICdob3VyJyB8ICdtaW51dGUnO1xuXG4vKipcbiAqIEEgY2xvY2sgdGhhdCBpcyB1c2VkIGFzIHBhcnQgb2YgdGhlIGRhdGVwaWNrZXIuXG4gKiBAZG9jcy1wcml2YXRlXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ21hdC1jbG9jay12aWV3JyxcbiAgdGVtcGxhdGVVcmw6ICdjbG9jay12aWV3Lmh0bWwnLFxuICBleHBvcnRBczogJ21hdENsb2NrVmlldycsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBob3N0OiB7XG4gICAgcm9sZTogJ2Nsb2NrJyxcbiAgICAnKG1vdXNlZG93biknOiAnX2hhbmRsZU1vdXNlZG93bigkZXZlbnQpJ1xuICB9LFxuICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBmYWxzZVxufSlcbmV4cG9ydCBjbGFzcyBNYXRDbG9ja1ZpZXc8RD4gaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBBZnRlckNvbnRlbnRJbml0IHtcbiAgLyoqXG4gICAqIFRoZSB0aW1lIHRvIGRpc3BsYXkgaW4gdGhpcyBjbG9jayB2aWV3LiAodGhlIHJlc3QgaXMgaWdub3JlZClcbiAgICovXG4gIEBJbnB1dCgpXG4gIGdldCBhY3RpdmVEYXRlKCk6IEQge1xuICAgIHJldHVybiB0aGlzLl9hY3RpdmVEYXRlO1xuICB9XG4gIHNldCBhY3RpdmVEYXRlKHZhbHVlOiBEKSB7XG4gICAgY29uc3Qgb2xkQWN0aXZlRGF0ZSA9IHRoaXMuX2FjdGl2ZURhdGU7XG4gICAgY29uc3QgdmFsaWREYXRlID1cbiAgICAgIHRoaXMuX2dldFZhbGlkRGF0ZU9yTnVsbCh0aGlzLl9kYXRlQWRhcHRlci5kZXNlcmlhbGl6ZSh2YWx1ZSkpIHx8XG4gICAgICB0aGlzLl9kYXRlQWRhcHRlci50b2RheSgpO1xuICAgIHRoaXMuX2FjdGl2ZURhdGUgPSB0aGlzLl9kYXRlQWRhcHRlci5jbGFtcERhdGUoXG4gICAgICB2YWxpZERhdGUsXG4gICAgICB0aGlzLm1pbkRhdGUsXG4gICAgICB0aGlzLm1heERhdGVcbiAgICApO1xuXG4gICAgaWYgKFxuICAgICAgb2xkQWN0aXZlRGF0ZSAmJlxuICAgICAgdGhpcy5fZGF0ZUFkYXB0ZXIuY29tcGFyZURhdGUob2xkQWN0aXZlRGF0ZSwgdGhpcy5fYWN0aXZlRGF0ZSlcbiAgICApIHtcbiAgICAgIHRoaXMuX2luaXQoKTtcbiAgICB9XG4gIH1cbiAgcHJpdmF0ZSBfYWN0aXZlRGF0ZTogRDtcblxuICAvLyBUaGUgY3VycmVudGx5IHNlbGVjdGVkIGRhdGUuXG4gIEBJbnB1dCgpXG4gIGdldCBzZWxlY3RlZCgpOiBEIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX3NlbGVjdGVkO1xuICB9XG4gIHNldCBzZWxlY3RlZCh2YWx1ZTogRCB8IG51bGwpIHtcbiAgICB0aGlzLl9zZWxlY3RlZCA9IHRoaXMuX2dldFZhbGlkRGF0ZU9yTnVsbChcbiAgICAgIHRoaXMuX2RhdGVBZGFwdGVyLmRlc2VyaWFsaXplKHZhbHVlKVxuICAgICk7XG4gIH1cbiAgcHJpdmF0ZSBfc2VsZWN0ZWQ6IEQgfCBudWxsO1xuXG4gIC8qKiBUaGUgbWluaW11bSBzZWxlY3RhYmxlIGRhdGUuICovXG4gIEBJbnB1dCgpXG4gIGdldCBtaW5EYXRlKCk6IEQgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fbWluRGF0ZTtcbiAgfVxuICBzZXQgbWluRGF0ZSh2YWx1ZTogRCB8IG51bGwpIHtcbiAgICB0aGlzLl9taW5EYXRlID0gdGhpcy5fZ2V0VmFsaWREYXRlT3JOdWxsKFxuICAgICAgdGhpcy5fZGF0ZUFkYXB0ZXIuZGVzZXJpYWxpemUodmFsdWUpXG4gICAgKTtcbiAgfVxuICBwcml2YXRlIF9taW5EYXRlOiBEIHwgbnVsbDtcblxuICAvKiogVGhlIG1heGltdW0gc2VsZWN0YWJsZSBkYXRlLiAqL1xuICBASW5wdXQoKVxuICBnZXQgbWF4RGF0ZSgpOiBEIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX21heERhdGU7XG4gIH1cbiAgc2V0IG1heERhdGUodmFsdWU6IEQgfCBudWxsKSB7XG4gICAgdGhpcy5fbWF4RGF0ZSA9IHRoaXMuX2dldFZhbGlkRGF0ZU9yTnVsbChcbiAgICAgIHRoaXMuX2RhdGVBZGFwdGVyLmRlc2VyaWFsaXplKHZhbHVlKVxuICAgICk7XG4gIH1cbiAgcHJpdmF0ZSBfbWF4RGF0ZTogRCB8IG51bGw7XG5cbiAgLy8gQSBmdW5jdGlvbiB1c2VkIHRvIGZpbHRlciB3aGljaCBkYXRlcyBhcmUgc2VsZWN0YWJsZS5cbiAgQElucHV0KCkgZGF0ZUZpbHRlcjogRGF0ZUZpbHRlckZuPEQ+O1xuXG4gIC8qKiBGdW5jdGlvbiB0aGF0IGNhbiBiZSB1c2VkIHRvIGFkZCBjdXN0b20gQ1NTIGNsYXNzZXMgdG8gZGF0ZXMuICovXG4gIEBJbnB1dCgpIGRhdGVDbGFzczogTWF0Q2FsZW5kYXJDZWxsQ2xhc3NGdW5jdGlvbjxEPjtcblxuICBASW5wdXQoKSBjbG9ja1N0ZXA6IG51bWJlciA9IDE7XG5cbiAgQElucHV0KCkgdHdlbHZlSG91cjogQm9vbGVhbiA9IGZhbHNlO1xuXG4gIEBJbnB1dCgpIGN1cnJlbnRWaWV3OiBDbG9ja1ZpZXc7XG5cbiAgQE91dHB1dCgpIGN1cnJlbnRWaWV3Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxDbG9ja1ZpZXc+KCk7XG5cbiAgLyoqIEVtaXRzIHdoZW4gYSBuZXcgZGF0ZSBpcyBzZWxlY3RlZC4gKi9cbiAgQE91dHB1dCgpXG4gIHJlYWRvbmx5IHNlbGVjdGVkQ2hhbmdlOiBFdmVudEVtaXR0ZXI8RCB8IG51bGw+ID0gbmV3IEV2ZW50RW1pdHRlcjxEIHwgbnVsbD4oKTtcblxuICAvKiogRW1pdHMgd2hlbiBhbnkgZGF0ZSBpcyBzZWxlY3RlZC4gKi9cbiAgQE91dHB1dCgpIHJlYWRvbmx5IF91c2VyU2VsZWN0aW9uID0gbmV3IEV2ZW50RW1pdHRlcjxNYXRDYWxlbmRhclVzZXJFdmVudDxEIHwgbnVsbD4+KCk7XG5cbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OnJlc2l6ZScpXG4gIHVwZGF0ZVNpemUoKSB7XG4gICAgY29uc3QgeyBvZmZzZXRXaWR0aCwgb2Zmc2V0SGVpZ2h0IH0gPSB0aGlzLl9lbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgdGhpcy5fc2l6ZSA9IChvZmZzZXRXaWR0aCA8IG9mZnNldEhlaWdodCA/IG9mZnNldFdpZHRoIDogb2Zmc2V0SGVpZ2h0KSAqIDAuOTtcbiAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gIH1cblxuICAvLyBIb3VycyBhbmQgTWludXRlcyByZXByZXNlbnRpbmcgdGhlIGNsb2NrIHZpZXcuXG4gIF9ob3VyczogYW55W10gPSBbXTtcbiAgX21pbnV0ZXM6IGFueVtdID0gW107XG5cbiAgX2RyYWdnaW5nTW91c2U6IGJvb2xlYW47XG4gIF9zZWxlY3RlZEhvdXI6IG51bWJlciB8IG51bGw7XG4gIF9zZWxlY3RlZE1pbnV0ZTogbnVtYmVyIHwgbnVsbDtcbiAgX2FudGVNZXJpZGlhbjogYm9vbGVhbjtcbiAgX3NpemU6IG51bWJlcjtcblxuICBwcml2YXRlIG1vdXNlTW92ZUxpc3RlbmVyOiBhbnk7XG4gIHByaXZhdGUgbW91c2VVcExpc3RlbmVyOiBhbnk7XG5cbiAgZ2V0IGluSG91clZpZXcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY3VycmVudFZpZXcgPT09ICdob3VyJztcbiAgfVxuXG4gIGdldCBfaGFuZCgpOiBhbnkge1xuICAgIHRoaXMuX3NlbGVjdGVkSG91ciA9IHRoaXMuX2RhdGVBZGFwdGVyLmdldEhvdXJzKHRoaXMuYWN0aXZlRGF0ZSk7XG4gICAgdGhpcy5fc2VsZWN0ZWRNaW51dGUgPSB0aGlzLl9kYXRlQWRhcHRlci5nZXRNaW51dGVzKHRoaXMuYWN0aXZlRGF0ZSk7XG4gICAgbGV0IHJhZGl1cyA9IENMT0NLX09VVEVSX1JBRElVUztcbiAgICBsZXQgZGVnID0gMDtcblxuICAgIGlmICh0aGlzLmluSG91clZpZXcpIHtcbiAgICAgIGNvbnN0IG91dGVyID0gdGhpcy50d2VsdmVIb3VyIHx8IHRoaXMuX3NlbGVjdGVkSG91ciA+PSAwICYmIHRoaXMuX3NlbGVjdGVkSG91ciA8IDEyO1xuICAgICAgcmFkaXVzID0gb3V0ZXIgPyBDTE9DS19PVVRFUl9SQURJVVMgOiBDTE9DS19JTk5FUl9SQURJVVM7XG4gICAgICBkZWcgPSBNYXRoLnJvdW5kKHRoaXMuX3NlbGVjdGVkSG91ciAqICgzNjAgLyAoMjQgLyAyKSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWcgPSBNYXRoLnJvdW5kKHRoaXMuX3NlbGVjdGVkTWludXRlICogKDM2MCAvIDYwKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHRyYW5zZm9ybTogYHJvdGF0ZSgke2RlZ31kZWcpYCxcbiAgICAgIGhlaWdodDogYCR7cmFkaXVzfSVgLFxuICAgICAgJ21hcmdpbi10b3AnOiBgJHs1MCAtIHJhZGl1c30lYCxcbiAgICAgIHRyYW5zaXRpb246IHRoaXMuX2RyYWdnaW5nTW91c2UgPyAnbm9uZScgOiAnYWxsIDMwMG1zIGVhc2UnLFxuICAgIH07XG4gIH1cblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIF9jaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSBfZWxlbWVudDogRWxlbWVudFJlZixcbiAgICBAT3B0aW9uYWwoKSBwdWJsaWMgX2RhdGVBZGFwdGVyOiBEYXRlQWRhcHRlcjxEPixcbiAgICBAT3B0aW9uYWwoKVxuICAgIEBJbmplY3QoTUFUX0RBVEVfRk9STUFUUylcbiAgICBwcml2YXRlIF9kYXRlRm9ybWF0czogTWF0RGF0ZUZvcm1hdHNcbiAgKSB7XG4gICAgaWYgKCF0aGlzLl9kYXRlQWRhcHRlcikge1xuICAgICAgdGhyb3cgY3JlYXRlTWlzc2luZ0RhdGVJbXBsRXJyb3IoJ0RhdGVBZGFwdGVyJyk7XG4gICAgfVxuICAgIGlmICghdGhpcy5fZGF0ZUZvcm1hdHMpIHtcbiAgICAgIHRocm93IGNyZWF0ZU1pc3NpbmdEYXRlSW1wbEVycm9yKCdNQVRfREFURV9GT1JNQVRTJyk7XG4gICAgfVxuXG4gICAgdGhpcy5tb3VzZU1vdmVMaXN0ZW5lciA9IChldmVudDogYW55KSA9PiB7XG4gICAgICB0aGlzLl9oYW5kbGVNb3VzZW1vdmUoZXZlbnQpO1xuICAgIH07XG4gICAgdGhpcy5tb3VzZVVwTGlzdGVuZXIgPSAoKSA9PiB7XG4gICAgICB0aGlzLl9oYW5kbGVNb3VzZXVwKCk7XG4gICAgfTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB0aGlzLnVwZGF0ZVNpemUoKTtcbiAgfVxuXG4gIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcbiAgICB0aGlzLl9pbml0KCk7XG4gIH1cblxuICAvLyBIYW5kbGVzIG1vdXNlZG93biBldmVudHMgb24gdGhlIGNsb2NrIGJvZHkuXG4gIF9oYW5kbGVNb3VzZWRvd24oZXZlbnQ6IGFueSkge1xuICAgIHRoaXMuX2RyYWdnaW5nTW91c2UgPSB0cnVlO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIHRoaXMubW91c2VNb3ZlTGlzdGVuZXIpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3RvdWNobW92ZScsIHRoaXMubW91c2VNb3ZlTGlzdGVuZXIpO1xuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLm1vdXNlVXBMaXN0ZW5lcik7XG4gICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLm1vdXNlVXBMaXN0ZW5lcik7XG4gICAgdGhpcy5zZXRUaW1lKGV2ZW50KTtcbiAgfVxuXG4gIF9oYW5kbGVNb3VzZW1vdmUoZXZlbnQ6IGFueSkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5zZXRUaW1lKGV2ZW50KTtcbiAgfVxuXG4gIF9oYW5kbGVNb3VzZXVwKCkge1xuICAgIHRoaXMuX2RyYWdnaW5nTW91c2UgPSBmYWxzZTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLm1vdXNlTW92ZUxpc3RlbmVyKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCB0aGlzLm1vdXNlTW92ZUxpc3RlbmVyKTtcbiAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZXVwJywgdGhpcy5tb3VzZVVwTGlzdGVuZXIpO1xuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgdGhpcy5tb3VzZVVwTGlzdGVuZXIpO1xuXG4gICAgaWYgKHRoaXMuZGF0ZUZpbHRlciAmJiAhdGhpcy5kYXRlRmlsdGVyKHRoaXMuYWN0aXZlRGF0ZSwgdGhpcy5jdXJyZW50VmlldykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pbkhvdXJWaWV3KSB7XG4gICAgICAvLyB3ZSByZWZyZXNoIHRoZSB2YWxpZCBtaW51dGVzXG4gICAgICB0aGlzLmN1cnJlbnRWaWV3Q2hhbmdlLmVtaXQoJ21pbnV0ZScpO1xuICAgICAgdGhpcy5zZWxlY3RlZENoYW5nZS5lbWl0KHRoaXMuYWN0aXZlRGF0ZSk7XG4gICAgICB0aGlzLl9pbml0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3VzZXJTZWxlY3Rpb24uZW1pdCh7IHZhbHVlOiB0aGlzLmFjdGl2ZURhdGUsIGV2ZW50IH0pO1xuICAgIH1cbiAgfVxuXG4gIC8vIEluaXRpYWxpemVzIHRoaXMgY2xvY2sgdmlldy5cbiAgX2luaXQoKSB7XG4gICAgdGhpcy5faG91cnMubGVuZ3RoID0gMDtcbiAgICB0aGlzLl9taW51dGVzLmxlbmd0aCA9IDA7XG5cbiAgICBjb25zdCBob3VyTmFtZXMgPSB0aGlzLl9kYXRlQWRhcHRlci5nZXRIb3VyTmFtZXMoKTtcbiAgICBjb25zdCBtaW51dGVOYW1lcyA9IHRoaXMuX2RhdGVBZGFwdGVyLmdldE1pbnV0ZU5hbWVzKCk7XG5cbiAgICBpZiAodGhpcy50d2VsdmVIb3VyKSB7XG4gICAgICB0aGlzLl9hbnRlTWVyaWRpYW4gPSB0aGlzLl9kYXRlQWRhcHRlci5nZXRIb3Vycyh0aGlzLmFjdGl2ZURhdGUpIDwgMTI7XG5cbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaG91ck5hbWVzLmxlbmd0aCAvIDI7IGkrKykge1xuICAgICAgICBjb25zdCByYWRpYW4gPSAoaSAvIDYpICogTWF0aC5QSTtcbiAgICAgICAgY29uc3QgcmFkaXVzID0gQ0xPQ0tfT1VURVJfUkFESVVTO1xuICAgICAgICBjb25zdCBkYXRlID0gdGhpcy5fZGF0ZUFkYXB0ZXIuY3JlYXRlRGF0ZShcbiAgICAgICAgICB0aGlzLl9kYXRlQWRhcHRlci5nZXRZZWFyKHRoaXMuYWN0aXZlRGF0ZSksXG4gICAgICAgICAgdGhpcy5fZGF0ZUFkYXB0ZXIuZ2V0TW9udGgodGhpcy5hY3RpdmVEYXRlKSxcbiAgICAgICAgICB0aGlzLl9kYXRlQWRhcHRlci5nZXREYXRlKHRoaXMuYWN0aXZlRGF0ZSksXG4gICAgICAgICAgdGhpcy5fYW50ZU1lcmlkaWFuID8gaSA6IGkgKyAxMixcbiAgICAgICAgICAwLFxuICAgICAgICAgIDAsXG4gICAgICAgICAgMFxuICAgICAgICApO1xuICAgICAgICB0aGlzLl9ob3Vycy5wdXNoKHtcbiAgICAgICAgICB2YWx1ZTogdGhpcy5fYW50ZU1lcmlkaWFuID8gaSA6IGkgKyAxMixcbiAgICAgICAgICBkaXNwbGF5VmFsdWU6IGkgPT09IDAgPyBob3VyTmFtZXNbMTJdIDogaG91ck5hbWVzW2ldLFxuICAgICAgICAgIGVuYWJsZWQ6ICF0aGlzLmRhdGVGaWx0ZXIgfHwgdGhpcy5kYXRlRmlsdGVyKGRhdGUsICdob3VyJyksXG4gICAgICAgICAgY3NzQ2xhc3NlczogdGhpcy5kYXRlQ2xhc3MgPyB0aGlzLmRhdGVDbGFzcyhkYXRlLCAnaG91cicpIDogdW5kZWZpbmVkLFxuICAgICAgICAgIHRvcDogQ0xPQ0tfUkFESVVTIC0gTWF0aC5jb3MocmFkaWFuKSAqIHJhZGl1cyAtIENMT0NLX1RJQ0tfUkFESVVTLFxuICAgICAgICAgIGxlZnQ6IENMT0NLX1JBRElVUyArIE1hdGguc2luKHJhZGlhbikgKiByYWRpdXMgLSBDTE9DS19USUNLX1JBRElVUyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaG91ck5hbWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IHJhZGlhbiA9IChpIC8gNikgKiBNYXRoLlBJO1xuICAgICAgICBjb25zdCBvdXRlciA9IGkgPiAwICYmIGkgPCAxMztcbiAgICAgICAgY29uc3QgcmFkaXVzID0gb3V0ZXIgPyBDTE9DS19PVVRFUl9SQURJVVMgOiBDTE9DS19JTk5FUl9SQURJVVM7XG4gICAgICAgIGNvbnN0IGhvdXIgPSBpICUgMTIgPyBpIDogKGkgPT09IDAgPyAxMiA6IDApO1xuICAgICAgICBjb25zdCBkYXRlID0gdGhpcy5fZGF0ZUFkYXB0ZXIuY3JlYXRlRGF0ZShcbiAgICAgICAgICB0aGlzLl9kYXRlQWRhcHRlci5nZXRZZWFyKHRoaXMuYWN0aXZlRGF0ZSksXG4gICAgICAgICAgdGhpcy5fZGF0ZUFkYXB0ZXIuZ2V0TW9udGgodGhpcy5hY3RpdmVEYXRlKSxcbiAgICAgICAgICB0aGlzLl9kYXRlQWRhcHRlci5nZXREYXRlKHRoaXMuYWN0aXZlRGF0ZSksXG4gICAgICAgICAgaG91cixcbiAgICAgICAgICAwLFxuICAgICAgICAgIDAsXG4gICAgICAgICAgMFxuICAgICAgICApO1xuICAgICAgICB0aGlzLl9ob3Vycy5wdXNoKHtcbiAgICAgICAgICB2YWx1ZTogaG91cixcbiAgICAgICAgICBkaXNwbGF5VmFsdWU6IGhvdXJOYW1lc1tob3VyXSxcbiAgICAgICAgICBlbmFibGVkOiAhdGhpcy5kYXRlRmlsdGVyIHx8IHRoaXMuZGF0ZUZpbHRlcihkYXRlLCAnaG91cicpLFxuICAgICAgICAgIGNzc0NsYXNzZXM6IHRoaXMuZGF0ZUNsYXNzID8gdGhpcy5kYXRlQ2xhc3MoZGF0ZSwgJ2hvdXInKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICB0b3A6IENMT0NLX1JBRElVUyAtIE1hdGguY29zKHJhZGlhbikgKiByYWRpdXMgLSBDTE9DS19USUNLX1JBRElVUyxcbiAgICAgICAgICBsZWZ0OiBDTE9DS19SQURJVVMgKyBNYXRoLnNpbihyYWRpYW4pICogcmFkaXVzIC0gQ0xPQ0tfVElDS19SQURJVVMsXG4gICAgICAgICAgZm9udFNpemU6IGkgPiAwICYmIGkgPCAxMyA/ICcnIDogJzgwJScsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbWludXRlTmFtZXMubGVuZ3RoOyBpICs9IDUpIHtcbiAgICAgIGNvbnN0IHJhZGlhbiA9IChpIC8gMzApICogTWF0aC5QSTtcbiAgICAgIGNvbnN0IGRhdGUgPSB0aGlzLl9kYXRlQWRhcHRlci5jcmVhdGVEYXRlKFxuICAgICAgICB0aGlzLl9kYXRlQWRhcHRlci5nZXRZZWFyKHRoaXMuYWN0aXZlRGF0ZSksXG4gICAgICAgIHRoaXMuX2RhdGVBZGFwdGVyLmdldE1vbnRoKHRoaXMuYWN0aXZlRGF0ZSksXG4gICAgICAgIHRoaXMuX2RhdGVBZGFwdGVyLmdldERhdGUodGhpcy5hY3RpdmVEYXRlKSxcbiAgICAgICAgdGhpcy5fZGF0ZUFkYXB0ZXIuZ2V0SG91cnModGhpcy5hY3RpdmVEYXRlKSxcbiAgICAgICAgaSxcbiAgICAgICAgMCxcbiAgICAgICAgMFxuICAgICAgKTtcbiAgICAgIHRoaXMuX21pbnV0ZXMucHVzaCh7XG4gICAgICAgIHZhbHVlOiBpLFxuICAgICAgICBkaXNwbGF5VmFsdWU6IGkgPT09IDAgPyAnMDAnIDogbWludXRlTmFtZXNbaV0sXG4gICAgICAgIGVuYWJsZWQ6ICF0aGlzLmRhdGVGaWx0ZXIgfHwgdGhpcy5kYXRlRmlsdGVyKGRhdGUsICdtaW51dGUnKSxcbiAgICAgICAgY3NzQ2xhc3NlczogdGhpcy5kYXRlQ2xhc3MgPyB0aGlzLmRhdGVDbGFzcyhkYXRlLCAnbWludXRlJykgOiB1bmRlZmluZWQsXG4gICAgICAgIHRvcDpcbiAgICAgICAgICBDTE9DS19SQURJVVMgLVxuICAgICAgICAgIE1hdGguY29zKHJhZGlhbikgKiBDTE9DS19PVVRFUl9SQURJVVMgLVxuICAgICAgICAgIENMT0NLX1RJQ0tfUkFESVVTLFxuICAgICAgICBsZWZ0OlxuICAgICAgICAgIENMT0NLX1JBRElVUyArXG4gICAgICAgICAgTWF0aC5zaW4ocmFkaWFuKSAqIENMT0NLX09VVEVSX1JBRElVUyAtXG4gICAgICAgICAgQ0xPQ0tfVElDS19SQURJVVMsXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIC8vIFNldCBUaW1lXG4gIHByaXZhdGUgc2V0VGltZShldmVudDogYW55KSB7XG4gICAgY29uc3QgdHJpZ2dlciA9IHRoaXMuX2VsZW1lbnQubmF0aXZlRWxlbWVudDtcbiAgICBjb25zdCB0cmlnZ2VyUmVjdCA9IHRyaWdnZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3Qgd2lkdGggPSB0cmlnZ2VyLm9mZnNldFdpZHRoO1xuICAgIGNvbnN0IGhlaWdodCA9IHRyaWdnZXIub2Zmc2V0SGVpZ2h0O1xuICAgIGNvbnN0IHBhZ2VYID1cbiAgICAgIGV2ZW50LnBhZ2VYICE9PSB1bmRlZmluZWQgPyBldmVudC5wYWdlWCA6IGV2ZW50LnRvdWNoZXNbMF0ucGFnZVg7XG4gICAgY29uc3QgcGFnZVkgPVxuICAgICAgZXZlbnQucGFnZVkgIT09IHVuZGVmaW5lZCA/IGV2ZW50LnBhZ2VZIDogZXZlbnQudG91Y2hlc1swXS5wYWdlWTtcbiAgICBjb25zdCB4ID0gd2lkdGggLyAyIC0gKHBhZ2VYIC0gdHJpZ2dlclJlY3QubGVmdCAtIHdpbmRvdy5wYWdlWE9mZnNldCk7XG4gICAgY29uc3QgeSA9IGhlaWdodCAvIDIgLSAocGFnZVkgLSB0cmlnZ2VyUmVjdC50b3AgLSB3aW5kb3cucGFnZVlPZmZzZXQpO1xuICAgIGNvbnN0IHVuaXQgPVxuICAgICAgTWF0aC5QSSAvXG4gICAgICAodGhpcy5pbkhvdXJWaWV3ID8gNiA6IHRoaXMuY2xvY2tTdGVwID8gMzAgLyB0aGlzLmNsb2NrU3RlcCA6IDMwKTtcbiAgICBjb25zdCB6ID0gTWF0aC5zcXJ0KHggKiB4ICsgeSAqIHkpO1xuICAgIGNvbnN0IGF2ZyA9ICh3aWR0aCAqIChDTE9DS19PVVRFUl9SQURJVVMgLyAxMDApICsgd2lkdGggKiAoQ0xPQ0tfSU5ORVJfUkFESVVTIC8gMTAwKSkgLyAyO1xuICAgIGNvbnN0IG91dGVyID0gdGhpcy5pbkhvdXJWaWV3ICYmIHogPiBhdmcgLSAxNiAvKiBidXR0b24gcmFkaXVzICovO1xuXG4gICAgbGV0IHJhZGlhbiA9IE1hdGguYXRhbjIoLXgsIHkpO1xuICAgIGlmIChyYWRpYW4gPCAwKSB7XG4gICAgICByYWRpYW4gPSBNYXRoLlBJICogMiArIHJhZGlhbjtcbiAgICB9XG4gICAgbGV0IHZhbHVlID0gTWF0aC5yb3VuZChyYWRpYW4gLyB1bml0KTtcblxuICAgIGxldCBkYXRlID0gdGhpcy5fZGF0ZUFkYXB0ZXIuY2xvbmUodGhpcy5hY3RpdmVEYXRlKTtcblxuICAgIGlmICh0aGlzLmluSG91clZpZXcpIHtcbiAgICAgIGlmICh2YWx1ZSA9PT0gMTIpIHtcbiAgICAgICAgdmFsdWUgPSAwO1xuICAgICAgfVxuICAgICAgdmFsdWUgPSB0aGlzLnR3ZWx2ZUhvdXJcbiAgICAgICAgPyAodGhpcy5fYW50ZU1lcmlkaWFuID8gdmFsdWUgOiB2YWx1ZSArIDEyKVxuICAgICAgICA6IChvdXRlciA/IHZhbHVlIDogdmFsdWUgKyAxMik7XG4gICAgICBkYXRlID0gdGhpcy5fZGF0ZUFkYXB0ZXIuc2V0SG91cnMoZGF0ZSwgdmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5jbG9ja1N0ZXApIHtcbiAgICAgICAgdmFsdWUgKj0gdGhpcy5jbG9ja1N0ZXA7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUgPT09IDYwKSB7XG4gICAgICAgIHZhbHVlID0gMDtcbiAgICAgIH1cbiAgICAgIGRhdGUgPSB0aGlzLl9kYXRlQWRhcHRlci5zZXRNaW51dGVzKGRhdGUsIHZhbHVlKTtcbiAgICB9XG5cbiAgICAvLyB2YWxpZGF0ZSBpZiB0aGUgcmVzdWx0aW5nIHZhbHVlIGlzIGRpc2FibGVkIGFuZCBkbyBub3QgdGFrZSBhY3Rpb25cbiAgICBpZiAodGhpcy5kYXRlRmlsdGVyICYmICF0aGlzLmRhdGVGaWx0ZXIoZGF0ZSwgdGhpcy5jdXJyZW50VmlldykpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyB3ZSBkb24ndCB3YW50IHRvIHJlLXJlbmRlciB0aGUgY2xvY2tcbiAgICB0aGlzLl9hY3RpdmVEYXRlID0gZGF0ZTtcbiAgICB0aGlzLnNlbGVjdGVkQ2hhbmdlLmVtaXQodGhpcy5hY3RpdmVEYXRlKTtcbiAgfVxuXG4gIF9mb2N1c0FjdGl2ZUNlbGwoKSB7fVxuXG4gIC8qKlxuICAgKiBAcGFyYW0gb2JqIFRoZSBvYmplY3QgdG8gY2hlY2suXG4gICAqIEByZXR1cm5zIFRoZSBnaXZlbiBvYmplY3QgaWYgaXQgaXMgYm90aCBhIGRhdGUgaW5zdGFuY2UgYW5kIHZhbGlkLCBvdGhlcndpc2UgbnVsbC5cbiAgICovXG4gIHByaXZhdGUgX2dldFZhbGlkRGF0ZU9yTnVsbChvYmo6IGFueSk6IEQgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fZGF0ZUFkYXB0ZXIuaXNEYXRlSW5zdGFuY2Uob2JqKSAmJiB0aGlzLl9kYXRlQWRhcHRlci5pc1ZhbGlkKG9iaikgPyBvYmogOiBudWxsO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwibWF0LWNsb2NrXCIgW3N0eWxlLndpZHRoLnB4XT1cIl9zaXplXCIgW3N0eWxlLmhlaWdodC5weF09XCJfc2l6ZVwiPlxuICA8ZGl2IGNsYXNzPVwibWF0LWNsb2NrLWNlbnRlclwiPjwvZGl2PlxuICA8ZGl2IGNsYXNzPVwibWF0LWNsb2NrLWhhbmRcIiBbbmdTdHlsZV09XCJfaGFuZFwiPjwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJtYXQtY2xvY2staG91cnNcIiBbY2xhc3MuYWN0aXZlXT1cImluSG91clZpZXdcIj5cbiAgICA8ZGl2ICpuZ0Zvcj1cImxldCBpdGVtIG9mIF9ob3Vyc1wiXG4gICAgICBjbGFzcz1cIm1hdC1jbG9jay1jZWxsXCJcbiAgICAgIFtuZ0NsYXNzXT1cIml0ZW0uY3NzQ2xhc3Nlc1wiXG4gICAgICBbY2xhc3MubWF0LWNsb2NrLWNlbGwtc2VsZWN0ZWRdPVwiX3NlbGVjdGVkSG91ciA9PSBpdGVtLnZhbHVlXCJcbiAgICAgIFtjbGFzcy5tYXQtY2xvY2stY2VsbC1kaXNhYmxlZF09XCIhaXRlbS5lbmFibGVkXCJcbiAgICAgIFtzdHlsZS50b3AuJV09XCJpdGVtLnRvcFwiXG4gICAgICBbc3R5bGUubGVmdC4lXT1cIml0ZW0ubGVmdFwiXG4gICAgICBbc3R5bGUuZm9udFNpemVdPVwiaXRlbS5mb250U2l6ZVwiPlxuICAgICAge3sgaXRl