UNPKG

fundamental-ngx

Version:

SAP Fundamentals, implemented in Angular

758 lines 76.9 kB
/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
import { Component, ElementRef, EventEmitter, HostBinding, Input, Output, ViewEncapsulation } from '@angular/core';
import { CalendarI18n } from '../../i18n/calendar-i18n';
import { FdDate } from '../../models/fd-date';
import { CalendarService } from '../../calendar.service';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
/**
 * Component representing the day view of the calendar.
 */
export class CalendarDayViewComponent {
    /**
     * @hidden
     * @param {?} calendarI18n
     * @param {?} eRef
     */
    constructor(calendarI18n, eRef) {
        this.calendarI18n = calendarI18n;
        this.eRef = eRef;
        /**
         * @hidden
         */
        this.newFocusedDayId = '';
        /**
         * An RxJS Subject that will kill the data stream upon component’s destruction (for unsubscribing)
         */
        this.onDestroy$ = new Subject();
        /**
         * @hidden
         */
        this.fdCalendarDateViewClass = true;
        /**
         * The type of calendar, 'single' for single date selection or 'range' for a range of dates.
         */
        this.calType = 'single';
        /**
         * Event emitted always, when model is changed in range mode
         */
        this.selectedRangeDateChange = new EventEmitter();
        /**
         * Event emitted always, when next month is selected, by focus
         */
        this.nextMonthSelect = new EventEmitter();
        /**
         * Event emitted always, when previous month is selected, by focus
         */
        this.previousMonthSelect = new EventEmitter();
        /**
         * Event emitted always, when model is changed in single mode
         */
        this.selectedDateChange = new EventEmitter();
        /**
         * Function used to disable certain dates in the calendar.
         * @param fdDate FdDate
         */
        this.disableFunction = (/**
         * @param {?} fdDate
         * @return {?}
         */
        function (fdDate) {
            return false;
        });
        /**
         * Function used to disable certain dates in the calendar for the range start selection.
         * @param fdDate FdDate
         */
        this.disableRangeStartFunction = (/**
         * @param {?} fdDate
         * @return {?}
         */
        function (fdDate) {
            return false;
        });
        /**
         * Function used to disable certain dates in the calendar for the range end selection.
         * @param fdDate FdDate
         */
        this.disableRangeEndFunction = (/**
         * @param {?} fdDate
         * @return {?}
         */
        function (fdDate) {
            return false;
        });
        /**
         * Function used to block certain dates in the calendar for the range start selection.
         * @param fdDate FdDate
         */
        this.blockRangeStartFunction = (/**
         * @param {?} fdDate
         * @return {?}
         */
        function (fdDate) {
            return false;
        });
        /**
         * Function used to block certain dates in the calendar for the range end selection.
         * @param fdDate FdDate
         */
        this.blockRangeEndFunction = (/**
         * @param {?} fdDate
         * @return {?}
         */
        function (fdDate) {
            return false;
        });
        /**
         * Function used to block certain dates in the calendar.
         * @param fdDate FdDate
         */
        this.blockFunction = (/**
         * @param {?} fdDate
         * @return {?}
         */
        function (fdDate) {
            return false;
        });
    }
    /**
     * Function for selecting a date on the calendar. Typically called when a date is clicked, but can also be called programmatically.
     * @param {?} day CalendarDay object to be selected.
     * @param {?=} event
     * @return {?}
     */
    selectDate(day, event) {
        if (event) {
            /**
             * There are some problems with popup integration. After clicking inside day component, the popover closes.
             */
            event.stopPropagation();
            event.preventDefault();
            this.newFocusedDayId = day.id;
            this.focusElement(this.newFocusedDayId);
        }
        if (!day.blocked && !day.disabled) {
            if (this.calType === 'single') {
                this.selectedDate = day.date;
                this.selectedDateChange.emit(day.date);
                this.buildDayViewGrid();
            }
            else {
                if (this.selectCounter === 0 || this.selectCounter === 2) {
                    this.selectedRangeDate = { start: day.date, end: null };
                    this.selectedRangeDateChange.emit(this.selectedRangeDate);
                    this.buildDayViewGrid();
                }
                else if (this.selectCounter === 1) {
                    // Check if date picked is higher than already chosen, otherwise just first one
                    if (this.selectedRangeDate.start.getTimeStamp() < day.date.getTimeStamp()) {
                        this.selectedRangeDate = { start: this.selectedRangeDate.start, end: day.date };
                    }
                    else {
                        this.selectedRangeDate = { start: day.date, end: null };
                    }
                    this.selectedRangeDateChange.emit(this.selectedRangeDate);
                    this.buildDayViewGrid();
                }
            }
        }
    }
    /**
     * @hidden
     * @return {?}
     */
    ngOnInit() {
        this.buildDayViewGrid();
        this.shortWeekDays = this.getShortWeekDays();
        this.calendarI18n.i18nChange
            .pipe(takeUntil(this.onDestroy$))
            .subscribe((/**
         * @return {?}
         */
        () => this.shortWeekDays = this.getShortWeekDays()));
    }
    /**
     * @hidden
     *  Amount of selected days
     *  0, when none,
     *  1, when only startDate, or endDate same as startDate,
     *  2, when both
     * @return {?}
     */
    get selectCounter() {
        if (!this.selectedRangeDate || !this.selectedRangeDate.start) {
            return 0;
        }
        else if (this.selectedRangeDate.start &&
            (!this.selectedRangeDate.end ||
                CalendarService.datesEqual(this.selectedRangeDate.start, this.selectedRangeDate.end))) {
            return 1;
        }
        else if (this.selectedRangeDate.start && this.selectedRangeDate.end) {
            return 2;
        }
    }
    /**
     * @hidden
     * Method that handles day cells keydown events,
     * @param {?} event KeyboardEvent
     * @param {?} cell CalendarDay
     * @param {?} grid with specified column and row as a x and y
     * @return {?}
     */
    onKeydownDayHandler(event, cell, grid) {
        if (event.code === 'Tab' && !event.shiftKey) {
            if (this.focusEscapeFunction) {
                event.preventDefault();
                this.focusEscapeFunction();
            }
        }
        else {
            switch (event.code) {
                case ('Space'):
                case ('Enter'): {
                    event.preventDefault();
                    this.selectDate(cell);
                    this.newFocusedDayId = cell.id;
                    break;
                }
                case ('ArrowUp'): {
                    event.preventDefault();
                    if (grid.y > 0) {
                        this.newFocusedDayId = this.dayViewGrid[grid.y - 1][grid.x].id;
                    }
                    else {
                        this.selectPreviousMonth();
                        this.newFocusedDayId = this.dayViewGrid[this.dayViewGrid.length - 1][grid.x].id;
                    }
                    break;
                }
                case ('ArrowDown'): {
                    event.preventDefault();
                    if (grid.y < this.dayViewGrid.length - 1) {
                        this.newFocusedDayId = this.dayViewGrid[grid.y + 1][grid.x].id;
                    }
                    else {
                        this.selectNextMonth();
                        this.newFocusedDayId = this.dayViewGrid[0][grid.x].id;
                    }
                    break;
                }
                case ('ArrowLeft'): {
                    event.preventDefault();
                    if (grid.x > 0) {
                        this.newFocusedDayId = this.dayViewGrid[grid.y][grid.x - 1].id;
                    }
                    else if (grid.y > 0) {
                        this.newFocusedDayId = this.dayViewGrid[grid.y - 1][this.dayViewGrid[0].length - 1].id;
                    }
                    else {
                        this.selectPreviousMonth();
                        this.newFocusedDayId =
                            this.dayViewGrid[this.dayViewGrid.length - 1][this.dayViewGrid[0].length - 1].id;
                    }
                    break;
                }
                case ('ArrowRight'): {
                    event.preventDefault();
                    if (grid.x < this.dayViewGrid[0].length - 1) {
                        this.newFocusedDayId = this.dayViewGrid[grid.y][grid.x + 1].id;
                    }
                    else if (grid.y < this.dayViewGrid.length - 1) {
                        this.newFocusedDayId = this.dayViewGrid[grid.y + 1][0].id;
                    }
                    else {
                        this.selectNextMonth();
                        this.newFocusedDayId = this.dayViewGrid[0][0].id;
                    }
                    break;
                }
            }
        }
        if (this.newFocusedDayId) {
            this.focusElement(this.newFocusedDayId);
        }
    }
    /**
     * @hidden
     * @return {?}
     */
    ngOnChanges() {
        this.buildDayViewGrid();
    }
    /**
     * @hidden
     * @return {?}
     */
    ngAfterViewChecked() {
        if (this.newFocusedDayId) {
            this.focusElement(this.newFocusedDayId);
            this.newFocusedDayId = null;
        }
    }
    /**
     * @hidden
     *  Method that allow to focus elements inside this component
     * @param {?} elementSelector
     * @return {?}
     */
    focusElement(elementSelector) {
        /** @type {?} */
        const elementToFocus = this.eRef.nativeElement.querySelector('#' + elementSelector);
        if (elementToFocus) {
            elementToFocus.focus();
        }
    }
    /**
     * Active day means that with tabindex = 0, it's selected day or today or first day
     * @return {?}
     */
    focusActiveDay() {
        this.newFocusedDayId = this.getActiveCell(this.calendarDayList.filter((/**
         * @param {?} cell
         * @return {?}
         */
        cell => cell.monthStatus === 'current'))).id;
    }
    /**
     * Function that gives array of all displayed CalendarDays
     * @return {?}
     */
    get calendarDayList() {
        return this.dayViewGrid.reduce((/**
         * @param {?} totalCalendarRows
         * @param {?} calendarRow
         * @return {?}
         */
        (totalCalendarRows, calendarRow) => {
            if (!calendarRow) {
                calendarRow = [];
            }
            return totalCalendarRows.concat(calendarRow);
        }));
    }
    /**
     * Method that selects previous month
     * Triggered only when the month is changed during changing focus
     * Also triggers event to parent calendar component and rebuilds day view grid
     * @private
     * @return {?}
     */
    selectPreviousMonth() {
        if (this.currentlyDisplayed.month > 1) {
            this.currentlyDisplayed = Object.assign({}, this.currentlyDisplayed, { month: this.currentlyDisplayed.month - 1 });
        }
        else {
            this.currentlyDisplayed = { year: this.currentlyDisplayed.year - 1, month: 12 };
        }
        this.buildDayViewGrid();
        this.previousMonthSelect.emit();
    }
    /**
     * Method that selects next month
     * Triggered only when the month is changed during changing focus
     * Also triggers event to parent calendar component and rebuilds day view grid
     * @private
     * @return {?}
     */
    selectNextMonth() {
        if (this.currentlyDisplayed.month > 1) {
            this.currentlyDisplayed = Object.assign({}, this.currentlyDisplayed, { month: this.currentlyDisplayed.month + 1 });
        }
        else {
            this.currentlyDisplayed = { year: this.currentlyDisplayed.year + 1, month: 1 };
        }
        this.buildDayViewGrid();
        this.nextMonthSelect.emit();
    }
    /**
     * Method that creates array of CalendarDay models which will be shown on day grid,
     * depending on current month and year.
     * @private
     * @return {?}
     */
    populateCalendar() {
        /** @type {?} */
        let calendar = [];
        calendar = this.getPreviousMonthDays(calendar);
        calendar = calendar.concat(this.getCurrentMonthDays());
        calendar = this.getNextMonthDays(calendar);
        calendar.forEach((/**
         * @param {?} call
         * @param {?} index
         * @return {?}
         */
        (call, index) => call.id = this.id + '-fd-day-' + (Math.floor(index / 7) + 1) + '' + (index % 7)));
        return calendar;
    }
    /**
     * Method that builds 2 dimensions day view grid, also sets up currently displayed month, or year,
     * when there is not any.
     * @private
     * @return {?}
     */
    buildDayViewGrid() {
        if (!this.currentlyDisplayed) {
            if (this.selectedDate) {
                this.currentlyDisplayed = { month: this.selectedDate.month, year: this.selectedDate.year };
            }
            else {
                this.currentlyDisplayed = { month: FdDate.getToday().month, year: FdDate.getToday().year };
            }
        }
        /** @type {?} */
        const calendarDays = this.populateCalendar();
        /** @type {?} */
        const dayViewGrid = [];
        while (calendarDays.length > 0) {
            dayViewGrid.push(calendarDays.splice(0, 7));
        }
        this.dayViewGrid = dayViewGrid;
        return;
    }
    /**
     * Method which provides array of CalendarDay, which contains every single day of currently shown month/year.
     * @private
     * @return {?}
     */
    getCurrentMonthDays() {
        /** @type {?} */
        const month = this.currentlyDisplayed.month;
        /** @type {?} */
        const year = this.currentlyDisplayed.year;
        /** @type {?} */
        const calendarDays = [];
        /** @type {?} */
        const amountOfDaysInCurrentMonth = CalendarService.getDaysInMonth(month, year);
        for (let dayNumber = 1; dayNumber <= amountOfDaysInCurrentMonth; dayNumber++) {
            /** @type {?} */
            const fdDate = new FdDate(year, month, dayNumber);
            calendarDays.push(Object.assign({}, this.getDay(fdDate), { monthStatus: 'current', today: CalendarService.datesEqual(FdDate.getToday(), fdDate) }));
        }
        this.getActiveCell(calendarDays).isTabIndexed = true;
        return calendarDays;
    }
    /**
     * Method that returns active cell, which means:
     * if there is any selected day, return selected day
     * if there is no selected day, but there is today day, return today day
     * if there is no today, or selected, return first one
     * @private
     * @param {?} calendarDays
     * @return {?}
     */
    getActiveCell(calendarDays) {
        if (calendarDays.find((/**
         * @param {?} cell
         * @return {?}
         */
        cell => cell.selected))) {
            return calendarDays.find((/**
             * @param {?} cell
             * @return {?}
             */
            cell => cell.selected));
        }
        else if (calendarDays.find((/**
         * @param {?} cell
         * @return {?}
         */
        cell => cell.today))) {
            return calendarDays.find((/**
             * @param {?} cell
             * @return {?}
             */
            cell => cell.today));
        }
        else {
            return calendarDays[0];
        }
    }
    /**
     * Method which provides array of CalendarDay, which contains last 0-6 days of previous month/year. Theses days
     * fills the gap between starting startingDayOfWeek and first day of current month
     * @private
     * @param {?} calendarDays
     * @return {?}
     */
    getPreviousMonthDays(calendarDays) {
        /** @type {?} */
        const month = this.currentlyDisplayed.month > 1 ? this.currentlyDisplayed.month - 1 : 12;
        /** @type {?} */
        const year = this.currentlyDisplayed.month > 1 ? this.currentlyDisplayed.year : this.currentlyDisplayed.year - 1;
        /** @type {?} */
        const amountOfDaysInCurrentMonth = CalendarService.getDaysInMonth(month, year);
        /** @type {?} */
        const prevMonthLastDate = new FdDate(year, month, amountOfDaysInCurrentMonth);
        /** @type {?} */
        const prevMonthLastDay = amountOfDaysInCurrentMonth;
        /** @type {?} */
        let prevMonthLastWeekDay = prevMonthLastDate.getDay() - this.startingDayOfWeek;
        /** Checking if there are some days cut by startingDayOfWeek option
         *  If yes, there is whole week added, to avoid hiding
         */
        if (prevMonthLastWeekDay < 0) {
            prevMonthLastWeekDay = prevMonthLastWeekDay + 7;
        }
        if (prevMonthLastWeekDay < 6) {
            while (prevMonthLastWeekDay >= 0) {
                /** @type {?} */
                const prevMonthDay = prevMonthLastDay - prevMonthLastWeekDay;
                /** @type {?} */
                const fdDate = new FdDate(year, month, prevMonthDay);
                calendarDays.push(Object.assign({}, this.getDay(fdDate), { monthStatus: 'previous' }));
                prevMonthLastWeekDay--;
            }
        }
        return calendarDays;
    }
    /**
     * Method which provides array of CalendarDay, which contains first days of next month/year. Theses days
     * fills the gap between last day of current day and end of 6-weeks calendar grid.
     * @private
     * @param {?} calendarDays
     * @return {?}
     */
    getNextMonthDays(calendarDays) {
        /** @type {?} */
        const month = this.currentlyDisplayed.month < 12 ? this.currentlyDisplayed.month + 1 : 1;
        /** @type {?} */
        const year = this.currentlyDisplayed.month < 12 ? this.currentlyDisplayed.year : this.currentlyDisplayed.year + 1;
        // The calendar grid can have 6 (42 days) weeks
        /** @type {?} */
        const nextMonthDisplayedDays = 42 - calendarDays.length;
        for (let nextD = 1; nextD <= nextMonthDisplayedDays; nextD++) {
            /** @type {?} */
            const fdDate = new FdDate(year, month, nextD);
            calendarDays.push(Object.assign({}, this.getDay(fdDate), { monthStatus: 'next' }));
        }
        return calendarDays;
    }
    /**
     * Method that generates whole day model basing on fdDate, disabling functions, block functions, and actually
     * chosen range / single date.
     * @private
     * @param {?} fdDate
     * @return {?}
     */
    getDay(fdDate) {
        /** @type {?} */
        const day = {
            date: fdDate,
            weekDay: fdDate.getDay(),
            disabled: this.disableFunction(fdDate),
            blocked: this.blockFunction(fdDate),
            selected: ((this.calType === 'single' && CalendarService.datesEqual(fdDate, this.selectedDate)) ||
                (this.selectedRangeDate && CalendarService.datesEqual(fdDate, this.selectedRangeDate.start)) ||
                (this.selectedRangeDate && CalendarService.datesEqual(fdDate, this.selectedRangeDate.end))),
            selectedFirst: (this.selectedRangeDate && CalendarService.datesEqual(fdDate, this.selectedRangeDate.start)),
            selectedLast: (this.selectedRangeDate && CalendarService.datesEqual(fdDate, this.selectedRangeDate.end)),
            selectedRange: (this.selectedRangeDate && ((this.selectedRangeDate.start && (this.selectedRangeDate.start.getTimeStamp() < fdDate.getTimeStamp())) &&
                (this.selectedRangeDate.end && (this.selectedRangeDate.end.getTimeStamp() > fdDate.getTimeStamp())))),
            ariaLabel: this.calendarI18n.getDayAriaLabel(fdDate.toDate())
        };
        if (this.calType === 'range' && (this.selectCounter === 0 || this.selectCounter === 2)) {
            if (this.disableRangeStartFunction && !day.disabled) {
                day.disabled = this.disableRangeStartFunction(day.date);
            }
            if (this.blockRangeStartFunction && !day.blocked) {
                day.blocked = this.blockRangeStartFunction(day.date);
            }
        }
        else if (this.selectCounter === 1) {
            if (this.disableRangeEndFunction && !day.disabled) {
                day.disabled = this.disableRangeEndFunction(day.date);
            }
            if (this.blockRangeEndFunction && !day.blocked) {
                day.blocked = this.blockRangeEndFunction(day.date);
            }
        }
        return day;
    }
    /**
     * Method that returns first letter of every weekday, basing on CalendarI18nDefault. Can be changed by user by
     * providing other class which implements CalendarI18n
     * @private
     * @return {?}
     */
    getShortWeekDays() {
        return this.calendarI18n.getAllShortWeekdays()
            .slice(this.startingDayOfWeek - 1)
            .concat(this.calendarI18n.getAllShortWeekdays().slice(0, this.startingDayOfWeek - 1))
            .map((/**
         * @param {?} weekday
         * @return {?}
         */
        weekday => weekday[0].toLocaleUpperCase()));
    }
}
CalendarDayViewComponent.decorators = [
    { type: Component, args: [{
                selector: 'fd-calendar-day-view',
                template: "<table class=\"fd-calendar__table\" role=\"grid\">\n    <thead class=\"fd-calendar__group\">\n    <tr class=\"fd-calendar__row\">\n        <th class=\"fd-calendar__column-header\" *ngFor=\"let day of shortWeekDays\">\n            <span class=\"fd-calendar__day-of-week\">{{day}}</span>\n        </th>\n    </tr>\n    </thead>\n    <tbody class=\"fd-calendar__group\">\n        <tr class=\"fd-calendar__row\"\n            *ngFor=\"let row of dayViewGrid; let rowIndex = index;\">\n\n            <td class=\"fd-calendar__item\"\n                role=\"gridcell\"\n                [attr.aria-label]=\"cell.ariaLabel\"\n                *ngFor=\"let cell of row; let cellIndex = index;\"\n                [ngClass]=\"{\n                    'fd-calendar__item--other-month': cell.monthStatus !== 'current',\n                    'is-selected': cell.selected,\n                    'is-selected-range-last': cell.selectedLast && !cell.selectedFirst,\n                    'is-selected-range-first': cell.selectedFirst,\n                    'is-selected-range': cell.selectedRange && !cell.selectedFirst && !cell.selectedLast,\n                    'fd-calendar__item--current': cell.today,\n                    'is-disabled': cell.disabled,\n                    'is-blocked': cell.blocked\n                }\"\n                [attr.id]=\"cell.id\"\n                [attr.tabindex]=\"cell.isTabIndexed ? 0 : -1\"\n                (click)=\"selectDate(cell, $event)\"\n                (keydown)=\"onKeydownDayHandler($event, cell, { x: cellIndex, y: rowIndex })\"\n            >\n                <span class=\"fd-calendar__text\" role=\"button\">{{cell.date.day}}</span>\n            </td>\n        </tr>\n    </tbody>\n</table>\n",
                encapsulation: ViewEncapsulation.None,
                host: {
                    '[attr.id]': 'id + "-day-view"'
                },
                styles: [""]
            }] }
];
/** @nocollapse */
CalendarDayViewComponent.ctorParameters = () => [
    { type: CalendarI18n },
    { type: ElementRef }
];
CalendarDayViewComponent.propDecorators = {
    fdCalendarDateViewClass: [{ type: HostBinding, args: ['class.fd-calendar__dates',] }],
    currentlyDisplayed: [{ type: Input }],
    selectedDate: [{ type: Input }],
    selectedRangeDate: [{ type: Input }],
    startingDayOfWeek: [{ type: Input }],
    calType: [{ type: Input }],
    id: [{ type: Input }],
    focusEscapeFunction: [{ type: Input }],
    selectedRangeDateChange: [{ type: Output }],
    nextMonthSelect: [{ type: Output }],
    previousMonthSelect: [{ type: Output }],
    selectedDateChange: [{ type: Output }],
    disableFunction: [{ type: Input }],
    disableRangeStartFunction: [{ type: Input }],
    disableRangeEndFunction: [{ type: Input }],
    blockRangeStartFunction: [{ type: Input }],
    blockRangeEndFunction: [{ type: Input }],
    blockFunction: [{ type: Input }]
};
if (false) {
    /**
     * @hidden
     * @type {?}
     */
    CalendarDayViewComponent.prototype.newFocusedDayId;
    /**
     * @hidden
     * @type {?}
     */
    CalendarDayViewComponent.prototype.shortWeekDays;
    /**
     * Actual day grid with previous/current/next month days
     * @type {?}
     */
    CalendarDayViewComponent.prototype.dayViewGrid;
    /**
     * An RxJS Subject that will kill the data stream upon component’s destruction (for unsubscribing)
     * @type {?}
     * @private
     */
    CalendarDayViewComponent.prototype.onDestroy$;
    /**
     * @hidden
     * @type {?}
     */
    CalendarDayViewComponent.prototype.fdCalendarDateViewClass;
    /**
     * Currently displayed month and year for days
     * @type {?}
     */
    CalendarDayViewComponent.prototype.currentlyDisplayed;
    /**
     * The currently selected FdDate model in single mode.
     * @type {?}
     */
    CalendarDayViewComponent.prototype.selectedDate;
    /**
     * The currently selected FdDates model start and end in range mode.
     * @type {?}
     */
    CalendarDayViewComponent.prototype.selectedRangeDate;
    /**
     * The day of the week the calendar should start on. 1 represents Sunday, 2 is Monday, 3 is Tuesday, and so on.
     * @type {?}
     */
    CalendarDayViewComponent.prototype.startingDayOfWeek;
    /**
     * The type of calendar, 'single' for single date selection or 'range' for a range of dates.
     * @type {?}
     */
    CalendarDayViewComponent.prototype.calType;
    /**
     * Id of the calendar. If none is provided, one will be generated.
     * @type {?}
     */
    CalendarDayViewComponent.prototype.id;
    /**
     * Function that allows to specify which function would be called, when focus wants to escape
     * @type {?}
     */
    CalendarDayViewComponent.prototype.focusEscapeFunction;
    /**
     * Event emitted always, when model is changed in range mode
     * @type {?}
     */
    CalendarDayViewComponent.prototype.selectedRangeDateChange;
    /**
     * Event emitted always, when next month is selected, by focus
     * @type {?}
     */
    CalendarDayViewComponent.prototype.nextMonthSelect;
    /**
     * Event emitted always, when previous month is selected, by focus
     * @type {?}
     */
    CalendarDayViewComponent.prototype.previousMonthSelect;
    /**
     * Event emitted always, when model is changed in single mode
     * @type {?}
     */
    CalendarDayViewComponent.prototype.selectedDateChange;
    /**
     * Function used to disable certain dates in the calendar.
     * \@param fdDate FdDate
     * @type {?}
     */
    CalendarDayViewComponent.prototype.disableFunction;
    /**
     * Function used to disable certain dates in the calendar for the range start selection.
     * \@param fdDate FdDate
     * @type {?}
     */
    CalendarDayViewComponent.prototype.disableRangeStartFunction;
    /**
     * Function used to disable certain dates in the calendar for the range end selection.
     * \@param fdDate FdDate
     * @type {?}
     */
    CalendarDayViewComponent.prototype.disableRangeEndFunction;
    /**
     * Function used to block certain dates in the calendar for the range start selection.
     * \@param fdDate FdDate
     * @type {?}
     */
    CalendarDayViewComponent.prototype.blockRangeStartFunction;
    /**
     * Function used to block certain dates in the calendar for the range end selection.
     * \@param fdDate FdDate
     * @type {?}
     */
    CalendarDayViewComponent.prototype.blockRangeEndFunction;
    /**
     * Function used to block certain dates in the calendar.
     * \@param fdDate FdDate
     * @type {?}
     */
    CalendarDayViewComponent.prototype.blockFunction;
    /**
     * @type {?}
     * @private
     */
    CalendarDayViewComponent.prototype.calendarI18n;
    /**
     * @type {?}
     * @private
     */
    CalendarDayViewComponent.prototype.eRef;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXItZGF5LXZpZXcuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vZnVuZGFtZW50YWwtbmd4LyIsInNvdXJjZXMiOlsibGliL2NhbGVuZGFyL2NhbGVuZGFyLXZpZXdzL2NhbGVuZGFyLWRheS12aWV3L2NhbGVuZGFyLWRheS12aWV3LmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUVILFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFdBQVcsRUFDWCxLQUFLLEVBRUwsTUFBTSxFQUNOLGlCQUFpQixFQUNwQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDeEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBSTlDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV6RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7OztBQVkzQyxNQUFNLE9BQU8sd0JBQXdCOzs7Ozs7SUFvSGpDLFlBQ1ksWUFBMEIsRUFDMUIsSUFBZ0I7UUFEaEIsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsU0FBSSxHQUFKLElBQUksQ0FBWTs7OztRQW5INUIsb0JBQWUsR0FBVyxFQUFFLENBQUM7Ozs7UUFTWixlQUFVLEdBQWtCLElBQUksT0FBTyxFQUFRLENBQUM7Ozs7UUFJMUQsNEJBQXVCLEdBQVksSUFBSSxDQUFDOzs7O1FBb0IvQyxZQUFPLEdBQWlCLFFBQVEsQ0FBQzs7OztRQVdqQiw0QkFBdUIsR0FBOEIsSUFBSSxZQUFZLEVBQWUsQ0FBQzs7OztRQUlyRixvQkFBZSxHQUF1QixJQUFJLFlBQVksRUFBUSxDQUFDOzs7O1FBSS9ELHdCQUFtQixHQUF1QixJQUFJLFlBQVksRUFBUSxDQUFDOzs7O1FB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OzthQUNKOzs7O1lBbkJRLFlBQVk7WUFSakIsVUFBVTs7O3NDQTJDVCxXQUFXLFNBQUMsMEJBQTBCO2lDQUl0QyxLQUFLOzJCQUlMLEtBQUs7Z0NBSUwsS0FBSztnQ0FJTCxLQUFLO3NCQUlMLEtBQUs7aUJBSUwsS0FBSztrQ0FHTCxLQUFLO3NDQUlMLE1BQU07OEJBSU4sTUFBTTtrQ0FJTixNQUFNO2lDQUlOLE1BQU07OEJBT04sS0FBSzt3Q0FTTCxLQUFLO3NDQVNMLEtBQUs7c0NBU0wsS0FBSztvQ0FTTCxLQUFLOzRCQVNMLEtBQUs7Ozs7Ozs7SUEzR04sbURBQTZCOzs7OztJQUc3QixpREFBd0I7Ozs7O0lBR3hCLCtDQUFvQzs7Ozs7O0lBR3BDLDhDQUFpRTs7Ozs7SUFHakUsMkRBQytDOzs7OztJQUcvQyxzREFDMkM7Ozs7O0lBRzNDLGdEQUM0Qjs7Ozs7SUFHNUIscURBQ3NDOzs7OztJQUd0QyxxREFDcUM7Ozs7O0lBR3JDLDJDQUNpQzs7Ozs7SUFHakMsc0NBQW9COzs7OztJQUdwQix1REFDOEI7Ozs7O0lBRzlCLDJEQUNxRzs7Ozs7SUFHckcsbURBQytFOzs7OztJQUcvRSx1REFDbUY7Ozs7O0lBR25GLHNEQUNzRjs7Ozs7O0lBTXRGLG1EQUdFOzs7Ozs7SUFNRiw2REFHRTs7Ozs7O0lBTUYsMkRBR0U7Ozs7OztJQU1GLDJEQUdFOzs7Ozs7SUFNRix5REFHRTs7Ozs7O0lBTUYsaURBR0U7Ozs7O0lBSUUsZ0RBQWtDOzs7OztJQUNsQyx3Q0FBd0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICAgIEFmdGVyVmlld0NoZWNrZWQsXG4gICAgQ29tcG9uZW50LFxuICAgIEVsZW1lbnRSZWYsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIEhvc3RCaW5kaW5nLFxuICAgIElucHV0LCBPbkNoYW5nZXMsXG4gICAgT25Jbml0LFxuICAgIE91dHB1dCxcbiAgICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENhbGVuZGFySTE4biB9IGZyb20gJy4uLy4uL2kxOG4vY2FsZW5kYXItaTE4bic7XG5pbXBvcnQgeyBGZERhdGUgfSBmcm9tICcuLi8uLi9tb2RlbHMvZmQtZGF0ZSc7XG5pbXBvcnQgeyBDYWxlbmRhckN1cnJlbnQgfSBmcm9tICcuLi8uLi9tb2RlbHMvY2FsZW5kYXItY3VycmVudCc7XG5pbXBvcnQgeyBDYWxlbmRhclR5cGUsIERheXNPZldlZWsgfSBmcm9tICcuLi8uLi9jYWxlbmRhci5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ2FsZW5kYXJEYXkgfSBmcm9tICcuLi8uLi9tb2RlbHMvY2FsZW5kYXItZGF5JztcbmltcG9ydCB7IENhbGVuZGFyU2VydmljZSB9IGZyb20gJy4uLy4uL2NhbGVuZGFyLnNlcnZpY2UnO1xuaW1wb3J0IHsgRmRSYW5nZURhdGUgfSBmcm9tICcuLi8uLi9tb2RlbHMvZmQtcmFuZ2UtZGF0ZSc7XG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbi8qKiBDb21wb25lbnQgcmVwcmVzZW50aW5nIHRoZSBkYXkgdmlldyBvZiB0aGUgY2FsZW5kYXIuICovXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2ZkLWNhbGVuZGFyLWRheS12aWV3JyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vY2FsZW5kYXItZGF5LXZpZXcuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL2NhbGVuZGFyLWRheS12aWV3LmNvbXBvbmVudC5zY3NzJ10sXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgICBob3N0OiB7XG4gICAgICAgICdbYXR0ci5pZF0nOiAnaWQgKyBcIi1kYXktdmlld1wiJ1xuICAgIH1cbn0pXG5leHBvcnQgY2xhc3MgQ2FsZW5kYXJEYXlWaWV3Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdDaGVja2VkLCBPbkNoYW5nZXMge1xuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBuZXdGb2N1c2VkRGF5SWQ6IHN0cmluZyA9ICcnO1xuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBzaG9ydFdlZWtEYXlzOiBzdHJpbmdbXTtcblxuICAgIC8qKiBBY3R1YWwgZGF5IGdyaWQgd2l0aCBwcmV2aW91cy9jdXJyZW50L25leHQgbW9udGggZGF5cyAqL1xuICAgIHB1YmxpYyBkYXlWaWV3R3JpZDogQ2FsZW5kYXJEYXlbXVtdO1xuXG4gICAgLyoqIEFuIFJ4SlMgU3ViamVjdCB0aGF0IHdpbGwga2lsbCB0aGUgZGF0YSBzdHJlYW0gdXBvbiBjb21wb25lbnTigJlzIGRlc3RydWN0aW9uIChmb3IgdW5zdWJzY3JpYmluZykgICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBvbkRlc3Ryb3kkOiBTdWJqZWN0PHZvaWQ+ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5mZC1jYWxlbmRhcl9fZGF0ZXMnKVxuICAgIHB1YmxpYyBmZENhbGVuZGFyRGF0ZVZpZXdDbGFzczogYm9vbGVhbiA9IHRydWU7XG5cbiAgICAvKiogQ3VycmVudGx5IGRpc3BsYXllZCBtb250aCBhbmQgeWVhciBmb3IgZGF5cyAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGN1cnJlbnRseURpc3BsYXllZDogQ2FsZW5kYXJDdXJyZW50O1xuXG4gICAgLyoqIFRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgRmREYXRlIG1vZGVsIGluIHNpbmdsZSBtb2RlLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNlbGVjdGVkRGF0ZTogRmREYXRlO1xuXG4gICAgLyoqIFRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgRmREYXRlcyBtb2RlbCBzdGFydCBhbmQgZW5kIGluIHJhbmdlIG1vZGUuICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgc2VsZWN0ZWRSYW5nZURhdGU6IEZkUmFuZ2VEYXRlO1xuXG4gICAgLyoqIFRoZSBkYXkgb2YgdGhlIHdlZWsgdGhlIGNhbGVuZGFyIHNob3VsZCBzdGFydCBvbi4gMSByZXByZXNlbnRzIFN1bmRheSwgMiBpcyBNb25kYXksIDMgaXMgVHVlc2RheSwgYW5kIHNvIG9uLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHN0YXJ0aW5nRGF5T2ZXZWVrOiBEYXlzT2ZXZWVrO1xuXG4gICAgLyoqIFRoZSB0eXBlIG9mIGNhbGVuZGFyLCAnc2luZ2xlJyBmb3Igc2luZ2xlIGRhdGUgc2VsZWN0aW9uIG9yICdyYW5nZScgZm9yIGEgcmFuZ2Ugb2YgZGF0ZXMuICovXG4gICAgQElucHV0KClcbiAgICBjYWxUeXBlOiBDYWxlbmRhclR5cGUgPSAnc2luZ2xlJztcblxuICAgIC8qKiBJZCBvZiB0aGUgY2FsZW5kYXIuIElmIG5vbmUgaXMgcHJvdmlkZWQsIG9uZSB3aWxsIGJlIGdlbmVyYXRlZC4gKi9cbiAgICBASW5wdXQoKSBpZDogc3RyaW5nO1xuXG4gICAgLyoqIEZ1bmN0aW9uIHRoYXQgYWxsb3dzIHRvIHNwZWNpZnkgd2hpY2ggZnVuY3Rpb24gd291bGQgYmUgY2FsbGVkLCB3aGVuIGZvY3VzIHdhbnRzIHRvIGVzY2FwZSAqL1xuICAgIEBJbnB1dCgpXG4gICAgZm9jdXNFc2NhcGVGdW5jdGlvbjogRnVuY3Rpb247XG5cbiAgICAvKiogRXZlbnQgZW1pdHRlZCBhbHdheXMsIHdoZW4gbW9kZWwgaXMgY2hhbmdlZCBpbiByYW5nZSBtb2RlICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIHJlYWRvbmx5IHNlbGVjdGVkUmFuZ2VEYXRlQ2hhbmdlOiBFdmVudEVtaXR0ZXI8RmRSYW5nZURhdGU+ID0gbmV3IEV2ZW50RW1pdHRlcjxGZFJhbmdlRGF0ZT4oKTtcblxuICAgIC8qKiBFdmVudCBlbWl0dGVkIGFsd2F5cywgd2hlbiBuZXh0IG1vbnRoIGlzIHNlbGVjdGVkLCBieSBmb2N1cyAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyByZWFkb25seSBuZXh0TW9udGhTZWxlY3Q6IEV2ZW50RW1pdHRlcjx2b2lkPiA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICAgIC8qKiBFdmVudCBlbWl0dGVkIGFsd2F5cywgd2hlbiBwcmV2aW91cyBtb250aCBpcyBzZWxlY3RlZCwgYnkgZm9jdXMgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgcmVhZG9ubHkgcHJldmlvdXNNb250aFNlbGVjdDogRXZlbnRFbWl0dGVyPHZvaWQ+ID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gICAgLyoqIEV2ZW50IGVtaXR0ZWQgYWx3YXlzLCB3aGVuIG1vZGVsIGlzIGNoYW5nZWQgaW4gc2luZ2xlIG1vZGUgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgcmVhZG9ubHkgc2VsZWN0ZWREYXRlQ2hhbmdlOiBFdmVudEVtaXR0ZXI8RmREYXRlPiA9IG5ldyBFdmVudEVtaXR0ZXI8RmREYXRlPigpO1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gdXNlZCB0byBkaXNhYmxlIGNlcnRhaW4gZGF0ZXMgaW4gdGhlIGNhbGVuZGFyLlxuICAgICAqIEBwYXJhbSBmZERhdGUgRmREYXRlXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBkaXNhYmxlRnVuY3Rpb24gPSBmdW5jdGlvbihmZERhdGU6IEZkRGF0ZSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHVzZWQgdG8gZGlzYWJsZSBjZXJ0YWluIGRhdGVzIGluIHRoZSBjYWxlbmRhciBmb3IgdGhlIHJhbmdlIHN0YXJ0IHNlbGVjdGlvbi5cbiAgICAgKiBAcGFyYW0gZmREYXRlIEZkRGF0ZVxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgZGlzYWJsZVJhbmdlU3RhcnRGdW5jdGlvbiA9IGZ1bmN0aW9uKGZkRGF0ZTogRmREYXRlKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gdXNlZCB0byBkaXNhYmxlIGNlcnRhaW4gZGF0ZXMgaW4gdGhlIGNhbGVuZGFyIGZvciB0aGUgcmFuZ2UgZW5kIHNlbGVjdGlvbi5cbiAgICAgKiBAcGFyYW0gZmREYXRlIEZkRGF0ZVxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgZGlzYWJsZVJhbmdlRW5kRnVuY3Rpb24gPSBmdW5jdGlvbihmZERhdGU6IEZkRGF0ZSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHVzZWQgdG8gYmxvY2sgY2VydGFpbiBkYXRlcyBpbiB0aGUgY2FsZW5kYXIgZm9yIHRoZSByYW5nZSBzdGFydCBzZWxlY3Rpb24uXG4gICAgICogQHBhcmFtIGZkRGF0ZSBGZERhdGVcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGJsb2NrUmFuZ2VTdGFydEZ1bmN0aW9uID0gZnVuY3Rpb24oZmREYXRlOiBGZERhdGUpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB1c2VkIHRvIGJsb2NrIGNlcnRhaW4gZGF0ZXMgaW4gdGhlIGNhbGVuZGFyIGZvciB0aGUgcmFuZ2UgZW5kIHNlbGVjdGlvbi5cbiAgICAgKiBAcGFyYW0gZmREYXRlIEZkRGF0ZVxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgYmxvY2tSYW5nZUVuZEZ1bmN0aW9uID0gZnVuY3Rpb24oZmREYXRlOiBGZERhdGUpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB1c2VkIHRvIGJsb2NrIGNlcnRhaW4gZGF0ZXMgaW4gdGhlIGNhbGVuZGFyLlxuICAgICAqIEBwYXJhbSBmZERhdGUgRmREYXRlXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBibG9ja0Z1bmN0aW9uID0gZnVuY3Rpb24oZmREYXRlOiBGZERhdGUpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcml2YXRlIGNhbGVuZGFySTE4bjogQ2FsZW5kYXJJMThuLFxuICAgICAgICBwcml2YXRlIGVSZWY6IEVsZW1lbnRSZWZcbiAgICApIHtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiBmb3Igc2VsZWN0aW5nIGEgZGF0ZSBvbiB0aGUgY2FsZW5kYXIuIFR5cGljYWxseSBjYWxsZWQgd2hlbiBhIGRhdGUgaXMgY2xpY2tlZCwgYnV0IGNhbiBhbHNvIGJlIGNhbGxlZCBwcm9ncmFtbWF0aWNhbGx5LlxuICAgICAqIEBwYXJhbSBkYXkgQ2FsZW5kYXJEYXkgb2JqZWN0IHRvIGJlIHNlbGVjdGVkLlxuICAgICAqL1xuICAgIHNlbGVjdERhdGUoZGF5OiBDYWxlbmRhckRheSwgZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgLyoqXG4gICAgICAgICAgICAgKiBUaGVyZSBhcmUgc29tZSBwcm9ibGVtcyB3aXRoIHBvcHVwIGludGVncmF0aW9uLiBBZnRlciBjbGlja2luZyBpbnNpZGUgZGF5IGNvbXBvbmVudCwgdGhlIHBvcG92ZXIgY2xvc2VzLlxuICAgICAgICAgICAgICovXG4gICAgICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICB0aGlzLm5ld0ZvY3VzZWREYXlJZCA9IGRheS5pZDtcbiAgICAgICAgICAgIHRoaXMuZm9jdXNFbGVtZW50KHRoaXMubmV3Rm9jdXNlZERheUlkKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWRheS5ibG9ja2VkICYmICFkYXkuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmNhbFR5cGUgPT09ICdzaW5nbGUnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZERhdGUgPSBkYXkuZGF0ZTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkRGF0ZUNoYW5nZS5lbWl0KGRheS5kYXRlKTtcbiAgICAgICAgICAgICAgICB0aGlzLmJ1aWxkRGF5Vmlld0dyaWQoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc2VsZWN0Q291bnRlciA9PT0gMCB8fCB0aGlzLnNlbGVjdENvdW50ZXIgPT09IDIpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFJhbmdlRGF0ZSA9IHsgc3RhcnQ6IGRheS5kYXRlLCBlbmQ6IG51bGwgfTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFJhbmdlRGF0ZUNoYW5nZS5lbWl0KHRoaXMuc2VsZWN0ZWRSYW5nZURhdGUpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmJ1aWxkRGF5Vmlld0dyaWQoKTtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuc2VsZWN0Q291bnRlciA9PT0gMSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiBkYXRlIHBpY2tlZCBpcyBoaWdoZXIgdGhhbiBhbHJlYWR5IGNob3Nlbiwgb3RoZXJ3aXNlIGp1c3QgZmlyc3Qgb25lXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlLnN0YXJ0LmdldFRpbWVTdGFtcCgpIDwgZGF5LmRhdGUuZ2V0VGltZVN0YW1wKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRSYW5nZURhdGUgPSB7IHN0YXJ0OiB0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlLnN0YXJ0LCBlbmQ6IGRheS5kYXRlIH07XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlID0geyBzdGFydDogZGF5LmRhdGUsIGVuZDogbnVsbCB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRSYW5nZURhdGVDaGFuZ2UuZW1pdCh0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5idWlsZERheVZpZXdHcmlkKCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIG5nT25Jbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLmJ1aWxkRGF5Vmlld0dyaWQoKTtcbiAgICAgICAgdGhpcy5zaG9ydFdlZWtEYXlzID0gdGhpcy5nZXRTaG9ydFdlZWtEYXlzKCk7XG4gICAgICAgIHRoaXMuY2FsZW5kYXJJMThuLmkxOG5DaGFuZ2VcbiAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLm9uRGVzdHJveSQpKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLnNob3J0V2Vla0RheXMgPSB0aGlzLmdldFNob3J0V2Vla0RheXMoKSlcbiAgICAgICAgO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuXG4gICAgICogIEFtb3VudCBvZiBzZWxlY3RlZCBkYXlzXG4gICAgICogIDAsIHdoZW4gbm9uZSxcbiAgICAgKiAgMSwgd2hlbiBvbmx5IHN0YXJ0RGF0ZSwgb3IgZW5kRGF0ZSBzYW1lIGFzIHN0YXJ0RGF0ZSxcbiAgICAgKiAgMiwgd2hlbiBib3RoXG4gICAgICovXG4gICAgZ2V0IHNlbGVjdENvdW50ZXIoKTogbnVtYmVyIHtcbiAgICAgICAgaWYgKCF0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlIHx8ICF0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlLnN0YXJ0KSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlLnN0YXJ0ICYmXG4gICAgICAgICAgICAoIXRoaXMuc2VsZWN0ZWRSYW5nZURhdGUuZW5kIHx8XG4gICAgICAgICAgICAgICAgQ2FsZW5kYXJTZXJ2aWNlLmRhdGVzRXF1YWwodGhpcy5zZWxlY3RlZFJhbmdlRGF0ZS5zdGFydCwgdGhpcy5zZWxlY3RlZFJhbmdlRGF0ZS5lbmQpXG4gICAgICAgICAgICApXG4gICAgICAgICkge1xuICAgICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5zZWxlY3RlZFJhbmdlRGF0ZS5zdGFydCAmJiB0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlLmVuZCkge1xuICAgICAgICAgICAgcmV0dXJuIDI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogTWV0aG9kIHRoYXQgaGFuZGxlcyBkYXkgY2VsbHMga2V5ZG93biBldmVudHMsXG4gICAgICogQHBhcmFtIGV2ZW50IEtleWJvYXJkRXZlbnRcbiAgICAgKiBAcGFyYW0gY2VsbCBDYWxlbmRhckRheVxuICAgICAqIEBwYXJhbSBncmlkIHdpdGggc3BlY2lmaWVkIGNvbHVtbiBhbmQgcm93IGFzIGEgeCBhbmQgeVxuICAgICAqL1xuICAgIG9uS2V5ZG93bkRheUhhbmRsZXIoZXZlbnQsIGNlbGw6IENhbGVuZGFyRGF5LCBncmlkOiB7IHg6IG51bWJlciwgeTogbnVtYmVyIH0pOiB2b2lkIHtcbiAgICAgICAgaWYgKGV2ZW50LmNvZGUgPT09ICdUYWInICYmICFldmVudC5zaGlmdEtleSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuZm9jdXNFc2NhcGVGdW5jdGlvbikge1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgdGhpcy5mb2N1c0VzY2FwZUZ1bmN0aW9uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBzd2l0Y2ggKGV2ZW50LmNvZGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlKCdTcGFjZScpOlxuICAgICAgICAgICAgICAgIGNhc2UoJ0VudGVyJyk6IHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3REYXRlKGNlbGwpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm5ld0ZvY3VzZWREYXlJZCA9IGNlbGwuaWQ7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlKCdBcnJvd1VwJyk6IHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGdyaWQueSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmV3Rm9jdXNlZERheUlkID0gdGhpcy5kYXlWaWV3R3JpZFtncmlkLnkgLSAxXVtncmlkLnhdLmlkO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RQcmV2aW91c01vbnRoKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5ld0ZvY3VzZWREYXlJZCA9IHRoaXMuZGF5Vmlld0dyaWRbdGhpcy5kYXlWaWV3R3JpZC5sZW5ndGggLSAxXVtncmlkLnhdLmlkO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlKCdBcnJvd0Rvd24nKToge1xuICAgICAgICAgICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoZ3JpZC55IDwgdGhpcy5kYXlWaWV3R3JpZC5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5ld0ZvY3VzZWREYXlJZCA9IHRoaXMuZGF5Vmlld0dyaWRbZ3JpZC55ICsgMV1bZ3JpZC54XS5pZDtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0TmV4dE1vbnRoKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5ld0ZvY3VzZWREYXlJZCA9IHRoaXMuZGF5Vmlld0dyaWRbMF1bZ3JpZC54XS5pZDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSgnQXJyb3dMZWZ0Jyk6IHtcbiAgICAgICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGdyaWQueCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmV3Rm9jdXNlZERheUlkID0gdGhpcy5kYXlWaWV3R3JpZFtncmlkLnldW2dyaWQueCAtIDFdLmlkO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGdyaWQueSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmV3Rm9jdXNlZERheUlkID0gdGhpcy5kYXlWaWV3R3JpZFtncmlkLnkgLSAxXVt0aGlzLmRheVZpZXdHcmlkWzBdLmxlbmd0aCAtIDFdLmlkO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RQcmV2aW91c01vbnRoKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm5ld0ZvY3VzZWREYXlJZCA9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kYXlWaWV3R3JpZFt0aGlzLmRheVZpZXdHcmlkLmxlbmd0aCAtIDFdW3RoaXMuZGF5Vmlld0dyaWRbMF0ubGVuZ3RoIC0gMV0uaWRcbiAgICAgICAgICAgICAgICAgICAgICAgIDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSgnQXJyb3dSaWdodCcpOiB7XG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChncmlkLnggPCB0aGlzLmRheVZpZXdHcmlkWzBdLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmV3Rm9jdXNlZERheUlkID0gdGhpcy5kYXlWaWV3R3JpZFtncmlkLnldW2dyaWQueCArIDFdLmlkO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGdyaWQueSA8IHRoaXMuZGF5Vmlld0dyaWQubGVuZ3RoIC0gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5uZXdGb2N1c2VkRGF5SWQgPSB0aGlzLmRheVZpZXdHcmlkW2dyaWQueSArIDFdWzBdLmlkO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3ROZXh0TW9udGgoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubmV3Rm9jdXNlZERheUlkID0gdGhpcy5kYXlWaWV3R3JpZFswXVswXS5pZDtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5uZXdGb2N1c2VkRGF5SWQpIHtcbiAgICAgICAgICAgIHRoaXMuZm9jdXNFbGVtZW50KHRoaXMubmV3Rm9jdXNlZERheUlkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgcHVibGljIG5nT25DaGFuZ2VzKCk6IHZvaWQge1xuICAgICAgICB0aGlzLmJ1aWxkRGF5Vmlld0dyaWQoKTtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIG5nQWZ0ZXJWaWV3Q2hlY2tlZCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMubmV3Rm9jdXNlZERheUlkKSB7XG4gICAgICAgICAgICB0aGlzLmZvY3VzRWxlbWVudCh0aGlzLm5ld0ZvY3VzZWREYXlJZCk7XG4gICAgICAgICAgICB0aGlzLm5ld0ZvY3VzZWREYXlJZCA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlblxuICAgICAqICBNZXRob2QgdGhhdCBhbGxvdyB0byBmb2N1cyBlbGVtZW50cyBpbnNpZGUgdGhpcyBjb21wb25lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgZm9jdXNFbGVtZW50KGVsZW1lbnRTZWxlY3Rvcik6IHZvaWQge1xuICAgICAgICBjb25zdCBlbGVtZW50VG9Gb2N1cyA9IHRoaXMuZVJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJyMnICsgZWxlbWVudFNlbGVjdG9yKTtcbiAgICAgICAgaWYgKGVsZW1lbnRUb0ZvY3VzKSB7XG4gICAgICAgICAgICBlbGVtZW50VG9Gb2N1cy5mb2N1cygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIEFjdGl2ZSBkYXkgbWVhbnMgdGhhdCB3aXRoIHRhYmluZGV4ID0gMCwgaXQncyBzZWxlY3RlZCBkYXkgb3IgdG9kYXkgb3IgZmlyc3QgZGF5ICovXG4gICAgcHVibGljIGZvY3VzQWN0aXZlRGF5KCk6IHZvaWQge1xuICAgICAgICB0aGlzLm5ld0ZvY3VzZWREYXlJZCA9IHRoaXMuZ2V0QWN0aXZlQ2VsbChcbiAgICAgICAgICAgIHRoaXMuY2FsZW5kYXJEYXlMaXN0LmZpbHRlcihjZWxsID0+IGNlbGwubW9udGhTdGF0dXMgPT09ICdjdXJyZW50JylcbiAgICAgICAgKS5pZDtcbiAgICB9XG5cbiAgICAvKiogRnVuY3Rpb24gdGhhdCBnaXZlcyBhcnJheSBvZiBhbGwgZGlzcGxheWVkIENhbGVuZGFyRGF5cyAqL1xuICAgIHB1YmxpYyBnZXQgY2FsZW5kYXJEYXlMaXN0KCk6IENhbGVuZGFyRGF5W10ge1xuICAgICAgICByZXR1cm4gdGhpcy5kYXlWaWV3R3JpZC5yZWR1Y2UoKHRvdGFsQ2FsZW5kYXJSb3dzOiBDYWxlbmRhckRheVtdLCBjYWxlbmRhclJvdzogQ2FsZW5kYXJEYXlbXSkgPT4ge1xuICAgICAgICAgICAgaWYgKCFjYWxlbmRhclJvdykge1xuICAgICAgICAgICAgICAgIGNhbGVuZGFyUm93ID0gW107XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gdG90YWxDYWxlbmRhclJvd3MuY29uY2F0KGNhbGVuZGFyUm93KTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWV0aG9kIHRoYXQgc2VsZWN0cyBwcmV2aW91cyBtb250aFxuICAgICAqIFRyaWdnZXJlZCBvbmx5IHdoZW4gdGhlIG1vbnRoIGlzIGNoYW5nZWQgZHVyaW5nIGNoYW5naW5nIGZvY3VzXG4gICAgICogQWxzbyB0cmlnZ2VycyBldmVudCB0byBwYXJlbnQgY2FsZW5kYXIgY29tcG9uZW50IGFuZCByZWJ1aWxkcyBkYXkgdmlldyBncmlkXG4gICAgICovXG4gICAgcHJpdmF0ZSBzZWxlY3RQcmV2aW91c01vbnRoKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50bHlEaXNwbGF5ZWQubW9udGggPiAxKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRseURpc3BsYXllZCA9IHsgLi4udGhpcy5jdXJyZW50bHlEaXNwbGF5ZWQsIG1vbnRoOiB0aGlzLmN1cnJlbnRseURpc3BsYXllZC5tb250aCAtIDEgfTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudGx5RGlzcGxheWVkID0geyB5ZWFyOiB0aGlzLmN1cnJlbnRseURpc3BsYXllZC55ZWFyIC0gMSwgbW9udGg6IDEyIH07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5idWlsZERheVZpZXdHcmlkKCk7XG4gICAgICAgIHRoaXMucHJldmlvdXNNb250aFNlbGVjdC5lbWl0KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWV0aG9kIHRoYXQgc2VsZWN0cyBuZXh0IG1vbnRoXG4gICAgICogVHJpZ2dlcmVkIG9ubHkgd2hlbiB0aGUgbW9udGggaXMgY2hhbmdlZCBkdXJpbmcgY2hhbmdpbmcgZm9jdXNcbiAgICAgKiBBbHNvIHRyaWdnZXJzIGV2ZW50IHRvIHBhcmVudCBjYWxlbmRhciBjb21wb25lbnQgYW5kIHJlYnVpbGRzIGRheSB2aWV3IGdyaWRcbiAgICAgKi9cbiAgICBwcml2YXRlIHNlbGVjdE5leHRNb250aCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuY3VycmVudGx5RGlzcGxheWVkLm1vbnRoID4gMSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50bHlEaXNwbGF5ZWQgPSB7IC4uLnRoaXMuY3VycmVudGx5RGlzcGxheWVkLCBtb250aDogdGhpcy5jdXJyZW50bHlEaXNwbGF5ZWQubW9udGggKyAxIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRseURpc3BsYXllZCA9IHsgeWVhcjogdGhpcy5jdXJyZW50bHlEaXNwbGF5ZWQueWVhciArIDEsIG1vbnRoOiAxIH07XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5idWlsZERheVZpZXdHcmlkKCk7XG4gICAgICAgIHRoaXMubmV4dE1vbnRoU2VsZWN0LmVtaXQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNZXRob2QgdGhhdCBjcmVhdGVzIGFycmF5IG9mIENhbGVuZGFyRGF5IG1vZGVscyB3aGljaCB3aWxsIGJlIHNob3duIG9uIGRheSBncmlkLFxuICAgICAqIGRlcGVuZGluZyBvbiBjdXJyZW50IG1vbnRoIGFuZCB5ZWFyLlxuICAgICAqL1xuICAgIHByaXZhdGUgcG9wdWxhdGVDYWxlbmRhcigpOiBDYWxlbmRhckRheVtdIHtcbiAgICAgICAgbGV0IGNhbGVuZGFyOiBDYWxlbmRhckRheVtdID0gW107XG5cbiAgICAgICAgY2FsZW5kYXIgPSB0aGlzLmdldFByZXZpb3VzTW9udGhEYXlzKGNhbGVuZGFyKTtcbiAgICAgICAgY2FsZW5kYXIgPSBjYWxlbmRhci5jb25jYXQodGhpcy5nZXRDdXJyZW50TW9udGhEYXlzKCkpO1xuICAgICAgICBjYWxlbmRhciA9IHRoaXMuZ2V0TmV4dE1vbnRoRGF5cyhjYWxlbmRhcik7XG5cbiAgICAgICAgY2FsZW5kYXIuZm9yRWFjaCgoY2FsbCwgaW5kZXg6IG51bWJlcikgPT4gY2FsbC5pZCA9IHRoaXMuaWQgKyAnLWZkLWRheS0nICsgKE1hdGguZmxvb3IoaW5kZXggLyA3KSArIDEpICsgJycgKyAoaW5kZXggJSA3KSk7XG5cbiAgICAgICAgcmV0dXJuIGNhbGVuZGFyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1ldGhvZCB0aGF0IGJ1aWxkcyAyIGRpbWVuc2lvbnMgZGF5IHZpZXcgZ3JpZCwgYWxzbyBzZXRzIHVwIGN1cnJlbnRseSBkaXNwbGF5ZWQgbW9udGgsIG9yIHllYXIsXG4gICAgICogd2hlbiB0aGVyZSBpcyBub3QgYW55LlxuICAgICAqL1xuICAgIHByaXZhdGUgYnVpbGREYXlWaWV3R3JpZCgpOiB2b2lkIHtcbiAgICAgICAgaWYgKCF0aGlzLmN1cnJlbnRseURpc3BsYXllZCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWREYXRlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50bHlEaXNwbGF5ZWQgPSB7IG1vbnRoOiB0aGlzLnNlbGVjdGVkRGF0ZS5tb250aCwgeWVhcjogdGhpcy5zZWxlY3RlZERhdGUueWVhciB9O1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRseURpc3BsYXllZCA9IHsgbW9udGg6IEZkRGF0ZS5nZXRUb2RheSgpLm1vbnRoLCB5ZWFyOiBGZERhdGUuZ2V0VG9kYXkoKS55ZWFyIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBjYWxlbmRhckRheXMgPSB0aGlzLnBvcHVsYXRlQ2FsZW5kYXIoKTtcbiAgICAgICAgY29uc3QgZGF5Vmlld0dyaWQ6IENhbGVuZGFyRGF5W11bXSA9IFtdO1xuXG4gICAgICAgIHdoaWxlIChjYWxlbmRhckRheXMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgZGF5Vmlld0dyaWQucHVzaChjYWxlbmRhckRheXMuc3BsaWNlKDAsIDcpKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmRheVZpZXdHcmlkID0gZGF5Vmlld0dyaWQ7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNZXRob2Qgd2hpY2ggcHJvdmlkZXMgYXJyYXkgb2YgQ2FsZW5kYXJEYXksIHdoaWNoIGNvbnRhaW5zIGV2ZXJ5IHNpbmdsZSBkYXkgb2YgY3VycmVudGx5IHNob3duIG1vbnRoL3llYXIuXG4gICAgICovXG4gICAgcHJpdmF0ZSBnZXRDdXJyZW50TW9udGhEYXlzKCk6IENhbGVuZGFyRGF5W10ge1xuICAgICAgICBjb25zdCBtb250aCA9IHRoaXMuY3VycmVudGx5RGlzcGxheWVkLm1vbnRoO1xuICAgICAgICBjb25zdCB5ZWFyID0gdGhpcy5jdXJyZW50bHlEaXNwbGF5ZWQueWVhcjtcbiAgICAgICAgY29uc3QgY2FsZW5kYXJEYXlzOiBDYWxlbmRhckRheVtdID0gW107XG4gICAgICAgIGNvbnN0IGFtb3VudE9mRGF5c0luQ3VycmVudE1vbnRoOiBudW1iZXIgPSBDYWxlbmRhclNlcnZpY2UuZ2V0RGF5c0luTW9udGgobW9udGgsIHllYXIpO1xuICAgICAgICBmb3IgKGxldCBkYXlOdW1iZXIgPSAxOyBkYXlOdW1iZXIgPD0gYW1vdW50T2ZEYXlzSW5DdXJyZW50TW9udGg7IGRheU51bWJlcisrKSB7XG4gICAgICAgICAgICBjb25zdCBmZERhdGU6IEZkRGF0ZSA9IG5ldyBGZERhdGUoeWVhciwgbW9udGgsIGRheU51bWJlcik7XG4gICAgICAgICAgICBjYWxlbmRhckRheXMucHVzaCh7XG4gICAgICAgICAgICAgICAgLi4udGhpcy5nZXREYXkoZmREYXRlKSxcbiAgICAgICAgICAgICAgICBtb250aFN0YXR1czogJ2N1cnJlbnQnLFxuICAgICAgICAgICAgICAgIHRvZGF5OiBDYWxlbmRhclNlcnZpY2UuZGF0ZXNFcXVhbChGZERhdGUuZ2V0VG9kYXkoKSwgZmREYXRlKVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5nZXRBY3RpdmVDZWxsKGNhbGVuZGFyRGF5cykuaXNUYWJJbmRleGVkID0gdHJ1ZTtcbiAgICAgICAgcmV0dXJuIGNhbGVuZGFyRGF5cztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNZXRob2QgdGhhdCByZXR1cm5zIGFjdGl2ZSBjZWxsLCB3aGljaCBtZWFuczpcbiAgICAgKiBpZiB0aGVyZSBpcyBhbnkgc2VsZWN0ZWQgZGF5LCByZXR1cm4gc2VsZWN0ZWQgZGF5XG4gICAgICogaWYgdGhlcmUgaXMgbm8gc2VsZWN0ZWQgZGF5LCBidXQgdGhlcmUgaXMgdG9kYXkgZGF5LCByZXR1cm4gdG9kYXkgZGF5XG4gICAgICogaWYgdGhlcmUgaXMgbm8gdG9kYXksIG9yIHNlbGVjdGVkLCByZXR1cm4gZmlyc3Qgb25lXG4gICAgICovXG4gICAgcHJpdmF0ZSBnZXRBY3RpdmVDZWxsKGNhbGVuZGFyRGF5czogQ2FsZW5kYXJEYXlbXSk6IENhbGVuZGFyRGF5IHtcbiAgICAgICAgaWYgKGNhbGVuZGFyRGF5cy5maW5kKGNlbGwgPT4gY2VsbC5zZWxlY3RlZCkpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxlbmRhckRheXMuZmluZChjZWxsID0+IGNlbGwuc2VsZWN0ZWQpO1xuICAgICAgICB9IGVsc2UgaWYgKGNhbGVuZGFyRGF5cy5maW5kKGNlbGwgPT4gY2VsbC50b2RheSkpIHtcbiAgICAgICAgICAgIHJldHVybiBjYWxlbmRhckRheXMuZmluZChjZWxsID0+IGNlbGwudG9kYXkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGVuZGFyRGF5c1swXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE1ldGhvZCB3aGljaCBwcm92aWRlcyBhcnJheSBvZiBDYWxlbmRhckRheSwgd2hpY2ggY29udGFpbnMgbGFzdCAwLTYgZGF5cyBvZiBwcmV2aW91cyBtb250aC95ZWFyLiBUaGVzZXMgZGF5c1xuICAgICAqIGZpbGxzIHRoZSBnYXAgYmV0d2VlbiBzdGFydGluZyBzdGFydGluZ0RheU9mV2VlayBhbmQgZmlyc3QgZGF5IG9mIGN1cnJlbnQgbW9udGhcbiAgICAgKi9cbiAgICBwcml2YXRlIGdldFByZXZpb3VzTW9udGhEYXlzKGNhbGVuZGFyRGF5czogQ2FsZW5kYXJEYXlbXSk6IENhbGVuZGFyRGF5W10ge1xuICAgICAgICBjb25zdCBtb250aCA9IHRoaXMuY3VycmVudGx5RGlzcGxheWVkLm1vbnRoID4gMSA/IHRoaXMuY3VycmVudGx5RGlzcGxheWVkLm1vbnRoIC0gMSA6IDEyO1xuICAgICAgICBjb25zdCB5ZWFyID0gdGhpcy5jdXJyZW50bHlEaXNwbGF5ZWQubW9udGggPiAxID8gdGhpcy5jdXJyZW50bHlEaXNwbGF5ZWQueWVhciA6IHRoaXMuY3VycmVudGx5RGlzcGxheWVkLnllYXIgLSAxO1xuICAgICAgICBjb25zdCBhbW91bnRPZkRheXNJbkN1cnJlbnRNb250aDogbnVtYmVyID0gQ2FsZW5kYXJTZXJ2aWNlLmdldERheXNJbk1vbnRoKG1vbnRoLCB5ZWFyKTtcbiAgICAgICAgY29uc3QgcHJldk1vbnRoTGFzdERhdGUgPSBuZXcgRmREYXRlKHllYXIsIG1vbnRoLCBhbW91bnRPZkRheXNJbkN1cnJlbnRNb250aCk7XG4gICAgICAgIGNvbnN0IHByZXZNb250aExhc3REYXkgPSBhbW91bnRPZkRheXNJbkN1cnJlbnRNb250aDtcbiAgICAgICAgbGV0IHByZXZNb250aExhc3RXZWVrRGF5ID0gcHJldk1vbnRoTGFzdERhdGUuZ2V0RGF5KCkgLSB0aGlzLnN0YXJ0aW5nRGF5T2ZXZWVrO1xuXG4gICAgICAgIC8qKiBDaGVja2luZyBpZiB0aGVyZSBhcmUgc29tZSBkYXlzIGN1dCBieSBzdGFydGluZ0RheU9mV2VlayBvcHRpb25cbiAgICAgICAgICogIElmIHllcywgdGhlcmUgaXMgd2hvbGUgd2VlayBhZGRlZCwgdG8gYXZvaWQgaGlkaW5nXG4gICAgICAgICAqL1xuICAgICAgICBpZiAocHJldk1vbnRoTGFzdFdlZWtEYXkgPCAwKSB7XG4gICAgICAgICAgICBwcmV2TW9udGhMYXN0V2Vla0RheSA9IHByZXZNb250aExhc3RXZWVrRGF5ICsgNztcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwcmV2TW9udGhMYXN0V2Vla0RheSA8IDYpIHtcbiAgICAgICAgICAgIHdoaWxlIChwcmV2TW9udGhMYXN0V2Vla0RheSA+PSAwKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcHJldk1vbnRoRGF5ID0gcHJldk1vbnRoTGFzdERheSAtIHByZXZNb250aExhc3RXZWVrRGF5O1xuICAgICAgICAgICAgICAgIGNvbnN0IGZkRGF0ZSA9IG5ldyBGZERhdGUoeWVhciwgbW9udGgsIHByZXZNb250aERheSk7XG4gICAgICAgICAgICAgICAgY2FsZW5kYXJEYXlzLnB1c2goeyAuLi50aGlzLmdldERheShmZERhdGUpLCBtb250aFN0YXR1czogJ3ByZXZpb3VzJyB9KTtcbiAgICAgICAgICAgICAgICBwcmV2TW9udGhMYXN0V2Vla0RheS0tO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYWxlbmRhckRheXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWV0aG9kIHdoaWNoIHByb3ZpZGVzIGFycmF5IG9mIENhbGVuZGFyRGF5LCB3aGljaCBjb250YWlucyBmaXJzdCBkYXlzIG9mIG5leHQgbW9udGgveWVhci4gVGhlc2VzIGRheXNcbiAgICAgKiBmaWxscyB0aGUgZ2FwIGJldHdlZW4gbGFzdCBkYXkgb2YgY3VycmVudCBkYXkgYW5kIGVuZCBvZiA2LXdlZWtzIGNhbGVuZGFyIGdyaWQuXG4gICAgICovXG4gICAgcHJpdmF0ZSBnZXROZXh0TW9udGhEYXlzKGNhbGVuZGFyRGF5czogQ2FsZW5kYXJEYXlbXSk6IENhbGVuZGFyRGF5W10ge1xuICAgICAgICBjb25zdCBtb250aCA9IHRoaXMuY3VycmVudGx5RGlzcGxheWVkLm1vbnRoIDwgMTIgPyB0aGlzLmN1cnJlbnRseURpc3BsYXllZC5tb250aCArIDEgOiAxO1xuICAgICAgICBjb25zdCB5ZWFyID0gdGhpcy5jdXJyZW50bHlEaXNwbGF5ZWQubW9udGggPCAxMiA/IHRoaXMuY3VycmVudGx5RGlzcGxheWVkLnllYXIgOiB0aGlzLmN1cnJlbnRseURpc3BsYXllZC55ZWFyICsgMTtcblxuICAgICAgICAvLyBUaGUgY2FsZW5kYXIgZ3JpZCBjYW4gaGF2ZSA2ICg0MiBkYXlzKSB3ZWVrc1xuICAgICAgICBjb25zdCBuZXh0TW9udGhEaXNwbGF5ZWREYXlzID0gNDIgLSBjYWxlbmRhckRheXMubGVuZ3RoO1xuXG4gICAgICAgIGZvciAobGV0IG5leHREID0gMTsgbmV4dEQgPD0gbmV4dE1vbnRoRGlzcGxheWVkRGF5czsgbmV4dEQrKykge1xuICAgICAgICAgICAgY29uc3QgZmREYXRlID0gbmV3IEZkRGF0ZSh5ZWFyLCBtb250aCwgbmV4dEQpO1xuICAgICAgICAgICAgY2FsZW5kYXJEYXlzLnB1c2goeyAuLi50aGlzLmdldERheShmZERhdGUpLCBtb250aFN0YXR1czogJ25leHQnIH0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYWxlbmRhckRheXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWV0aG9kIHRoYXQgZ2VuZXJhdGVzIHdob2xlIGRheSBtb2RlbCBiYXNpbmcgb24gZmREYXRlLCBkaXNhYmxpbmcgZnVuY3Rpb25zLCBibG9jayBmdW5jdGlvbnMsIGFuZCBhY3R1YWxseVxuICAgICAqIGNob3NlbiByYW5nZSAvIHNpbmdsZSBkYXRlLlxuICAgICAqL1xuICAgIHByaXZhdGUgZ2V0RGF5KGZkRGF0ZTogRmREYXRlKTogQ2FsZW5kYXJEYXkge1xuICAgICAgICBjb25zdCBkYXk6IENhbGVuZGFyRGF5ID0ge1xuICAgICAgICAgICAgZGF0ZTogZmREYXRlLFxuICAgICAgICAgICAgd2Vla0RheTogZmREYXRlLmdldERheSgpLFxuICAgICAgICAgICAgZGlzYWJsZWQ6IHRoaXMuZGlzYWJsZUZ1bmN0aW9uKGZkRGF0ZSksXG4gICAgICAgICAgICBibG9ja2VkOiB0aGlzLmJsb2NrRnVuY3Rpb24oZmREYXRlKSxcbiAgICAgICAgICAgIHNlbGVjdGVkOiAoXG4gICAgICAgICAgICAgICAgKHRoaXMuY2FsVHlwZSA9PT0gJ3NpbmdsZScgJiYgQ2FsZW5kYXJTZXJ2aWNlLmRhdGVzRXF1YWwoZmREYXRlLCB0aGlzLnNlbGVjdGVkRGF0ZSkpIHx8XG4gICAgICAgICAgICAgICAgKHRoaXMuc2VsZWN0ZWRSYW5nZURhdGUgJiYgQ2FsZW5kYXJTZXJ2aWNlLmRhdGVzRXF1YWwoZmREYXRlLCB0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlLnN0YXJ0KSkgfHxcbiAgICAgICAgICAgICAgICAodGhpcy5zZWxlY3RlZFJhbmdlRGF0ZSAmJiBDYWxlbmRhclNlcnZpY2UuZGF0ZXNFcXVhbChmZERhdGUsIHRoaXMuc2VsZWN0ZWRSYW5nZURhdGUuZW5kKSlcbiAgICAgICAgICAgICksXG4gICAgICAgICAgICBzZWxlY3RlZEZpcnN0OiAodGhpcy5zZWxlY3RlZFJhbmdlRGF0ZSAmJiBDYWxlbmRhclNlcnZpY2UuZGF0ZXNFcXVhbChmZERhdGUsIHRoaXMuc2VsZWN0ZWRSYW5nZURhdGUuc3RhcnQpKSxcbiAgICAgICAgICAgIHNlbGVjdGVkTGFzdDogKHRoaXMuc2VsZWN0ZWRSYW5nZURhdGUgJiYgQ2FsZW5kYXJTZXJ2aWNlLmRhdGVzRXF1YWwoZmREYXRlLCB0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlLmVuZCkpLFxuICAgICAgICAgICAgc2VsZWN0ZWRSYW5nZTogKHRoaXMuc2VsZWN0ZWRSYW5nZURhdGUgJiYgKFxuICAgICAgICAgICAgICAgICh0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlLnN0YXJ0ICYmICh0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlLnN0YXJ0LmdldFRpbWVTdGFtcCgpIDwgZmREYXRlLmdldFRpbWVTdGFtcCgpKSkgJiZcbiAgICAgICAgICAgICAgICAodGhpcy5zZWxlY3RlZFJhbmdlRGF0ZS5lbmQgJiYgKHRoaXMuc2VsZWN0ZWRSYW5nZURhdGUuZW5kLmdldFRpbWVTdGFtcCgpID4gZmREYXRlLmdldFRpbWVTdGFtcCgpKSlcbiAgICAgICAgICAgICkpLFxuICAgICAgICAgICAgYXJpYUxhYmVsOiB0aGlzLmNhbGVuZGFySTE4bi5nZXREYXlBcmlhTGFiZWwoZmREYXRlLnRvRGF0ZSgpKVxuICAgICAgICB9O1xuXG4gICAgICAgIGlmICh0aGlzLmNhbFR5cGUgPT09ICdyYW5nZScgJiYgKHRoaXMuc2VsZWN0Q291bnRlciA9PT0gMCB8fCB0aGlzLnNlbGVjdENvdW50ZXIgPT09IDIpKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5kaXNhYmxlUmFuZ2VTdGFydEZ1bmN0aW9uICYmICFkYXkuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgICAgICBkYXkuZGlzYWJsZWQgPSB0aGlzLmRpc2FibGVSYW5nZVN0YXJ0RnVuY3Rpb24oZGF5LmRhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuYmxvY2tSYW5nZVN0YXJ0RnVuY3Rpb24gJiYgIWRheS5ibG9ja2VkKSB7XG4gICAgICAgICAgICAgICAgZGF5LmJsb2NrZWQgPSB0aGlzLmJsb2NrUmFuZ2VTdGFydEZ1bmN0aW9uKGRheS5kYXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLnNlbGVjdENvdW50ZXIgPT09IDEpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLmRpc2FibGVSYW5nZUVuZEZ1bmN0aW9uICYmICFkYXkuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgICAgICBkYXkuZGlzYWJsZWQgPSB0aGlzLmRpc2FibGVSYW5nZUVuZEZ1bmN0aW9uKGRheS5kYXRlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMuYmxvY2tSYW5nZUVuZEZ1bmN0aW9uICYmICFkYXkuYmxvY2tlZCkge1xuICAgICAgICAgICAgICAgIGRheS5ibG9ja2VkID0gdGhpcy5ibG9ja1JhbmdlRW5kRnVuY3Rpb24oZGF5LmRhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRheTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNZXRob2QgdGhhdCByZXR1cm5zIGZpcnN0IGxldHRlciBvZiBldmVyeSB3ZWVrZGF5LCBiYXNpbmcgb24gQ2FsZW5kYXJJMThuRGVmYXVsdC4gQ2FuIGJlIGNoYW5nZWQgYnkgdXNlciBieVxuICAgICAqIHByb3ZpZGluZyBvdGhlciBjbGFzcyB3aGljaCBpbXBsZW1lbnRzIENhbGVuZGFySTE4blxuICAgICAqL1xuICAgIHByaXZhdGUgZ2V0U2hvcnRXZWVrRGF5cygpOiBzdHJpbmdbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNhbGVuZGFySTE4bi5nZXRBbGxTaG9ydFdlZWtkYXlzKClcbiAgICAgICAgICAgIC5zbGljZSh0aGlzLnN0YXJ0aW5nRGF5T2ZXZWVrIC0gMSlcbiAgICAgICAgICAgIC5jb25jYXQodGhpcy5jYWxlbmRhckkxOG4uZ2V0QWxsU2hvcnRXZWVrZGF5cygpLnNsaWNlKDAsIHRoaXMuc3RhcnRpbmdEYXlPZldlZWsgLSAxKSlcbiAgICAgICAgICAgIC5tYXAod2Vla2RheSA9PiB3ZWVrZGF5WzBdLnRvTG9jYWxlVXBwZXJDYXNlKCkpO1xuICAgIH1cbn1cbiJdfQ==