UNPKG

ng-zorro-antd-mobile

Version:

An enterprise-class mobile UI components based on Ant Design and Angular

427 lines 56.3 kB
import { Component, forwardRef, ViewEncapsulation, Input, Output, HostBinding, EventEmitter, ViewChild } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { zh_CN, en_US } from 'ng-zorro-antd-mobile/locale-provider'; import { LocaleProviderService } from 'ng-zorro-antd-mobile/locale-provider'; import { mergeDateTime, isSameDate } from './util/index'; import { takeUntil } from 'rxjs/operators'; import { CalendarDatePickerComponent } from './datepicker/datepicker.component'; import { Subject } from 'rxjs'; import * as i0 from "@angular/core"; import * as i1 from "ng-zorro-antd-mobile/locale-provider"; import * as i2 from "@angular/common"; import * as i3 from "ng-zorro-antd-mobile/icon"; import * as i4 from "./header/header.component"; import * as i5 from "./datepicker/datepicker.component"; import * as i6 from "./timepicker/timepicker.component"; import * as i7 from "./confirm-panel/confirm-panel.component"; import * as i8 from "./shortcut-panel/shortcut-panel.component"; export class CalendarComponent { set locale(value) { if (value === 'enUS') { this.props.locale = en_US.Calendar; } else if (value === 'zhCN') { this.props.locale = zh_CN.Calendar; } this._unsubscribe$.next(); this._unsubscribe$.complete(); } set defaultTimeValue(value) { if (value) { this.props.defaultTimeValue = value; } } set prefixCls(value) { if (value) { this.props.prefixCls = value; } } set enterDirection(value) { this._enterDirection = value; if (this._enterDirection === 'horizontal') { this.contentAnimateClass = 'slideH-enter slideH-enter-active'; } else { this.contentAnimateClass = 'slideV-enter slideV-enter-active'; } } set visible(value) { this.props.visible = value; if (value === true || value === 'true') { this.showAnimation(); this.isShow = true; } else { this.hideAnimation(); setTimeout(() => { this.isShow = false; }, 300); } } set getDateExtra(value) { this.props.getDateExtra = value; } set defaultDate(value) { this.props.defaultDate = value; } set minDate(value) { this.props.minDate = value; } set maxDate(value) { this.props.maxDate = value; } set pickTime(value) { this.props.pickTime = value; } set type(value) { this.props.type = value; } set showShortcut(value) { this.props.showShortcut = value; } set rowSize(value) { this.props.rowSize = value; } set infinite(value) { } set defaultValue(value) { this.props.defaultValue = value; if (value) { this.receiveProps(this.props); } } set onSelect(value) { this.props.onSelect = value; } constructor(_localeProviderService) { this._localeProviderService = _localeProviderService; this.isShow = false; this.showClear = false; this.isSameDate = isSameDate; this.props = { visible: false, showHeader: true, locale: zh_CN.Calendar, pickTime: false, showShortcut: false, prefixCls: 'rmc-calendar', type: 'range', defaultTimeValue: new Date(2000, 0, 1, 8) }; this.state = { showTimePicker: false, timePickerTitle: '', startDate: undefined, endDate: undefined, disConfirmBtn: true, clientHight: 0 }; this._unsubscribe$ = new Subject(); this._dateModelTime = 0; this.onCancel = new EventEmitter(); this.onConfirm = new EventEmitter(); this.onSelectHasDisableDate = new EventEmitter(); this.class = 'am-calendar'; this.selectDate = (date, useDateTime = false, oldState = {}, props = this.props) => { if (!date) { return {}; } let newState = {}; const { type, pickTime, defaultTimeValue, locale = {} } = props; const newDate = pickTime && !useDateTime ? mergeDateTime(date, defaultTimeValue) : date; const { startDate, endDate } = oldState; switch (type) { case 'one': newState = { ...newState, startDate: newDate, disConfirmBtn: false }; if (pickTime) { newState = { ...newState, timePickerTitle: locale.selectTime, showTimePicker: true }; } break; case 'range': if (!startDate || endDate) { newState = { ...newState, startDate: newDate, endDate: undefined, disConfirmBtn: true }; if (pickTime) { newState = { ...newState, timePickerTitle: locale.selectStartTime, showTimePicker: true }; } } else { newState = { ...newState, timePickerTitle: +newDate >= +startDate || this.isSameDate(startDate, newDate) ? locale.selectEndTime : locale.selectStartTime, disConfirmBtn: false, endDate: pickTime && !useDateTime && (+newDate >= +startDate || this.isSameDate(startDate, newDate)) ? new Date(+mergeDateTime(newDate, startDate) + 3600000) : newDate }; } break; } this.writeModelData(date); return newState; }; this.onSelectedDate = (date) => { const { startDate, endDate } = this.state; const { onSelect } = this.props; if (onSelect) { const value = onSelect(date, [startDate, endDate]); if (value) { this.shortcutSelect(value[0], value[1]); return; } } this.state = { ...this.state, ...this.selectDate(date, false, { startDate, endDate }) }; this.showClear = !!this.state.startDate; }; this.triggerSelectHasDisableDate = (date) => { this.triggerClear(); if (this.onSelectHasDisableDate) { this.onSelectHasDisableDate.emit(date); } }; this.onClose = () => { this.state = { showTimePicker: false, timePickerTitle: '', startDate: undefined, endDate: undefined, disConfirmBtn: true, clientHight: 0 }; this.showClear = !!this.state.startDate; }; this.triggerConfirm = () => { const { startDate, endDate } = this.state; if (startDate && endDate && +startDate > +endDate) { this.onClose(); return this.onConfirm && this.onConfirm.emit({ startDate: endDate, endDate: startDate }); } if (this.onConfirm) { this.onConfirm.emit({ startDate, endDate }); } this.onClose(); }; this.triggerClear = () => { // 清除数据做延迟,否则同步刷新数据导致报错 setTimeout(() => { this.state = { ...this.state, ...{ startDate: undefined, endDate: undefined, showTimePicker: false } }; if (this.props.onClear) { this.props.onClear(); } this.showClear = !!this.state.startDate; }, 0); }; this.onTimeChange = (date) => { const { startDate, endDate } = this.state; if (endDate) { this.state.endDate = date; } else if (startDate) { this.state.startDate = date; } }; this.shortcutSelect = (startDate, endDate, props = this.props) => { this.state = { ...this.state, ...{ startDate, showTimePicker: false }, ...this.selectDate(endDate, true, { startDate }, props) }; this.showClear = !!this.state.startDate; }; this.setClientHeight = (height) => { this.state.clientHight = height; }; this.onChangeFn = () => { }; this.onTouchFn = () => { }; } writeValue(value) { this._dateModelType = null; if (value && value instanceof Array) { if (value.length === 0) { console.error('[ng-zorro-antd-mobile]: calendar ngModel array need params!'); return; } if (this.props.type === 'one' && value.length >= 2) { this._dateModelType = 1; console.error('[ng-zorro-antd-mobile]: type is one, but ngmodel has more than one param, just use first one'); this.onSelectedDate(value[0]); } else if (value.length === 1) { this._dateModelType = 1; this.onSelectedDate(value[0]); } else { this._dateModelType = 2; this.onSelectedDate(value[0]); this.onSelectedDate(value[1]); } } else if (value && value instanceof Date) { this._dateModelType = 3; this.onSelectedDate(value); } } registerOnChange(fn) { this.onChangeFn = fn; } registerOnTouched(fn) { this.onTouchFn = fn; } receiveProps(nextProps) { if (nextProps.visible && nextProps.defaultValue) { this.shortcutSelect(nextProps.defaultValue[0], nextProps.defaultValue[1], nextProps); } } showAnimation() { if (this._enterDirection === 'horizontal') { this.contentAnimateClass = 'slideH-enter slideH-enter-active'; } else { this.contentAnimateClass = 'slideV-enter slideV-enter-active'; } this.maskAnimateClass = 'fade-enter fade-enter-active'; } hideAnimation() { if (this._enterDirection === 'horizontal') { this.contentAnimateClass = 'slideH-leave slideH-leave-active'; } else { this.contentAnimateClass = 'slideV-leave slideV-leave-active'; } this.maskAnimateClass = 'fade-leave fade-leave-active'; } writeModelData(date) { if (this._dateModelValue instanceof Array) { this._dateModelTime = this._dateModelValue.length; } else { this._dateModelTime = 0; } switch (this._dateModelType) { case 1: this._dateModelValue = [date]; this.onChangeFn(this._dateModelValue); break; case 2: if (this._dateModelTime === 1) { if (+date < +this._dateModelValue[0]) { this._dateModelValue.unshift(date); } else { this._dateModelValue.push(date); } this.onChangeFn(this._dateModelValue); } else { this._dateModelValue = []; this._dateModelValue.push(date); } break; case 3: this._dateModelValue = date; this.onChangeFn(this._dateModelValue); break; default: break; } } triggerCancel() { if (this.props.onCancel) { this.props.onCancel(); } this.onClose(); if (this.onCancel) { this.onCancel.emit(); } } ngOnInit() { const defaultValue = this.props.defaultValue; if (defaultValue) { this.state = { ...this.state, ...this.selectDate(defaultValue[1], true, { startDate: defaultValue[0] }, this.props) }; } this._localeProviderService.localeChange.pipe(takeUntil(this._unsubscribe$)).subscribe(_ => { this.props.locale = { ...this._localeProviderService.getLocaleSubObj('Calendar') }; }); } ngOnDestroy() { this._unsubscribe$.next(); this._unsubscribe$.complete(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: CalendarComponent, deps: [{ token: i1.LocaleProviderService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.8", type: CalendarComponent, selector: "Calendar, nzm-calendar", inputs: { locale: "locale", defaultTimeValue: "defaultTimeValue", prefixCls: "prefixCls", enterDirection: "enterDirection", visible: "visible", getDateExtra: "getDateExtra", defaultDate: "defaultDate", minDate: "minDate", maxDate: "maxDate", pickTime: "pickTime", type: "type", showShortcut: "showShortcut", rowSize: "rowSize", infinite: "infinite", defaultValue: "defaultValue", onSelect: "onSelect" }, outputs: { onCancel: "onCancel", onConfirm: "onConfirm", onSelectHasDisableDate: "onSelectHasDisableDate" }, host: { properties: { "class": "this.class" } }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CalendarComponent), multi: true }], viewQueries: [{ propertyName: "datepicker", first: true, predicate: CalendarDatePickerComponent, descendants: true }], ngImport: i0, template: "<span *ngIf=\"isShow\">\n <div class=\"{{ 'mask ' + maskAnimateClass }}\"></div>\n</span>\n<span *ngIf=\"isShow\">\n <div class=\"{{ 'content animate ' + contentAnimateClass }}\">\n <CalendarHeader\n [locale]=\"props.locale\"\n [closeIcon]=\"closeIconHtml\"\n [showClear]=\"showClear\"\n (onCancel)=\"triggerCancel()\"\n (onClear)=\"triggerClear()\"\n ></CalendarHeader>\n <CalendarDatePicker\n [propsData]=\"props\"\n [endDate]=\"state.endDate\"\n [startDate]=\"state.startDate\"\n [onCellClick]=\"onSelectedDate\"\n [onSelectHasDisableDate]=\"triggerSelectHasDisableDate\"\n [onLayout]=\"setClientHeight\"\n ></CalendarDatePicker>\n <CalendarTimePicker\n *ngIf=\"state.showTimePicker\"\n [propsData]=\"props\"\n [title]=\"state.timePickerTitle\"\n [clientHeight]=\"state.clientHight\"\n [prefixCls]=\"props.timePickerPrefixCls\"\n [defaultValue]=\"props.defaultTimeValue\"\n [pickerPrefixCls]=\"props.timePickerPickerPrefixCls\"\n [value]=\"state.endDate ? state.endDate : state.startDate\"\n [onValueChange]=\"onTimeChange\"\n ></CalendarTimePicker>\n <CalendarShortcutPanel\n *ngIf=\"props.showShortcut && !state.showTimePicker\"\n [locale]=\"props.locale\"\n [onSelect]=\"shortcutSelect\"\n ></CalendarShortcutPanel>\n <CalendarConfirmPanel\n *ngIf=\"state.startDate\"\n [propsData]=\"props\"\n [startDateTime]=\"state.startDate\"\n [endDateTime]=\"state.endDate\"\n [disableBtn]=\"state.disConfirmBtn\"\n [formatStr]=\"props.pickTime ? props.locale.dateTimeFormat : props.locale.dateFormat\"\n [onConfirm]=\"triggerConfirm\"\n ></CalendarConfirmPanel>\n </div>\n</span>\n<ng-template #closeIconHtml>\n <Icon [type]=\"'cross'\"></Icon>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i3.IconComponent, selector: "Icon, nzm-icon", inputs: ["color", "type", "src", "size"] }, { kind: "component", type: i4.CalendarHeaderComponent, selector: "CalendarHeader, nzm-calendar-header", inputs: ["locale", "closeIcon", "showClear"], outputs: ["onCancel", "onClear"] }, { kind: "component", type: i5.CalendarDatePickerComponent, selector: "CalendarDatePicker, nzm-calendar-date-picker", inputs: ["onCellClick", "endDate", "startDate", "propsData", "onSelectHasDisableDate", "onLayout"] }, { kind: "component", type: i6.CalendarTimePickerComponent, selector: "CalendarTimePicker, nzm-calendar-time-picker", inputs: ["propsData", "title", "value", "prefixCls", "defaultValue", "pickerPrefixCls", "clientHeight", "onValueChange"] }, { kind: "component", type: i7.CalendarConfirmPanelComponent, selector: "CalendarConfirmPanel, nzm-calendar-confirm-panel", inputs: ["propsData", "disableBtn", "formatStr", "startDateTime", "endDateTime", "onConfirm"] }, { kind: "component", type: i8.CalendarShortcutPanelComponent, selector: "CalendarShortcutPanel, nzm-calendar-shortcut-panel", inputs: ["locale", "onSelect"] }], encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.8", ngImport: i0, type: CalendarComponent, decorators: [{ type: Component, args: [{ selector: 'Calendar, nzm-calendar', encapsulation: ViewEncapsulation.None, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => CalendarComponent), multi: true }], template: "<span *ngIf=\"isShow\">\n <div class=\"{{ 'mask ' + maskAnimateClass }}\"></div>\n</span>\n<span *ngIf=\"isShow\">\n <div class=\"{{ 'content animate ' + contentAnimateClass }}\">\n <CalendarHeader\n [locale]=\"props.locale\"\n [closeIcon]=\"closeIconHtml\"\n [showClear]=\"showClear\"\n (onCancel)=\"triggerCancel()\"\n (onClear)=\"triggerClear()\"\n ></CalendarHeader>\n <CalendarDatePicker\n [propsData]=\"props\"\n [endDate]=\"state.endDate\"\n [startDate]=\"state.startDate\"\n [onCellClick]=\"onSelectedDate\"\n [onSelectHasDisableDate]=\"triggerSelectHasDisableDate\"\n [onLayout]=\"setClientHeight\"\n ></CalendarDatePicker>\n <CalendarTimePicker\n *ngIf=\"state.showTimePicker\"\n [propsData]=\"props\"\n [title]=\"state.timePickerTitle\"\n [clientHeight]=\"state.clientHight\"\n [prefixCls]=\"props.timePickerPrefixCls\"\n [defaultValue]=\"props.defaultTimeValue\"\n [pickerPrefixCls]=\"props.timePickerPickerPrefixCls\"\n [value]=\"state.endDate ? state.endDate : state.startDate\"\n [onValueChange]=\"onTimeChange\"\n ></CalendarTimePicker>\n <CalendarShortcutPanel\n *ngIf=\"props.showShortcut && !state.showTimePicker\"\n [locale]=\"props.locale\"\n [onSelect]=\"shortcutSelect\"\n ></CalendarShortcutPanel>\n <CalendarConfirmPanel\n *ngIf=\"state.startDate\"\n [propsData]=\"props\"\n [startDateTime]=\"state.startDate\"\n [endDateTime]=\"state.endDate\"\n [disableBtn]=\"state.disConfirmBtn\"\n [formatStr]=\"props.pickTime ? props.locale.dateTimeFormat : props.locale.dateFormat\"\n [onConfirm]=\"triggerConfirm\"\n ></CalendarConfirmPanel>\n </div>\n</span>\n<ng-template #closeIconHtml>\n <Icon [type]=\"'cross'\"></Icon>\n</ng-template>\n" }] }], ctorParameters: () => [{ type: i1.LocaleProviderService }], propDecorators: { datepicker: [{ type: ViewChild, args: [CalendarDatePickerComponent] }], locale: [{ type: Input }], defaultTimeValue: [{ type: Input }], prefixCls: [{ type: Input }], enterDirection: [{ type: Input }], visible: [{ type: Input }], getDateExtra: [{ type: Input }], defaultDate: [{ type: Input }], minDate: [{ type: Input }], maxDate: [{ type: Input }], pickTime: [{ type: Input }], type: [{ type: Input }], showShortcut: [{ type: Input }], rowSize: [{ type: Input }], infinite: [{ type: Input }], defaultValue: [{ type: Input }], onSelect: [{ type: Input }], onCancel: [{ type: Output }], onConfirm: [{ type: Output }], onSelectHasDisableDate: [{ type: Output }], class: [{ type: HostBinding, args: ['class'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vY29tcG9uZW50cy9jYWxlbmRhci9jYWxlbmRhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi9jb21wb25lbnRzL2NhbGVuZGFyL2NhbGVuZGFyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsVUFBVSxFQUdWLGlCQUFpQixFQUNqQixLQUFLLEVBQ0wsTUFBTSxFQUNOLFdBQVcsRUFDWCxZQUFZLEVBQ1osU0FBUyxFQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV6RSxPQUFPLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBRXBFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQzdFLE9BQU8sRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3pELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNoRixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDOzs7Ozs7Ozs7O0FBbUIvQixNQUFNLE9BQU8saUJBQWlCO0lBb0M1QixJQUNJLE1BQU0sQ0FBQyxLQUFLO1FBQ2QsSUFBSSxLQUFLLEtBQUssTUFBTSxFQUFFO1lBQ3BCLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUM7U0FDcEM7YUFBTSxJQUFJLEtBQUssS0FBSyxNQUFNLEVBQUU7WUFDM0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQztTQUNwQztRQUVELElBQUksQ0FBQyxh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UTtzQkFEWCxLQUFLO2dCQU1OLFFBQVE7c0JBRFAsTUFBTTtnQkFHUCxTQUFTO3NCQURSLE1BQU07Z0JBR1Asc0JBQXNCO3NCQURyQixNQUFNO2dCQUlQLEtBQUs7c0JBREosV0FBVzt1QkFBQyxPQUFPIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBmb3J3YXJkUmVmLFxuICBPbkluaXQsXG4gIE9uRGVzdHJveSxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIEhvc3RCaW5kaW5nLFxuICBFdmVudEVtaXR0ZXIsXG4gIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IERhdGVNb2RlbHMgfSBmcm9tICcuL2RhdGUvRGF0YVR5cGVzJztcbmltcG9ydCB7IHpoX0NOLCBlbl9VUyB9IGZyb20gJ25nLXpvcnJvLWFudGQtbW9iaWxlL2xvY2FsZS1wcm92aWRlcic7XG5pbXBvcnQgeyBDYWxlbmRhclByb3BzVHlwZSB9IGZyb20gJy4vY2FsZW5kYXIucHJvcHMuY29tcG9uZW50JztcbmltcG9ydCB7IExvY2FsZVByb3ZpZGVyU2VydmljZSB9IGZyb20gJ25nLXpvcnJvLWFudGQtbW9iaWxlL2xvY2FsZS1wcm92aWRlcic7XG5pbXBvcnQgeyBtZXJnZURhdGVUaW1lLCBpc1NhbWVEYXRlIH0gZnJvbSAnLi91dGlsL2luZGV4JztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IENhbGVuZGFyRGF0ZVBpY2tlckNvbXBvbmVudCB9IGZyb20gJy4vZGF0ZXBpY2tlci9kYXRlcGlja2VyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmV4cG9ydCB7IENhbGVuZGFyUHJvcHNUeXBlIH07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FsZW5kYXJTdGF0ZVR5cGUge1xuICBzaG93VGltZVBpY2tlcjogYm9vbGVhbjtcbiAgdGltZVBpY2tlclRpdGxlPzogc3RyaW5nO1xuICBzdGFydERhdGU/OiBEYXRlO1xuICBlbmREYXRlPzogRGF0ZTtcbiAgZGlzQ29uZmlybUJ0bj86IGJvb2xlYW47XG4gIGNsaWVudEhpZ2h0PzogbnVtYmVyO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdDYWxlbmRhciwgbnptLWNhbGVuZGFyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NhbGVuZGFyLmNvbXBvbmVudC5odG1sJyxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgcHJvdmlkZXJzOiBbeyBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUiwgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gQ2FsZW5kYXJDb21wb25lbnQpLCBtdWx0aTogdHJ1ZSB9XVxufSlcbmV4cG9ydCBjbGFzcyBDYWxlbmRhckNvbXBvbmVudCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkluaXQsIE9uRGVzdHJveSB7XG4gIGlzU2hvdzogYm9vbGVhbiA9IGZhbHNlO1xuICBjb250ZW50QW5pbWF0ZUNsYXNzOiBzdHJpbmc7XG4gIG1hc2tBbmltYXRlQ2xhc3M6IHN0cmluZztcbiAgc2hvd0NsZWFyOiBib29sZWFuID0gZmFsc2U7XG4gIGlzU2FtZURhdGU6IEZ1bmN0aW9uID0gaXNTYW1lRGF0ZTtcblxuICBwcm9wcyA9IHtcbiAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICBzaG93SGVhZGVyOiB0cnVlLFxuICAgIGxvY2FsZTogemhfQ04uQ2FsZW5kYXIsXG4gICAgcGlja1RpbWU6IGZhbHNlLFxuICAgIHNob3dTaG9ydGN1dDogZmFsc2UsXG4gICAgcHJlZml4Q2xzOiAncm1jLWNhbGVuZGFyJyxcbiAgICB0eXBlOiAncmFuZ2UnLFxuICAgIGRlZmF1bHRUaW1lVmFsdWU6IG5ldyBEYXRlKDIwMDAsIDAsIDEsIDgpXG4gIH0gYXMgQ2FsZW5kYXJQcm9wc1R5cGU7XG5cbiAgc3RhdGUgPSB7XG4gICAgc2hvd1RpbWVQaWNrZXI6IGZhbHNlLFxuICAgIHRpbWVQaWNrZXJUaXRsZTogJycsXG4gICAgc3RhcnREYXRlOiB1bmRlZmluZWQsXG4gICAgZW5kRGF0ZTogdW5kZWZpbmVkLFxuICAgIGRpc0NvbmZpcm1CdG46IHRydWUsXG4gICAgY2xpZW50SGlnaHQ6IDBcbiAgfSBhcyBDYWxlbmRhclN0YXRlVHlwZTtcblxuICBwcml2YXRlIF91bnN1YnNjcmliZSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIF9lbnRlckRpcmVjdGlvbjogc3RyaW5nO1xuICBwcml2YXRlIF9kYXRlTW9kZWxUeXBlOiBudW1iZXI7XG4gIHByaXZhdGUgX2RhdGVNb2RlbFZhbHVlOiBhbnk7XG4gIHByaXZhdGUgX2RhdGVNb2RlbFRpbWU6IG51bWJlciA9IDA7XG5cbiAgQFZpZXdDaGlsZChDYWxlbmRhckRhdGVQaWNrZXJDb21wb25lbnQpXG4gIGRhdGVwaWNrZXI6IENhbGVuZGFyRGF0ZVBpY2tlckNvbXBvbmVudDtcblxuICBASW5wdXQoKVxuICBzZXQgbG9jYWxlKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlID09PSAnZW5VUycpIHtcbiAgICAgIHRoaXMucHJvcHMubG9jYWxlID0gZW5fVVMuQ2FsZW5kYXI7XG4gICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gJ3poQ04nKSB7XG4gICAgICB0aGlzLnByb3BzLmxvY2FsZSA9IHpoX0NOLkNhbGVuZGFyO1xuICAgIH1cblxuICAgIHRoaXMuX3Vuc3Vic2NyaWJlJC5uZXh0KCk7XG4gICAgdGhpcy5fdW5zdWJzY3JpYmUkLmNvbXBsZXRlKCk7XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IGRlZmF1bHRUaW1lVmFsdWUodmFsdWUpIHtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIHRoaXMucHJvcHMuZGVmYXVsdFRpbWVWYWx1ZSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuICBASW5wdXQoKVxuICBzZXQgcHJlZml4Q2xzKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLnByb3BzLnByZWZpeENscyA9IHZhbHVlO1xuICAgIH1cbiAgfVxuICBASW5wdXQoKVxuICBzZXQgZW50ZXJEaXJlY3Rpb24odmFsdWUpIHtcbiAgICB0aGlzLl9lbnRlckRpcmVjdGlvbiA9IHZhbHVlO1xuICAgIGlmICh0aGlzLl9lbnRlckRpcmVjdGlvbiA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICB0aGlzLmNvbnRlbnRBbmltYXRlQ2xhc3MgPSAnc2xpZGVILWVudGVyIHNsaWRlSC1lbnRlci1hY3RpdmUnO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNvbnRlbnRBbmltYXRlQ2xhc3MgPSAnc2xpZGVWLWVudGVyIHNsaWRlVi1lbnRlci1hY3RpdmUnO1xuICAgIH1cbiAgfVxuICBASW5wdXQoKVxuICBzZXQgdmlzaWJsZSh2YWx1ZSkge1xuICAgIHRoaXMucHJvcHMudmlzaWJsZSA9IHZhbHVlO1xuICAgIGlmICh2YWx1ZSA9PT0gdHJ1ZSB8fCB2YWx1ZSA9PT0gJ3RydWUnKSB7XG4gICAgICB0aGlzLnNob3dBbmltYXRpb24oKTtcbiAgICAgIHRoaXMuaXNTaG93ID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5oaWRlQW5pbWF0aW9uKCk7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5pc1Nob3cgPSBmYWxzZTtcbiAgICAgIH0sIDMwMCk7XG4gICAgfVxuICB9XG4gIEBJbnB1dCgpXG4gIHNldCBnZXREYXRlRXh0cmEodmFsdWUpIHtcbiAgICB0aGlzLnByb3BzLmdldERhdGVFeHRyYSA9IHZhbHVlO1xuICB9XG4gIEBJbnB1dCgpXG4gIHNldCBkZWZhdWx0RGF0ZSh2YWx1ZSkge1xuICAgIHRoaXMucHJvcHMuZGVmYXVsdERhdGUgPSB2YWx1ZTtcbiAgfVxuICBASW5wdXQoKVxuICBzZXQgbWluRGF0ZSh2YWx1ZSkge1xuICAgIHRoaXMucHJvcHMubWluRGF0ZSA9IHZhbHVlO1xuICB9XG4gIEBJbnB1dCgpXG4gIHNldCBtYXhEYXRlKHZhbHVlKSB7XG4gICAgdGhpcy5wcm9wcy5tYXhEYXRlID0gdmFsdWU7XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IHBpY2tUaW1lKHZhbHVlKSB7XG4gICAgdGhpcy5wcm9wcy5waWNrVGltZSA9IHZhbHVlO1xuICB9XG4gIEBJbnB1dCgpXG4gIHNldCB0eXBlKHZhbHVlKSB7XG4gICAgdGhpcy5wcm9wcy50eXBlID0gdmFsdWU7XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IHNob3dTaG9ydGN1dCh2YWx1ZSkge1xuICAgIHRoaXMucHJvcHMuc2hvd1Nob3J0Y3V0ID0gdmFsdWU7XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IHJvd1NpemUodmFsdWUpIHtcbiAgICB0aGlzLnByb3BzLnJvd1NpemUgPSB2YWx1ZTtcbiAgfVxuICBASW5wdXQoKVxuICBzZXQgaW5maW5pdGUodmFsdWUpIHt9XG4gIEBJbnB1dCgpXG4gIHNldCBkZWZhdWx0VmFsdWUodmFsdWUpIHtcbiAgICB0aGlzLnByb3BzLmRlZmF1bHRWYWx1ZSA9IHZhbHVlO1xuXG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLnJlY2VpdmVQcm9wcyh0aGlzLnByb3BzKTtcbiAgICB9XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IG9uU2VsZWN0KHZhbHVlKSB7XG4gICAgdGhpcy5wcm9wcy5vblNlbGVjdCA9IHZhbHVlO1xuICB9XG5cbiAgQE91dHB1dCgpXG4gIG9uQ2FuY2VsOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KClcbiAgb25Db25maXJtOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KClcbiAgb25TZWxlY3RIYXNEaXNhYmxlRGF0ZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBASG9zdEJpbmRpbmcoJ2NsYXNzJylcbiAgY2xhc3M6IHN0cmluZyA9ICdhbS1jYWxlbmRhcic7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBfbG9jYWxlUHJvdmlkZXJTZXJ2aWNlOiBMb2NhbGVQcm92aWRlclNlcnZpY2UpIHt9XG5cbiAgd3JpdGVWYWx1ZSh2YWx1ZTogRGF0ZSB8IEFycmF5PERhdGU+IHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMuX2RhdGVNb2RlbFR5cGUgPSBudWxsO1xuICAgIGlmICh2YWx1ZSAmJiB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBpZiAodmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tuZy16b3Jyby1hbnRkLW1vYmlsZV06IGNhbGVuZGFyIG5nTW9kZWwgYXJyYXkgbmVlZCBwYXJhbXMhJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnByb3BzLnR5cGUgPT09ICdvbmUnICYmIHZhbHVlLmxlbmd0aCA+PSAyKSB7XG4gICAgICAgIHRoaXMuX2RhdGVNb2RlbFR5cGUgPSAxO1xuICAgICAgICBjb25zb2xlLmVycm9yKCdbbmctem9ycm8tYW50ZC1tb2JpbGVdOiB0eXBlIGlzIG9uZSwgYnV0IG5nbW9kZWwgaGFzIG1vcmUgdGhhbiBvbmUgcGFyYW0sIGp1c3QgdXNlIGZpcnN0IG9uZScpO1xuICAgICAgICB0aGlzLm9uU2VsZWN0ZWREYXRlKHZhbHVlWzBdKTtcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHRoaXMuX2RhdGVNb2RlbFR5cGUgPSAxO1xuICAgICAgICB0aGlzLm9uU2VsZWN0ZWREYXRlKHZhbHVlWzBdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2RhdGVNb2RlbFR5cGUgPSAyO1xuICAgICAgICB0aGlzLm9uU2VsZWN0ZWREYXRlKHZhbHVlWzBdKTtcbiAgICAgICAgdGhpcy5vblNlbGVjdGVkRGF0ZSh2YWx1ZVsxXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh2YWx1ZSAmJiB2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgIHRoaXMuX2RhdGVNb2RlbFR5cGUgPSAzO1xuICAgICAgdGhpcy5vblNlbGVjdGVkRGF0ZSh2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogKGRhdGU6IERhdGUgfCBBcnJheTxEYXRlPikgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMub25DaGFuZ2VGbiA9IGZuO1xuICB9XG5cbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uVG91Y2hGbiA9IGZuO1xuICB9XG5cbiAgcmVjZWl2ZVByb3BzKG5leHRQcm9wczogQ2FsZW5kYXJQcm9wc1R5cGUpIHtcbiAgICBpZiAobmV4dFByb3BzLnZpc2libGUgJiYgbmV4dFByb3BzLmRlZmF1bHRWYWx1ZSkge1xuICAgICAgdGhpcy5zaG9ydGN1dFNlbGVjdChuZXh0UHJvcHMuZGVmYXVsdFZhbHVlWzBdLCBuZXh0UHJvcHMuZGVmYXVsdFZhbHVlWzFdLCBuZXh0UHJvcHMpO1xuICAgIH1cbiAgfVxuXG4gIHNob3dBbmltYXRpb24oKSB7XG4gICAgaWYgKHRoaXMuX2VudGVyRGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgIHRoaXMuY29udGVudEFuaW1hdGVDbGFzcyA9ICdzbGlkZUgtZW50ZXIgc2xpZGVILWVudGVyLWFjdGl2ZSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29udGVudEFuaW1hdGVDbGFzcyA9ICdzbGlkZVYtZW50ZXIgc2xpZGVWLWVudGVyLWFjdGl2ZSc7XG4gICAgfVxuICAgIHRoaXMubWFza0FuaW1hdGVDbGFzcyA9ICdmYWRlLWVudGVyIGZhZGUtZW50ZXItYWN0aXZlJztcbiAgfVxuXG4gIGhpZGVBbmltYXRpb24oKSB7XG4gICAgaWYgKHRoaXMuX2VudGVyRGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgIHRoaXMuY29udGVudEFuaW1hdGVDbGFzcyA9ICdzbGlkZUgtbGVhdmUgc2xpZGVILWxlYXZlLWFjdGl2ZSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29udGVudEFuaW1hdGVDbGFzcyA9ICdzbGlkZVYtbGVhdmUgc2xpZGVWLWxlYXZlLWFjdGl2ZSc7XG4gICAgfVxuICAgIHRoaXMubWFza0FuaW1hdGVDbGFzcyA9ICdmYWRlLWxlYXZlIGZhZGUtbGVhdmUtYWN0aXZlJztcbiAgfVxuXG4gIHNlbGVjdERhdGUgPSAoXG4gICAgZGF0ZTogRGF0ZSxcbiAgICB1c2VEYXRlVGltZSA9IGZhbHNlLFxuICAgIG9sZFN0YXRlOiB7IHN0YXJ0RGF0ZT86IERhdGU7IGVuZERhdGU/OiBEYXRlIH0gPSB7fSxcbiAgICBwcm9wcyA9IHRoaXMucHJvcHNcbiAgKSA9PiB7XG4gICAgaWYgKCFkYXRlKSB7XG4gICAgICByZXR1cm4ge30gYXMgQ2FsZW5kYXJTdGF0ZVR5cGU7XG4gICAgfVxuICAgIGxldCBuZXdTdGF0ZSA9IHt9IGFzIENhbGVuZGFyU3RhdGVUeXBlO1xuICAgIGNvbnN0IHsgdHlwZSwgcGlja1RpbWUsIGRlZmF1bHRUaW1lVmFsdWUsIGxvY2FsZSA9IHt9IGFzIERhdGVNb2RlbHMuTG9jYWxlIH0gPSBwcm9wcztcbiAgICBjb25zdCBuZXdEYXRlID0gcGlja1RpbWUgJiYgIXVzZURhdGVUaW1lID8gbWVyZ2VEYXRlVGltZShkYXRlLCBkZWZhdWx0VGltZVZhbHVlKSA6IGRhdGU7XG4gICAgY29uc3QgeyBzdGFydERhdGUsIGVuZERhdGUgfSA9IG9sZFN0YXRlO1xuXG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlICdvbmUnOlxuICAgICAgICBuZXdTdGF0ZSA9IHtcbiAgICAgICAgICAuLi5uZXdTdGF0ZSxcbiAgICAgICAgICBzdGFydERhdGU6IG5ld0RhdGUsXG4gICAgICAgICAgZGlzQ29uZmlybUJ0bjogZmFsc2VcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHBpY2tUaW1lKSB7XG4gICAgICAgICAgbmV3U3RhdGUgPSB7XG4gICAgICAgICAgICAuLi5uZXdTdGF0ZSxcbiAgICAgICAgICAgIHRpbWVQaWNrZXJUaXRsZTogbG9jYWxlLnNlbGVjdFRpbWUsXG4gICAgICAgICAgICBzaG93VGltZVBpY2tlcjogdHJ1ZVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3JhbmdlJzpcbiAgICAgICAgaWYgKCFzdGFydERhdGUgfHwgZW5kRGF0ZSkge1xuICAgICAgICAgIG5ld1N0YXRlID0ge1xuICAgICAgICAgICAgLi4ubmV3U3RhdGUsXG4gICAgICAgICAgICBzdGFydERhdGU6IG5ld0RhdGUsXG4gICAgICAgICAgICBlbmREYXRlOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBkaXNDb25maXJtQnRuOiB0cnVlXG4gICAgICAgICAgfTtcbiAgICAgICAgICBpZiAocGlja1RpbWUpIHtcbiAgICAgICAgICAgIG5ld1N0YXRlID0ge1xuICAgICAgICAgICAgICAuLi5uZXdTdGF0ZSxcbiAgICAgICAgICAgICAgdGltZVBpY2tlclRpdGxlOiBsb2NhbGUuc2VsZWN0U3RhcnRUaW1lLFxuICAgICAgICAgICAgICBzaG93VGltZVBpY2tlcjogdHJ1ZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmV3U3RhdGUgPSB7XG4gICAgICAgICAgICAuLi5uZXdTdGF0ZSxcbiAgICAgICAgICAgIHRpbWVQaWNrZXJUaXRsZTpcbiAgICAgICAgICAgICAgK25ld0RhdGUgPj0gK3N0YXJ0RGF0ZSB8fCB0aGlzLmlzU2FtZURhdGUoc3RhcnREYXRlLCBuZXdEYXRlKVxuICAgICAgICAgICAgICAgID8gbG9jYWxlLnNlbGVjdEVuZFRpbWVcbiAgICAgICAgICAgICAgICA6IGxvY2FsZS5zZWxlY3RTdGFydFRpbWUsXG4gICAgICAgICAgICBkaXNDb25maXJtQnRuOiBmYWxzZSxcbiAgICAgICAgICAgIGVuZERhdGU6XG4gICAgICAgICAgICAgIHBpY2tUaW1lICYmICF1c2VEYXRlVGltZSAmJiAoK25ld0RhdGUgPj0gK3N0YXJ0RGF0ZSB8fCB0aGlzLmlzU2FtZURhdGUoc3RhcnREYXRlLCBuZXdEYXRlKSlcbiAgICAgICAgICAgICAgICA/IG5ldyBEYXRlKCttZXJnZURhdGVUaW1lKG5ld0RhdGUsIHN0YXJ0RGF0ZSkgKyAzNjAwMDAwKVxuICAgICAgICAgICAgICAgIDogbmV3RGF0ZVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgdGhpcy53cml0ZU1vZGVsRGF0YShkYXRlKTtcbiAgICByZXR1cm4gbmV3U3RhdGU7XG4gIH07XG5cbiAgd3JpdGVNb2RlbERhdGEoZGF0ZSkge1xuICAgIGlmICh0aGlzLl9kYXRlTW9kZWxWYWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICB0aGlzLl9kYXRlTW9kZWxUaW1lID0gdGhpcy5fZGF0ZU1vZGVsVmFsdWUubGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9kYXRlTW9kZWxUaW1lID0gMDtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHRoaXMuX2RhdGVNb2RlbFR5cGUpIHtcbiAgICAgIGNhc2UgMTpcbiAgICAgICAgdGhpcy5fZGF0ZU1vZGVsVmFsdWUgPSBbZGF0ZV07XG4gICAgICAgIHRoaXMub25DaGFuZ2VGbih0aGlzLl9kYXRlTW9kZWxWYWx1ZSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICBpZiAodGhpcy5fZGF0ZU1vZGVsVGltZSA9PT0gMSkge1xuICAgICAgICAgIGlmICgrZGF0ZSA8ICt0aGlzLl9kYXRlTW9kZWxWYWx1ZVswXSkge1xuICAgICAgICAgICAgdGhpcy5fZGF0ZU1vZGVsVmFsdWUudW5zaGlmdChkYXRlKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5fZGF0ZU1vZGVsVmFsdWUucHVzaChkYXRlKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5vbkNoYW5nZUZuKHRoaXMuX2RhdGVNb2RlbFZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLl9kYXRlTW9kZWxWYWx1ZSA9IFtdO1xuICAgICAgICAgIHRoaXMuX2RhdGVNb2RlbFZhbHVlLnB1c2goZGF0ZSk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIHRoaXMuX2RhdGVNb2RlbFZhbHVlID0gZGF0ZTtcbiAgICAgICAgdGhpcy5vbkNoYW5nZUZuKHRoaXMuX2RhdGVNb2RlbFZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICBvblNlbGVjdGVkRGF0ZSA9IChkYXRlOiBEYXRlKSA9PiB7XG4gICAgY29uc3QgeyBzdGFydERhdGUsIGVuZERhdGUgfSA9IHRoaXMuc3RhdGU7XG4gICAgY29uc3QgeyBvblNlbGVjdCB9ID0gdGhpcy5wcm9wcztcblxuICAgIGlmIChvblNlbGVjdCkge1xuICAgICAgY29uc3QgdmFsdWUgPSBvblNlbGVjdChkYXRlLCBbc3RhcnREYXRlLCBlbmREYXRlXSk7XG4gICAgICBpZiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy5zaG9ydGN1dFNlbGVjdCh2YWx1ZVswXSwgdmFsdWVbMV0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5zdGF0ZSA9IHtcbiAgICAgIC4uLnRoaXMuc3RhdGUsXG4gICAgI