UNPKG

ng-zorro-antd-mobile

Version:

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

638 lines 53.7 kB
/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
import { Component, forwardRef, ViewEncapsulation, Input, Output, HostBinding, EventEmitter, ViewChild } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import zhCN from './locale/zh_CN';
import enUS from './locale/en_US';
import { LocaleProviderService } from '../locale-provider/locale-provider.service';
import { mergeDateTime, isSameDate } from './util/index';
import { takeUntil } from 'rxjs/operators';
import { CalendarDatePickerComponent } from './datepicker/datepicker.component';
import { Subject } from 'rxjs';
/**
 * @record
 */
export function CalendarStateType() { }
if (false) {
    /** @type {?} */
    CalendarStateType.prototype.showTimePicker;
    /** @type {?|undefined} */
    CalendarStateType.prototype.timePickerTitle;
    /** @type {?|undefined} */
    CalendarStateType.prototype.startDate;
    /** @type {?|undefined} */
    CalendarStateType.prototype.endDate;
    /** @type {?|undefined} */
    CalendarStateType.prototype.disConfirmBtn;
    /** @type {?|undefined} */
    CalendarStateType.prototype.clientHight;
}
export class CalendarComponent {
    /**
     * @param {?} _localeProviderService
     */
    constructor(_localeProviderService) {
        this._localeProviderService = _localeProviderService;
        this.isShow = false;
        this.showClear = false;
        this.isSameDate = isSameDate;
        this.props = (/** @type {?} */ ({
            visible: false,
            showHeader: true,
            locale: zhCN,
            pickTime: false,
            showShortcut: false,
            prefixCls: 'rmc-calendar',
            type: 'range',
            defaultTimeValue: new Date(2000, 0, 1, 8)
        }));
        this.state = (/** @type {?} */ ({
            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 = (/**
         * @param {?} date
         * @param {?=} useDateTime
         * @param {?=} oldState
         * @param {?=} props
         * @return {?}
         */
        (date, useDateTime = false, oldState = {}, props = this.props) => {
            if (!date) {
                return (/** @type {?} */ ({}));
            }
            /** @type {?} */
            let newState = (/** @type {?} */ ({}));
            const { type, pickTime, defaultTimeValue, locale = (/** @type {?} */ ({})) } = props;
            /** @type {?} */
            const newDate = pickTime && !useDateTime ? mergeDateTime(date, defaultTimeValue) : date;
            const { startDate, endDate } = oldState;
            switch (type) {
                case 'one':
                    newState = Object.assign({}, newState, { startDate: newDate, disConfirmBtn: false });
                    if (pickTime) {
                        newState = Object.assign({}, newState, { timePickerTitle: locale.selectTime, showTimePicker: true });
                    }
                    break;
                case 'range':
                    if (!startDate || endDate) {
                        newState = Object.assign({}, newState, { startDate: newDate, endDate: undefined, disConfirmBtn: true });
                        if (pickTime) {
                            newState = Object.assign({}, newState, { timePickerTitle: locale.selectStartTime, showTimePicker: true });
                        }
                    }
                    else {
                        newState = Object.assign({}, 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 = (/**
         * @param {?} date
         * @return {?}
         */
        (date) => {
            const { startDate, endDate } = this.state;
            const { onSelect } = this.props;
            if (onSelect) {
                /** @type {?} */
                const value = onSelect(date, [startDate, endDate]);
                if (value) {
                    this.shortcutSelect(value[0], value[1]);
                    return;
                }
            }
            this.state = Object.assign({}, this.state, this.selectDate(date, false, { startDate, endDate }));
            this.showClear = !!this.state.startDate;
        });
        this.triggerSelectHasDisableDate = (/**
         * @param {?} date
         * @return {?}
         */
        (date) => {
            this.triggerClear();
            if (this.onSelectHasDisableDate) {
                this.onSelectHasDisableDate.emit(date);
            }
        });
        this.onClose = (/**
         * @return {?}
         */
        () => {
            this.state = (/** @type {?} */ ({
                showTimePicker: false,
                timePickerTitle: '',
                startDate: undefined,
                endDate: undefined,
                disConfirmBtn: true,
                clientHight: 0
            }));
            this.showClear = !!this.state.startDate;
        });
        this.triggerConfirm = (/**
         * @return {?}
         */
        () => {
            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 = (/**
         * @return {?}
         */
        () => {
            // 清除数据做延迟,否则同步刷新数据导致报错
            setTimeout((/**
             * @return {?}
             */
            () => {
                this.state = Object.assign({}, this.state, { startDate: undefined, endDate: undefined, showTimePicker: false });
                if (this.props.onClear) {
                    this.props.onClear();
                }
                this.showClear = !!this.state.startDate;
            }), 0);
        });
        this.onTimeChange = (/**
         * @param {?} date
         * @return {?}
         */
        (date) => {
            const { startDate, endDate } = this.state;
            if (endDate) {
                this.state.endDate = date;
            }
            else if (startDate) {
                this.state.startDate = date;
            }
        });
        this.shortcutSelect = (/**
         * @param {?} startDate
         * @param {?} endDate
         * @param {?=} props
         * @return {?}
         */
        (startDate, endDate, props = this.props) => {
            this.state = Object.assign({}, this.state, { startDate, showTimePicker: false }, this.selectDate(endDate, true, { startDate }, props));
            this.showClear = !!this.state.startDate;
        });
        this.setClientHeight = (/**
         * @param {?} height
         * @return {?}
         */
        (height) => {
            this.state.clientHight = height;
        });
        this.onChangeFn = (/**
         * @return {?}
         */
        () => { });
        this.onTouchFn = (/**
         * @return {?}
         */
        () => { });
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set locale(value) {
        if (value === 'enUS') {
            this.props.locale = enUS;
        }
        else if (value === 'zhCN') {
            this.props.locale = zhCN;
        }
        this._unsubscribe$.next();
        this._unsubscribe$.complete();
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set defaultTimeValue(value) {
        if (value) {
            this.props.defaultTimeValue = value;
        }
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set prefixCls(value) {
        if (value) {
            this.props.prefixCls = value;
        }
    }
    /**
     * @param {?} value
     * @return {?}
     */
    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';
        }
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set visible(value) {
        this.props.visible = value;
        if (value === true || value === 'true') {
            this.showAnimation();
            this.isShow = true;
        }
        else {
            this.hideAnimation();
            setTimeout((/**
             * @return {?}
             */
            () => {
                this.isShow = false;
            }), 300);
        }
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set getDateExtra(value) {
        this.props.getDateExtra = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set defaultDate(value) {
        this.props.defaultDate = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set minDate(value) {
        this.props.minDate = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set maxDate(value) {
        this.props.maxDate = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set pickTime(value) {
        this.props.pickTime = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set type(value) {
        this.props.type = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set showShortcut(value) {
        this.props.showShortcut = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set rowSize(value) {
        this.props.rowSize = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set infinite(value) { }
    /**
     * @param {?} value
     * @return {?}
     */
    set defaultValue(value) {
        this.props.defaultValue = value;
        if (value) {
            this.receiveProps(this.props);
        }
    }
    /**
     * @param {?} value
     * @return {?}
     */
    set onSelect(value) {
        this.props.onSelect = value;
    }
    /**
     * @param {?} value
     * @return {?}
     */
    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);
        }
    }
    /**
     * @param {?} fn
     * @return {?}
     */
    registerOnChange(fn) {
        this.onChangeFn = fn;
    }
    /**
     * @param {?} fn
     * @return {?}
     */
    registerOnTouched(fn) {
        this.onTouchFn = fn;
    }
    /**
     * @param {?} nextProps
     * @return {?}
     */
    receiveProps(nextProps) {
        if (nextProps.visible && nextProps.defaultValue) {
            this.shortcutSelect(nextProps.defaultValue[0], nextProps.defaultValue[1], nextProps);
        }
    }
    /**
     * @return {?}
     */
    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';
    }
    /**
     * @return {?}
     */
    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';
    }
    /**
     * @param {?} date
     * @return {?}
     */
    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;
        }
    }
    /**
     * @return {?}
     */
    triggerCancel() {
        if (this.props.onCancel) {
            this.props.onCancel();
        }
        this.onClose();
        if (this.onCancel) {
            this.onCancel.emit();
        }
    }
    /**
     * @return {?}
     */
    ngOnInit() {
        /** @type {?} */
        const defaultValue = this.props.defaultValue;
        if (defaultValue) {
            this.state = Object.assign({}, this.state, this.selectDate(defaultValue[1], true, { startDate: defaultValue[0] }, this.props));
        }
        this._localeProviderService.localeChange.pipe(takeUntil(this._unsubscribe$)).subscribe((/**
         * @param {?} _
         * @return {?}
         */
        _ => {
            this.props.locale = (/** @type {?} */ (Object.assign({}, this._localeProviderService.getLocaleSubObj('Calendar'))));
        }));
    }
    /**
     * @return {?}
     */
    ngOnDestroy() {
        this._unsubscribe$.next();
        this._unsubscribe$.complete();
    }
}
CalendarComponent.decorators = [
    { type: Component, args: [{
                selector: 'Calendar, nzm-calendar',
                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      [startDateTime]=\"state.startDate\"\n      [endDateTime]=\"state.endDate\"\n      [propsData]=\"props\"\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",
                encapsulation: ViewEncapsulation.None,
                providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/**
                         * @return {?}
                         */
                        () => CalendarComponent)), multi: true }]
            }] }
];
/** @nocollapse */
CalendarComponent.ctorParameters = () => [
    { type: LocaleProviderService }
];
CalendarComponent.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',] }]
};
if (false) {
    /** @type {?} */
    CalendarComponent.prototype.isShow;
    /** @type {?} */
    CalendarComponent.prototype.contentAnimateClass;
    /** @type {?} */
    CalendarComponent.prototype.maskAnimateClass;
    /** @type {?} */
    CalendarComponent.prototype.showClear;
    /** @type {?} */
    CalendarComponent.prototype.isSameDate;
    /** @type {?} */
    CalendarComponent.prototype.props;
    /** @type {?} */
    CalendarComponent.prototype.state;
    /**
     * @type {?}
     * @private
     */
    CalendarComponent.prototype._unsubscribe$;
    /**
     * @type {?}
     * @private
     */
    CalendarComponent.prototype._enterDirection;
    /**
     * @type {?}
     * @private
     */
    CalendarComponent.prototype._dateModelType;
    /**
     * @type {?}
     * @private
     */
    CalendarComponent.prototype._dateModelValue;
    /**
     * @type {?}
     * @private
     */
    CalendarComponent.prototype._dateModelTime;
    /** @type {?} */
    CalendarComponent.prototype.datepicker;
    /** @type {?} */
    CalendarComponent.prototype.onCancel;
    /** @type {?} */
    CalendarComponent.prototype.onConfirm;
    /** @type {?} */
    CalendarComponent.prototype.onSelectHasDisableDate;
    /** @type {?} */
    CalendarComponent.prototype.class;
    /** @type {?} */
    CalendarComponent.prototype.selectDate;
    /** @type {?} */
    CalendarComponent.prototype.onSelectedDate;
    /** @type {?} */
    CalendarComponent.prototype.triggerSelectHasDisableDate;
    /** @type {?} */
    CalendarComponent.prototype.onClose;
    /** @type {?} */
    CalendarComponent.prototype.triggerConfirm;
    /** @type {?} */
    CalendarComponent.prototype.triggerClear;
    /** @type {?} */
    CalendarComponent.prototype.onTimeChange;
    /** @type {?} */
    CalendarComponent.prototype.shortcutSelect;
    /** @type {?} */
    CalendarComponent.prototype.setClientHeight;
    /**
     * @type {?}
     * @private
     */
    CalendarComponent.prototype.onChangeFn;
    /**
     * @type {?}
     * @private
     */
    CalendarComponent.prototype.onTouchFn;
    /**
     * @type {?}
     * @private
     */
    CalendarComponent.prototype._localeProviderService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmctem9ycm8tYW50ZC1tb2JpbGUvIiwic291cmNlcyI6WyJjYWxlbmRhci9jYWxlbmRhci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsVUFBVSxFQUdWLGlCQUFpQixFQUNqQixLQUFLLEVBQ0wsTUFBTSxFQUNOLFdBQVcsRUFDWCxZQUFZLEVBQ1osU0FBUyxFQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUV6RSxPQUFPLElBQUksTUFBTSxnQkFBZ0IsQ0FBQztBQUNsQyxPQUFPLElBQUksTUFBTSxnQkFBZ0IsQ0FBQztBQUVsQyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQztBQUNuRixPQUFPLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUN6RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0MsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDaEYsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQzs7OztBQUkvQix1Q0FPQzs7O0lBTkMsMkNBQXdCOztJQUN4Qiw0Q0FBeUI7O0lBQ3pCLHNDQUFpQjs7SUFDakIsb0NBQWU7O0lBQ2YsMENBQXdCOztJQUN4Qix3Q0FBcUI7O0FBU3ZCLE1BQU0sT0FBTyxpQkFBaUI7Ozs7SUEwSTVCLFlBQW9CLHNCQUE2QztRQUE3QywyQkFBc0IsR0FBdEIsc0JBQXNCLENBQXVCO1FBeklqRSxXQUFNLEdBQVksS0FBSyxDQUFDO1FBR3hCLGNBQVMsR0FBWSxLQUFLLENBQUM7UUFDM0IsZUFBVSxHQUFhLFVBQVUsQ0FBQztRQUVsQyxVQUFLLEdBQUcsbUJBQUE7WUFDTixPQUFPLEVBQUUsS0FBSztZQUNkLFVBQVUsRUFBRSxJQUFJO1lBQ2hCLE1BQU0sRUFBRSxJQUFJO1lBQ1osUUFBUSxFQUFFLEtBQUs7WUFDZixZQUFZLEVBQUUsS0FBSztZQUNuQixTQUFTLEVBQUUsY0FBYztZQUN6QixJQUFJLEVBQUUsT0FBTztZQUNiLGdCQUFnQixFQUFFLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUMxQyxFQUFxQixDQUFDO1FBRXZCLFVBQUssR0FBRyxtQkFBQTtZQUNOLGNBQWMsRUFBRSxLQUFLO1lBQ3JCLGVBQWUsRUFBRSxFQUFFO1lBQ25CLFNBQVMsRUFBRSxTQUFTO1lBQ3BCLE9BQU8sRUFBRSxTQUFTO1lBQ2xCLGFBQWEsRUFBRSxJQUFJO1lBQ25CLFdBQVcsRUFBRSxDQUFDO1NBQ2YsRUFBcUIsQ0FBQztRQUVmLGtCQUFhLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUlwQyxtQkFBYyxHQUFXLENBQUMsQ0FBQztRQWtHbkMsYUFBUSxHQUFzQixJQUFJLFlBQVksRUFBTyxDQUFDO1FBRXRELGNBQVMsR0FBc0IsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUV2RCwyQkFBc0IsR0FBc0IsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUdwRSxVQUFLLEdBQVcsYUFBYSxDQUFDO1FBNkQ5QixlQUFVOzs7Ozs7O1FBQUcsQ0FDWCxJQUFVLEVBQ1YsV0FBVyxHQUFHLEtBQUssRUFDbkIsV0FBaUQsRUFBRSxFQUNuRCxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFDbEIsRUFBRTtZQUNGLElBQUksQ0FBQyxJQUFJLEVBQUU7Z0JBQ1QsT0FBTyxtQkFBQSxFQUFFLEVBQXFCLENBQUM7YUFDaEM7O2dCQUNHLFFBQVEsR0FBRyxtQkFBQSxFQUFFLEVBQXFCO2tCQUNoQyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxHQUFHLG1CQUFBLEVBQUUsRUFBcUIsRUFBRSxHQUFHLEtBQUs7O2tCQUM5RSxPQUFPLEdBQUcsUUFBUSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsSUFBSSxFQUFFLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUk7a0JBQ2pGLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxHQUFHLFFBQVE7WUFFdkMsUUFBUSxJQUFJLEVBQUU7Z0JBQ1osS0FBSyxLQUFLO29CQUNSLFFBQVEscUJBQ0gsUUFBUSxJQUNYLFNBQVMsRUFBRSxPQUFPLEVBQ2xCLGFBQWEsRUFBRSxLQUFLLEdBQ3JCLENBQUM7b0JBQ0YsSUFBSSxRQUFRLEVBQUU7d0JBQ1osUUFBUSxxQkFDSCxRQUFRLElBQ1gsZUFBZSxFQUFFLE1BQU0sQ0FBQyxVQUFVLEVBQ2xDLGNBQWMsRUFBRSxJQUFJLEdBQ3JCLENBQUM7cUJBQ0g7b0JBQ0QsTUFBTTtnQkFFUixLQUFLLE9BQU87b0JBQ1YsSUFBSSxDQUFDLFNBQVMsSUFBSSxPQUFPLEVBQUU7d0JBQ3pCLFFBQVEscUJBQ0gsUUFBUSxJQUNYLFNBQVMsRUFBRSxPQUFPLEVBQ2xCLE9BQU8sRUFBRSxTQUFTLEVBQ2xCLGFBQWEsRUFBRSxJQUFJLEdBQ3BCLENBQUM7d0JBQ0YsSUFBSSxRQUFRLEVBQUU7NEJBQ1osUUFBUSxxQkFDSCxRQUFRLElBQ1gsZUFBZSxFQUFFLE1BQU0sQ0FBQyxlQUFlLEVBQ3ZDLGNBQWMsRUFBRSxJQUFJLEdBQ3JCLENBQUM7eUJBQ0g7cUJBQ0Y7eUJBQU07d0JBQ0wsUUFBUSxxQkFDSCxRQUFRLElBQ1gsZUFBZSxFQUNiLENBQUMsT0FBTyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQztnQ0FDM0QsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxhQUFhO2dDQUN0QixDQUFDLENBQUMsTUFBTSxDQUFDLGVBQWUsRUFDNUIsYUFBYSxFQUFFLEtBQUssRUFDcEIsT0FBTyxFQUNMLFFBQVEsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLENBQUMsT0FBTyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dDQUN6RixDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxhQUFhLENBQUMsT0FBTyxFQUFFLFNBQVMsQ0FBQyxHQUFHLE9BQU8sQ0FBQztnQ0FDeEQsQ0FBQyxDQUFDLE9BQU8sR0FDZCxDQUFDO3FCQUNIO29CQUNELE1BQU07YUFDVDtZQUVELElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDMUIsT0FBTyxRQUFRLENBQUM7UUFDbEIsQ0FBQyxFQUFBO1FBb0NELG1CQUFjOzs7O1FBQUcsQ0FBQyxJQUFVLEVBQUUsRUFBRTtrQkFDeEIsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUs7a0JBQ25DLEVBQUUsUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUs7WUFFL0IsSUFBSSxRQUFRLEVBQUU7O3NCQUNOLEtBQUssR0FBRyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUNsRCxJQUFJLEtBQUssRUFBRTtvQkFDVCxJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDeEMsT0FBTztpQkFDUjthQUNGO1lBRUQsSUFBSSxDQUFDLEtBQUsscUJBQ0wsSUFBSSxDQUFDLEtBQUssRUFDVixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FDeEQsQ0FBQztZQUVGLElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO1FBQzFDLENBQUMsRUFBQTtRQUVELGdDQUEyQjs7OztRQUFHLENBQUMsSUFBWSxFQUFFLEVBQUU7WUFDN0MsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3BCLElBQUksSUFBSSxDQUFDLHNCQUFzQixFQUFFO2dCQUMvQixJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ3hDO1FBQ0gsQ0FBQyxFQUFBO1FBRUQsWUFBTzs7O1FBQUcsR0FBRyxFQUFFO1lBQ2IsSUFBSSxDQUFDLEtBQUssR0FBRyxtQkFBQTtnQkFDWCxjQUFjLEVBQUUsS0FBSztnQkFDckIsZUFBZSxFQUFFLEVBQUU7Z0JBQ25CLFNBQVMsRUFBRSxTQUFTO2dCQUNwQixPQUFPLEVBQUUsU0FBUztnQkFDbEIsYUFBYSxFQUFFLElBQUk7Z0JBQ25CLFdBQVcsRUFBRSxDQUFDO2FBQ2YsRUFBcUIsQ0FBQztZQUN2QixJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztRQUMxQyxDQUFDLEVBQUE7UUFFRCxtQkFBYzs7O1FBQUcsR0FBRyxFQUFFO2tCQUNkLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLO1lBQ3pDLElBQUksU0FBUyxJQUFJLE9BQU8sSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLE9BQU8sRUFBRTtnQkFDakQsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUNmLE9BQU8sSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUM7YUFDMUY7WUFDRCxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7Z0JBQ2xCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7YUFDN0M7WUFDRCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDakIsQ0FBQyxFQUFBO1FBWUQsaUJBQVk7OztRQUFHLEdBQUcsRUFBRTtZQUNsQix1QkFBdUI7WUFDdkIsVUFBVTs7O1lBQUMsR0FBRyxFQUFFO2dCQUNkLElBQUksQ0FBQyxLQUFLLHFCQUNMLElBQUksQ0FBQyxLQUFLLEVBQ1YsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxDQUN2RSxDQUFDO2dCQUNGLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUU7b0JBQ3RCLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7aUJBQ3RCO2dCQUNELElBQUksQ0FBQyxTQUFTLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDO1lBQzFDLENBQUMsR0FBRSxDQUFDLENBQUMsQ0FBQztRQUNSLENBQUMsRUFBQTtRQUVELGlCQUFZOzs7O1FBQUcsQ0FBQyxJQUFVLEVBQUUsRUFBRTtrQkFDdEIsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUs7WUFDekMsSUFBSSxPQUFPLEVBQUU7Z0JBQ1gsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO2FBQzNCO2lCQUFNLElBQUksU0FBUyxFQUFFO2dCQUNwQixJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUM7YUFDN0I7UUFDSCxDQUFDLEVBQUE7UUFFRCxtQkFBYzs7Ozs7O1FBQUcsQ0FBQyxTQUFlLEVBQUUsT0FBYSxFQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDdEUsSUFBSSxDQUFDLEtBQUsscUJBQ0wsSUFBSSxDQUFDLEtBQUssRUFDVixFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUUsS0FBSyxFQUFFLEVBQ3BDLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUN4RCxDQUFDO1lBQ0YsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUM7UUFDMUMsQ0FBQyxFQUFBO1FBRUQsb0JBQWU7Ozs7UUFBRyxDQUFDLE1BQWMsRUFBRSxFQUFFO1lBQ25DLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQztRQUNsQyxDQUFDLEVBQUE7UUFxQk8sZUFBVTs7O1FBQXVDLEdBQUcsRUFBRSxHQUFFLENBQUMsRUFBQztRQUMxRCxjQUFTOzs7UUFBdUMsR0FBRyxFQUFFLEdBQUUsQ0FBQyxFQUFDO0lBcFJHLENBQUM7Ozs7O0lBdEdyRSxJQUNJLE1BQU0sQ0FBQyxLQUFLO1FBQ2QsSUFBSSxLQUFLLEtBQUssTUFBTSxFQUFFO1lBQ3BCLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztTQUMxQjthQUFNLElBQUksS0FBSyxLQUFLLE1BQU0sRUFBRTtZQUMzQixJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7U0FDMUI7UUFFRCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDaEMsQ0FBQzs7Ozs7SUFDRCxJQUNJLGdCQUFnQixDQUFDLEtBQUs7UUFDeEIsSUFBSSxLQUFLLEVBQUU7WUFDVCxJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQztTQUNyQztJQUNILENBQUM7Ozs7O0lBQ0QsSUFDSSxTQUFTLENBQUMsS0FBSztRQUNqQixJQUFJLEtBQUssRUFBRTtZQUNULElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztTQUM5QjtJQUNILENBQUM7Ozs7O0lBQ0QsSUFDSSxjQUFjLENBQUMsS0FBSztRQUN0QixJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztRQUM3QixJQUFJLElBQUksQ0FBQyxlQUFlLEtBQUssWUFBWSxFQUFFO1lBQ3pDLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxrQ0FBa0MsQ0FBQztTQUMvRDthQUFNO1lBQ0wsSUFBSSxDQUFDLG1CQUFtQixHQUFHLGtDQUFrQyxDQUFDO1NBQy9EO0lBQ0gsQ0FBQzs7Ozs7SUFDRCxJQUNJLE9BQU8sQ0FBQyxLQUFLO1FBQ2YsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQzNCLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxLQUFLLEtBQUssTUFBTSxFQUFFO1lBQ3RDLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNyQixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztTQUNwQjthQUFNO1lBQ0wsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3JCLFVBQVU7OztZQUFDLEdBQUcsRUFBRTtnQkFDZCxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztZQUN0QixDQUFDLEdBQUUsR0FBRyxDQUFDLENBQUM7U0FDVDtJQUNILENBQUM7Ozs7O0lBQ0QsSUFDSSxZQUFZLENBQUMsS0FBSztRQUNwQixJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7SUFDbEMsQ0FBQzs7Ozs7SUFDRCxJQUNJLFdBQVcsQ0FBQyxLQUFLO1FBQ25CLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQztJQUNqQyxDQUFDOzs7OztJQUNELElBQ0ksT0FBTyxDQUFDLEtBQUs7UUFDZixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7SUFDN0IsQ0FBQzs7Ozs7SUFDRCxJQUNJLE9BQU8sQ0FBQyxLQUFLO1FBQ2YsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO0lBQzdCLENBQUM7Ozs7O0lBQ0QsSUFDSSxRQUFRLENBQUMsS0FBSztRQUNoQixJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7SUFDOUIsQ0FBQzs7Ozs7SUFDRCxJQUNJLElBQUksQ0FBQyxLQUFLO1FBQ1osSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDO0lBQzFCLENBQUM7Ozs7O0lBQ0QsSUFDSSxZQUFZLENBQUMsS0FBSztRQUNwQixJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7SUFDbEMsQ0FBQzs7Ozs7SUFDRCxJQUNJLE9BQU8sQ0FBQyxLQUFLO1FBQ2YsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO0lBQzdCLENBQUM7Ozs7O0lBQ0QsSUFDSSxRQUFRLENBQUMsS0FBSyxJQUFHLENBQUM7Ozs7O0lBQ3RCLElBQ0ksWUFBWSxDQUFDLEtBQUs7UUFDcEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1FBRWhDLElBQUksS0FBSyxFQUFFO1lBQ1QsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDL0I7SUFDSCxDQUFDOzs7OztJQUNELElBQ0ksUUFBUSxDQUFDLEtBQUs7UUFDaEIsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO0lBQzlCLENBQUM7Ozs7O0lBY0QsVUFBVSxDQUFDLEtBQWdDO1FBQ3pDLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDO1FBQzNCLElBQUksS0FBSyxJQUFJLEtBQUssWUFBWSxLQUFLLEVBQUU7WUFDbkMsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtnQkFDdEIsT0FBTyxDQUFDLEtBQUssQ0FBQyw2REFBNkQsQ0FBQyxDQUFDO2dCQUM3RSxPQUFPO2FBQ1I7WUFDRCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLEtBQUssSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRTtnQkFDbEQsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUM7Z0JBQ3hCLE9BQU8sQ0FBQyxLQUFLLENBQUMsOEZBQThGLENBQUMsQ0FBQztnQkFDOUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUMvQjtpQkFBTSxJQUFJLEtBQUssQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO2dCQUM3QixJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsQ0FBQztnQkFDeEIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUMvQjtpQkFBTTtnQkFDTCxJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsQ0FBQztnQkFDeEIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDOUIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUMvQjtTQUNGO2FBQU0sSUFBSSxLQUFLLElBQUksS0FBSyxZQUFZLElBQUksRUFBRTtZQUN6QyxJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsQ0FBQztZQUN4QixJQUFJLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQzVCO0lBQ0gsQ0FBQzs7Ozs7SUFFRCxnQkFBZ0IsQ0FBQyxFQUFzQztRQUNyRCxJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQztJQUN2QixDQUFDOzs7OztJQUVELGlCQUFpQixDQUFDLEVBQWM7UUFDOUIsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7SUFDdEIsQ0FBQzs7Ozs7SUFFRCxZQUFZLENBQUMsU0FBNEI7UUFDdkMsSUFBSSxTQUFTLENBQUMsT0FBTyxJQUFJLFNBQVMsQ0FBQyxZQUFZLEVBQUU7WUFDL0MsSUFBSSxDQUFDLGNBQWMsQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsU0FBUyxDQUFDLENBQUM7U0FDdEY7SUFDSCxDQUFDOzs7O0lBRUQsYUFBYTtRQUNYLElBQUksSUFBSSxDQUFDLGVBQWUsS0FBSyxZQUFZLEVBQUU7WUFDekMsSUFBSSxDQUFDLG1CQUFtQixHQUFHLGtDQUFrQyxDQUFDO1NBQy9EO2FBQU07WUFDTCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsa0NBQWtDLENBQUM7U0FDL0Q7UUFDRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsOEJBQThCLENBQUM7SUFDekQsQ0FBQzs7OztJQUVELGFBQWE7UUFDWCxJQUFJLElBQUksQ0FBQyxlQUFlLEtBQUssWUFBWSxFQUFFO1lBQ3pDLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxrQ0FBa0MsQ0FBQztTQUMvRDthQUFNO1lBQ0wsSUFBSSxDQUFDLG1CQUFtQixHQUFHLGtDQUFrQyxDQUFDO1NBQy9EO1FBQ0QsSUFBSSxDQUFDLGdCQUFnQixHQUFHLDhCQUE4QixDQUFDO0lBQ3pELENBQUM7Ozs7O0lBb0VELGNBQWMsQ0FBQyxJQUFJO1FBQ2pCLElBQUksSUFBSSxDQUFDLGVBQWUsWUFBWSxLQUFLLEVBQUU7WUFDekMsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQztTQUNuRDthQUFNO1lBQ0wsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUM7U0FDekI7UUFFRCxRQUFRLElBQUksQ0FBQyxjQUFjLEVBQUU7WUFDM0IsS0FBSyxDQUFDO2dCQUNKLElBQUksQ0FBQyxlQUFlLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDOUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7Z0JBQ3RDLE1BQU07WUFDUixLQUFLLENBQUM7Z0JBQ0osSUFBSSxJQUFJLENBQUMsY0FBYyxLQUFLLENBQUMsRUFBRTtvQkFDN0IsSUFBSSxDQUFDLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLEVBQUU7d0JBQ3BDLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO3FCQUNwQzt5QkFBTTt3QkFDTCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztxQkFDakM7b0JBQ0QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7aUJBQ3ZDO3FCQUFNO29CQUNMLElBQUksQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO29CQUMxQixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztpQkFDakM7Z0JBQ0QsTUFBTTtZQUNSLEtBQUssQ0FBQztnQkFDSixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQztnQkFDNUIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7Z0JBQ3RDLE1BQU07WUFDUjtnQkFDRSxNQUFNO1NBQ1Q7SUFDSCxDQUFDOzs7O0lBcURELGFBQWE7UUFDWCxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFO1lBQ3ZCLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUM7U0FDdkI7UUFDRCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDZixJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDakIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUN0QjtJQUNILENBQUM7Ozs7SUFzQ0QsUUFBUTs7Y0FDQSxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZO1FBQzVDLElBQUksWUFBWSxFQUFFO1lBQ2hCLElBQUksQ0FBQyxLQUFLLHFCQUNMLElBQUksQ0FBQyxLQUFLLEVBQ1YsSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FDdEYsQ0FBQztTQUNIO1FBRUQsSUFBSSxDQUFDLHNCQUFzQixDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLFNBQVM7Ozs7UUFBQyxDQUFDLENBQUMsRUFBRTtZQUN6RixJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxxQ0FBSyxJQUFJLENBQUMsc0JBQXNCLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxHQUF1QixDQUFDO1FBQzFHLENBQUMsRUFBQyxDQUFDO0lBQ0wsQ0FBQzs7OztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDaEMsQ0FBQzs7O1lBamFGLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsd0JBQXdCO2dCQUNsQyw4ekRBQXdDO2dCQUN4QyxhQUFhLEVBQUUsaUJBQWlCLENBQUMsSUFBSTtnQkFDckMsU0FBUyxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLFVBQVU7Ozt3QkFBQyxHQUFHLEVBQUUsQ0FBQyxpQkFBaUIsRUFBQyxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsQ0FBQzthQUMzRzs7OztZQXRCUSxxQkFBcUI7Ozt5QkF3RDNCLFNBQVMsU0FBQywyQkFBMkI7cUJBR3JDLEtBQUs7K0JBV0wsS0FBSzt3QkFNTCxLQUFLOzZCQU1MLEtBQUs7c0JBU0wsS0FBSzsyQkFhTCxLQUFLOzBCQUlMLEtBQUs7c0JBSUwsS0FBSztzQkFJTCxLQUFLO3VCQUlMLEtBQUs7bUJBSUwsS0FBSzsyQkFJTCxLQUFLO3NCQUlMLEtBQUs7dUJBSUwsS0FBSzsyQkFFTCxLQUFLO3VCQVFMLEtBQUs7dUJBS0wsTUFBTTt3QkFFTixNQUFNO3FDQUVOLE1BQU07b0JBR04sV0FBVyxTQUFDLE9BQU87Ozs7SUF0SXBCLG1DQUF3Qjs7SUFDeEIsZ0RBQTRCOztJQUM1Qiw2Q0FBeUI7O0lBQ3pCLHNDQUEyQjs7SUFDM0IsdUNBQWtDOztJQUVsQyxrQ0FTdUI7O0lBRXZCLGtDQU91Qjs7Ozs7SUFFdkIsMENBQTRDOzs7OztJQUM1Qyw0Q0FBZ0M7Ozs7O0lBQ2hDLDJDQUErQjs7Ozs7SUFDL0IsNENBQTZCOzs7OztJQUM3QiwyQ0FBbUM7O0lBRW5DLHVDQUN3Qzs7SUE4RnhDLHFDQUNzRDs7SUFDdEQsc0NBQ3VEOztJQUN2RCxtREFDb0U7O0lBRXBFLGtDQUM4Qjs7SUE2RDlCLHVDQWdFQzs7SUFvQ0QsMkNBa0JDOztJQUVELHdEQUtDOztJQUVELG9DQVVDOztJQUVELDJDQVVDOztJQVlELHlDQVlDOztJQUVELHlDQU9DOztJQUVELDJDQU9DOztJQUVELDRDQUVDOzs7OztJQXFCRCx1Q0FBa0U7Ozs7O0lBQ2xFLHNDQUFpRTs7Ozs7SUFwUnJELG1EQUFxRCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgZm9yd2FyZFJlZixcbiAgT25Jbml0LFxuICBPbkRlc3Ryb3ksXG4gIFZpZXdFbmNhcHN1bGF0aW9uLFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBIb3N0QmluZGluZyxcbiAgRXZlbnRFbWl0dGVyLFxuICBWaWV3Q2hpbGRcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBEYXRlTW9kZWxzIH0gZnJvbSAnLi9kYXRlL0RhdGFUeXBlcyc7XG5pbXBvcnQgemhDTiBmcm9tICcuL2xvY2FsZS96aF9DTic7XG5pbXBvcnQgZW5VUyBmcm9tICcuL2xvY2FsZS9lbl9VUyc7XG5pbXBvcnQgeyBDYWxlbmRhclByb3BzVHlwZSB9IGZyb20gJy4vY2FsZW5kYXIucHJvcHMuY29tcG9uZW50JztcbmltcG9ydCB7IExvY2FsZVByb3ZpZGVyU2VydmljZSB9IGZyb20gJy4uL2xvY2FsZS1wcm92aWRlci9sb2NhbGUtcHJvdmlkZXIuc2VydmljZSc7XG5pbXBvcnQgeyBtZXJnZURhdGVUaW1lLCBpc1NhbWVEYXRlIH0gZnJvbSAnLi91dGlsL2luZGV4JztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IENhbGVuZGFyRGF0ZVBpY2tlckNvbXBvbmVudCB9IGZyb20gJy4vZGF0ZXBpY2tlci9kYXRlcGlja2VyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cbmV4cG9ydCB7IENhbGVuZGFyUHJvcHNUeXBlIH07XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FsZW5kYXJTdGF0ZVR5cGUge1xuICBzaG93VGltZVBpY2tlcjogYm9vbGVhbjtcbiAgdGltZVBpY2tlclRpdGxlPzogc3RyaW5nO1xuICBzdGFydERhdGU/OiBEYXRlO1xuICBlbmREYXRlPzogRGF0ZTtcbiAgZGlzQ29uZmlybUJ0bj86IGJvb2xlYW47XG4gIGNsaWVudEhpZ2h0PzogbnVtYmVyO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdDYWxlbmRhciwgbnptLWNhbGVuZGFyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2NhbGVuZGFyLmNvbXBvbmVudC5odG1sJyxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgcHJvdmlkZXJzOiBbeyBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUiwgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gQ2FsZW5kYXJDb21wb25lbnQpLCBtdWx0aTogdHJ1ZSB9XVxufSlcbmV4cG9ydCBjbGFzcyBDYWxlbmRhckNvbXBvbmVudCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBPbkluaXQsIE9uRGVzdHJveSB7XG4gIGlzU2hvdzogYm9vbGVhbiA9IGZhbHNlO1xuICBjb250ZW50QW5pbWF0ZUNsYXNzOiBzdHJpbmc7XG4gIG1hc2tBbmltYXRlQ2xhc3M6IHN0cmluZztcbiAgc2hvd0NsZWFyOiBib29sZWFuID0gZmFsc2U7XG4gIGlzU2FtZURhdGU6IEZ1bmN0aW9uID0gaXNTYW1lRGF0ZTtcblxuICBwcm9wcyA9IHtcbiAgICB2aXNpYmxlOiBmYWxzZSxcbiAgICBzaG93SGVhZGVyOiB0cnVlLFxuICAgIGxvY2FsZTogemhDTixcbiAgICBwaWNrVGltZTogZmFsc2UsXG4gICAgc2hvd1Nob3J0Y3V0OiBmYWxzZSxcbiAgICBwcmVmaXhDbHM6ICdybWMtY2FsZW5kYXInLFxuICAgIHR5cGU6ICdyYW5nZScsXG4gICAgZGVmYXVsdFRpbWVWYWx1ZTogbmV3IERhdGUoMjAwMCwgMCwgMSwgOClcbiAgfSBhcyBDYWxlbmRhclByb3BzVHlwZTtcblxuICBzdGF0ZSA9IHtcbiAgICBzaG93VGltZVBpY2tlcjogZmFsc2UsXG4gICAgdGltZVBpY2tlclRpdGxlOiAnJyxcbiAgICBzdGFydERhdGU6IHVuZGVmaW5lZCxcbiAgICBlbmREYXRlOiB1bmRlZmluZWQsXG4gICAgZGlzQ29uZmlybUJ0bjogdHJ1ZSxcbiAgICBjbGllbnRIaWdodDogMFxuICB9IGFzIENhbGVuZGFyU3RhdGVUeXBlO1xuXG4gIHByaXZhdGUgX3Vuc3Vic2NyaWJlJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgX2VudGVyRGlyZWN0aW9uOiBzdHJpbmc7XG4gIHByaXZhdGUgX2RhdGVNb2RlbFR5cGU6IG51bWJlcjtcbiAgcHJpdmF0ZSBfZGF0ZU1vZGVsVmFsdWU6IGFueTtcbiAgcHJpdmF0ZSBfZGF0ZU1vZGVsVGltZTogbnVtYmVyID0gMDtcblxuICBAVmlld0NoaWxkKENhbGVuZGFyRGF0ZVBpY2tlckNvbXBvbmVudClcbiAgZGF0ZXBpY2tlcjogQ2FsZW5kYXJEYXRlUGlja2VyQ29tcG9uZW50O1xuXG4gIEBJbnB1dCgpXG4gIHNldCBsb2NhbGUodmFsdWUpIHtcbiAgICBpZiAodmFsdWUgPT09ICdlblVTJykge1xuICAgICAgdGhpcy5wcm9wcy5sb2NhbGUgPSBlblVTO1xuICAgIH0gZWxzZSBpZiAodmFsdWUgPT09ICd6aENOJykge1xuICAgICAgdGhpcy5wcm9wcy5sb2NhbGUgPSB6aENOO1xuICAgIH1cblxuICAgIHRoaXMuX3Vuc3Vic2NyaWJlJC5uZXh0KCk7XG4gICAgdGhpcy5fdW5zdWJzY3JpYmUkLmNvbXBsZXRlKCk7XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IGRlZmF1bHRUaW1lVmFsdWUodmFsdWUpIHtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIHRoaXMucHJvcHMuZGVmYXVsdFRpbWVWYWx1ZSA9IHZhbHVlO1xuICAgIH1cbiAgfVxuICBASW5wdXQoKVxuICBzZXQgcHJlZml4Q2xzKHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLnByb3BzLnByZWZpeENscyA9IHZhbHVlO1xuICAgIH1cbiAgfVxuICBASW5wdXQoKVxuICBzZXQgZW50ZXJEaXJlY3Rpb24odmFsdWUpIHtcbiAgICB0aGlzLl9lbnRlckRpcmVjdGlvbiA9IHZhbHVlO1xuICAgIGlmICh0aGlzLl9lbnRlckRpcmVjdGlvbiA9PT0gJ2hvcml6b250YWwnKSB7XG4gICAgICB0aGlzLmNvbnRlbnRBbmltYXRlQ2xhc3MgPSAnc2xpZGVILWVudGVyIHNsaWRlSC1lbnRlci1hY3RpdmUnO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNvbnRlbnRBbmltYXRlQ2xhc3MgPSAnc2xpZGVWLWVudGVyIHNsaWRlVi1lbnRlci1hY3RpdmUnO1xuICAgIH1cbiAgfVxuICBASW5wdXQoKVxuICBzZXQgdmlzaWJsZSh2YWx1ZSkge1xuICAgIHRoaXMucHJvcHMudmlzaWJsZSA9IHZhbHVlO1xuICAgIGlmICh2YWx1ZSA9PT0gdHJ1ZSB8fCB2YWx1ZSA9PT0gJ3RydWUnKSB7XG4gICAgICB0aGlzLnNob3dBbmltYXRpb24oKTtcbiAgICAgIHRoaXMuaXNTaG93ID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5oaWRlQW5pbWF0aW9uKCk7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5pc1Nob3cgPSBmYWxzZTtcbiAgICAgIH0sIDMwMCk7XG4gICAgfVxuICB9XG4gIEBJbnB1dCgpXG4gIHNldCBnZXREYXRlRXh0cmEodmFsdWUpIHtcbiAgICB0aGlzLnByb3BzLmdldERhdGVFeHRyYSA9IHZhbHVlO1xuICB9XG4gIEBJbnB1dCgpXG4gIHNldCBkZWZhdWx0RGF0ZSh2YWx1ZSkge1xuICAgIHRoaXMucHJvcHMuZGVmYXVsdERhdGUgPSB2YWx1ZTtcbiAgfVxuICBASW5wdXQoKVxuICBzZXQgbWluRGF0ZSh2YWx1ZSkge1xuICAgIHRoaXMucHJvcHMubWluRGF0ZSA9IHZhbHVlO1xuICB9XG4gIEBJbnB1dCgpXG4gIHNldCBtYXhEYXRlKHZhbHVlKSB7XG4gICAgdGhpcy5wcm9wcy5tYXhEYXRlID0gdmFsdWU7XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IHBpY2tUaW1lKHZhbHVlKSB7XG4gICAgdGhpcy5wcm9wcy5waWNrVGltZSA9IHZhbHVlO1xuICB9XG4gIEBJbnB1dCgpXG4gIHNldCB0eXBlKHZhbHVlKSB7XG4gICAgdGhpcy5wcm9wcy50eXBlID0gdmFsdWU7XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IHNob3dTaG9ydGN1dCh2YWx1ZSkge1xuICAgIHRoaXMucHJvcHMuc2hvd1Nob3J0Y3V0ID0gdmFsdWU7XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IHJvd1NpemUodmFsdWUpIHtcbiAgICB0aGlzLnByb3BzLnJvd1NpemUgPSB2YWx1ZTtcbiAgfVxuICBASW5wdXQoKVxuICBzZXQgaW5maW5pdGUodmFsdWUpIHt9XG4gIEBJbnB1dCgpXG4gIHNldCBkZWZhdWx0VmFsdWUodmFsdWUpIHtcbiAgICB0aGlzLnByb3BzLmRlZmF1bHRWYWx1ZSA9IHZhbHVlO1xuXG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLnJlY2VpdmVQcm9wcyh0aGlzLnByb3BzKTtcbiAgICB9XG4gIH1cbiAgQElucHV0KClcbiAgc2V0IG9uU2VsZWN0KHZhbHVlKSB7XG4gICAgdGhpcy5wcm9wcy5vblNlbGVjdCA9IHZhbHVlO1xuICB9XG5cbiAgQE91dHB1dCgpXG4gIG9uQ2FuY2VsOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KClcbiAgb25Db25maXJtOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KClcbiAgb25TZWxlY3RIYXNEaXNhYmxlRGF0ZTogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBASG9zdEJpbmRpbmcoJ2NsYXNzJylcbiAgY2xhc3M6IHN0cmluZyA9ICdhbS1jYWxlbmRhcic7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBfbG9jYWxlUHJvdmlkZXJTZXJ2aWNlOiBMb2NhbGVQcm92aWRlclNlcnZpY2UpIHt9XG5cbiAgd3JpdGVWYWx1ZSh2YWx1ZTogRGF0ZSB8IEFycmF5PERhdGU+IHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMuX2RhdGVNb2RlbFR5cGUgPSBudWxsO1xuICAgIGlmICh2YWx1ZSAmJiB2YWx1ZSBpbnN0YW5jZW9mIEFycmF5KSB7XG4gICAgICBpZiAodmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tuZy16b3Jyby1hbnRkLW1vYmlsZV06IGNhbGVuZGFyIG5nTW9kZWwgYXJyYXkgbmVlZCBwYXJhbXMhJyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLnByb3BzLnR5cGUgPT09ICdvbmUnICYmIHZhbHVlLmxlbmd0aCA+PSAyKSB7XG4gICAgICAgIHRoaXMuX2RhdGVNb2RlbFR5cGUgPSAxO1xuICAgICAgICBjb25zb2xlLmVycm9yKCdbbmctem9ycm8tYW50ZC1tb2JpbGVdOiB0eXBlIGlzIG9uZSwgYnV0IG5nbW9kZWwgaGFzIG1vcmUgdGhhbiBvbmUgcGFyYW0sIGp1c3QgdXNlIGZpcnN0IG9uZScpO1xuICAgICAgICB0aGlzLm9uU2VsZWN0ZWREYXRlKHZhbHVlWzBdKTtcbiAgICAgIH0gZWxzZSBpZiAodmFsdWUubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHRoaXMuX2RhdGVNb2RlbFR5cGUgPSAxO1xuICAgICAgICB0aGlzLm9uU2VsZWN0ZWREYXRlKHZhbHVlWzBdKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuX2RhdGVNb2RlbFR5cGUgPSAyO1xuICAgICAgICB0aGlzLm9uU2VsZWN0ZWREYXRlKHZhbHVlWzBdKTtcbiAgICAgICAgdGhpcy5vblNlbGVjdGVkRGF0ZSh2YWx1ZVsxXSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh2YWx1ZSAmJiB2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICAgIHRoaXMuX2RhdGVNb2RlbFR5cGUgPSAzO1xuICAgICAgdGhpcy5vblNlbGVjdGVkRGF0ZSh2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogKGRhdGU6IERhdGUgfCBBcnJheTxEYXRlPikgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMub25DaGFuZ2VGbiA9IGZuO1xuICB9XG5cbiAgcmVnaXN0ZXJPblRvdWNoZWQoZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLm9uVG91Y2hGbiA9IGZuO1xuICB9XG5cbiAgcmVjZWl2ZVByb3BzKG5leHRQcm9wczogQ2FsZW5kYXJQcm9wc1R5cGUpIHtcbiAgICBpZiAobmV4dFByb3BzLnZpc2libGUgJiYgbmV4dFByb3BzLmRlZmF1bHRWYWx1ZSkge1xuICAgICAgdGhpcy5zaG9ydGN1dFNlbGVjdChuZXh0UHJvcHMuZGVmYXVsdFZhbHVlWzBdLCBuZXh0UHJvcHMuZGVmYXVsdFZhbHVlWzFdLCBuZXh0UHJvcHMpO1xuICAgIH1cbiAgfVxuXG4gIHNob3dBbmltYXRpb24oKSB7XG4gICAgaWYgKHRoaXMuX2VudGVyRGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgIHRoaXMuY29udGVudEFuaW1hdGVDbGFzcyA9ICdzbGlkZUgtZW50ZXIgc2xpZGVILWVudGVyLWFjdGl2ZSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29udGVudEFuaW1hdGVDbGFzcyA9ICdzbGlkZVYtZW50ZXIgc2xpZGVWLWVudGVyLWFjdGl2ZSc7XG4gICAgfVxuICAgIHRoaXMubWFza0FuaW1hdGVDbGFzcyA9ICdmYWRlLWVudGVyIGZhZGUtZW50ZXItYWN0aXZlJztcbiAgfVxuXG4gIGhpZGVBbmltYXRpb24oKSB7XG4gICAgaWYgKHRoaXMuX2VudGVyRGlyZWN0aW9uID09PSAnaG9yaXpvbnRhbCcpIHtcbiAgICAgIHRoaXMuY29udGVudEFuaW1hdGVDbGFzcyA9ICdzbGlkZUgtbGVhdmUgc2xpZGVILWxlYXZlLWFjdGl2ZSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY29udGVudEFuaW1hdGVDbGFzcyA9ICdzbGlkZVYtbGVhdmUgc2xpZGVWLWxlYXZlLWFjdGl2ZSc7XG4gICAgfVxuICAgIHRoaXMubWFza0FuaW1hdGVDbGFzcyA9ICdmYWRlLWxlYXZlIGZhZGUtbGVhdmUtYWN0aXZlJztcbiAgfVxuXG4gIHNlbGVjdERhdGUgPSAoXG4gICAgZGF0ZTogRGF0ZSxcbiAgICB1c2VEYXRlVGltZSA9IGZhbHNlLFxuICAgIG9sZFN0YXRlOiB7IHN0YXJ0RGF0ZT86IERhdGU7IGVuZERhdGU/OiBEYXRlIH0gPSB7fSxcbiAgICBwcm9wcyA9IHRoaXMucHJvcHNcbiAgKSA9PiB7XG4gICAgaWYgKCFkYXRlKSB7XG4gICAgICByZXR1cm4ge30gYXMgQ2FsZW5kYXJTdGF0ZVR5cGU7XG4gICAgfVxuICAgIGxldCBuZXdTdGF0ZSA9IHt9IGFzIENhbGVuZGFyU3RhdGVUeXBlO1xuICAgIGNvbnN0IHsgdHlwZSwgcGlja1RpbWUsIGRlZmF1bHRUaW1lVmFsdWUsIGxvY2FsZSA9IHt9IGFzIERhdGVNb2RlbHMuTG9jYWxlIH0gPSBwcm9wcztcbiAgICBjb25zdCBuZXdEYXRlID0gcGlja1RpbWUgJiYgIXVzZURhdGVUaW1lID8gbWVyZ2VEYXRlVGltZShkYXRlLCBkZWZhdWx0VGltZVZhbHVlKSA6IGRhdGU7XG4gICAgY29uc3QgeyBzdGFydERhdGUsIGVuZERhdGUgfSA9IG9sZFN0YXRlO1xuXG4gICAgc3dpdGNoICh0eXBlKSB7XG4gICAgICBjYXNlICdvbmUnOlxuICAgICAgICBuZXdTdGF0ZSA9IHtcbiAgICAgICAgICAuLi5uZXdTdGF0ZSxcbiAgICAgICAgICBzdGFydERhdGU6IG5ld0RhdGUsXG4gICAgICAgICAgZGlzQ29uZmlybUJ0bjogZmFsc2VcbiAgICAgICAgfTtcbiAgICAgICAgaWYgKHBpY2tUaW1lKSB7XG4gICAgICAgICAgbmV3U3RhdGUgPSB7XG4gICAgICAgICAgICAuLi5uZXdTdGF0ZSxcbiAgICAgICAgICAgIHRpbWVQaWNrZXJUaXRsZTogbG9jYWxlLnNlbGVjdFRpbWUsXG4gICAgICAgICAgICBzaG93VGltZVBpY2tlcjogdHJ1ZVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3JhbmdlJzpcbiAgICAgICAgaWYgKCFzdGFydERhdGUgfHwgZW5kRGF0ZSkge1xuICAgICAgICAgIG5ld1N0YXRlID0ge1xuICAgICAgICAgICAgLi4ubmV3U3RhdGUsXG4gICAgICAgICAgICBzdGFydERhdGU6IG5ld0RhdGUsXG4gICAgICAgICAgICBlbmREYXRlOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBkaXNDb25maXJtQnRuOiB0cnVlXG4gICAgICAgICAgfTtcbiAgICAgICAgICBpZiAocGlja1RpbWUpIHtcbiAgICAgICAgICAgIG5ld1N0YXRlID0ge1xuICAgICAgICAgICAgICAuLi5uZXdTdGF0ZSxcbiAgICAgICAgICAgICAgdGltZVBpY2tlclRpdGxlOiBsb2NhbGUuc2VsZWN0U3RhcnRUaW1lLFxuICAgICAgICAgICAgICBzaG93VGltZVBpY2tlcjogdHJ1ZVxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbmV3U3RhdGUgPSB7XG4gICAgICAgICAgICAuLi5uZXdTdGF0ZSxcbiAgICAgICAgICAgIHRpbWVQaWNrZXJUaXRsZTpcbiAgICAgICAgICAgICAgK25ld0RhdGUgPj0gK3N0YXJ0RGF0ZSB8fCB0aGlzLmlzU2FtZURhdGUoc3RhcnREYXRlLCBuZXdEYXRlKVxuICAgICAgICAgICAgICAgID8gbG9jYWxlLnNlbGVjdEVuZFRpbWVcbiAgICAgICAgICAgICAgICA6IGxvY2FsZS5zZWxlY3RTdGFydFRpbWUsXG4gICAgICAgICAgICBkaXNDb25maXJtQnRuOiBmYWxzZSxcbiAgICAgICAgICAgIGVuZERhdGU6XG4gICAgICAgICAgICAgIHBpY2tUaW1lICYmICF1c2VEYXRlVGltZSAmJiAoK25ld0RhdGUgPj0gK3N0YXJ0RGF0ZSB8fCB0aGlzLmlzU2FtZURhdGUoc3RhcnREYXRlLCBuZXdEYXRlKSlcbiAgICAgICAgICAgICAgICA/IG5ldyBEYXRlKCttZXJnZURhdGVUaW1lKG5ld0RhdGUsIHN0YXJ0RGF0ZSkgKyAzNjAwMDAwKVxuICAgICAgICAgICAgICAgIDogbmV3RGF0ZVxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgfVxuXG4gICAgdGhpcy53cml0ZU1vZGVsRGF0YShkYXRlKTtcbiAgICByZXR1cm4gbmV3U3RhdGU7XG4gIH1cblxuICB3cml0ZU1vZGVsRGF0YShkYXRlKSB7XG4gICAgaWYgKHRoaXMuX2RhdGVNb2RlbFZhbHVlIGluc3RhbmNlb2YgQXJyYXkpIHtcbiAgICAgIHRoaXMuX2RhdGVNb2RlbFRpbWUgPSB0aGlzLl9kYXRlTW9kZWxWYWx1ZS5sZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2RhdGVNb2RlbFRpbWUgPSAwO1xuICAgIH1cblxuICAgIHN3aXRjaCAodGhpcy5fZGF0ZU1vZGVsVHlwZSkge1xuICAgICAgY2FzZSAxOlxuICAgICAgICB0aGlzLl9kYXRlTW9kZWxWYWx1ZSA9IFtkYXRlXTtcbiAgICAgICAgdGhpcy5vbkNoYW5nZUZuKHRoaXMuX2RhdGVNb2RlbFZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDI6XG4gICAgICAgIGlmICh0aGlzLl9kYXRlTW9kZWxUaW1lID09PSAxKSB7XG4gICAgICAgICAgaWYgKCtkYXRlIDwgK3RoaXMuX2RhdGVNb2RlbFZhbHVlWzBdKSB7XG4gICAgICAgICAgICB0aGlzLl9kYXRlTW9kZWxWYWx1ZS51bnNoaWZ0KGRhdGUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9kYXRlTW9kZWxWYWx1ZS5wdXNoKGRhdGUpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLm9uQ2hhbmdlRm4odGhpcy5fZGF0ZU1vZGVsVmFsdWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuX2RhdGVNb2RlbFZhbHVlID0gW107XG4gICAgICAgICAgdGhpcy5fZGF0ZU1vZGVsVmFsdWUucHVzaChkYXRlKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgMzpcbiAgICAgICAgdGhpcy5fZGF0ZU1vZGVsVmFsdWUgPSBkYXRlO1xuICAgICAgICB0aGlzLm9uQ2hhbmdlRm4odGhpcy5fZGF0ZU1vZGVsVmFsdWUpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIG9uU2VsZWN0ZWREYXRlID0gKGRhdGU6IERhdGUpID0+IHtcbiAgICBjb25zdCB7IHN0YXJ0RGF0ZSwgZW5kRGF0ZSB9ID0gdGhpcy5zdGF0ZTtcbiAgICBjb25zdCB7IG9uU2VsZWN0IH0gPSB0aGlzLnByb3BzO1xuXG4gICAgaWYgKG9uU2VsZWN0KSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IG9uU2VsZWN0KGRhdGUsIFtzdGFydERhdGUsIGVuZERhdGVdKTtcbiAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICB0aGlzLnNob3J0Y3V0U2VsZWN0KHZhbHVlWzBdLCB2YWx1ZVsxXSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgLi4udGhpcy5zdGF0ZSxcbiAgICAgIC4uLnRoaXMuc2VsZWN0RGF0ZShkYXRlLCBmYWxzZSwgeyBzdGFydERhdGUsIGVuZERhdGUgfSlcbiAgICB9O1xuXG4gICAgdGhpcy5zaG93Q2xlYXIgPSAhIXRoaXMuc3RhdGUuc3RhcnREYXRlO1xuICB9XG5cbiAgdHJpZ2dlclNlbGVjdEhhc0Rpc2FibGVEYXRlID0gKGRhdGU6IERhdGVbXSkgPT4ge1xuICAgIHRoaXMudHJpZ2dlckNsZWFyKCk7XG4gICAgaWYgKHRoaXMub25TZWxlY3RIYXNEaXNhYmxlRGF0ZSkge1xuICAgICAgdGhpcy5vblNlbGVjdEhhc0Rpc2FibGVEYXRlLmVtaXQoZGF0ZSk7XG4gICAgfVxuICB9XG5cbiAgb25DbG9zZSA9ICgpID0+IHtcbiAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgc2hvd1RpbWVQaWNrZXI6IGZhbHNlLFxuICAgICAgdGltZVBpY2tlclRpdGxlOiAnJyxcbiAgICAgIHN0YXJ0RGF0ZTogdW5kZWZpbmVkLFxuICAgICAgZW5kRGF0ZTogdW5kZWZpbmVkLFxuICAgICAgZGlzQ29uZmlybUJ0bjogdHJ1ZSxcbiAgICAgIGNsaWVudEhpZ2h0OiAwXG4gICAgfSBhcyBDYWxlbmRhclN0YXRlVHlwZTtcbiAgICB0aGlzLnNob3dDbGVhciA9ICEhdGhpcy5zdGF0ZS5zdGFydERhdGU7XG4gIH1cblxuICB0cmlnZ2VyQ29uZmlybSA9ICgpID0+IHtcbiAgICBjb25zdCB7IHN0YXJ0RGF0ZSwgZW5kRGF0ZSB9ID0gdGhpcy5zdGF0ZTtcbiAgICBpZiAoc3RhcnREYXRlICYmIGVuZERhdGUgJiYgK3N0YXJ0RGF0ZSA+ICtlbmREYXRlKSB7XG4gICAgICB0aGlzLm9uQ2xvc2UoKTtcbiAgICAgIHJldHVybiB0aGlzLm9uQ29uZmlybSAmJiB0aGlzLm9uQ29uZmlybS5lbWl0KHsgc3RhcnREYXRlOiBlbmREYXRlLCBlbmREYXRlOiBzdGFydERhdGUgfSk7XG4gICAgfVxuICAgIGlmICh0aGlzLm9uQ29uZmlybSkge1xuICAgICAgdGhpcy5vbkNvbmZpcm0uZW1pdCh7IHN0YXJ0RGF0ZSwgZW5kRGF0ZSB9KTtcbiAgICB9XG4gICAgdGhpcy5vbkNsb3NlKCk7XG4gIH1cblxuICB0cmlnZ2VyQ2FuY2VsKCkge1xuICAgIGlmICh0aGlzLnByb3BzLm9uQ2FuY2VsKSB7XG4gICAgICB0aGlzLnByb3BzLm9uQ2FuY2VsKCk7XG4gICAgfVxuICAgIHRoaXMub25DbG9zZSgpO1xuICAgIGlmICh0aGlzLm9uQ2FuY2VsKSB7XG4gICAgICB0aGlzLm9uQ2FuY2VsLmVtaXQoKTtcbiAgICB9XG4gIH1cblxuICB0cmlnZ2VyQ2xlYXIgPSAoKSA9PiB7XG4gICAgLy8g5riF6Zmk5pWw5o2u5YGa5bu26L+f77yM5ZCm5YiZ5ZCM5q2l5Yi35paw5pWw5o2u5a+86Ie05oql6ZSZXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnN0YXRlID0ge1xuICAgICAgICAuLi50aGlzLnN0YXRlLFxuICAgICAgICAuLi57IHN0YXJ0RGF0ZTogdW5kZWZpbmVkLCBlbmREYXRlOiB1bmRlZmluZWQsIHNob3dUaW1lUGlja2VyOiBmYWxzZSB9XG4gICAgICB9O1xuICAgICAgaWYgKHRoaXMucHJvcHMub25DbGVhcikge1xuICAgICAgICB0aGlzLnByb3BzLm9uQ2xlYXIoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2hvd0NsZWFyID0gISF0aGlzLnN0YXRlLnN0YXJ0RGF0ZTtcbiAgICB9LCAwKTtcbiAgfVxuXG4gIG9uVGltZUNoYW5nZSA9IChkYXRlOiBEYXRlKSA9PiB7XG4gICAgY29uc3QgeyBzdGFydERhdGUsIGVuZERhdGUgfSA9IHRoaXMuc3RhdGU7XG4gICAgaWYgKGVuZERhdGUpIHtcbiAgICAgIHRoaXMuc3RhdGUuZW5kRGF0ZSA9IGRhdGU7XG4gICAgfSBlbHNlIGlmIChzdGFydERhdGUpIHtcbiAgICAgIHRoaXMuc3RhdGUuc3RhcnREYXRlID0gZGF0ZTtcbiAgICB9XG4gIH1cblxuICBzaG9ydGN1dFNlbGVjdCA9IChzdGFydERhdGU6IERhdGUsIGVuZERhdGU6IERhdGUsIHByb3BzID0gdGhpcy5wcm9wcykgPT4ge1xuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAuLi50aGlzLnN0YXRlLFxuICAgICAgLi4ueyBzdGFydERhdGUsIHNob3dUaW1lUGlja2VyOiBmYWxzZSB9LFxuICAgICAgLi4udGhpcy5zZWxlY3REYXRlKGVuZERhdGUsIHRydWUsIHsgc3RhcnREYXRlIH0sIHByb3BzKVxuICAgIH07XG4gICAgdGhpcy5zaG93Q2xlYXIgPSAhIXRoaXMuc3RhdGUuc3RhcnREYXRlO1xuICB9XG5cbiAgc2V0Q2xpZW50SGVpZ2h0ID0gKGhlaWdodDogbnVtYmVyKSA9PiB7XG4gICAgdGhpcy5zdGF0ZS5jbGllbnRIaWdodCA9IGhlaWdodDtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IHRoaXMucHJvcHMuZGVmYXVsdFZhbHVlO1xuICAgIGlmIChkZWZhdWx0VmFsdWUpIHtcbiAgICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICAgIC4uLnRoaXMuc3RhdGUsXG4gICAgICAgIC4uLnRoaXMuc2VsZWN0RGF0ZShkZWZhdWx0VmFsdWVbMV0sIHRydWUsIHsgc3RhcnREYXRlOiBkZWZhdWx0VmFsdWVbMF0gfSwgdGhpcy5wcm9wcylcbiAgICAgIH07XG4gICAgfVxuXG4gICAgdGhpcy5fbG9jYWxlUHJvdmlkZXJTZXJ2aWNlLmxvY2FsZUNoYW5nZS5waXBlKHRha2VVbnRpbCh0aGlzLl91bnN1YnNjcmliZSQpKS5zdWJzY3JpYmUoXyA9PiB7XG4gICAgICB0aGlzLnByb3BzLmxvY2FsZSA9IHsgLi4udGhpcy5fbG9jYWxlUHJvdmlkZXJTZXJ2aWNlLmdldExvY2FsZVN1Yk9iaignQ2FsZW5kYXInKSB9IGFzIERhdGVNb2RlbHMuTG9jYWxlO1xuICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5fdW5zdWJzY3JpYmUkLm5leHQoKTtcbiAgICB0aGlzLl91bnN1YnNjcmliZSQuY29tcGxldGUoKTtcbiAgfVxuXG4gIHByaXZhdGUgb25DaGFuZ2VGbjogKGRhdGU6IERhdGUgfCBBcnJheTxEYXRlPikgPT4gdm9pZCA9ICgpID0+IHt9O1xuICBwcml2YXRlIG9uVG91Y2hGbjogKGRhdGU6IERhdGUgfCBBcnJheTxEYXRlPikgPT4gdm9pZCA9ICgpID0+IHt9O1xufVxuIl19