UNPKG

ng-devui

Version:

DevUI components based on Angular

353 lines 55.3 kB
import { __decorate, __metadata } from "tslib"; import { CdkOverlayOrigin } from '@angular/cdk/overlay'; import { DOCUMENT } from '@angular/common'; import { ChangeDetectorRef, Component, ElementRef, EventEmitter, Inject, Input, Output, ViewChild, } from '@angular/core'; import { I18nService } from 'ng-devui/i18n'; import { DefaultDateConverter, DevConfigService, WithConfig, fadeInOut } from 'ng-devui/utils'; import { Subject } from 'rxjs'; import { distinctUntilChanged } from 'rxjs/operators'; import { DatePickerConfigService as DatePickerConfig } from '../date-picker.config.service'; import * as i0 from "@angular/core"; import * as i1 from "../date-picker.config.service"; import * as i2 from "ng-devui/i18n"; import * as i3 from "ng-devui/utils"; import * as i4 from "@angular/common"; import * as i5 from "@angular/cdk/overlay"; import * as i6 from "ng-devui/button"; import * as i7 from "./two-datepicker-single.component"; export class TwoDatePickerComponent { set dateConfig(dateConfig) { if (this.checkDateConfig(dateConfig)) { this._dateConfig = dateConfig; } else { this._dateConfig = this.datePickerConfig.dateConfig; } this._dateFormat = this.showTime ? this._dateConfig.format.time : this._dateConfig.format.date; } get dateConfig() { return this._dateConfig; } set dateFormat(dateFormat) { if (dateFormat && this._dateFormat !== dateFormat) { this._dateFormat = dateFormat; } } get dateFormat() { return this._dateFormat || this.datePickerConfig.defaultFormat; } set maxDate(date) { const parseDate = this.convertDate(date); if (parseDate) { this._maxDate = parseDate; } } get maxDate() { return this._maxDate; } set minDate(date) { const parseDate = this.convertDate(date); if (parseDate) { this._minDate = parseDate; } } get minDate() { return this._minDate; } set whichOpen(side) { this._whichOpen = side; this.switchOriginPositionSub.next(side); } get whichOpen() { return this._whichOpen; } set isOpen(isOpen) { this._isOpen = isOpen; if (!isOpen) { this.startAnimation = false; this.document.removeEventListener('click', this.onDocumentClick); } else { setTimeout(() => { this.startAnimation = true; this.cdr.detectChanges(); this.document.addEventListener('click', this.onDocumentClick); }); } } get isOpen() { return this._isOpen; } constructor(el, datePickerConfig, i18n, cdr, devConfigService, doc) { this.el = el; this.datePickerConfig = datePickerConfig; this.i18n = i18n; this.cdr = cdr; this.devConfigService = devConfigService; this.doc = doc; this.showAnimation = true; this.showTime = false; this.selectedRange = [null, null]; this.hideOnRangeSelected = true; this.selectedRangeChange = new EventEmitter(); this.datePosition = 'bottom'; this.selectDateSubject = new Subject(); this.hoverOnDate = new Subject(); this.switchOriginPositionSub = new Subject(); this.today = new Date(); this.startAnimation = false; this.currentCalendars = [null, null]; this._isOpen = false; this.onDocumentClick = ($event) => { if (!this.el.nativeElement.contains($event.target)) { this.whichOpen = false; this.isOpen = false; } this.cdr.markForCheck(); }; this.toggle = (side = 'start') => { if (this.isOpen) { if (side === 'start') { if (this.whichOpen === 'start') { this.whichOpen = false; this.isOpen = false; } else { // this.whichOpen === 'end' this.whichOpen = 'start'; } } else { // side === 'end' if (this.whichOpen === 'start') { this.whichOpen = 'end'; } else { // this.whichOpen === 'end' this.whichOpen = false; this.isOpen = false; } } } else { this.whichOpen = side; this.isOpen = true; } }; this.chooseDate = (range) => { if (range && Array.isArray(this.selectedRange)) { this.selectedRange = range; [this.rangeStart, this.rangeEnd] = this.selectedRange; this.notifyValueChange(); } }; this.clear = (side) => { if (this.disabled) { return; } if (side === 'start') { this.selectStart(null); } else if (side === 'end') { this.selectEnd(null); } [this.rangeStart, this.rangeEnd] = this.selectedRange; }; this._dateConfig = datePickerConfig.dateConfig; this.dateConverter = datePickerConfig.dateConfig.dateConverter || new DefaultDateConverter(); this.setI18nText(); this.document = this.doc; } checkDateConfig(dateConfig) { if (!dateConfig) { return false; } if (typeof dateConfig.timePicker !== 'boolean' || !dateConfig.max || !dateConfig.min || !dateConfig.format) { return false; } return true; } ngOnInit() { this._minDate = this.minDate ? new Date(this.minDate) : new Date(this.dateConfig.min, 0, 1, 0, 0, 0); this._maxDate = this.maxDate ? new Date(this.maxDate) : new Date(this.dateConfig.max, 11, 31, 23, 59, 59); this.updateCdkConnectedOverlayOrigin(this.el.nativeElement); this.subscribeHoverActions(); } isDisableToday() { if (this.minDate.getTime() >= this.today.getTime() || this.maxDate.getTime() <= this.today.getTime()) { this.disableToday = true; } else { this.disableToday = false; } } onPositionChange(position) { switch (position.connectionPair.overlayY) { case 'top': case 'center': this.datePosition = 'bottom'; break; case 'bottom': this.datePosition = 'top'; break; default: } this.switchOriginPositionSub.next(this.whichOpen); } convertDate(date) { return date ? this.dateConverter.parse(date, this.dateFormat) : null; } formatDate(date) { return date ? this.dateConverter.format(date, this.dateFormat, this.locale || this.i18nLocale) : null; } updateCdkConnectedOverlayOrigin(el) { if (el) { this.cdkConnectedOverlayOrigin = new CdkOverlayOrigin(el); } else { this.cdkConnectedOverlayOrigin = undefined; } } syncPickerPair(currentCalender, orientation) { switch (orientation) { case 'left': this.currentCalendars[0] = currentCalender; break; case 'right': this.currentCalendars[1] = currentCalender; break; default: } } rangeChange(data) { this.chooseDate(data.selectedRange); this.selectDateSubject.next({ side: 'start', date: this.rangeStart, onlyWrite: true }); this.selectDateSubject.next({ side: 'end', date: this.rangeEnd, onlyWrite: true }); } notifyValueChange() { this.selectedRangeChange.emit(this.selectedRange); } selectingDate(event) { this.hoverOnDate.next(event); } subscribeHoverActions() { this.hoverOnDate.pipe(distinctUntilChanged()).subscribe((date) => { this.previewRangeEnd(date); }); } previewRangeEnd(date) { this.leftPicker.previewEnd = date; this.rightPicker.previewEnd = date; } syncRangeStart(rangeStart, picker) { if (this.whichOpen === 'end') { this.selectEnd(rangeStart); } else { // this.whichOpen === 'start' this.selectStart(rangeStart); } picker.selectRange(rangeStart, true); } selectStart(date, passive = false) { this.selectedRange[0] = date; this.rangeStart = date; this.isDisableToday(); if (!passive) { this.selectDateSubject.next({ side: 'start', date }); this.whichOpen = 'end'; } } selectEnd(date, passive = false) { this.selectedRange[1] = date; this.rangeEnd = date; this.isDisableToday(); if (!passive) { this.selectDateSubject.next({ side: 'end', date: date }); if (!this.showTime && this.hideOnRangeSelected) { this.isOpen = false; this.whichOpen = false; } } } chooseToday(event) { event.preventDefault(); event.stopPropagation(); if (this.minDate.getTime() <= this.today.getTime() && this.maxDate.getTime() >= this.today.getTime()) { if (this.whichOpen === 'start') { this.selectStart(this.today); } else if (this.whichOpen === 'end') { this.selectEnd(this.today); } [this.rangeStart, this.rangeEnd] = this.selectedRange; } } clearBtn(event) { event.preventDefault(); event.stopPropagation(); if (this.whichOpen) { this.clear(this.whichOpen); } } setI18nText() { this.i18nText = this.i18n.getI18nText().datePicker; this.i18nLocale = this.i18n.getI18nText().locale; this.i18nSubscription = this.i18n.langChange().subscribe((data) => { this.i18nText = data.datePicker; this.i18nLocale = data.locale; }); } ngOnDestroy() { this.isOpen = false; if (this.i18nSubscription) { this.i18nSubscription.unsubscribe(); } this.document.removeEventListener('click', this.onDocumentClick); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TwoDatePickerComponent, deps: [{ token: i0.ElementRef }, { token: i1.DatePickerConfigService }, { token: i2.I18nService }, { token: i0.ChangeDetectorRef }, { token: i3.DevConfigService }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: TwoDatePickerComponent, selector: "[dTwoDatePicker]", inputs: { locale: "locale", cssClass: "cssClass", disabled: "disabled", dateConverter: "dateConverter", showAnimation: "showAnimation", hideOnRangeSelected: "hideOnRangeSelected", dateConfig: "dateConfig", dateFormat: "dateFormat", maxDate: "maxDate", minDate: "minDate" }, outputs: { selectedRangeChange: "selectedRangeChange" }, viewQueries: [{ propertyName: "leftPicker", first: true, predicate: ["leftPicker"], descendants: true }, { propertyName: "rightPicker", first: true, predicate: ["rightPicker"], descendants: true }, { propertyName: "templateWrap", first: true, predicate: ["templateWrap"], descendants: true }], exportAs: ["twoDatePicker"], ngImport: i0, template: "<ng-content></ng-content>\n<ng-template\n cdk-connected-overlay\n [cdkConnectedOverlayOrigin]=\"cdkConnectedOverlayOrigin\"\n [cdkConnectedOverlayOpen]=\"isOpen\"\n (backdropClick)=\"isOpen = false\"\n (positionChange)=\"onPositionChange($event)\"\n>\n <div [@fadeInOut]=\"startAnimation ? datePosition : 'void'\" [@.disabled]=\"!showAnimation\" class=\"devui-two-date-wrapper\">\n <div class=\"devui-two-date-picker\">\n <d-two-datepicker-single\n class=\"devui-date-picker\"\n [locale]=\"locale\"\n [cssClass]=\"cssClass\"\n [disabled]=\"disabled\"\n [dateConverter]=\"dateConverter\"\n [dateConfig]=\"dateConfig\"\n [maxDate]=\"maxDate\"\n [minDate]=\"minDate\"\n [rangePicker]=\"true\"\n [selectedRange]=\"[rangeStart, rangeEnd]\"\n [currentCalendars]=\"currentCalendars\"\n [showTime]=\"showTime\"\n (rangeSelected)=\"rangeChange($event)\"\n (hoverOnDate)=\"selectingDate($event)\"\n (rangeSelecting)=\"syncRangeStart($event, rightPicker)\"\n (syncPickerPair)=\"syncPickerPair($event, 'left')\"\n [whichOpen]=\"whichOpen\"\n #leftPicker\n >\n </d-two-datepicker-single>\n <d-two-datepicker-single\n class=\"devui-date-picker\"\n [locale]=\"locale\"\n [cssClass]=\"cssClass\"\n [disabled]=\"disabled\"\n [dateConverter]=\"dateConverter\"\n [dateConfig]=\"dateConfig\"\n [maxDate]=\"maxDate\"\n [minDate]=\"minDate\"\n [rangePicker]=\"true\"\n [selectedRange]=\"[rangeStart, rangeEnd]\"\n [currentCalendars]=\"currentCalendars\"\n [showTime]=\"showTime\"\n (rangeSelected)=\"rangeChange($event)\"\n (hoverOnDate)=\"selectingDate($event)\"\n (rangeSelecting)=\"syncRangeStart($event, leftPicker)\"\n (syncPickerPair)=\"syncPickerPair($event, 'right')\"\n [isAuxiliary]=\"true\"\n [whichOpen]=\"whichOpen\"\n #rightPicker\n >\n </d-two-datepicker-single>\n </div>\n <div *ngIf=\"!customViewTemplate\" class=\"devui-two-date-footer devui-two-date-custom\">\n <a\n [ngClass]=\"{\n disabled: disableToday\n }\"\n (click)=\"chooseToday($event)\"\n >{{ i18nText.today }}</a\n >\n <d-button bsStyle=\"common\" (btnClick)=\"clearBtn($event)\" bsSize=\"sm\">{{ i18nText.clear }}</d-button>\n </div>\n </div>\n</ng-template>\n", styles: [".devui-two-date-wrapper{display:inline-flex!important;box-shadow:var(--devui-shadow-length-connected-overlay, 0 4px 12px 0) var(--devui-shadow, rgba(0, 0, 0, .16));background-color:var(--devui-connected-overlay-bg, #ffffff);transform:perspective(1px) translateZ(0);flex-direction:column;border-radius:var(--devui-border-radius, 2px);margin:4px 0}.devui-two-date-wrapper .devui-two-date-picker{display:inline-flex!important;-webkit-user-select:none;user-select:none}.devui-two-date-wrapper .devui-two-date-custom{width:500px;border-top:1px solid var(--devui-line, #dbdbdb)}.devui-two-date-wrapper .devui-two-date-footer{padding:10px;display:flex;justify-content:space-between;align-items:center}.devui-two-date-wrapper .devui-two-date-footer a{color:var(--devui-link, #0950de);text-decoration:none;cursor:pointer}.devui-two-date-wrapper .devui-two-date-footer a.disabled{color:var(--devui-line, #dbdbdb);cursor:not-allowed}.devui-date-picker:not(:last-child){margin-right:20px}.host-wrapper{color:red}\n"], dependencies: [{ kind: "directive", type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "component", type: i6.ButtonComponent, selector: "d-button", inputs: ["id", "type", "bsStyle", "shape", "bsSize", "bsPosition", "bordered", "icon", "disabled", "showLoading", "width", "autofocus", "loadingTemplateRef"], outputs: ["btnClick"] }, { kind: "component", type: i7.TwoDatepickerSingleComponent, selector: "d-two-datepicker-single", inputs: ["selectedRange", "rangePicker", "isAuxiliary", "currentCalendars", "whichOpen"], outputs: ["hoverOnDate", "rangeSelected", "rangeSelecting", "syncPickerPair", "consolidateTime"] }], animations: [fadeInOut] }); } } __decorate([ WithConfig(), __metadata("design:type", Object) ], TwoDatePickerComponent.prototype, "showAnimation", void 0); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TwoDatePickerComponent, decorators: [{ type: Component, args: [{ selector: '[dTwoDatePicker]', exportAs: 'twoDatePicker', animations: [fadeInOut], template: "<ng-content></ng-content>\n<ng-template\n cdk-connected-overlay\n [cdkConnectedOverlayOrigin]=\"cdkConnectedOverlayOrigin\"\n [cdkConnectedOverlayOpen]=\"isOpen\"\n (backdropClick)=\"isOpen = false\"\n (positionChange)=\"onPositionChange($event)\"\n>\n <div [@fadeInOut]=\"startAnimation ? datePosition : 'void'\" [@.disabled]=\"!showAnimation\" class=\"devui-two-date-wrapper\">\n <div class=\"devui-two-date-picker\">\n <d-two-datepicker-single\n class=\"devui-date-picker\"\n [locale]=\"locale\"\n [cssClass]=\"cssClass\"\n [disabled]=\"disabled\"\n [dateConverter]=\"dateConverter\"\n [dateConfig]=\"dateConfig\"\n [maxDate]=\"maxDate\"\n [minDate]=\"minDate\"\n [rangePicker]=\"true\"\n [selectedRange]=\"[rangeStart, rangeEnd]\"\n [currentCalendars]=\"currentCalendars\"\n [showTime]=\"showTime\"\n (rangeSelected)=\"rangeChange($event)\"\n (hoverOnDate)=\"selectingDate($event)\"\n (rangeSelecting)=\"syncRangeStart($event, rightPicker)\"\n (syncPickerPair)=\"syncPickerPair($event, 'left')\"\n [whichOpen]=\"whichOpen\"\n #leftPicker\n >\n </d-two-datepicker-single>\n <d-two-datepicker-single\n class=\"devui-date-picker\"\n [locale]=\"locale\"\n [cssClass]=\"cssClass\"\n [disabled]=\"disabled\"\n [dateConverter]=\"dateConverter\"\n [dateConfig]=\"dateConfig\"\n [maxDate]=\"maxDate\"\n [minDate]=\"minDate\"\n [rangePicker]=\"true\"\n [selectedRange]=\"[rangeStart, rangeEnd]\"\n [currentCalendars]=\"currentCalendars\"\n [showTime]=\"showTime\"\n (rangeSelected)=\"rangeChange($event)\"\n (hoverOnDate)=\"selectingDate($event)\"\n (rangeSelecting)=\"syncRangeStart($event, leftPicker)\"\n (syncPickerPair)=\"syncPickerPair($event, 'right')\"\n [isAuxiliary]=\"true\"\n [whichOpen]=\"whichOpen\"\n #rightPicker\n >\n </d-two-datepicker-single>\n </div>\n <div *ngIf=\"!customViewTemplate\" class=\"devui-two-date-footer devui-two-date-custom\">\n <a\n [ngClass]=\"{\n disabled: disableToday\n }\"\n (click)=\"chooseToday($event)\"\n >{{ i18nText.today }}</a\n >\n <d-button bsStyle=\"common\" (btnClick)=\"clearBtn($event)\" bsSize=\"sm\">{{ i18nText.clear }}</d-button>\n </div>\n </div>\n</ng-template>\n", styles: [".devui-two-date-wrapper{display:inline-flex!important;box-shadow:var(--devui-shadow-length-connected-overlay, 0 4px 12px 0) var(--devui-shadow, rgba(0, 0, 0, .16));background-color:var(--devui-connected-overlay-bg, #ffffff);transform:perspective(1px) translateZ(0);flex-direction:column;border-radius:var(--devui-border-radius, 2px);margin:4px 0}.devui-two-date-wrapper .devui-two-date-picker{display:inline-flex!important;-webkit-user-select:none;user-select:none}.devui-two-date-wrapper .devui-two-date-custom{width:500px;border-top:1px solid var(--devui-line, #dbdbdb)}.devui-two-date-wrapper .devui-two-date-footer{padding:10px;display:flex;justify-content:space-between;align-items:center}.devui-two-date-wrapper .devui-two-date-footer a{color:var(--devui-link, #0950de);text-decoration:none;cursor:pointer}.devui-two-date-wrapper .devui-two-date-footer a.disabled{color:var(--devui-line, #dbdbdb);cursor:not-allowed}.devui-date-picker:not(:last-child){margin-right:20px}.host-wrapper{color:red}\n"] }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.DatePickerConfigService }, { type: i2.I18nService }, { type: i0.ChangeDetectorRef }, { type: i3.DevConfigService }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT] }] }], propDecorators: { locale: [{ type: Input }], cssClass: [{ type: Input }], disabled: [{ type: Input }], dateConverter: [{ type: Input }], showAnimation: [{ type: Input }], hideOnRangeSelected: [{ type: Input }], selectedRangeChange: [{ type: Output }], leftPicker: [{ type: ViewChild, args: ['leftPicker'] }], rightPicker: [{ type: ViewChild, args: ['rightPicker'] }], templateWrap: [{ type: ViewChild, args: ['templateWrap'] }], dateConfig: [{ type: Input }], dateFormat: [{ type: Input }], maxDate: [{ type: Input }], minDate: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHdvLWRhdGVwaWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vZGV2dWkvZGF0ZXBpY2tlci90d28tZGF0ZXBpY2tlci90d28tZGF0ZXBpY2tlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9kZXZ1aS9kYXRlcGlja2VyL3R3by1kYXRlcGlja2VyL3R3by1kYXRlcGlja2VyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsZ0JBQWdCLEVBQXlELE1BQU0sc0JBQXNCLENBQUM7QUFDL0csT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFDTCxpQkFBaUIsRUFDakIsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFHTCxNQUFNLEVBRU4sU0FBUyxHQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBaUIsV0FBVyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNELE9BQU8sRUFBaUIsb0JBQW9CLEVBQUUsZ0JBQWdCLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlHLE9BQU8sRUFBRSxPQUFPLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBQzdDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3RELE9BQU8sRUFBRSx1QkFBdUIsSUFBSSxnQkFBZ0IsRUFBRSxNQUFNLCtCQUErQixDQUFDOzs7Ozs7Ozs7QUFVNUYsTUFBTSxPQUFPLHNCQUFzQjtJQXFDakMsSUFBYSxVQUFVLENBQUMsVUFBZTtRQUNyQyxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztZQUNyQyxJQUFJLENBQUMsV0FBVyxHQUFHLFVBQVUsQ0FBQztRQUNoQyxDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxX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Z0JBd0JaLFVBQVU7c0JBQXRCLEtBQUs7Z0JBV08sVUFBVTtzQkFBdEIsS0FBSztnQkFRTyxPQUFPO3NCQUFuQixLQUFLO2dCQVNPLE9BQU87c0JBQW5CLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDZGtPdmVybGF5T3JpZ2luLCBDb25uZWN0ZWRPdmVybGF5UG9zaXRpb25DaGFuZ2UsIFZlcnRpY2FsQ29ubmVjdGlvblBvcyB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9vdmVybGF5JztcclxuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5pbXBvcnQge1xyXG4gIENoYW5nZURldGVjdG9yUmVmLFxyXG4gIENvbXBvbmVudCxcclxuICBFbGVtZW50UmVmLFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBJbmplY3QsXHJcbiAgSW5wdXQsXHJcbiAgT25EZXN0cm95LFxyXG4gIE9uSW5pdCxcclxuICBPdXRwdXQsXHJcbiAgVGVtcGxhdGVSZWYsXHJcbiAgVmlld0NoaWxkLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBJMThuSW50ZXJmYWNlLCBJMThuU2VydmljZSB9IGZyb20gJ25nLWRldnVpL2kxOG4nO1xyXG5pbXBvcnQgeyBEYXRlQ29udmVydGVyLCBEZWZhdWx0RGF0ZUNvbnZlcnRlciwgRGV2Q29uZmlnU2VydmljZSwgV2l0aENvbmZpZywgZmFkZUluT3V0IH0gZnJvbSAnbmctZGV2dWkvdXRpbHMnO1xyXG5pbXBvcnQgeyBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IERhdGVQaWNrZXJDb25maWdTZXJ2aWNlIGFzIERhdGVQaWNrZXJDb25maWcgfSBmcm9tICcuLi9kYXRlLXBpY2tlci5jb25maWcuc2VydmljZSc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAvKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQGFuZ3VsYXItZXNsaW50L2NvbXBvbmVudC1zZWxlY3RvciovXHJcbiAgc2VsZWN0b3I6ICdbZFR3b0RhdGVQaWNrZXJdJyxcclxuICBleHBvcnRBczogJ3R3b0RhdGVQaWNrZXInLFxyXG4gIHRlbXBsYXRlVXJsOiAndHdvLWRhdGVwaWNrZXIuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL3R3by1kYXRlcGlja2VyLmNvbXBvbmVudC5zY3NzJ10sXHJcbiAgYW5pbWF0aW9uczogW2ZhZGVJbk91dF0sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBUd29EYXRlUGlja2VyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xyXG4gIEBJbnB1dCgpIGxvY2FsZTogc3RyaW5nO1xyXG4gIEBJbnB1dCgpIGNzc0NsYXNzOiBzdHJpbmc7XHJcbiAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW47XHJcbiAgQElucHV0KCkgZGF0ZUNvbnZlcnRlcjogRGF0ZUNvbnZlcnRlcjtcclxuICBASW5wdXQoKSBAV2l0aENvbmZpZygpIHNob3dBbmltYXRpb24gPSB0cnVlO1xyXG4gIHNob3dUaW1lID0gZmFsc2U7XHJcbiAgc2VsZWN0ZWRSYW5nZSA9IFtudWxsLCBudWxsXTtcclxuICBASW5wdXQoKSBoaWRlT25SYW5nZVNlbGVjdGVkID0gdHJ1ZTtcclxuICBjdXN0b21WaWV3VGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XHJcbiAgQE91dHB1dCgpIHNlbGVjdGVkUmFuZ2VDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICBAVmlld0NoaWxkKCdsZWZ0UGlja2VyJykgbGVmdFBpY2tlcjogRWxlbWVudFJlZjtcclxuICBAVmlld0NoaWxkKCdyaWdodFBpY2tlcicpIHJpZ2h0UGlja2VyOiBFbGVtZW50UmVmO1xyXG4gIEBWaWV3Q2hpbGQoJ3RlbXBsYXRlV3JhcCcpIHRlbXBsYXRlV3JhcDogRWxlbWVudFJlZjtcclxuXHJcbiAgZGF0ZVBvc2l0aW9uOiBWZXJ0aWNhbENvbm5lY3Rpb25Qb3MgPSAnYm90dG9tJztcclxuICBzZWxlY3REYXRlU3ViamVjdCA9IG5ldyBTdWJqZWN0PHsgc2lkZTogc3RyaW5nOyBkYXRlOiBEYXRlOyBvbmx5V3JpdGU/OiBib29sZWFuIH0+KCk7XHJcbiAgaG92ZXJPbkRhdGU6IFN1YmplY3Q8b2JqZWN0PiA9IG5ldyBTdWJqZWN0PG9iamVjdD4oKTtcclxuICBzd2l0Y2hPcmlnaW5Qb3NpdGlvblN1YjogU3ViamVjdDwnc3RhcnQnIHwgJ2VuZCcgfCBmYWxzZT4gPSBuZXcgU3ViamVjdDwnc3RhcnQnIHwgJ2VuZCcgfCBmYWxzZT4oKTtcclxuICB0b2RheSA9IG5ldyBEYXRlKCk7XHJcbiAgcmFuZ2VTdGFydDtcclxuICByYW5nZUVuZDtcclxuICBkaXNhYmxlVG9kYXk7XHJcbiAgaTE4blRleHQ6IEkxOG5JbnRlcmZhY2VbJ2RhdGVQaWNrZXInXTtcclxuICBpMThuTG9jYWxlOiBJMThuSW50ZXJmYWNlWydsb2NhbGUnXTtcclxuICBpMThuU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XHJcbiAgc3RhcnRBbmltYXRpb24gPSBmYWxzZTtcclxuXHJcbiAgcHVibGljIGN1cnJlbnRDYWxlbmRhcnMgPSBbbnVsbCwgbnVsbF07XHJcbiAgcHVibGljIGNka0Nvbm5lY3RlZE92ZXJsYXlPcmlnaW46IENka092ZXJsYXlPcmlnaW47XHJcbiAgcHJpdmF0ZSBfaXNPcGVuID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSBfd2hpY2hPcGVuOiAnc3RhcnQnIHwgJ2VuZCcgfCBmYWxzZTtcclxuICBwcml2YXRlIF9kYXRlQ29uZmlnOiBhbnk7XHJcbiAgcHJpdmF0ZSBfZGF0ZUZvcm1hdDogc3RyaW5nO1xyXG4gIHByaXZhdGUgX21heERhdGU6IERhdGU7XHJcbiAgcHJpdmF0ZSBfbWluRGF0ZTogRGF0ZTtcclxuICBkb2N1bWVudDogRG9jdW1lbnQ7XHJcbiAgQElucHV0KCkgc2V0IGRhdGVDb25maWcoZGF0ZUNvbmZpZzogYW55KSB7XHJcbiAgICBpZiAodGhpcy5jaGVja0RhdGVDb25maWcoZGF0ZUNvbmZpZykpIHtcclxuICAgICAgdGhpcy5fZGF0ZUNvbmZpZyA9IGRhdGVDb25maWc7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLl9kYXRlQ29uZmlnID0gdGhpcy5kYXRlUGlja2VyQ29uZmlnLmRhdGVDb25maWc7XHJcbiAgICB9XHJcbiAgICB0aGlzLl9kYXRlRm9ybWF0ID0gdGhpcy5zaG93VGltZSA/IHRoaXMuX2RhdGVDb25maWcuZm9ybWF0LnRpbWUgOiB0aGlzLl9kYXRlQ29uZmlnLmZvcm1hdC5kYXRlO1xyXG4gIH1cclxuICBnZXQgZGF0ZUNvbmZpZygpIHtcclxuICAgIHJldHVybiB0aGlzLl9kYXRlQ29uZmlnO1xyXG4gIH1cclxuICBASW5wdXQoKSBzZXQgZGF0ZUZvcm1hdChkYXRlRm9ybWF0OiBzdHJpbmcpIHtcclxuICAgIGlmIChkYXRlRm9ybWF0ICYmIHRoaXMuX2RhdGVGb3JtYXQgIT09IGRhdGVGb3JtYXQpIHtcclxuICAgICAgdGhpcy5fZGF0ZUZvcm1hdCA9IGRhdGVGb3JtYXQ7XHJcbiAgICB9XHJcbiAgfVxyXG4gIGdldCBkYXRlRm9ybWF0KCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX2RhdGVGb3JtYXQgfHwgdGhpcy5kYXRlUGlja2VyQ29uZmlnLmRlZmF1bHRGb3JtYXQ7XHJcbiAgfVxyXG4gIEBJbnB1dCgpIHNldCBtYXhEYXRlKGRhdGU6IERhdGUgfCBhbnkpIHtcclxuICAgIGNvbnN0IHBhcnNlRGF0ZSA9IHRoaXMuY29udmVydERhdGUoZGF0ZSk7XHJcbiAgICBpZiAocGFyc2VEYXRlKSB7XHJcbiAgICAgIHRoaXMuX21heERhdGUgPSBwYXJzZURhdGU7XHJcbiAgICB9XHJcbiAgfVxyXG4gIGdldCBtYXhEYXRlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX21heERhdGU7XHJcbiAgfVxyXG4gIEBJbnB1dCgpIHNldCBtaW5EYXRlKGRhdGU6IERhdGUgfCBhbnkpIHtcclxuICAgIGNvbnN0IHBhcnNlRGF0ZSA9IHRoaXMuY29udmVydERhdGUoZGF0ZSk7XHJcbiAgICBpZiAocGFyc2VEYXRlKSB7XHJcbiAgICAgIHRoaXMuX21pbkRhdGUgPSBwYXJzZURhdGU7XHJcbiAgICB9XHJcbiAgfVxyXG4gIGdldCBtaW5EYXRlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX21pbkRhdGU7XHJcbiAgfVxyXG4gIHNldCB3aGljaE9wZW4oc2lkZTogJ3N0YXJ0JyB8ICdlbmQnIHwgZmFsc2UpIHtcclxuICAgIHRoaXMuX3doaWNoT3BlbiA9IHNpZGU7XHJcbiAgICB0aGlzLnN3aXRjaE9yaWdpblBvc2l0aW9uU3ViLm5leHQoc2lkZSk7XHJcbiAgfVxyXG4gIGdldCB3aGljaE9wZW4oKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fd2hpY2hPcGVuO1xyXG4gIH1cclxuICBzZXQgaXNPcGVuKGlzT3BlbjogYm9vbGVhbikge1xyXG4gICAgdGhpcy5faXNPcGVuID0gaXNPcGVuO1xyXG4gICAgaWYgKCFpc09wZW4pIHtcclxuICAgICAgdGhpcy5zdGFydEFuaW1hdGlvbiA9IGZhbHNlO1xyXG4gICAgICB0aGlzLmRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5vbkRvY3VtZW50Q2xpY2spO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5zdGFydEFuaW1hdGlvbiA9IHRydWU7XHJcbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gICAgICAgIHRoaXMuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCB0aGlzLm9uRG9jdW1lbnRDbGljayk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gIH1cclxuICBnZXQgaXNPcGVuKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX2lzT3BlbjtcclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHVibGljIGVsOiBFbGVtZW50UmVmLFxyXG4gICAgcHJvdGVjdGVkIGRhdGVQaWNrZXJDb25maWc6IERhdGVQaWNrZXJDb25maWcsXHJcbiAgICBwcml2YXRlIGkxOG46IEkxOG5TZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxyXG4gICAgcHJpdmF0ZSBkZXZDb25maWdTZXJ2aWNlOiBEZXZDb25maWdTZXJ2aWNlLFxyXG4gICAgQEluamVjdChET0NVTUVOVCkgcHJpdmF0ZSBkb2M6IGFueVxyXG4gICkge1xyXG4gICAgdGhpcy5fZGF0ZUNvbmZpZyA9IGRhdGVQaWNrZXJDb25maWcuZGF0ZUNvbmZpZztcclxuICAgIHRoaXMuZGF0ZUNvbnZlcnRlciA9IGRhdGVQaWNrZXJDb25maWcuZGF0ZUNvbmZpZy5kYXRlQ29udmVydGVyIHx8IG5ldyBEZWZhdWx0RGF0ZUNvbnZlcnRlcigpO1xyXG4gICAgdGhpcy5zZXRJMThuVGV4dCgpO1xyXG4gICAgdGhpcy5kb2N1bWVudCA9IHRoaXMuZG9jO1xyXG4gIH1cclxuXHJcbiAgY2hlY2tEYXRlQ29uZmlnKGRhdGVDb25maWc6IGFueSkge1xyXG4gICAgaWYgKCFkYXRlQ29uZmlnKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIGlmICh0eXBlb2YgZGF0ZUNvbmZpZy50aW1lUGlja2VyICE9PSAnYm9vbGVhbicgfHwgIWRhdGVDb25maWcubWF4IHx8ICFkYXRlQ29uZmlnLm1pbiB8fCAhZGF0ZUNvbmZpZy5mb3JtYXQpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICBvbkRvY3VtZW50Q2xpY2sgPSAoJGV2ZW50KSA9PiB7XHJcbiAgICBpZiAoIXRoaXMuZWwubmF0aXZlRWxlbWVudC5jb250YWlucygkZXZlbnQudGFyZ2V0KSkge1xyXG4gICAgICB0aGlzLndoaWNoT3BlbiA9IGZhbHNlO1xyXG4gICAgICB0aGlzLmlzT3BlbiA9IGZhbHNlO1xyXG4gICAgfVxyXG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XHJcbiAgfTtcclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICB0aGlzLl9taW5EYXRlID0gdGhpcy5taW5EYXRlID8gbmV3IERhdGUodGhpcy5taW5EYXRlKSA6IG5ldyBEYXRlKHRoaXMuZGF0ZUNvbmZpZy5taW4sIDAsIDEsIDAsIDAsIDApO1xyXG4gICAgdGhpcy5fbWF4RGF0ZSA9IHRoaXMubWF4RGF0ZSA/IG5ldyBEYXRlKHRoaXMubWF4RGF0ZSkgOiBuZXcgRGF0ZSh0aGlzLmRhdGVDb25maWcubWF4LCAxMSwgMzEsIDIzLCA1OSwgNTkpO1xyXG4gICAgdGhpcy51cGRhdGVDZGtDb25uZWN0ZWRPdmVybGF5T3JpZ2luKHRoaXMuZWwubmF0aXZlRWxlbWVudCk7XHJcbiAgICB0aGlzLnN1YnNjcmliZUhvdmVyQWN0aW9ucygpO1xyXG4gIH1cclxuXHJcbiAgaXNEaXNhYmxlVG9kYXkoKSB7XHJcbiAgICBpZiAodGhpcy5taW5EYXRlLmdldFRpbWUoKSA+PSB0aGlzLnRvZGF5LmdldFRpbWUoKSB8fCB0aGlzLm1heERhdGUuZ2V0VGltZSgpIDw9IHRoaXMudG9kYXkuZ2V0VGltZSgpKSB7XHJcbiAgICAgIHRoaXMuZGlzYWJsZVRvZGF5ID0gdHJ1ZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZGlzYWJsZVRvZGF5ID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB0b2dnbGUgPSAoc2lkZTogJ3N0YXJ0JyB8ICdlbmQnID0gJ3N0YXJ0JykgPT4ge1xyXG4gICAgaWYgKHRoaXMuaXNPcGVuKSB7XHJcbiAgICAgIGlmIChzaWRlID09PSAnc3RhcnQnKSB7XHJcbiAgICAgICAgaWYgKHRoaXMud2hpY2hPcGVuID09PSAnc3RhcnQnKSB7XHJcbiAgICAgICAgICB0aGlzLndoaWNoT3BlbiA9IGZhbHNlO1xyXG4gICAgICAgICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgLy8gdGhpcy53aGljaE9wZW4gPT09ICdlbmQnXHJcbiAgICAgICAgICB0aGlzLndoaWNoT3BlbiA9ICdzdGFydCc7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vIHNpZGUgPT09ICdlbmQnXHJcbiAgICAgICAgaWYgKHRoaXMud2hpY2hPcGVuID09PSAnc3RhcnQnKSB7XHJcbiAgICAgICAgICB0aGlzLndoaWNoT3BlbiA9ICdlbmQnO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAvLyB0aGlzLndoaWNoT3BlbiA9PT0gJ2VuZCdcclxuICAgICAgICAgIHRoaXMud2hpY2hPcGVuID0gZmFsc2U7XHJcbiAgICAgICAgICB0aGlzLmlzT3BlbiA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy53aGljaE9wZW4gPSBzaWRlO1xyXG4gICAgICB0aGlzLmlzT3BlbiA9IHRydWU7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgb25Qb3NpdGlvbkNoYW5nZShwb3NpdGlvbjogQ29ubmVjdGVkT3ZlcmxheVBvc2l0aW9uQ2hhbmdlKSB7XHJcbiAgICBzd2l0Y2ggKHBvc2l0aW9uLmNvbm5lY3Rpb25QYWlyLm92ZXJsYXlZKSB7XHJcbiAgICBjYXNlICd0b3AnOlxyXG4gICAgY2FzZSAnY2VudGVyJzpcclxuICAgICAgdGhpcy5kYXRlUG9zaXRpb24gPSAnYm90dG9tJztcclxuICAgICAgYnJlYWs7XHJcbiAgICBjYXNlICdib3R0b20nOlxyXG4gICAgICB0aGlzLmRhdGVQb3NpdGlvbiA9ICd0b3AnO1xyXG4gICAgICBicmVhaztcclxuICAgIGRlZmF1bHQ6XHJcbiAgICB9XHJcbiAgICB0aGlzLnN3aXRjaE9yaWdpblBvc2l0aW9uU3ViLm5leHQodGhpcy53aGljaE9wZW4pO1xyXG4gIH1cclxuXHJcbiAgY29udmVydERhdGUoZGF0ZSkge1xyXG4gICAgcmV0dXJuIGRhdGUgPyB0aGlzLmRhdGVDb252ZXJ0ZXIucGFyc2UoZGF0ZSwgdGhpcy5kYXRlRm9ybWF0KSA6IG51bGw7XHJcbiAgfVxyXG5cclxuICBmb3JtYXREYXRlKGRhdGUpIHtcclxuICAgIHJldHVybiBkYXRlID8gdGhpcy5kYXRlQ29udmVydGVyLmZvcm1hdChkYXRlLCB0aGlzLmRhdGVGb3JtYXQsIHRoaXMubG9jYWxlIHx8IHRoaXMuaTE4bkxvY2FsZSkgOiBudWxsO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlQ2RrQ29ubmVjdGVkT3ZlcmxheU9yaWdpbihlbDogRWxlbWVudFJlZikge1xyXG4gICAgaWYgKGVsKSB7XHJcbiAgICAgIHRoaXMuY2RrQ29ubmVjdGVkT3ZlcmxheU9yaWdpbiA9IG5ldyBDZGtPdmVybGF5T3JpZ2luKGVsKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuY2RrQ29ubmVjdGVkT3ZlcmxheU9yaWdpbiA9IHVuZGVmaW5lZDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHN5bmNQaWNrZXJQYWlyKGN1cnJlbnRDYWxlbmRlcjogb2JqZWN0LCBvcmllbnRhdGlvbjogc3RyaW5nKSB7XHJcbiAgICBzd2l0Y2ggKG9yaWVudGF0aW9uKSB7XHJcbiAgICBjYXNlICdsZWZ0JzpcclxuICAgICAgdGhpcy5jdXJyZW50Q2FsZW5kYXJzWzBdID0gY3VycmVudENhbGVuZGVyO1xyXG4gICAgICBicmVhaztcclxuICAgIGNhc2UgJ3JpZ2h0JzpcclxuICAgICAgdGhpcy5jdXJyZW50Q2FsZW5kYXJzWzFdID0gY3VycmVudENhbGVuZGVyO1xyXG4gICAgICBicmVhaztcclxuICAgIGRlZmF1bHQ6XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByYW5nZUNoYW5nZShkYXRhKSB7XHJcbiAgICB0aGlzLmNob29zZURhdGUoZGF0YS5zZWxlY3RlZFJhbmdlKTtcclxuICAgIHRoaXMuc2VsZWN0RGF0ZVN1YmplY3QubmV4dCh7IHNpZGU6ICdzdGFydCcsIGRhdGU6IHRoaXMucmFuZ2VTdGFydCwgb25seVdyaXRlOiB0cnVlIH0pO1xyXG4gICAgdGhpcy5zZWxlY3REYXRlU3ViamVjdC5uZXh0KHsgc2lkZTogJ2VuZCcsIGRhdGU6IHRoaXMucmFuZ2VFbmQsIG9ubHlXcml0ZTogdHJ1ZSB9KTtcclxuICB9XHJcblxyXG4gIGNob29zZURhdGUgPSAocmFuZ2UpID0+IHtcclxuICAgIGlmIChyYW5nZSAmJiBBcnJheS5pc0FycmF5KHRoaXMuc2VsZWN0ZWRSYW5nZSkpIHtcclxuICAgICAgdGhpcy5zZWxlY3RlZFJhbmdlID0gcmFuZ2U7XHJcbiAgICAgIFt0aGlzLnJhbmdlU3RhcnQsIHRoaXMucmFuZ2VFbmRdID0gdGhpcy5zZWxlY3RlZFJhbmdlO1xyXG4gICAgICB0aGlzLm5vdGlmeVZhbHVlQ2hhbmdlKCk7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgbm90aWZ5VmFsdWVDaGFuZ2UoKSB7XHJcbiAgICB0aGlzLnNlbGVjdGVkUmFuZ2VDaGFuZ2UuZW1pdCh0aGlzLnNlbGVjdGVkUmFuZ2UpO1xyXG4gIH1cclxuXHJcbiAgc2VsZWN0aW5nRGF0ZShldmVudCkge1xyXG4gICAgdGhpcy5ob3Zlck9uRGF0ZS5uZXh0KGV2ZW50KTtcclxuICB9XHJcblxyXG4gIHN1YnNjcmliZUhvdmVyQWN0aW9ucygpIHtcclxuICAgIHRoaXMuaG92ZXJPbkRhdGUucGlwZShkaXN0aW5jdFVudGlsQ2hhbmdlZCgpKS5zdWJzY3JpYmUoKGRhdGUpID0+IHtcclxuICAgICAgdGhpcy5wcmV2aWV3UmFuZ2VFbmQoZGF0ZSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByZXZpZXdSYW5nZUVuZChkYXRlKSB7XHJcbiAgICAodGhpcy5sZWZ0UGlja2VyIGFzIGFueSkucHJldmlld0VuZCA9IGRhdGU7XHJcbiAgICAodGhpcy5yaWdodFBpY2tlciBhcyBhbnkpLnByZXZpZXdFbmQgPSBkYXRlO1xyXG4gIH1cclxuXHJcbiAgc3luY1JhbmdlU3RhcnQocmFuZ2VTdGFydCwgcGlja2VyOiBhbnkpIHtcclxuICAgIGlmICh0aGlzLndoaWNoT3BlbiA9PT0gJ2VuZCcpIHtcclxuICAgICAgdGhpcy5zZWxlY3RFbmQocmFuZ2VTdGFydCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyB0aGlzLndoaWNoT3BlbiA9PT0gJ3N0YXJ0J1xyXG4gICAgICB0aGlzLnNlbGVjdFN0YXJ0KHJhbmdlU3RhcnQpO1xyXG4gICAgfVxyXG4gICAgcGlja2VyLnNlbGVjdFJhbmdlKHJhbmdlU3RhcnQsIHRydWUpO1xyXG4gIH1cclxuXHJcbiAgc2VsZWN0U3RhcnQoZGF0ZTogRGF0ZSwgcGFzc2l2ZSA9IGZhbHNlKSB7XHJcbiAgICB0aGlzLnNlbGVjdGVkUmFuZ2VbMF0gPSBkYXRlO1xyXG4gICAgdGhpcy5yYW5nZVN0YXJ0ID0gZGF0ZTtcclxuICAgIHRoaXMuaXNEaXNhYmxlVG9kYXkoKTtcclxuICAgIGlmICghcGFzc2l2ZSkge1xyXG4gICAgICB0aGlzLnNlbGVjdERhdGVTdWJqZWN0Lm5leHQoeyBzaWRlOiAnc3RhcnQnLCBkYXRlIH0pO1xyXG4gICAgICB0aGlzLndoaWNoT3BlbiA9ICdlbmQnO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgc2VsZWN0RW5kKGRhdGU6IERhdGUsIHBhc3NpdmUgPSBmYWxzZSkge1xyXG4gICAgdGhpcy5zZWxlY3RlZFJhbmdlWzFdID0gZGF0ZTtcclxuICAgIHRoaXMucmFuZ2VFbmQgPSBkYXRlO1xyXG4gICAgdGhpcy5pc0Rpc2FibGVUb2RheSgpO1xyXG4gICAgaWYgKCFwYXNzaXZlKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0RGF0ZVN1YmplY3QubmV4dCh7IHNpZGU6ICdlbmQnLCBkYXRlOiBkYXRlIH0pO1xyXG4gICAgICBpZiAoIXRoaXMuc2hvd1RpbWUgJiYgdGhpcy5oaWRlT25SYW5nZVNlbGVjdGVkKSB7XHJcbiAgICAgICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcclxuICAgICAgICB0aGlzLndoaWNoT3BlbiA9IGZhbHNlO1xyXG4gICAgICB9XHJcbiAgICB9XH