UNPKG

fundamental-ngx

Version:

SAP Fundamentals, implemented in Angular

807 lines 63.2 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { ChangeDetectorRef, Component, EventEmitter, forwardRef, HostBinding, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core'; import { CalendarI18n } from './i18n/calendar-i18n'; import { FdDate } from './models/fd-date'; import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms'; import { CalendarDayViewComponent } from './calendar-views/calendar-day-view/calendar-day-view.component'; import { CalendarYearViewComponent } from './calendar-views/calendar-year-view/calendar-year-view.component'; /** @type {?} */ var calendarUniqueId = 0; /** * Months: 1 = January, 12 = december. * Days: 1 = Sunday, 7 = Saturday * * Calendar component used for selecting dates, typically used by the DatePicker and DateTimePicker components. * Supports the Angular forms module, enabling form validity, ngModel, etc. */ var CalendarComponent = /** @class */ (function () { /** @hidden */ function CalendarComponent(calendarI18n, changeDetectorRef) { var _this = this; this.calendarI18n = calendarI18n; this.changeDetectorRef = changeDetectorRef; /** * @hidden */ this.fdCalendarClass = true; /** * @hidden */ this.fdHasDisplayBlockClass = true; /** * The currently selected FdDate model in single mode. */ this.selectedDate = FdDate.getToday(); /** * Actually shown active view one of 'day' | 'month' | 'year' */ this.activeView = 'day'; /** * The day of the week the calendar should start on. 1 represents Sunday, 2 is Monday, 3 is Tuesday, and so on. */ this.startingDayOfWeek = 1; /** * The type of calendar, 'single' for single date selection or 'range' for a range of dates. */ this.calType = 'single'; /** * Id of the calendar. If none is provided, one will be generated. */ this.id = 'fd-calendar-' + calendarUniqueId++; /** * Event thrown every time active view is changed */ this.activeViewChange = new EventEmitter(); /** * Event thrown every time selected date in single mode is changed */ this.selectedDateChange = new EventEmitter(); /** * Event thrown every time selected first or last date in range mode is changed */ this.selectedRangeDateChange = new EventEmitter(); /** * Event thrown every time when value is overwritten from outside and throw back isValid */ this.isValidDateChange = new EventEmitter(); /** * Event thrown every time when calendar should be closed */ this.closeCalendar = new EventEmitter(); /** * @hidden */ this.onChange = (/** * @return {?} */ function () { }); /** * @hidden */ this.onTouched = (/** * @return {?} */ function () { }); /** * 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; }); /** * That allows to define function that should happen, when focus should normally escape of component */ this.escapeFocusFunction = (/** * @return {?} */ function () { if (document.getElementById(_this.id + '-left-arrow')) { document.getElementById(_this.id + '-left-arrow').focus(); } }); } /** @hidden */ /** * @hidden * @return {?} */ CalendarComponent.prototype.ngOnInit = /** * @hidden * @return {?} */ function () { this.prepareDisplayedView(); }; /** * @hidden * Function that provides support for ControlValueAccessor that allows to use [(ngModel)] or forms. */ /** * @hidden * Function that provides support for ControlValueAccessor that allows to use [(ngModel)] or forms. * @param {?} selected * @return {?} */ CalendarComponent.prototype.writeValue = /** * @hidden * Function that provides support for ControlValueAccessor that allows to use [(ngModel)] or forms. * @param {?} selected * @return {?} */ function (selected) { /** @type {?} */ var valid = true; if (selected) { if (this.calType === 'single') { selected = (/** @type {?} */ (selected)); valid = selected.isDateValid(); this.selectedDate = selected; if (selected.isDateValid()) { this.prepareDisplayedView(); } } else if (this.calType === 'range') { selected = (/** @type {?} */ (selected)); if (!selected.start || !selected.end) { valid = false; } if (selected.start && !selected.start.isDateValid()) { valid = false; } if (selected.end && !selected.end.isDateValid()) { valid = false; } this.selectedRangeDate = { start: selected.start, end: selected.end }; if (valid) { this.prepareDisplayedView(); } } } this.isValidDateChange.emit(valid); }; /** * @hidden * Function that implements Validator Interface, adds validation support for forms */ /** * @hidden * Function that implements Validator Interface, adds validation support for forms * @param {?} control * @return {?} */ CalendarComponent.prototype.validate = /** * @hidden * Function that implements Validator Interface, adds validation support for forms * @param {?} control * @return {?} */ function (control) { return this.isModelValid() ? null : { dateValidation: { valid: false } }; }; /** @hidden */ /** * @hidden * @param {?} fn * @return {?} */ CalendarComponent.prototype.registerOnChange = /** * @hidden * @param {?} fn * @return {?} */ function (fn) { this.onChange = fn; }; /** @hidden */ /** * @hidden * @param {?} fn * @return {?} */ CalendarComponent.prototype.registerOnTouched = /** * @hidden * @param {?} fn * @return {?} */ function (fn) { this.onTouched = fn; }; /** @hidden */ /** * @hidden * @param {?} isDisabled * @return {?} */ CalendarComponent.prototype.setDisabledState = /** * @hidden * @param {?} isDisabled * @return {?} */ function (isDisabled) { // Not needed }; /** * Method that handle active view change and throws event. */ /** * Method that handle active view change and throws event. * @param {?} activeView * @return {?} */ CalendarComponent.prototype.handleActiveViewChange = /** * Method that handle active view change and throws event. * @param {?} activeView * @return {?} */ function (activeView) { this.activeView = activeView; this.activeViewChange.emit(activeView); }; /** * @hidden * Method that is triggered by events from day view component, when there is selected single date changed */ /** * @hidden * Method that is triggered by events from day view component, when there is selected single date changed * @param {?} date * @return {?} */ CalendarComponent.prototype.selectedDateChanged = /** * @hidden * Method that is triggered by events from day view component, when there is selected single date changed * @param {?} date * @return {?} */ function (date) { this.selectedDate = date; this.onChange(date); this.onTouched(); this.selectedDateChange.emit(date); this.closeCalendar.emit(); }; /** * @hidden * Method that is triggered by events from day view component, when there is selected range date changed */ /** * @hidden * Method that is triggered by events from day view component, when there is selected range date changed * @param {?} dates * @return {?} */ CalendarComponent.prototype.selectedRangeDateChanged = /** * @hidden * Method that is triggered by events from day view component, when there is selected range date changed * @param {?} dates * @return {?} */ function (dates) { if (dates) { this.selectedRangeDate = { start: dates.start, end: dates.end ? dates.end : dates.start }; this.selectedRangeDateChange.emit(this.selectedRangeDate); this.onChange(this.selectedRangeDate); this.onTouched(); this.closeCalendar.emit(); } }; /** Function that handles next arrow icon click, depending on current view it changes month, year or list of years */ /** * Function that handles next arrow icon click, depending on current view it changes month, year or list of years * @return {?} */ CalendarComponent.prototype.handleNextArrowClick = /** * Function that handles next arrow icon click, depending on current view it changes month, year or list of years * @return {?} */ function () { switch (this.activeView) { case 'day': this.displayNextMonth(); break; case 'month': this.displayNextYear(); break; case 'year': this.displayNextYearList(); break; } this.onTouched(); }; /** Function that handles previous arrow icon click, depending on current view it changes month, year or list of years */ /** * Function that handles previous arrow icon click, depending on current view it changes month, year or list of years * @return {?} */ CalendarComponent.prototype.handlePreviousArrowClick = /** * Function that handles previous arrow icon click, depending on current view it changes month, year or list of years * @return {?} */ function () { switch (this.activeView) { case 'day': this.displayPreviousMonth(); break; case 'month': this.displayPreviousYear(); break; case 'year': this.displayPreviousYearList(); break; } this.onTouched(); }; /** Function that allows to switch actual view to next month */ /** * Function that allows to switch actual view to next month * @return {?} */ CalendarComponent.prototype.displayNextMonth = /** * Function that allows to switch actual view to next month * @return {?} */ function () { if (this.currentlyDisplayed.month === 12) { this.currentlyDisplayed = { year: this.currentlyDisplayed.year + 1, month: 1 }; } else { this.currentlyDisplayed = { year: this.currentlyDisplayed.year, month: this.currentlyDisplayed.month + 1 }; } }; /** Function that allows to switch actual view to previous month */ /** * Function that allows to switch actual view to previous month * @return {?} */ CalendarComponent.prototype.displayPreviousMonth = /** * Function that allows to switch actual view to previous month * @return {?} */ function () { if (this.currentlyDisplayed.month <= 1) { this.currentlyDisplayed = { year: this.currentlyDisplayed.year - 1, month: 12 }; } else { this.currentlyDisplayed = { year: this.currentlyDisplayed.year, month: this.currentlyDisplayed.month - 1 }; } }; /** Function that allows to switch actual view to next year */ /** * Function that allows to switch actual view to next year * @return {?} */ CalendarComponent.prototype.displayNextYear = /** * Function that allows to switch actual view to next year * @return {?} */ function () { this.currentlyDisplayed = { month: this.currentlyDisplayed.month, year: this.currentlyDisplayed.year + 1 }; }; /** Function that allows to switch actual view to previous year */ /** * Function that allows to switch actual view to previous year * @return {?} */ CalendarComponent.prototype.displayPreviousYear = /** * Function that allows to switch actual view to previous year * @return {?} */ function () { this.currentlyDisplayed = { month: this.currentlyDisplayed.month, year: this.currentlyDisplayed.year - 1 }; }; /** Function that allows to switch actually displayed list of year to next year list*/ /** * Function that allows to switch actually displayed list of year to next year list * @return {?} */ CalendarComponent.prototype.displayNextYearList = /** * Function that allows to switch actually displayed list of year to next year list * @return {?} */ function () { this.yearViewComponent.loadNextYearList(); }; /** Function that allows to switch actually displayed list of year to previous year list*/ /** * Function that allows to switch actually displayed list of year to previous year list * @return {?} */ CalendarComponent.prototype.displayPreviousYearList = /** * Function that allows to switch actually displayed list of year to previous year list * @return {?} */ function () { this.yearViewComponent.loadPreviousYearList(); }; /** Function that allows to change currently displayed month/year configuration, * which are connected to days displayed */ /** * Function that allows to change currently displayed month/year configuration, * which are connected to days displayed * @param {?} fdDate * @return {?} */ CalendarComponent.prototype.setCurrentlyDisplayed = /** * Function that allows to change currently displayed month/year configuration, * which are connected to days displayed * @param {?} fdDate * @return {?} */ function (fdDate) { this.currentlyDisplayed = { month: fdDate.month, year: fdDate.year }; }; /** * @hidden * Function that handles changes from month view child component, changes actual view and changes currently displayed month */ /** * @hidden * Function that handles changes from month view child component, changes actual view and changes currently displayed month * @param {?} month * @return {?} */ CalendarComponent.prototype.handleMonthViewChange = /** * @hidden * Function that handles changes from month view child component, changes actual view and changes currently displayed month * @param {?} month * @return {?} */ function (month) { this.currentlyDisplayed = { month: month, year: this.currentlyDisplayed.year }; this.activeView = 'day'; this.activeViewChange.emit(this.activeView); this.changeDetectorRef.detectChanges(); this.dayViewComponent.focusActiveDay(); }; /** * @param {?} yearSelected * @return {?} */ CalendarComponent.prototype.selectedYear = /** * @param {?} yearSelected * @return {?} */ function (yearSelected) { this.activeView = 'day'; this.currentlyDisplayed.year = yearSelected; this.changeDetectorRef.detectChanges(); this.dayViewComponent.focusActiveDay(); }; /** Method that provides information if model selected date/dates have properly types and are valid */ /** * Method that provides information if model selected date/dates have properly types and are valid * @return {?} */ CalendarComponent.prototype.isModelValid = /** * Method that provides information if model selected date/dates have properly types and are valid * @return {?} */ function () { if (this.calType === 'single') { return this.selectedDate && this.selectedDate instanceof FdDate && this.selectedDate.isDateValid(); } else { return this.selectedRangeDate && (this.selectedRangeDate.start && this.selectedRangeDate.start instanceof FdDate && this.selectedRangeDate.start.isDateValid()) && (this.selectedRangeDate.end && this.selectedRangeDate.end instanceof FdDate && this.selectedRangeDate.start.isDateValid()); } }; /** * @hidden * Method that sets up the currently displayed variables, like shown month and year. * Day grid is based on currently displayed month and year */ /** * @hidden * Method that sets up the currently displayed variables, like shown month and year. * Day grid is based on currently displayed month and year * @private * @return {?} */ CalendarComponent.prototype.prepareDisplayedView = /** * @hidden * Method that sets up the currently displayed variables, like shown month and year. * Day grid is based on currently displayed month and year * @private * @return {?} */ function () { if (this.calType === 'single' && this.selectedDate && this.selectedDate.month && this.selectedDate.year) { this.currentlyDisplayed = { month: this.selectedDate.month, year: this.selectedDate.year }; } else if (this.selectedRangeDate && this.selectedRangeDate.start) { this.currentlyDisplayed = { month: this.selectedRangeDate.start.month, year: this.selectedRangeDate.start.year }; } else if (this.selectedRangeDate && this.selectedRangeDate.end) { this.currentlyDisplayed = { month: this.selectedRangeDate.end.month, year: this.selectedRangeDate.end.year }; } else { /** @type {?} */ var tempDate = FdDate.getToday(); this.currentlyDisplayed = { month: tempDate.month, year: tempDate.year }; } }; CalendarComponent.decorators = [ { type: Component, args: [{ selector: 'fd-calendar', template: "<fd-calendar-header [currentlyDisplayed]=\"currentlyDisplayed\"\n [activeView]=\"activeView\"\n (activeViewChange)=\"handleActiveViewChange($event)\"\n [id]=\"id\"\n (nextClicked)=\"handleNextArrowClick()\"\n (previousClicked)=\"handlePreviousArrowClick()\"\n></fd-calendar-header>\n<ng-container [ngSwitch]=\"activeView\">\n <div class=\"fd-calendar__content\">\n <fd-calendar-day-view *ngSwitchCase=\"'day'\"\n [selectedDate]=\"selectedDate\"\n (selectedDateChange)=\"selectedDateChanged($event)\"\n [selectedRangeDate]=\"selectedRangeDate\"\n (selectedRangeDateChange)=\"selectedRangeDateChanged($event)\"\n [currentlyDisplayed]=\"currentlyDisplayed\"\n [startingDayOfWeek]=\"startingDayOfWeek\"\n [blockFunction]=\"blockFunction\"\n [disableFunction]=\"disableFunction\"\n [disableRangeEndFunction]=\"disableRangeEndFunction\"\n [blockRangeEndFunction]=\"blockRangeEndFunction\"\n [disableRangeStartFunction]=\"disableRangeStartFunction\"\n [blockRangeStartFunction]=\"blockRangeStartFunction\"\n [calType]=\"calType\"\n [id]=\"id\"\n [focusEscapeFunction]=\"escapeFocusFunction\"\n (nextMonthSelect)=\"displayNextMonth()\"\n (previousMonthSelect)=\"displayPreviousMonth()\"\n ></fd-calendar-day-view>\n <fd-calendar-month-view *ngSwitchCase=\"'month'\"\n [monthSelected]=\"currentlyDisplayed?.month\"\n [id]=\"id\"\n [focusEscapeFunction]=\"escapeFocusFunction\"\n (monthClicked)=\"handleMonthViewChange($event)\"\n ></fd-calendar-month-view>\n <fd-calendar-year-view *ngSwitchCase=\"'year'\"\n (yearClicked)=\"selectedYear($event)\"\n [yearSelected]=\"currentlyDisplayed.year\"\n [id]=\"id\"\n [focusEscapeFunction]=\"escapeFocusFunction\">\n </fd-calendar-year-view>\n </div>\n</ng-container>\n\n", encapsulation: ViewEncapsulation.None, providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef((/** * @return {?} */ function () { return CalendarComponent; })), multi: true }, { provide: NG_VALIDATORS, useExisting: forwardRef((/** * @return {?} */ function () { return CalendarComponent; })), multi: true } ], host: { '(blur)': 'onTouched()', '[attr.id]': 'id' }, styles: [".fd-calendar__content{min-height:276px;background:#fff}.fd-calendar__content li:focus,.fd-calendar__content td:focus{outline:0;box-shadow:inset 0 0 2px 2px var(--fd-color-neutral-3)}.fd-calendar__content li:focus:after,.fd-calendar__content td:focus:after{display:none}"] }] } ]; /** @nocollapse */ CalendarComponent.ctorParameters = function () { return [ { type: CalendarI18n }, { type: ChangeDetectorRef } ]; }; CalendarComponent.propDecorators = { dayViewComponent: [{ type: ViewChild, args: [CalendarDayViewComponent,] }], yearViewComponent: [{ type: ViewChild, args: [CalendarYearViewComponent,] }], fdCalendarClass: [{ type: HostBinding, args: ['class.fd-calendar',] }], fdHasDisplayBlockClass: [{ type: HostBinding, args: ['class.fd-has-display-block',] }], selectedDate: [{ type: Input }], selectedRangeDate: [{ type: Input }], activeView: [{ type: Input }], startingDayOfWeek: [{ type: Input }], calType: [{ type: Input }], id: [{ type: Input }], activeViewChange: [{ type: Output }], selectedDateChange: [{ type: Output }], selectedRangeDateChange: [{ type: Output }], isValidDateChange: [{ type: Output }], closeCalendar: [{ type: Output }], disableFunction: [{ type: Input }], disableRangeStartFunction: [{ type: Input }], disableRangeEndFunction: [{ type: Input }], blockRangeStartFunction: [{ type: Input }], blockRangeEndFunction: [{ type: Input }], blockFunction: [{ type: Input }], escapeFocusFunction: [{ type: Input }] }; return CalendarComponent; }()); export { CalendarComponent }; if (false) { /** * @hidden * @type {?} */ CalendarComponent.prototype.dayViewComponent; /** * @hidden * @type {?} */ CalendarComponent.prototype.yearViewComponent; /** * @hidden * @type {?} */ CalendarComponent.prototype.fdCalendarClass; /** * @hidden * @type {?} */ CalendarComponent.prototype.fdHasDisplayBlockClass; /** * Currently displayed days depending on month and year * @type {?} */ CalendarComponent.prototype.currentlyDisplayed; /** * The currently selected FdDate model in single mode. * @type {?} */ CalendarComponent.prototype.selectedDate; /** * The currently selected FdDates model start and end in range mode. * @type {?} */ CalendarComponent.prototype.selectedRangeDate; /** * Actually shown active view one of 'day' | 'month' | 'year' * @type {?} */ CalendarComponent.prototype.activeView; /** * The day of the week the calendar should start on. 1 represents Sunday, 2 is Monday, 3 is Tuesday, and so on. * @type {?} */ CalendarComponent.prototype.startingDayOfWeek; /** * The type of calendar, 'single' for single date selection or 'range' for a range of dates. * @type {?} */ CalendarComponent.prototype.calType; /** * Id of the calendar. If none is provided, one will be generated. * @type {?} */ CalendarComponent.prototype.id; /** * Event thrown every time active view is changed * @type {?} */ CalendarComponent.prototype.activeViewChange; /** * Event thrown every time selected date in single mode is changed * @type {?} */ CalendarComponent.prototype.selectedDateChange; /** * Event thrown every time selected first or last date in range mode is changed * @type {?} */ CalendarComponent.prototype.selectedRangeDateChange; /** * Event thrown every time when value is overwritten from outside and throw back isValid * @type {?} */ CalendarComponent.prototype.isValidDateChange; /** * Event thrown every time when calendar should be closed * @type {?} */ CalendarComponent.prototype.closeCalendar; /** * @hidden * @type {?} */ CalendarComponent.prototype.onChange; /** * @hidden * @type {?} */ CalendarComponent.prototype.onTouched; /** * Function used to disable certain dates in the calendar. * \@param fdDate FdDate * @type {?} */ CalendarComponent.prototype.disableFunction; /** * Function used to disable certain dates in the calendar for the range start selection. * \@param fdDate FdDate * @type {?} */ CalendarComponent.prototype.disableRangeStartFunction; /** * Function used to disable certain dates in the calendar for the range end selection. * \@param fdDate FdDate * @type {?} */ CalendarComponent.prototype.disableRangeEndFunction; /** * Function used to block certain dates in the calendar for the range start selection. * \@param fdDate FdDate * @type {?} */ CalendarComponent.prototype.blockRangeStartFunction; /** * Function used to block certain dates in the calendar for the range end selection. * \@param fdDate FdDate * @type {?} */ CalendarComponent.prototype.blockRangeEndFunction; /** * Function used to block certain dates in the calendar. * \@param fdDate FdDate * @type {?} */ CalendarComponent.prototype.blockFunction; /** * That allows to define function that should happen, when focus should normally escape of component * @type {?} */ CalendarComponent.prototype.escapeFocusFunction; /** @type {?} */ CalendarComponent.prototype.calendarI18n; /** * @type {?} * @private */ CalendarComponent.prototype.changeDetectorRef; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vZnVuZGFtZW50YWwtbmd4LyIsInNvdXJjZXMiOlsibGliL2NhbGVuZGFyL2NhbGVuZGFyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUNILGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsWUFBWSxFQUNaLFVBQVUsRUFDVixXQUFXLEVBQ1gsS0FBSyxFQUVMLE1BQU0sRUFDTixTQUFTLEVBQ1QsaUJBQWlCLEVBQ3BCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNwRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFMUMsT0FBTyxFQUF5QyxhQUFhLEVBQUUsaUJBQWlCLEVBQWEsTUFBTSxnQkFBZ0IsQ0FBQztBQUNwSCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxnRUFBZ0UsQ0FBQztBQUUxRyxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxrRUFBa0UsQ0FBQzs7SUFFekcsZ0JBQWdCLEdBQVcsQ0FBQzs7Ozs7Ozs7QUFrQmhDO0lBMkpJLGNBQWM7SUFDZCwyQkFDVyxZQUEwQixFQUN6QixpQkFBb0M7UUFGaEQsaUJBR0k7UUFGTyxpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUN6QixzQkFBaUIsR0FBakIsaUJBQWlCLENBQW1COzs7O1FBOUhoRCxvQkFBZSxHQUFZLElBQUksQ0FBQzs7OztRQUloQywyQkFBc0IsR0FBWSxJQUFJLENBQUM7Ozs7UUFPaEMsaUJBQVksR0FBVyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUM7Ozs7UUFRekMsZUFBVSxHQUFtQixLQUFLLENBQUM7Ozs7UUFJbkMsc0JBQWlCLEdBQWUsQ0FBQyxDQUFDOzs7O1FBSWxDLFlBQU8sR0FBaUIsUUFBUSxDQUFDOzs7O1FBSXhDLE9BQUUsR0FBRyxjQUFjLEdBQUcsZ0JBQWdCLEVB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Qzs7Ozs7SUFHdEMsdUNBQzBDOzs7OztJQUcxQyw4Q0FDeUM7Ozs7O0lBR3pDLG9DQUN3Qzs7Ozs7SUFHeEMsK0JBQ3lDOzs7OztJQUd6Qyw2Q0FDb0c7Ozs7O0lBR3BHLCtDQUNzRjs7Ozs7SUFHdEYsb0RBQ3FHOzs7OztJQUdyRyw4Q0FDdUY7Ozs7O0lBR3ZGLDBDQUM2RTs7Ozs7SUFHN0UscUNBQ0U7Ozs7O0lBR0Ysc0NBQ0U7Ozs7OztJQU1GLDRDQUdFOzs7Ozs7SUFNRixzREFHRTs7Ozs7O0lBTUYsb0RBR0U7Ozs7OztJQU1GLG9EQUdFOzs7Ozs7SUFNRixrREFHRTs7Ozs7O0lBTUYsMENBR0U7Ozs7O0lBR0YsZ0RBS0U7O0lBSUUseUNBQWlDOzs7OztJQUNqQyw4Q0FBNEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIENvbXBvbmVudCxcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgZm9yd2FyZFJlZixcbiAgICBIb3N0QmluZGluZyxcbiAgICBJbnB1dCxcbiAgICBPbkluaXQsXG4gICAgT3V0cHV0LFxuICAgIFZpZXdDaGlsZCxcbiAgICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENhbGVuZGFySTE4biB9IGZyb20gJy4vaTE4bi9jYWxlbmRhci1pMThuJztcbmltcG9ydCB7IEZkRGF0ZSB9IGZyb20gJy4vbW9kZWxzL2ZkLWRhdGUnO1xuaW1wb3J0IHsgQ2FsZW5kYXJDdXJyZW50IH0gZnJvbSAnLi9tb2RlbHMvY2FsZW5kYXItY3VycmVudCc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxJREFUT1JTLCBOR19WQUxVRV9BQ0NFU1NPUiwgVmFsaWRhdG9yIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQ2FsZW5kYXJEYXlWaWV3Q29tcG9uZW50IH0gZnJvbSAnLi9jYWxlbmRhci12aWV3cy9jYWxlbmRhci1kYXktdmlldy9jYWxlbmRhci1kYXktdmlldy5jb21wb25lbnQnO1xuaW1wb3J0IHsgRmRSYW5nZURhdGUgfSBmcm9tICcuL21vZGVscy9mZC1yYW5nZS1kYXRlJztcbmltcG9ydCB7IENhbGVuZGFyWWVhclZpZXdDb21wb25lbnQgfSBmcm9tICcuL2NhbGVuZGFyLXZpZXdzL2NhbGVuZGFyLXllYXItdmlldy9jYWxlbmRhci15ZWFyLXZpZXcuY29tcG9uZW50JztcblxubGV0IGNhbGVuZGFyVW5pcXVlSWQ6IG51bWJlciA9IDA7XG5cbi8qKiBUeXBlIG9mIGNhbGVuZGFyICovXG5leHBvcnQgdHlwZSBDYWxlbmRhclR5cGUgPSAnc2luZ2xlJyB8ICdyYW5nZSc7XG5cbi8qKiBUeXBlIGZvciB0aGUgY2FsZW5kYXIgdmlldyAqL1xuZXhwb3J0IHR5cGUgRmRDYWxlbmRhclZpZXcgPSAnZGF5JyB8ICdtb250aCcgfCAneWVhcic7XG5cbi8qKiBUeXBlIGZvciB0aGUgZGF5cyBvZiB0aGUgd2Vlay4gKi9cbmV4cG9ydCB0eXBlIERheXNPZldlZWsgPSAxIHwgMiB8IDMgfCA0IHwgNSB8IDYgfCA3O1xuXG4vKipcbiAqIE1vbnRoczogMSA9IEphbnVhcnksIDEyID0gZGVjZW1iZXIuXG4gKiBEYXlzOiAxID0gU3VuZGF5LCA3ID0gU2F0dXJkYXlcbiAqXG4gKiBDYWxlbmRhciBjb21wb25lbnQgdXNlZCBmb3Igc2VsZWN0aW5nIGRhdGVzLCB0eXBpY2FsbHkgdXNlZCBieSB0aGUgRGF0ZVBpY2tlciBhbmQgRGF0ZVRpbWVQaWNrZXIgY29tcG9uZW50cy5cbiAqIFN1cHBvcnRzIHRoZSBBbmd1bGFyIGZvcm1zIG1vZHVsZSwgZW5hYmxpbmcgZm9ybSB2YWxpZGl0eSwgbmdNb2RlbCwgZXRjLlxuICovXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2ZkLWNhbGVuZGFyJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vY2FsZW5kYXIuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL2NhbGVuZGFyLmNvbXBvbmVudC5zY3NzJ10sXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgICBwcm92aWRlcnM6IFtcbiAgICAgICAge1xuICAgICAgICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICAgICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBDYWxlbmRhckNvbXBvbmVudCksXG4gICAgICAgICAgICBtdWx0aTogdHJ1ZVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgICBwcm92aWRlOiBOR19WQUxJREFUT1JTLFxuICAgICAgICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gQ2FsZW5kYXJDb21wb25lbnQpLFxuICAgICAgICAgICAgbXVsdGk6IHRydWVcbiAgICAgICAgfVxuICAgIF0sXG4gICAgaG9zdDoge1xuICAgICAgICAnKGJsdXIpJzogJ29uVG91Y2hlZCgpJyxcbiAgICAgICAgJ1thdHRyLmlkXSc6ICdpZCdcbiAgICB9XG59KVxuZXhwb3J0IGNsYXNzIENhbGVuZGFyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBDb250cm9sVmFsdWVBY2Nlc3NvciwgVmFsaWRhdG9yIHtcblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgQFZpZXdDaGlsZChDYWxlbmRhckRheVZpZXdDb21wb25lbnQpIGRheVZpZXdDb21wb25lbnQ6IENhbGVuZGFyRGF5Vmlld0NvbXBvbmVudDtcblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgQFZpZXdDaGlsZChDYWxlbmRhclllYXJWaWV3Q29tcG9uZW50KSB5ZWFyVmlld0NvbXBvbmVudDogQ2FsZW5kYXJZZWFyVmlld0NvbXBvbmVudDtcblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5mZC1jYWxlbmRhcicpXG4gICAgZmRDYWxlbmRhckNsYXNzOiBib29sZWFuID0gdHJ1ZTtcblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5mZC1oYXMtZGlzcGxheS1ibG9jaycpXG4gICAgZmRIYXNEaXNwbGF5QmxvY2tDbGFzczogYm9vbGVhbiA9IHRydWU7XG5cbiAgICAvKiogQ3VycmVudGx5IGRpc3BsYXllZCBkYXlzIGRlcGVuZGluZyBvbiBtb250aCBhbmQgeWVhciAqL1xuICAgIGN1cnJlbnRseURpc3BsYXllZDogQ2FsZW5kYXJDdXJyZW50O1xuXG4gICAgLyoqIFRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgRmREYXRlIG1vZGVsIGluIHNpbmdsZSBtb2RlLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNlbGVjdGVkRGF0ZTogRmREYXRlID0gRmREYXRlLmdldFRvZGF5KCk7XG5cbiAgICAvKiogVGhlIGN1cnJlbnRseSBzZWxlY3RlZCBGZERhdGVzIG1vZGVsIHN0YXJ0IGFuZCBlbmQgaW4gcmFuZ2UgbW9kZS4gKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzZWxlY3RlZFJhbmdlRGF0ZTogRmRSYW5nZURhdGU7XG5cbiAgICAvKiogQWN0dWFsbHkgc2hvd24gYWN0aXZlIHZpZXcgb25lIG9mICdkYXknIHwgJ21vbnRoJyB8ICd5ZWFyJyAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGFjdGl2ZVZpZXc6IEZkQ2FsZW5kYXJWaWV3ID0gJ2RheSc7XG5cbiAgICAvKiogVGhlIGRheSBvZiB0aGUgd2VlayB0aGUgY2FsZW5kYXIgc2hvdWxkIHN0YXJ0IG9uLiAxIHJlcHJlc2VudHMgU3VuZGF5LCAyIGlzIE1vbmRheSwgMyBpcyBUdWVzZGF5LCBhbmQgc28gb24uICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgc3RhcnRpbmdEYXlPZldlZWs6IERheXNPZldlZWsgPSAxO1xuXG4gICAgLyoqIFRoZSB0eXBlIG9mIGNhbGVuZGFyLCAnc2luZ2xlJyBmb3Igc2luZ2xlIGRhdGUgc2VsZWN0aW9uIG9yICdyYW5nZScgZm9yIGEgcmFuZ2Ugb2YgZGF0ZXMuICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgY2FsVHlwZTogQ2FsZW5kYXJUeXBlID0gJ3NpbmdsZSc7XG5cbiAgICAvKiogSWQgb2YgdGhlIGNhbGVuZGFyLiBJZiBub25lIGlzIHByb3ZpZGVkLCBvbmUgd2lsbCBiZSBnZW5lcmF0ZWQuICovXG4gICAgQElucHV0KClcbiAgICBpZCA9ICdmZC1jYWxlbmRhci0nICsgY2FsZW5kYXJVbmlxdWVJZCsrO1xuXG4gICAgLyoqIEV2ZW50IHRocm93biBldmVyeSB0aW1lIGFjdGl2ZSB2aWV3IGlzIGNoYW5nZWQgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgcmVhZG9ubHkgYWN0aXZlVmlld0NoYW5nZTogRXZlbnRFbWl0dGVyPEZkQ2FsZW5kYXJWaWV3PiA9IG5ldyBFdmVudEVtaXR0ZXI8RmRDYWxlbmRhclZpZXc+KCk7XG5cbiAgICAvKiogRXZlbnQgdGhyb3duIGV2ZXJ5IHRpbWUgc2VsZWN0ZWQgZGF0ZSBpbiBzaW5nbGUgbW9kZSBpcyBjaGFuZ2VkICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIHJlYWRvbmx5IHNlbGVjdGVkRGF0ZUNoYW5nZTogRXZlbnRFbWl0dGVyPEZkRGF0ZT4gPSBuZXcgRXZlbnRFbWl0dGVyPEZkRGF0ZT4oKTtcblxuICAgIC8qKiBFdmVudCB0aHJvd24gZXZlcnkgdGltZSBzZWxlY3RlZCBmaXJzdCBvciBsYXN0IGRhdGUgaW4gcmFuZ2UgbW9kZSBpcyBjaGFuZ2VkICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIHJlYWRvbmx5IHNlbGVjdGVkUmFuZ2VEYXRlQ2hhbmdlOiBFdmVudEVtaXR0ZXI8RmRSYW5nZURhdGU+ID0gbmV3IEV2ZW50RW1pdHRlcjxGZFJhbmdlRGF0ZT4oKTtcblxuICAgIC8qKiBFdmVudCB0aHJvd24gZXZlcnkgdGltZSB3aGVuIHZhbHVlIGlzIG92ZXJ3cml0dGVuIGZyb20gb3V0c2lkZSBhbmQgdGhyb3cgYmFjayBpc1ZhbGlkICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIHJlYWRvbmx5IGlzVmFsaWREYXRlQ2hhbmdlOiBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4gPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG5cbiAgICAvKiogRXZlbnQgdGhyb3duIGV2ZXJ5IHRpbWUgd2hlbiBjYWxlbmRhciBzaG91bGQgYmUgY2xvc2VkICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIHJlYWRvbmx5IGNsb3NlQ2FsZW5kYXI6IEV2ZW50RW1pdHRlcjx2b2lkPiA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgb25DaGFuZ2U6IEZ1bmN0aW9uID0gKCkgPT4ge1xuICAgIH07XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIG9uVG91Y2hlZDogRnVuY3Rpb24gPSAoKSA9PiB7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHVzZWQgdG8gZGlzYWJsZSBjZXJ0YWluIGRhdGVzIGluIHRoZSBjYWxlbmRhci5cbiAgICAgKiBAcGFyYW0gZmREYXRlIEZkRGF0ZVxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgZGlzYWJsZUZ1bmN0aW9uID0gZnVuY3Rpb24oZmREYXRlOiBGZERhdGUpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB1c2VkIHRvIGRpc2FibGUgY2VydGFpbiBkYXRlcyBpbiB0aGUgY2FsZW5kYXIgZm9yIHRoZSByYW5nZSBzdGFydCBzZWxlY3Rpb24uXG4gICAgICogQHBhcmFtIGZkRGF0ZSBGZERhdGVcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGRpc2FibGVSYW5nZVN0YXJ0RnVuY3Rpb24gPSBmdW5jdGlvbihmZERhdGU6IEZkRGF0ZSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHVzZWQgdG8gZGlzYWJsZSBjZXJ0YWluIGRhdGVzIGluIHRoZSBjYWxlbmRhciBmb3IgdGhlIHJhbmdlIGVuZCBzZWxlY3Rpb24uXG4gICAgICogQHBhcmFtIGZkRGF0ZSBGZERhdGVcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGRpc2FibGVSYW5nZUVuZEZ1bmN0aW9uID0gZnVuY3Rpb24oZmREYXRlOiBGZERhdGUpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB1c2VkIHRvIGJsb2NrIGNlcnRhaW4gZGF0ZXMgaW4gdGhlIGNhbGVuZGFyIGZvciB0aGUgcmFuZ2Ugc3RhcnQgc2VsZWN0aW9uLlxuICAgICAqIEBwYXJhbSBmZERhdGUgRmREYXRlXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBibG9ja1JhbmdlU3RhcnRGdW5jdGlvbiA9IGZ1bmN0aW9uKGZkRGF0ZTogRmREYXRlKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gdXNlZCB0byBibG9jayBjZXJ0YWluIGR