UNPKG

ng19-date-picker

Version:

https://github.com/vlio20/angular-datepicker

270 lines 50.3 kB
import { ECalendarMode } from '../common/types/calendar-mode-enum'; import { ChangeDetectionStrategy, Component, EventEmitter, forwardRef, HostBinding, Input, Output, ViewEncapsulation } from '@angular/core'; import { DayCalendarService } from './day-calendar.service'; import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms'; import { dayjsRef } from '../common/dayjs/dayjs.ref'; import * as i0 from "@angular/core"; import * as i1 from "./day-calendar.service"; import * as i2 from "../common/services/utils/utils.service"; import * as i3 from "@angular/common"; import * as i4 from "@angular/forms"; import * as i5 from "@angular/cdk/bidi"; import * as i6 from "../month-calendar/month-calendar.component"; import * as i7 from "../calendar-nav/calendar-nav.component"; export class DayCalendarComponent { constructor(dayCalendarService, utilsService, cd) { this.dayCalendarService = dayCalendarService; this.utilsService = utilsService; this.cd = cd; this.onSelect = new EventEmitter(); this.onMonthSelect = new EventEmitter(); this.onNavHeaderBtnClick = new EventEmitter(); this.onGoToCurrent = new EventEmitter(); this.onLeftNav = new EventEmitter(); this.onRightNav = new EventEmitter(); this.CalendarMode = ECalendarMode; this.isInited = false; this.currentCalendarMode = ECalendarMode.Day; this._shouldShowCurrent = true; this.api = { moveCalendarsBy: this.moveCalendarsBy.bind(this), moveCalendarTo: this.moveCalendarTo.bind(this), toggleCalendarMode: this.toggleCalendarMode.bind(this) }; } get selected() { return this._selected; } set selected(selected) { this._selected = selected; this.onChangeCallback(this.processOnChangeCallback(selected)); } get currentDateView() { return this._currentDateView; } set currentDateView(current) { this._currentDateView = dayjsRef(current.toDate()); this.weeks = this.dayCalendarService .generateMonthArray(this.componentConfig, this._currentDateView, this.selected); this.navLabel = this.dayCalendarService.getHeaderLabel(this.componentConfig, this._currentDateView); this.showLeftNav = this.dayCalendarService.shouldShowLeft(this.componentConfig.min, this.currentDateView); this.showRightNav = this.dayCalendarService.shouldShowRight(this.componentConfig.max, this.currentDateView); } ; ngOnInit() { this.isInited = true; this.init(); this.initValidators(); } init() { this.componentConfig = this.dayCalendarService.getConfig(this.config); this.selected = this.selected || []; this.currentDateView = this.displayDate ? this.utilsService.convertToDayjs(this.displayDate, this.componentConfig.format) : this.utilsService .getDefaultDisplayDate(this.currentDateView, this.selected, this.componentConfig.allowMultiSelect, this.componentConfig.min); this.weekdays = this.dayCalendarService .generateWeekdays(this.componentConfig.firstDayOfWeek); this.inputValueType = this.utilsService.getInputType(this.inputValue, this.componentConfig.allowMultiSelect); this.monthCalendarConfig = this.dayCalendarService.getMonthCalendarConfig(this.componentConfig); this._shouldShowCurrent = this.shouldShowCurrent(); } ngOnChanges(changes) { if (this.isInited) { const { minDate, maxDate, config } = changes; this.handleConfigChange(config); this.init(); if (minDate || maxDate) { this.initValidators(); } } } writeValue(value) { this.inputValue = value; if (value) { this.selected = this.utilsService .convertToDayjsArray(value, this.componentConfig); this.inputValueType = this.utilsService .getInputType(this.inputValue, this.componentConfig.allowMultiSelect); } else { this.selected = []; } this.weeks = this.dayCalendarService .generateMonthArray(this.componentConfig, this.currentDateView, this.selected); this.cd.markForCheck(); } registerOnChange(fn) { this.onChangeCallback = fn; } onChangeCallback(_) { } registerOnTouched(fn) { } validate(formControl) { if (this.minDate || this.maxDate) { return this.validateFn(formControl.value); } else { return () => null; } } processOnChangeCallback(value) { return this.utilsService.convertFromDayjsArray(this.componentConfig.format, value, this.componentConfig.returnedValueType || this.inputValueType); } initValidators() { this.validateFn = this.utilsService.createValidator({ minDate: this.minDate, maxDate: this.maxDate }, this.componentConfig.format, 'day'); this.onChangeCallback(this.processOnChangeCallback(this.selected)); } dayClicked(day) { if (day.selected && !this.componentConfig.unSelectOnClick) { return; } this.selected = this.utilsService .updateSelected(this.componentConfig.allowMultiSelect, this.selected, day); this.weeks = this.dayCalendarService .generateMonthArray(this.componentConfig, this.currentDateView, this.selected); this.onSelect.emit(day); } getDayBtnText(day) { return this.dayCalendarService.getDayBtnText(this.componentConfig, day.date); } getDayBtnCssClass(day) { const cssClasses = { 'dp-selected': day.selected, 'dp-current-month': day.currentMonth, 'dp-prev-month': day.prevMonth, 'dp-next-month': day.nextMonth, 'dp-current-day': day.currentDay }; const customCssClass = this.dayCalendarService.getDayBtnCssClass(this.componentConfig, day.date); if (customCssClass) { cssClasses[customCssClass] = true; } return cssClasses; } onLeftNavClick() { const from = dayjsRef(this.currentDateView.toDate()); this.moveCalendarsBy(this.currentDateView, -1, 'month'); const to = dayjsRef(this.currentDateView.toDate()); this.onLeftNav.emit({ from, to }); } onRightNavClick() { const from = dayjsRef(this.currentDateView.toDate()); this.moveCalendarsBy(this.currentDateView, 1, 'month'); const to = dayjsRef(this.currentDateView.toDate()); this.onRightNav.emit({ from, to }); } onMonthCalendarLeftClick(change) { this.onLeftNav.emit(change); } onMonthCalendarRightClick(change) { this.onRightNav.emit(change); } onMonthCalendarSecondaryLeftClick(change) { this.onRightNav.emit(change); } onMonthCalendarSecondaryRightClick(change) { this.onLeftNav.emit(change); } getWeekdayName(weekday) { if (this.componentConfig.weekDayFormatter) { return this.componentConfig.weekDayFormatter(weekday.day()); } return weekday.format(this.componentConfig.weekDayFormat); } toggleCalendarMode(mode) { if (this.currentCalendarMode !== mode) { this.currentCalendarMode = mode; this.onNavHeaderBtnClick.emit(mode); } this.cd.markForCheck(); } monthSelected(month) { this.currentDateView = dayjsRef(month.date.toDate()); this.currentCalendarMode = ECalendarMode.Day; this.onMonthSelect.emit(month); } moveCalendarsBy(current, amount, granularity = 'month') { this.currentDateView = dayjsRef(current.toDate()).add(amount, granularity); this.cd.markForCheck(); } moveCalendarTo(to) { if (to) { this.currentDateView = this.utilsService.convertToDayjs(to, this.componentConfig.format); } this.cd.markForCheck(); } shouldShowCurrent() { return this.utilsService.shouldShowCurrent(this.componentConfig.showGoToCurrent, 'day', this.componentConfig.min, this.componentConfig.max); } goToCurrent() { this.currentDateView = dayjsRef(); this.onGoToCurrent.emit(); } handleConfigChange(config) { if (config) { const prevConf = this.dayCalendarService.getConfig(config.previousValue); const currentConf = this.dayCalendarService.getConfig(config.currentValue); if (this.utilsService.shouldResetCurrentView(prevConf, currentConf)) { this._currentDateView = null; } } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: DayCalendarComponent, deps: [{ token: i1.DayCalendarService }, { token: i2.UtilsService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: DayCalendarComponent, selector: "dp-day-calendar", inputs: { config: "config", displayDate: "displayDate", minDate: "minDate", maxDate: "maxDate", theme: "theme" }, outputs: { onSelect: "onSelect", onMonthSelect: "onMonthSelect", onNavHeaderBtnClick: "onNavHeaderBtnClick", onGoToCurrent: "onGoToCurrent", onLeftNav: "onLeftNav", onRightNav: "onRightNav" }, host: { properties: { "class": "this.theme" } }, providers: [ DayCalendarService, { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DayCalendarComponent), multi: true }, { provide: NG_VALIDATORS, useExisting: forwardRef(() => DayCalendarComponent), multi: true } ], usesOnChanges: true, ngImport: i0, template: "<div *ngIf=\"currentCalendarMode === CalendarMode.Day\" class=\"dp-day-calendar-container\" dir=\"ltr\">\n <dp-calendar-nav\n (onGoToCurrent)=\"goToCurrent()\"\n (onLabelClick)=\"toggleCalendarMode(CalendarMode.Month)\"\n (onLeftNav)=\"onLeftNavClick()\"\n (onRightNav)=\"onRightNavClick()\"\n [isLabelClickable]=\"componentConfig.enableMonthSelector\"\n [label]=\"navLabel\"\n [showGoToCurrent]=\"_shouldShowCurrent\"\n [showLeftNav]=\"showLeftNav\"\n [showRightNav]=\"showRightNav\"\n [theme]=\"theme\">\n </dp-calendar-nav>\n\n <div [ngClass]=\"{'dp-hide-near-month': !componentConfig.showNearMonthDays}\"\n class=\"dp-calendar-wrapper\">\n <div class=\"dp-weekdays\">\n <span *ngFor=\"let weekday of weekdays\"\n [innerText]=\"getWeekdayName(weekday)\"\n class=\"dp-calendar-weekday\">\n </span>\n </div>\n <div *ngFor=\"let week of weeks\" class=\"dp-calendar-week\">\n <span *ngIf=\"componentConfig.showWeekNumbers\"\n [innerText]=\"week[0].date.isoWeek()\"\n class=\"dp-week-number\">\n </span>\n <button (click)=\"dayClicked(day)\"\n *ngFor=\"let day of week\"\n [attr.data-date]=\"day.date.format(componentConfig.format)\"\n [disabled]=\"day.disabled\"\n [innerText]=\"getDayBtnText(day)\"\n [ngClass]=\"getDayBtnCssClass(day)\"\n class=\"dp-calendar-day\"\n type=\"button\">\n </button>\n </div>\n </div>\n</div>\n\n<dp-month-calendar\n (onLeftNav)=\"onMonthCalendarLeftClick($event)\"\n (onLeftSecondaryNav)=\"onMonthCalendarSecondaryLeftClick($event)\"\n (onNavHeaderBtnClick)=\"toggleCalendarMode(CalendarMode.Day)\"\n (onRightNav)=\"onMonthCalendarRightClick($event)\"\n (onRightSecondaryNav)=\"onMonthCalendarSecondaryRightClick($event)\"\n (onSelect)=\"monthSelected($event)\"\n *ngIf=\"currentCalendarMode === CalendarMode.Month\"\n [config]=\"monthCalendarConfig\"\n [displayDate]=\"_currentDateView\"\n [ngModel]=\"_selected\"\n [theme]=\"theme\">\n</dp-month-calendar>\n", styles: ["dp-day-calendar{display:inline-block}dp-day-calendar .dp-day-calendar-container{background:#FFFFFF}dp-day-calendar .dp-calendar-wrapper{box-sizing:border-box;border:1px solid #000000}dp-day-calendar .dp-calendar-wrapper .dp-calendar-weekday:first-child{border-left:none}dp-day-calendar .dp-weekdays{font-size:15px;margin-bottom:5px}dp-day-calendar .dp-calendar-weekday{box-sizing:border-box;display:inline-block;width:30px;text-align:center;border-left:1px solid #000000;border-bottom:1px solid #000000}dp-day-calendar .dp-calendar-day{box-sizing:border-box;width:30px;height:30px;cursor:pointer}dp-day-calendar .dp-selected{background:#106CC8;color:#fff}dp-day-calendar .dp-prev-month,dp-day-calendar .dp-next-month{opacity:.5}dp-day-calendar .dp-hide-near-month .dp-prev-month,dp-day-calendar .dp-hide-near-month .dp-next-month{visibility:hidden}dp-day-calendar .dp-week-number{position:absolute;font-size:9px}dp-day-calendar.dp-material .dp-calendar-weekday{height:25px;width:30px;line-height:25px;color:#7a7a7a;border:none}dp-day-calendar.dp-material .dp-calendar-wrapper{border:1px solid #E0E0E0}dp-day-calendar.dp-material .dp-calendar-month,dp-day-calendar.dp-material .dp-calendar-day{box-sizing:border-box;background:#FFFFFF;border-radius:50%;border:none;outline:none}dp-day-calendar.dp-material .dp-calendar-month:hover,dp-day-calendar.dp-material .dp-calendar-day:hover{background:#E0E0E0}dp-day-calendar.dp-material .dp-selected{background:#106CC8;color:#fff}dp-day-calendar.dp-material .dp-selected:hover{background:#106CC8}dp-day-calendar.dp-material .dp-current-day{border:1px solid #106CC8}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i5.Dir, selector: "[dir]", inputs: ["dir"], outputs: ["dirChange"], exportAs: ["dir"] }, { kind: "component", type: i6.MonthCalendarComponent, selector: "dp-month-calendar", inputs: ["config", "displayDate", "minDate", "maxDate", "theme"], outputs: ["onSelect", "onNavHeaderBtnClick", "onGoToCurrent", "onLeftNav", "onRightNav", "onLeftSecondaryNav", "onRightSecondaryNav"] }, { kind: "component", type: i7.CalendarNavComponent, selector: "dp-calendar-nav", inputs: ["label", "isLabelClickable", "showLeftNav", "showLeftSecondaryNav", "showRightNav", "showRightSecondaryNav", "leftNavDisabled", "leftSecondaryNavDisabled", "rightNavDisabled", "rightSecondaryNavDisabled", "showGoToCurrent", "theme"], outputs: ["onLeftNav", "onLeftSecondaryNav", "onRightNav", "onRightSecondaryNav", "onLabelClick", "onGoToCurrent"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: DayCalendarComponent, decorators: [{ type: Component, args: [{ selector: 'dp-day-calendar', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [ DayCalendarService, { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DayCalendarComponent), multi: true }, { provide: NG_VALIDATORS, useExisting: forwardRef(() => DayCalendarComponent), multi: true } ], template: "<div *ngIf=\"currentCalendarMode === CalendarMode.Day\" class=\"dp-day-calendar-container\" dir=\"ltr\">\n <dp-calendar-nav\n (onGoToCurrent)=\"goToCurrent()\"\n (onLabelClick)=\"toggleCalendarMode(CalendarMode.Month)\"\n (onLeftNav)=\"onLeftNavClick()\"\n (onRightNav)=\"onRightNavClick()\"\n [isLabelClickable]=\"componentConfig.enableMonthSelector\"\n [label]=\"navLabel\"\n [showGoToCurrent]=\"_shouldShowCurrent\"\n [showLeftNav]=\"showLeftNav\"\n [showRightNav]=\"showRightNav\"\n [theme]=\"theme\">\n </dp-calendar-nav>\n\n <div [ngClass]=\"{'dp-hide-near-month': !componentConfig.showNearMonthDays}\"\n class=\"dp-calendar-wrapper\">\n <div class=\"dp-weekdays\">\n <span *ngFor=\"let weekday of weekdays\"\n [innerText]=\"getWeekdayName(weekday)\"\n class=\"dp-calendar-weekday\">\n </span>\n </div>\n <div *ngFor=\"let week of weeks\" class=\"dp-calendar-week\">\n <span *ngIf=\"componentConfig.showWeekNumbers\"\n [innerText]=\"week[0].date.isoWeek()\"\n class=\"dp-week-number\">\n </span>\n <button (click)=\"dayClicked(day)\"\n *ngFor=\"let day of week\"\n [attr.data-date]=\"day.date.format(componentConfig.format)\"\n [disabled]=\"day.disabled\"\n [innerText]=\"getDayBtnText(day)\"\n [ngClass]=\"getDayBtnCssClass(day)\"\n class=\"dp-calendar-day\"\n type=\"button\">\n </button>\n </div>\n </div>\n</div>\n\n<dp-month-calendar\n (onLeftNav)=\"onMonthCalendarLeftClick($event)\"\n (onLeftSecondaryNav)=\"onMonthCalendarSecondaryLeftClick($event)\"\n (onNavHeaderBtnClick)=\"toggleCalendarMode(CalendarMode.Day)\"\n (onRightNav)=\"onMonthCalendarRightClick($event)\"\n (onRightSecondaryNav)=\"onMonthCalendarSecondaryRightClick($event)\"\n (onSelect)=\"monthSelected($event)\"\n *ngIf=\"currentCalendarMode === CalendarMode.Month\"\n [config]=\"monthCalendarConfig\"\n [displayDate]=\"_currentDateView\"\n [ngModel]=\"_selected\"\n [theme]=\"theme\">\n</dp-month-calendar>\n", styles: ["dp-day-calendar{display:inline-block}dp-day-calendar .dp-day-calendar-container{background:#FFFFFF}dp-day-calendar .dp-calendar-wrapper{box-sizing:border-box;border:1px solid #000000}dp-day-calendar .dp-calendar-wrapper .dp-calendar-weekday:first-child{border-left:none}dp-day-calendar .dp-weekdays{font-size:15px;margin-bottom:5px}dp-day-calendar .dp-calendar-weekday{box-sizing:border-box;display:inline-block;width:30px;text-align:center;border-left:1px solid #000000;border-bottom:1px solid #000000}dp-day-calendar .dp-calendar-day{box-sizing:border-box;width:30px;height:30px;cursor:pointer}dp-day-calendar .dp-selected{background:#106CC8;color:#fff}dp-day-calendar .dp-prev-month,dp-day-calendar .dp-next-month{opacity:.5}dp-day-calendar .dp-hide-near-month .dp-prev-month,dp-day-calendar .dp-hide-near-month .dp-next-month{visibility:hidden}dp-day-calendar .dp-week-number{position:absolute;font-size:9px}dp-day-calendar.dp-material .dp-calendar-weekday{height:25px;width:30px;line-height:25px;color:#7a7a7a;border:none}dp-day-calendar.dp-material .dp-calendar-wrapper{border:1px solid #E0E0E0}dp-day-calendar.dp-material .dp-calendar-month,dp-day-calendar.dp-material .dp-calendar-day{box-sizing:border-box;background:#FFFFFF;border-radius:50%;border:none;outline:none}dp-day-calendar.dp-material .dp-calendar-month:hover,dp-day-calendar.dp-material .dp-calendar-day:hover{background:#E0E0E0}dp-day-calendar.dp-material .dp-selected{background:#106CC8;color:#fff}dp-day-calendar.dp-material .dp-selected:hover{background:#106CC8}dp-day-calendar.dp-material .dp-current-day{border:1px solid #106CC8}\n"] }] }], ctorParameters: () => [{ type: i1.DayCalendarService }, { type: i2.UtilsService }, { type: i0.ChangeDetectorRef }], propDecorators: { config: [{ type: Input }], displayDate: [{ type: Input }], minDate: [{ type: Input }], maxDate: [{ type: Input }], theme: [{ type: HostBinding, args: ['class'] }, { type: Input }], onSelect: [{ type: Output }], onMonthSelect: [{ type: Output }], onNavHeaderBtnClick: [{ type: Output }], onGoToCurrent: [{ type: Output }], onLeftNav: [{ type: Output }], onRightNav: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF5LWNhbGVuZGFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25nMi1kYXRlLXBpY2tlci9zcmMvbGliL2RheS1jYWxlbmRhci9kYXktY2FsZW5kYXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmcyLWRhdGUtcGlja2VyL3NyYy9saWIvZGF5LWNhbGVuZGFyL2RheS1jYWxlbmRhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sb0NBQW9DLENBQUM7QUFDakUsT0FBTyxFQUNMLHVCQUF1QixFQUV2QixTQUFTLEVBQ1QsWUFBWSxFQUNaLFVBQVUsRUFDVixXQUFXLEVBQ1gsS0FBSyxFQUdMLE1BQU0sRUFHTixpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFLMUQsT0FBTyxFQUdMLGFBQWEsRUFDYixpQkFBaUIsRUFHbEIsTUFBTSxnQkFBZ0IsQ0FBQztBQU94QixPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sMkJBQTJCLENBQUM7Ozs7Ozs7OztBQXNCbkQsTUFBTSxPQUFPLG9CQUFvQjtJQWlDL0IsWUFBNEIsa0JBQXNDLEVBQ3RDLFlBQTBCLEVBQzFCLEVBQXFCO1FBRnJCLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7UUFDdEMsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsT0FBRSxHQUFGLEVBQUUsQ0FBbUI7UUE1QnZDLGFBQVEsR0FBdUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUNsRCxrQkFBYSxHQUF5QixJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3pELHdCQUFtQixHQUFnQyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ3RFLGtCQUFhLEdBQXVCLElBQUksWUFBWSxFQUFFLENBQUM7UUFD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O3NCQUFsQixNQUFNO2dCQUNHLFVBQVU7c0JBQW5CLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0VDYWxlbmRhclZhbHVlfSBmcm9tICcuLi9jb21tb24vdHlwZXMvY2FsZW5kYXItdmFsdWUtZW51bSc7XG5pbXBvcnQge1NpbmdsZUNhbGVuZGFyVmFsdWV9IGZyb20gJy4uL2NvbW1vbi90eXBlcy9zaW5nbGUtY2FsZW5kYXItdmFsdWUnO1xuaW1wb3J0IHtFQ2FsZW5kYXJNb2RlfSBmcm9tICcuLi9jb21tb24vdHlwZXMvY2FsZW5kYXItbW9kZS1lbnVtJztcbmltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIGZvcndhcmRSZWYsXG4gIEhvc3RCaW5kaW5nLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7RGF5Q2FsZW5kYXJTZXJ2aWNlfSBmcm9tICcuL2RheS1jYWxlbmRhci5zZXJ2aWNlJztcblxuaW1wb3J0IHtEYXlqcywgTWFuaXB1bGF0ZVR5cGV9IGZyb20gJ2RheWpzJztcbmltcG9ydCB7SURheUNhbGVuZGFyQ29uZmlnLCBJRGF5Q2FsZW5kYXJDb25maWdJbnRlcm5hbH0gZnJvbSAnLi9kYXktY2FsZW5kYXItY29uZmlnLm1vZGVsJztcbmltcG9ydCB7SURheX0gZnJvbSAnLi9kYXkubW9kZWwnO1xuaW1wb3J0IHtcbiAgQ29udHJvbFZhbHVlQWNjZXNzb3IsXG4gIFVudHlwZWRGb3JtQ29udHJvbCxcbiAgTkdfVkFMSURBVE9SUyxcbiAgTkdfVkFMVUVfQUNDRVNTT1IsXG4gIFZhbGlkYXRpb25FcnJvcnMsXG4gIFZhbGlkYXRvclxufSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge0NhbGVuZGFyVmFsdWV9IGZyb20gJy4uL2NvbW1vbi90eXBlcy9jYWxlbmRhci12YWx1ZSc7XG5pbXBvcnQge1V0aWxzU2VydmljZX0gZnJvbSAnLi4vY29tbW9uL3NlcnZpY2VzL3V0aWxzL3V0aWxzLnNlcnZpY2UnO1xuaW1wb3J0IHtJTW9udGhDYWxlbmRhckNvbmZpZ30gZnJvbSAnLi4vbW9udGgtY2FsZW5kYXIvbW9udGgtY2FsZW5kYXItY29uZmlnJztcbmltcG9ydCB7SU1vbnRofSBmcm9tICcuLi9tb250aC1jYWxlbmRhci9tb250aC5tb2RlbCc7XG5pbXBvcnQge0RhdGVWYWxpZGF0b3J9IGZyb20gJy4uL2NvbW1vbi90eXBlcy92YWxpZGF0b3IudHlwZSc7XG5pbXBvcnQge0lOYXZFdmVudH0gZnJvbSAnLi4vY29tbW9uL21vZGVscy9uYXZpZ2F0aW9uLWV2ZW50Lm1vZGVsJztcbmltcG9ydCB7ZGF5anNSZWZ9IGZyb20gJy4uL2NvbW1vbi9kYXlqcy9kYXlqcy5yZWYnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdkcC1kYXktY2FsZW5kYXInLFxuICB0ZW1wbGF0ZVVybDogJ2RheS1jYWxlbmRhci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWydkYXktY2FsZW5kYXIuY29tcG9uZW50Lmxlc3MnXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHByb3ZpZGVyczogW1xuICAgIERheUNhbGVuZGFyU2VydmljZSxcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IERheUNhbGVuZGFyQ29tcG9uZW50KSxcbiAgICAgIG11bHRpOiB0cnVlXG4gICAgfSxcbiAgICB7XG4gICAgICBwcm92aWRlOiBOR19WQUxJREFUT1JTLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gRGF5Q2FsZW5kYXJDb21wb25lbnQpLFxuICAgICAgbXVsdGk6IHRydWVcbiAgICB9XG4gIF1cbn0pXG5leHBvcnQgY2xhc3MgRGF5Q2FsZW5kYXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgQ29udHJvbFZhbHVlQWNjZXNzb3IsIFZhbGlkYXRvciB7XG5cbiAgQElucHV0KCkgY29uZmlnOiBJRGF5Q2FsZW5kYXJDb25maWc7XG4gIEBJbnB1dCgpIGRpc3BsYXlEYXRlOiBTaW5nbGVDYWxlbmRhclZhbHVlO1xuICBASW5wdXQoKSBtaW5EYXRlOiBEYXlqcztcbiAgQElucHV0KCkgbWF4RGF0ZTogRGF5anM7XG4gIEBIb3N0QmluZGluZygnY2xhc3MnKSBASW5wdXQoKSB0aGVtZTogc3RyaW5nO1xuICBAT3V0cHV0KCkgb25TZWxlY3Q6IEV2ZW50RW1pdHRlcjxJRGF5PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIG9uTW9udGhTZWxlY3Q6IEV2ZW50RW1pdHRlcjxJTW9udGg+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgb25OYXZIZWFkZXJCdG5DbGljazogRXZlbnRFbWl0dGVyPEVDYWxlbmRhck1vZGU+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgb25Hb1RvQ3VycmVudDogRXZlbnRFbWl0dGVyPHZvaWQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgb25MZWZ0TmF2OiBFdmVudEVtaXR0ZXI8SU5hdkV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgQE91dHB1dCgpIG9uUmlnaHROYXY6IEV2ZW50RW1pdHRlcjxJTmF2RXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBDYWxlbmRhck1vZGUgPSBFQ2FsZW5kYXJNb2RlO1xuICBpc0luaXRlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBjb21wb25lbnRDb25maWc6IElEYXlDYWxlbmRhckNvbmZpZ0ludGVybmFsO1xuICB3ZWVrczogSURheVtdW107XG4gIHdlZWtkYXlzOiBEYXlqc1tdO1xuICBpbnB1dFZhbHVlOiBDYWxlbmRhclZhbHVlO1xuICBpbnB1dFZhbHVlVHlwZTogRUNhbGVuZGFyVmFsdWU7XG4gIHZhbGlkYXRlRm46IERhdGVWYWxpZGF0b3I7XG4gIGN1cnJlbnRDYWxlbmRhck1vZGU6IEVDYWxlbmRhck1vZGUgPSBFQ2FsZW5kYXJNb2RlLkRheTtcbiAgbW9udGhDYWxlbmRhckNvbmZpZzogSU1vbnRoQ2FsZW5kYXJDb25maWc7XG4gIF9zaG91bGRTaG93Q3VycmVudDogYm9vbGVhbiA9IHRydWU7XG4gIG5hdkxhYmVsOiBzdHJpbmc7XG4gIHNob3dMZWZ0TmF2OiBib29sZWFuO1xuICBzaG93UmlnaHROYXY6IGJvb2xlYW47XG4gIGFwaSA9IHtcbiAgICBtb3ZlQ2FsZW5kYXJzQnk6IHRoaXMubW92ZUNhbGVuZGFyc0J5LmJpbmQodGhpcyksXG4gICAgbW92ZUNhbGVuZGFyVG86IHRoaXMubW92ZUNhbGVuZGFyVG8uYmluZCh0aGlzKSxcbiAgICB0b2dnbGVDYWxlbmRhck1vZGU6IHRoaXMudG9nZ2xlQ2FsZW5kYXJNb2RlLmJpbmQodGhpcylcbiAgfTtcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgcmVhZG9ubHkgZGF5Q2FsZW5kYXJTZXJ2aWNlOiBEYXlDYWxlbmRhclNlcnZpY2UsXG4gICAgICAgICAgICAgIHB1YmxpYyByZWFkb25seSB1dGlsc1NlcnZpY2U6IFV0aWxzU2VydmljZSxcbiAgICAgICAgICAgICAgcHVibGljIHJlYWRvbmx5IGNkOiBDaGFuZ2VEZXRlY3RvclJlZikge1xuICB9XG5cbiAgX3NlbGVjdGVkOiBEYXlqc1tdO1xuXG4gIGdldCBzZWxlY3RlZCgpOiBEYXlqc1tdIHtcbiAgICByZXR1cm4gdGhpcy5fc2VsZWN0ZWQ7XG4gIH1cblxuICBzZXQgc2VsZWN0ZWQoc2VsZWN0ZWQ6IERheWpzW10pIHtcbiAgICB0aGlzLl9zZWxlY3RlZCA9IHNlbGVjdGVkO1xuICAgIHRoaXMub25DaGFuZ2VDYWxsYmFjayh0aGlzLnByb2Nlc3NPbkNoYW5nZUNhbGxiYWNrKHNlbGVjdGVkKSk7XG4gIH1cblxuICBfY3VycmVudERhdGVWaWV3OiBEYXlqcztcblxuICBnZXQgY3VycmVudERhdGVWaWV3KCk6IERheWpzIHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudERhdGVWaWV3O1xuICB9XG5cbiAgc2V0IGN1cnJlbnREYXRlVmlldyhjdXJyZW50OiBEYXlqcykge1xuICAgIHRoaXMuX2N1cnJlbnREYXRlVmlldyA9IGRheWpzUmVmKGN1cnJlbnQudG9EYXRlKCkpO1xuICAgIHRoaXMud2Vla3MgPSB0aGlzLmRheUNhbGVuZGFyU2VydmljZVxuICAgICAgLmdlbmVyYXRlTW9udGhBcnJheSh0aGlzLmNvbXBvbmVudENvbmZpZywgdGhpcy5fY3VycmVudERhdGVWaWV3LCB0aGlzLnNlbGVjdGVkKTtcbiAgICB0aGlzLm5hdkxhYmVsID0gdGhpcy5kYXlDYWxlbmRhclNlcnZpY2UuZ2V0SGVhZGVyTGFiZWwodGhpcy5jb21wb25lbnRDb25maWcsIHRoaXMuX2N1cnJlbnREYXRlVmlldyk7XG4gICAgdGhpcy5zaG93TGVmdE5hdiA9IHRoaXMuZGF5Q2FsZW5kYXJTZXJ2aWNlLnNob3VsZFNob3dMZWZ0KHRoaXMuY29tcG9uZW50Q29uZmlnLm1pbiwgdGhpcy5jdXJyZW50RGF0ZVZpZXcpO1xuICAgIHRoaXMuc2hvd1JpZ2h0TmF2ID0gdGhpcy5kYXlDYWxlbmRhclNlcnZpY2Uuc2hvdWxkU2hvd1JpZ2h0KHRoaXMuY29tcG9uZW50Q29uZmlnLm1heCwgdGhpcy5jdXJyZW50RGF0ZVZpZXcpO1xuICB9XG4gIDtcblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmlzSW5pdGVkID0gdHJ1ZTtcbiAgICB0aGlzLmluaXQoKTtcbiAgICB0aGlzLmluaXRWYWxpZGF0b3JzKCk7XG4gIH1cblxuICBpbml0KCkge1xuICAgIHRoaXMuY29tcG9uZW50Q29uZmlnID0gdGhpcy5kYXlDYWxlbmRhclNlcnZpY2UuZ2V0Q29uZmlnKHRoaXMuY29uZmlnKTtcbiAgICB0aGlzLnNlbGVjdGVkID0gdGhpcy5zZWxlY3RlZCB8fCBbXTtcbiAgICB0aGlzLmN1cnJlbnREYXRlVmlldyA9IHRoaXMuZGlzcGxheURhdGVcbiAgICAgID8gdGhpcy51dGlsc1NlcnZpY2UuY29udmVydFRvRGF5anModGhpcy5kaXNwbGF5RGF0ZSwgdGhpcy5jb21wb25lbnRDb25maWcuZm9ybWF0KVxuICAgICAgOiB0aGlzLnV0aWxzU2VydmljZVxuICAgICAgICAuZ2V0RGVmYXVsdERpc3BsYXlEYXRlKFxuICAgICAgICAgIHRoaXMuY3VycmVudERhdGVWaWV3LFxuICAgICAgICAgIHRoaXMuc2VsZWN0ZWQsXG4gICAgICAgICAgdGhpcy5jb21wb25lbnRDb25maWcuYWxsb3dNdWx0aVNlbGVjdCxcbiAgICAgICAgICB0aGlzLmNvbXBvbmVudENvbmZpZy5taW5cbiAgICAgICAgKTtcbiAgICB0aGlzLndlZWtkYXlzID0gdGhpcy5kYXlDYWxlbmRhclNlcnZpY2VcbiAgICAgIC5nZW5lcmF0ZVdlZWtkYXlzKHRoaXMuY29tcG9uZW50Q29uZmlnLmZpcnN0RGF5T2ZXZWVrKTtcbiAgICB0aGlzLmlucHV0VmFsdWVUeXBlID0gdGhpcy51dGlsc1NlcnZpY2UuZ2V0SW5wdXRUeXBlKHRoaXMuaW5wdXRWYWx1ZSwgdGhpcy5jb21wb25lbnRDb25maWcuYWxsb3dNdWx0aVNlbGVjdCk7XG4gICAgdGhpcy5tb250aENhbGVuZGFyQ29uZmlnID0gdGhpcy5kYXlDYWxlbmRhclNlcnZpY2UuZ2V0TW9udGhDYWxlbmRhckNvbmZpZyh0aGlzLmNvbXBvbmVudENvbmZpZyk7XG4gICAgdGhpcy5fc2hvdWxkU2hvd0N1cnJlbnQgPSB0aGlzLnNob3VsZFNob3dDdXJyZW50KCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNJbml0ZWQpIHtcbiAgICAgIGNvbnN0IHttaW5EYXRlLCBtYXhEYXRlLCBjb25maWd9ID0gY2hhbmdlcztcblxuICAgICAgdGhpcy5oYW5kbGVDb25maWdDaGFuZ2UoY29uZmlnKTtcbiAgICAgIHRoaXMuaW5pdCgpO1xuXG4gICAgICBpZiAobWluRGF0ZSB8fCBtYXhEYXRlKSB7XG4gICAgICAgIHRoaXMuaW5pdFZhbGlkYXRvcnMoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB3cml0ZVZhbHVlKHZhbHVlOiBDYWxlbmRhclZhbHVlKTogdm9pZCB7XG4gICAgdGhpcy5pbnB1dFZhbHVlID0gdmFsdWU7XG5cbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWQgPSB0aGlzLnV0aWxzU2VydmljZVxuICAgICAgICAuY29udmVydFRvRGF5anNBcnJheSh2YWx1ZSwgdGhpcy5jb21wb25lbnRDb25maWcpO1xuICAgICAgdGhpcy5pbnB1dFZhbHVlVHlwZSA9IHRoaXMudXRpbHNTZXJ2aWNlXG4gICAgICAgIC5nZXRJbnB1dFR5cGUodGhpcy5pbnB1dFZhbHVlLCB0aGlzLmNvbXBvbmVudENvbmZpZy5hbGxvd011bHRpU2VsZWN0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zZWxlY3RlZCA9IFtdO1xuICAgIH1cblxuICAgIHRoaXMud2Vla3MgPSB0aGlzLmRheUNhbGVuZGFyU2VydmljZVxuICAgICAgLmdlbmVyYXRlTW9udGhBcnJheSh0aGlzLmNvbXBvbmVudENvbmZpZywgdGhpcy5jdXJyZW50RGF0ZVZpZXcsIHRoaXMuc2VsZWN0ZWQpO1xuXG4gICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQge1xuICAgIHRoaXMub25DaGFuZ2VDYWxsYmFjayA9IGZuO1xuICB9XG5cbiAgb25DaGFuZ2VDYWxsYmFjayhfOiBhbnkpIHtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHtcbiAgfVxuXG4gIHZhbGlkYXRlKGZvcm1Db250cm9sOiBVbnR5cGVkRm9ybUNvbnRyb2wpOiBWYWxpZGF0aW9uRXJyb3JzIHwgYW55IHtcbiAgICBpZiAodGhpcy5taW5EYXRlIHx8IHRoaXMubWF4RGF0ZSkge1xuICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGVGbihmb3JtQ29udHJvbC52YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAoKSA9PiBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHByb2Nlc3NPbkNoYW5nZUNhbGxiYWNrKHZhbHVlOiBEYXlqc1tdKTogQ2FsZW5kYXJWYWx1ZSB7XG4gICAgcmV0dXJuIHRoaXMudXRpbHNTZXJ2aWNlLmNvbnZlcnRGcm9tRGF5anNBcnJheShcbiAgICAgIHRoaXMuY29tcG9uZW50Q29uZmlnLmZvcm1hdCxcbiAgICAgIHZhbHVlLFxuICAgICAgdGhpcy5jb21wb25lbnRDb25maWcucmV0dXJuZWRWYWx1ZVR5cGUgfHwgdGhpcy5pbnB1dFZhbHVlVHlwZVxuICAgICk7XG4gIH1cblxuICBpbml0VmFsaWRhdG9ycygpIHtcbiAgICB0aGlzLnZhbGlkYXRlRm4gPSB0aGlzLnV0aWxzU2VydmljZS5jcmVhdGVWYWxpZGF0b3IoXG4gICAgICB7bWluRGF0ZTogdGhpcy5taW5EYXRlLCBtYXhEYXRlOiB0aGlzLm1heERhdGV9LFxuICAgICAgdGhpcy5jb21wb25lbnRDb25maWcuZm9ybWF0LFxuICAgICAgJ2RheSdcbiAgICApO1xuXG4gICAgdGhpcy5vbkNoYW5nZUNhbGxiYWNrKHRoaXMucHJvY2Vzc09uQ2hhbmdlQ2FsbGJhY2sodGhpcy5zZWxlY3RlZCkpO1xuICB9XG5cbiAgZGF5Q2xpY2tlZChkYXk6IElEYXkpIHtcbiAgICBpZiAoZGF5LnNlbGVjdGVkICYmICF0aGlzLmNvbXBvbmVudENvbmZpZy51blNlbGVjdE9uQ2xpY2spIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnNlbGVjdGVkID0gdGhpcy51dGlsc1NlcnZpY2VcbiAgICAgIC51cGRhdGVTZWxlY3RlZCh0aGlzLmNvbXBvbmVudENvbmZpZy5hbGxvd011bHRpU2VsZWN0LCB0aGlzLnNlbGVjdGVkLCBkYXkpO1xuICAgIHRoaXMud2Vla3MgPSB0aGlzLmRheUNhbGVuZGFyU2VydmljZVxuICAgICAgLmdlbmVyYXRlTW9udGhBcnJheSh0aGlzLmNvbXBvbmVudENvbmZpZywgdGhpcy5jdXJyZW50RGF0ZVZpZXcsIHRoaXMuc2VsZWN0ZWQpO1xuICAgIHRoaXMub25TZWxlY3QuZW1pdChkYXkpO1xuICB9XG5cbiAgZ2V0RGF5QnRuVGV4dChkYXk6IElEYXkpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmRheUNhbGVuZGFyU2VydmljZS5nZXREYXlCdG5UZXh0KHRoaXMuY29tcG9uZW50Q29uZmlnLCBkYXkuZGF0ZSk7XG4gIH1cblxuICBnZXREYXlCdG5Dc3NDbGFzcyhkYXk6IElEYXkpOiB7IFtrbGFzczogc3RyaW5nXTogYm9vbGVhbiB9IHtcbiAgICBjb25zdCBjc3NDbGFzc2VzOiB7IFtrbGFzczogc3RyaW5nXTogYm9vbGVhbiB9ID0ge1xuICAgICAgJ2RwLXNlbGVjdGVkJzogZGF5LnNlbGVjdGVkLFxuICAgICAgJ2RwLWN1cnJlbnQtbW9udGgnOiBkYXkuY3VycmVudE1vbnRoLFxuICAgICAgJ2RwLXByZXYtbW9udGgnOiBkYXkucHJldk1vbnRoLFxuICAgICAgJ2RwLW5leHQtbW9udGgnOiBkYXkubmV4dE1vbnRoLFxuICAgICAgJ2RwLWN1cnJlbnQtZGF5JzogZGF5LmN1cnJlbnREYXlcbiAgICB9O1xuICAgIGNvbnN0IGN1c3RvbUNzc0NsYXNzOiBzdHJpbmcgPSB0aGlzLmRheUNhbGVuZGFyU2VydmljZS5nZXREYXlCdG5Dc3NDbGFzcyh0aGlzLmNvbXBvbmVudENvbmZpZywgZGF5LmRhdGUpO1xuICAgIGlmIChjdXN0b21Dc3NDbGFzcykge1xuICAgICAgY3NzQ2xhc3Nlc1tjdXN0b21Dc3NDbGFzc10gPSB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBjc3NDbGFzc2VzO1xuICB9XG5cbiAgb25MZWZ0TmF2Q2xpY2soKSB7XG4gICAgY29uc3QgZnJvbSA9IGRheWpzUmVmKHRoaXMuY3VycmVudERhdGVWaWV3LnRvRGF0ZSgpKTtcbiAgICB0aGlzLm1vdmVDYWxlbmRhcnNCeSh0aGlzLmN1cnJlbnREYXRlVmlldywgLTEsICdtb250aCcpO1xuICAgIGNvbnN0IHRvID0gZGF5anNSZWYodGhpcy5jdXJyZW50RGF0ZVZpZXcudG9EYXRlKCkpO1xuICAgIHRoaXMub25MZWZ0TmF2LmVtaXQoe2Zyb20sIHRvfSk7XG4gIH1cblxuICBvblJpZ2h0TmF2Q2xpY2soKSB7XG4gICAgY29uc3QgZnJvbSA9IGRheWpzUmVmKHRoaXMuY3VycmVudERhdGVWaWV3LnRvRGF0ZSgpKTtcbiAgICB0aGlzLm1vdmVDYWxlbmRhcnNCeSh0aGlzLmN1cnJlbnREYXRlVmlldywgMSwgJ21vbnRoJyk7XG4gICAgY29uc3QgdG8gPSBkYXlqc1JlZih0aGlzLmN1cnJlbnREYXRlVmlldy50b0RhdGUoKSk7XG4gICAgdGhpcy5vblJpZ2h0TmF2LmVtaXQoe2Zyb20sIHRvfSk7XG4gIH1cblxuICBvbk1vbnRoQ2FsZW5kYXJMZWZ0Q2xpY2soY2hhbmdlOiBJTmF2RXZlbnQpIHtcbiAgICB0aGlzLm9uTGVmdE5hdi5lbWl0KGNoYW5nZSk7XG4gIH1cblxuICBvbk1vbnRoQ2FsZW5kYXJSaWdodENsaWNrKGNoYW5nZTogSU5hdkV2ZW50KSB7XG4gICAgdGhpcy5vblJpZ2h0TmF2LmVtaXQoY2hhbmdlKTtcbiAgfVxuXG4gIG9uTW9udGhDYWxlbmRhclNlY29uZGFyeUxlZnRDbGljayhjaGFuZ2U6IElOYXZFdmVudCkge1xuICAgIHRoaXMub25SaWdodE5hdi5lbWl0KGNoYW5nZSk7XG4gIH1cblxuICBvbk1vbnRoQ2FsZW5kYXJTZWNvbmRhcnlSaWdodENsaWNrKGNoYW5nZTogSU5hdkV2ZW50KSB7XG4gICAgdGhpcy5vbkxlZnROYXYuZW1pdChjaGFuZ2UpO1xuICB9XG5cbiAgZ2V0V2Vla2RheU5hbWUod2Vla2RheTogRGF5anMpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLmNvbXBvbmVudENvbmZpZy53ZWVrRGF5Rm9ybWF0dGVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb21wb25lbnRDb25maWcud2Vla0RheUZvcm1hdHRlcih3ZWVrZGF5LmRheSgpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gd2Vla2RheS5mb3JtYXQodGhpcy5jb21wb25lbnRDb25maWcud2Vla0RheUZvcm1hdCk7XG4gIH1cblxuICB0b2dnbGVDYWxlbmRhck1vZGUobW9kZTogRUNhbGVuZGFyTW9kZSkge1xuICAgIGlmICh0aGlzLmN1cnJlbnRDYWxlbmRhck1vZGUgIT09IG1vZGUpIHtcbiAgICAgIHRoaXMuY3VycmVudENhbGVuZGFyTW9kZSA9IG1vZGU7XG4gICAgICB0aGlzLm9uTmF2SGVhZGVyQnRuQ2xpY2suZW1pdChtb2RlKTtcbiAgICB9XG5cbiAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgbW9udGhTZWxlY3RlZChtb250aDogSU1vbnRoKSB7XG4gICAgdGhpcy5jdXJyZW50RGF0ZVZpZXcgPSBkYXlqc1JlZihtb250aC5kYXRlLnRvRGF0ZSgpKTtcbiAgICB0aGlzLmN1cnJlbnRDYWxlbmRhck1vZGUgPSBFQ2FsZW5kYXJNb2RlLkRheTtcbiAgICB0aGlzLm9uTW9udGhTZWxlY3QuZW1pdChtb250aCk7XG4gIH1cblxuICBtb3ZlQ2FsZW5kYXJzQnkoY3VycmVudDogRGF5anMsIGFtb3VudDogbnVtYmVyLCBncmFudWxhcml0eTogTWFuaXB1bGF0ZVR5cGUgPSAnbW9udGgnKSB7XG4gICAgdGhpcy5jdXJyZW50RGF0ZVZpZXcgPSBkYXlqc1JlZihjdXJyZW50LnRvRGF0ZSgpKS5hZGQoYW1vdW50LCBncmFudWxhcml0eSk7XG4gICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG1vdmVDYWxlbmRhclRvKHRvOiBTaW5nbGVDYWxlbmRhclZhbHVlKSB7XG4gICAgaWYgKHRvKSB7XG4gICAgICB0aGlzLmN1cnJlbnREYXRlVmlldyA9IHRoaXMudXRpbHNTZXJ2aWNlLmNvbnZlcnRUb0RheWpzKHRvLCB0aGlzLmNvbXBvbmVudENvbmZpZy5mb3JtYXQpO1xuICAgIH1cblxuICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBzaG91bGRTaG93Q3VycmVudCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy51dGlsc1NlcnZpY2Uuc2hvdWxkU2hvd0N1cnJlbnQoXG4gICAgICB0aGlzLmNvbXBvbmVudENvbmZpZy5zaG93R29Ub0N1cnJlbnQsXG4gICAgICAnZGF5JyxcbiAgICAgIHRoaXMuY29tcG9uZW50Q29uZmlnLm1pbixcbiAgICAgIHRoaXMuY29tcG9uZW50Q29uZmlnLm1heFxuICAgICk7XG4gIH1cblxuICBnb1RvQ3VycmVudCgpIHtcbiAgICB0aGlzLmN1cnJlbnREYXRlVmlldyA9IGRheWpzUmVmKCk7XG4gICAgdGhpcy5vbkdvVG9DdXJyZW50LmVtaXQoKTtcbiAgfVxuXG4gIGhhbmRsZUNvbmZpZ0NoYW5nZShjb25maWc6IFNpbXBsZUNoYW5nZSk6IHZvaWQge1xuICAgIGlmIChjb25maWcpIHtcbiAgICAgIGNvbnN0IHByZXZDb25mOiBJRGF5Q2FsZW5kYXJDb25maWdJbnRlcm5hbCA9IHRoaXMuZGF5Q2FsZW5kYXJTZXJ2aWNlLmdldENvbmZpZyhjb25maWcucHJldmlvdXNWYWx1ZSk7XG4gICAgICBjb25zdCBjdXJyZW50Q29uZjogSURheUNhbGVuZGFyQ29uZmlnSW50ZXJuYWwgPSB0aGlzLmRheUNhbGVuZGFyU2VydmljZS5nZXRDb25maWcoY29uZmlnLmN1cnJlbnRWYWx1ZSk7XG5cbiAgICAgIGlmICh0aGlzLnV0aWxzU2VydmljZS5zaG91bGRSZXNldEN1cnJlbnRWaWV3KHByZXZDb25mLCBjdXJyZW50Q29uZikpIHtcbiAgICAgICAgdGhpcy5fY3VycmVudERhdGVWaWV3ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cbiIsIjxkaXYgKm5nSWY9XCJjdXJyZW50Q2FsZW5kYXJNb2RlID09PSAgQ2FsZW5kYXJNb2RlLkRheVwiIGNsYXNzPVwiZHAtZGF5LWNhbGVuZGFyLWNvbnRhaW5lclwiIGRpcj1cImx0clwiPlxuICA8ZHAtY2FsZW5kYXItbmF2XG4gICAgICAob25Hb1RvQ3VycmVudCk9XCJnb1RvQ3VycmVudCgpXCJcbiAgICAgIChvbkxhYmVsQ2xpY2spPVwidG9nZ2xlQ2FsZW5kYXJNb2RlKENhbGVuZGFyTW9kZS5Nb250aClcIlxuICAgICAgKG9uTGVmdE5hdik9XCJvbkxlZnROYXZDbGljaygpXCJcbiAgICAgIChvblJpZ2h0TmF2KT1cIm9uUmlnaHROYXZDbGljaygpXCJcbiAgICAgIFtpc0xhYmVsQ2xpY2thYmxlXT1cImNvbXBvbmVudENvbmZpZy5lbmFibGVNb250aFNlbGVjdG9yXCJcbiAgICAgIFtsYWJlbF09XCJuYXZMYWJlbFwiXG4gICAgICBbc2hvd0dvVG9DdXJyZW50XT1cIl9zaG91bGRTaG93Q3VycmVudFwiXG4gICAgICBbc2hvd0xlZnROYXZdPVwic2hvd0xlZnROYXZcIlxuICAgICAgW3Nob3dSaWdodE5hdl09XCJzaG93UmlnaHROYXZcIlxuICAgICAgW3RoZW1lXT1cInRoZW1lXCI+XG4gIDwvZHAtY2FsZW5kYXItbmF2PlxuXG4gIDxkaXYgW25nQ2xhc3NdPVwieydkcC1oaWRlLW5lYXItbW9udGgnOiAhY29tcG9uZW50Q29uZmlnLnNob3dOZWFyTW9udGhEYXlzfVwiXG4gICAgICAgY2xhc3M9XCJkcC1jYWxlbmRhci13cmFwcGVyXCI+XG4gICAgPGRpdiBjbGFzcz1cImRwLXdlZWtkYXlzXCI+XG4gICAgICA8c3BhbiAqbmdGb3I9XCJsZXQgd2Vla2RheSBvZiB3ZWVrZGF5c1wiXG4gICAgICAgICAgICBbaW5uZXJUZXh0XT1cImdldFdlZWtkYXlOYW1lKHdlZWtkYXkpXCJcbiAgICAgICAgICAgIGNsYXNzPVwiZHAtY2FsZW5kYXItd2Vla2RheVwiPlxuICAgICAgPC9zcGFuPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgKm5nRm9yPVwibGV0IHdlZWsgb2Ygd2Vla3NcIiBjbGFzcz1cImRwLWNhbGVuZGFyLXdlZWtcIj5cbiAgICAgIDxzcGFuICpuZ0lmPVwiY29tcG9uZW50Q29uZmlnLnNob3dXZWVrTnVtYmVyc1wiXG4gICAgICAgICAgICBbaW5uZXJUZXh0XT1cIndlZWtbMF0uZGF0ZS5pc29XZWVrKClcIlxuICAgICAgICAgICAgY2xhc3M9XCJkcC13ZWVrLW51bWJlclwiPlxuICAgICAgPC9zcGFuPlxuICAgICAgPGJ1dHRvbiAoY2xpY2spPVwiZGF5Q2xpY2tlZChkYXkpXCJcbiAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGRheSBvZiB3ZWVrXCJcbiAgICAgICAgICAgICAgW2F0dHIuZGF0YS1kYXRlXT1cImRheS5kYXRlLmZvcm1hdChjb21wb25lbnRDb25maWcuZm9ybWF0KVwiXG4gICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkYXkuZGlzYWJsZWRcIlxuICAgICAgICAgICAgICBbaW5uZXJUZXh0XT1cImdldERheUJ0blRleHQoZGF5KVwiXG4gICAgICAgICAgICAgIFtuZ0NsYXNzXT1cImdldERheUJ0bkNzc0NsYXNzKGRheSlcIlxuICAgICAgICAgICAgICBjbGFzcz1cImRwLWNhbGVuZGFyLWRheVwiXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIj5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuXG48ZHAtbW9udGgtY2FsZW5kYXJcbiAgICAob25MZWZ0TmF2KT1cIm9uTW9udGhDYWxlbmRhckxlZnRDbGljaygkZXZlbnQpXCJcbiAgICAob25MZWZ0U2Vjb25kYXJ5TmF2KT1cIm9uTW9udGhDYWxlbmRhclNlY29uZGFyeUxlZnRDbGljaygkZXZlbnQpXCJcbiAgICAob25OYXZIZWFkZXJCdG5DbGljayk9XCJ0b2dnbGVDYWxlbmRhck1vZGUoQ2FsZW5kYXJNb2RlLkRheSlcIlxuICAgIChvblJpZ2h0TmF2KT1cIm9uTW9udGhDYWxlbmRhclJpZ2h0Q2xpY2soJGV2ZW50KVwiXG4gICAgKG9uUmlnaHRTZWNvbmRhcnlOYXYpPVwib25Nb250aENhbGVuZGFyU2Vjb25kYXJ5UmlnaHRDbGljaygkZXZlbnQpXCJcbiAgICAob25TZWxlY3QpPVwibW9udGhTZWxlY3RlZCgkZXZlbnQpXCJcbiAgICAqbmdJZj1cI