fundamental-ngx
Version:
SAP Fundamentals, implemented in Angular
657 lines • 56.4 kB
JavaScript
/**
* @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 {?} */
let 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.
*/
export class CalendarComponent {
/**
* @hidden
* @param {?} calendarI18n
* @param {?} changeDetectorRef
*/
constructor(calendarI18n, changeDetectorRef) {
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. 0 represents Sunday, 1 is Monday, 2 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 {?}
*/
() => {
});
/**
* @hidden
*/
this.onTouched = (/**
* @return {?}
*/
() => {
});
/**
* 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 {?}
*/
() => {
if (document.getElementById(this.id + '-left-arrow')) {
document.getElementById(this.id + '-left-arrow').focus();
}
});
}
/**
* @hidden
* @return {?}
*/
ngOnInit() {
this.prepareDisplayedView();
}
/**
* @hidden
* Function that provides support for ControlValueAccessor that allows to use [(ngModel)] or forms.
* @param {?} selected
* @return {?}
*/
writeValue(selected) {
/** @type {?} */
let 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
* @param {?} control
* @return {?}
*/
validate(control) {
return this.isModelValid() ? null : {
dateValidation: {
valid: false
}
};
}
/**
* @hidden
* @param {?} fn
* @return {?}
*/
registerOnChange(fn) {
this.onChange = fn;
}
/**
* @hidden
* @param {?} fn
* @return {?}
*/
registerOnTouched(fn) {
this.onTouched = fn;
}
/**
* @hidden
* @param {?} isDisabled
* @return {?}
*/
setDisabledState(isDisabled) {
// Not needed
}
/**
* Method that handle active view change and throws event.
* @param {?} activeView
* @return {?}
*/
handleActiveViewChange(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
* @param {?} date
* @return {?}
*/
selectedDateChanged(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
* @param {?} dates
* @return {?}
*/
selectedRangeDateChanged(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
* @return {?}
*/
handleNextArrowClick() {
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
* @return {?}
*/
handlePreviousArrowClick() {
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
* @return {?}
*/
displayNextMonth() {
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
* @return {?}
*/
displayPreviousMonth() {
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
* @return {?}
*/
displayNextYear() {
this.currentlyDisplayed = { month: this.currentlyDisplayed.month, year: this.currentlyDisplayed.year + 1 };
}
/**
* Function that allows to switch actual view to previous year
* @return {?}
*/
displayPreviousYear() {
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
* @return {?}
*/
displayNextYearList() {
this.yearViewComponent.loadNextYearList();
}
/**
* Function that allows to switch actually displayed list of year to previous year list
* @return {?}
*/
displayPreviousYearList() {
this.yearViewComponent.loadPreviousYearList();
}
/**
* Function that allows to change currently displayed month/year configuration,
* which are connected to days displayed
* @param {?} fdDate
* @return {?}
*/
setCurrentlyDisplayed(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
* @param {?} month
* @return {?}
*/
handleMonthViewChange(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 {?}
*/
selectedYear(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
* @return {?}
*/
isModelValid() {
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
* @private
* @return {?}
*/
prepareDisplayedView() {
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 {?} */
const 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 {?}
*/
() => CalendarComponent)),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef((/**
* @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 = () => [
{ 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 }]
};
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. 0 represents Sunday, 1 is Monday, 2 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vZnVuZGFtZW50YWwtbmd4LyIsInNvdXJjZXMiOlsibGliL2NhbGVuZGFyL2NhbGVuZGFyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUNILGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsWUFBWSxFQUNaLFVBQVUsRUFDVixXQUFXLEVBQ1gsS0FBSyxFQUVMLE1BQU0sRUFDTixTQUFTLEVBQ1QsaUJBQWlCLEVBQ3BCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNwRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFMUMsT0FBTyxFQUF5QyxhQUFhLEVBQUUsaUJBQWlCLEVBQWEsTUFBTSxnQkFBZ0IsQ0FBQztBQUNwSCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxnRUFBZ0UsQ0FBQztBQUUxRyxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxrRUFBa0UsQ0FBQzs7SUFFekcsZ0JBQWdCLEdBQVcsQ0FBQzs7Ozs7Ozs7QUF3Q2hDLE1BQU0sT0FBTyxpQkFBaUI7Ozs7OztJQXNJMUIsWUFDVyxZQUEwQixFQUN6QixpQkFBb0M7UUFEckMsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDekIsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFtQjs7OztRQTlIaEQsb0JBQWUsR0FBWSxJQUFJLENBQUM7Ozs7UUFJaEMsMkJBQXNCLEdBQVksSUFBSSxDQUFDOzs7O1FBT2hDLGlCQUFZLEdBQVcsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDOzs7O1FBUXpDLGVBQVUsR0FBbUIsS0FBSyxDQUFDOzs7O1FBSW5DLHNCQUFpQixHQUFlLENBQUMsQ0FBQzs7OztRQUlsQyxZQUFPLEdBQWlCLFFBQVEsQ0FBQzs7OztRQUl4QyxPQUFFLEdBQUcsY0FBYyxHQUFHLGdCQUFnQixF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QUMsd0JBQXdCO2dDQUdsQyxTQUFTLFNBQUMseUJBQXlCOzhCQUduQyxXQUFXLFNBQUMsbUJBQW1CO3FDQUkvQixXQUFXLFNBQUMsNEJBQTRCOzJCQU94QyxLQUFLO2dDQUlMLEtBQUs7eUJBSUwsS0FBSztnQ0FJTCxLQUFLO3NCQUlMLEtBQUs7aUJBSUwsS0FBSzsrQkFJTCxNQUFNO2lDQUlOLE1BQU07c0NBSU4sTUFBTTtnQ0FJTixNQUFNOzRCQUlOLE1BQU07OEJBZU4sS0FBSzt3Q0FTTCxLQUFLO3NDQVNMLEtBQUs7c0NBU0wsS0FBSztvQ0FTTCxLQUFLOzRCQVNMLEtBQUs7a0NBTUwsS0FBSzs7Ozs7OztJQTNITiw2Q0FBZ0Y7Ozs7O0lBR2hGLDhDQUFtRjs7Ozs7SUFHbkYsNENBQ2dDOzs7OztJQUdoQyxtREFDdUM7Ozs7O0lBR3ZDLCtDQUFvQzs7Ozs7SUFHcEMseUNBQ2dEOzs7OztJQUdoRCw4Q0FDc0M7Ozs7O0lBR3RDLHVDQUMwQzs7Ozs7SUFHMUMsOENBQ3lDOzs7OztJQUd6QyxvQ0FDd0M7Ozs7O0lBR3hDLCtCQUN5Qzs7Ozs7SUFHekMsNkNBQ29HOzs7OztJQUdwRywrQ0FDc0Y7Ozs7O0lBR3RGLG9EQUNxRzs7Ozs7SUFHckcsOENBQ3VGOzs7OztJQUd2RiwwQ0FDNkU7Ozs7O0lBRzdFLHFDQUNFOzs7OztJQUdGLHNDQUNFOzs7Ozs7SUFNRiw0Q0FHRTs7Ozs7O0lBTUYsc0RBR0U7Ozs7OztJQU1GLG9EQUdFOzs7Ozs7SUFNRixvREFHRTs7Ozs7O0lBTUYsa0RBR0U7Ozs7OztJQU1GLDBDQUdFOzs7OztJQUdGLGdEQUtFOztJQUlFLHlDQUFpQzs7Ozs7SUFDakMsOENBQTRDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBDb21wb25lbnQsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIGZvcndhcmRSZWYsXG4gICAgSG9zdEJpbmRpbmcsXG4gICAgSW5wdXQsXG4gICAgT25Jbml0LFxuICAgIE91dHB1dCxcbiAgICBWaWV3Q2hpbGQsXG4gICAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDYWxlbmRhckkxOG4gfSBmcm9tICcuL2kxOG4vY2FsZW5kYXItaTE4bic7XG5pbXBvcnQgeyBGZERhdGUgfSBmcm9tICcuL21vZGVscy9mZC1kYXRlJztcbmltcG9ydCB7IENhbGVuZGFyQ3VycmVudCB9IGZyb20gJy4vbW9kZWxzL2NhbGVuZGFyLWN1cnJlbnQnO1xuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBDb250cm9sVmFsdWVBY2Nlc3NvciwgTkdfVkFMSURBVE9SUywgTkdfVkFMVUVfQUNDRVNTT1IsIFZhbGlkYXRvciB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IENhbGVuZGFyRGF5Vmlld0NvbXBvbmVudCB9IGZyb20gJy4vY2FsZW5kYXItdmlld3MvY2FsZW5kYXItZGF5LXZpZXcvY2FsZW5kYXItZGF5LXZpZXcuY29tcG9uZW50JztcbmltcG9ydCB7IEZkUmFuZ2VEYXRlIH0gZnJvbSAnLi9tb2RlbHMvZmQtcmFuZ2UtZGF0ZSc7XG5pbXBvcnQgeyBDYWxlbmRhclllYXJWaWV3Q29tcG9uZW50IH0gZnJvbSAnLi9jYWxlbmRhci12aWV3cy9jYWxlbmRhci15ZWFyLXZpZXcvY2FsZW5kYXIteWVhci12aWV3LmNvbXBvbmVudCc7XG5cbmxldCBjYWxlbmRhclVuaXF1ZUlkOiBudW1iZXIgPSAwO1xuXG4vKiogVHlwZSBvZiBjYWxlbmRhciAqL1xuZXhwb3J0IHR5cGUgQ2FsZW5kYXJUeXBlID0gJ3NpbmdsZScgfCAncmFuZ2UnO1xuXG4vKiogVHlwZSBmb3IgdGhlIGNhbGVuZGFyIHZpZXcgKi9cbmV4cG9ydCB0eXBlIEZkQ2FsZW5kYXJWaWV3ID0gJ2RheScgfCAnbW9udGgnIHwgJ3llYXInO1xuXG4vKiogVHlwZSBmb3IgdGhlIGRheXMgb2YgdGhlIHdlZWsuICovXG5leHBvcnQgdHlwZSBEYXlzT2ZXZWVrID0gMSB8IDIgfCAzIHwgNCB8IDUgfCA2IHwgNztcblxuLyoqXG4gKiBNb250aHM6IDEgPSBKYW51YXJ5LCAxMiA9IGRlY2VtYmVyLlxuICogRGF5czogMSA9IFN1bmRheSwgNyA9IFNhdHVyZGF5XG4gKlxuICogQ2FsZW5kYXIgY29tcG9uZW50IHVzZWQgZm9yIHNlbGVjdGluZyBkYXRlcywgdHlwaWNhbGx5IHVzZWQgYnkgdGhlIERhdGVQaWNrZXIgYW5kIERhdGVUaW1lUGlja2VyIGNvbXBvbmVudHMuXG4gKiBTdXBwb3J0cyB0aGUgQW5ndWxhciBmb3JtcyBtb2R1bGUsIGVuYWJsaW5nIGZvcm0gdmFsaWRpdHksIG5nTW9kZWwsIGV0Yy5cbiAqL1xuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdmZC1jYWxlbmRhcicsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2NhbGVuZGFyLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9jYWxlbmRhci5jb21wb25lbnQuc2NzcyddLFxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gICAgcHJvdmlkZXJzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gQ2FsZW5kYXJDb21wb25lbnQpLFxuICAgICAgICAgICAgbXVsdGk6IHRydWVcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgICAgcHJvdmlkZTogTkdfVkFMSURBVE9SUyxcbiAgICAgICAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IENhbGVuZGFyQ29tcG9uZW50KSxcbiAgICAgICAgICAgIG11bHRpOiB0cnVlXG4gICAgICAgIH1cbiAgICBdLFxuICAgIGhvc3Q6IHtcbiAgICAgICAgJyhibHVyKSc6ICdvblRvdWNoZWQoKScsXG4gICAgICAgICdbYXR0ci5pZF0nOiAnaWQnXG4gICAgfVxufSlcbmV4cG9ydCBjbGFzcyBDYWxlbmRhckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQ29udHJvbFZhbHVlQWNjZXNzb3IsIFZhbGlkYXRvciB7XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIEBWaWV3Q2hpbGQoQ2FsZW5kYXJEYXlWaWV3Q29tcG9uZW50KSBkYXlWaWV3Q29tcG9uZW50OiBDYWxlbmRhckRheVZpZXdDb21wb25lbnQ7XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIEBWaWV3Q2hpbGQoQ2FsZW5kYXJZZWFyVmlld0NvbXBvbmVudCkgeWVhclZpZXdDb21wb25lbnQ6IENhbGVuZGFyWWVhclZpZXdDb21wb25lbnQ7XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MuZmQtY2FsZW5kYXInKVxuICAgIGZkQ2FsZW5kYXJDbGFzczogYm9vbGVhbiA9IHRydWU7XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MuZmQtaGFzLWRpc3BsYXktYmxvY2snKVxuICAgIGZkSGFzRGlzcGxheUJsb2NrQ2xhc3M6IGJvb2xlYW4gPSB0cnVlO1xuXG4gICAgLyoqIEN1cnJlbnRseSBkaXNwbGF5ZWQgZGF5cyBkZXBlbmRpbmcgb24gbW9udGggYW5kIHllYXIgKi9cbiAgICBjdXJyZW50bHlEaXNwbGF5ZWQ6IENhbGVuZGFyQ3VycmVudDtcblxuICAgIC8qKiBUaGUgY3VycmVudGx5IHNlbGVjdGVkIEZkRGF0ZSBtb2RlbCBpbiBzaW5nbGUgbW9kZS4gKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBzZWxlY3RlZERhdGU6IEZkRGF0ZSA9IEZkRGF0ZS5nZXRUb2RheSgpO1xuXG4gICAgLyoqIFRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgRmREYXRlcyBtb2RlbCBzdGFydCBhbmQgZW5kIGluIHJhbmdlIG1vZGUuICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgc2VsZWN0ZWRSYW5nZURhdGU6IEZkUmFuZ2VEYXRlO1xuXG4gICAgLyoqIEFjdHVhbGx5IHNob3duIGFjdGl2ZSB2aWV3IG9uZSBvZiAnZGF5JyB8ICdtb250aCcgfCAneWVhcicgKi9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBhY3RpdmVWaWV3OiBGZENhbGVuZGFyVmlldyA9ICdkYXknO1xuXG4gICAgLyoqIFRoZSBkYXkgb2YgdGhlIHdlZWsgdGhlIGNhbGVuZGFyIHNob3VsZCBzdGFydCBvbi4gMCByZXByZXNlbnRzIFN1bmRheSwgMSBpcyBNb25kYXksIDIgaXMgVHVlc2RheSwgYW5kIHNvIG9uLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHN0YXJ0aW5nRGF5T2ZXZWVrOiBEYXlzT2ZXZWVrID0gMTtcblxuICAgIC8qKiBUaGUgdHlwZSBvZiBjYWxlbmRhciwgJ3NpbmdsZScgZm9yIHNpbmdsZSBkYXRlIHNlbGVjdGlvbiBvciAncmFuZ2UnIGZvciBhIHJhbmdlIG9mIGRhdGVzLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGNhbFR5cGU6IENhbGVuZGFyVHlwZSA9ICdzaW5nbGUnO1xuXG4gICAgLyoqIElkIG9mIHRoZSBjYWxlbmRhci4gSWYgbm9uZSBpcyBwcm92aWRlZCwgb25lIHdpbGwgYmUgZ2VuZXJhdGVkLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgaWQgPSAnZmQtY2FsZW5kYXItJyArIGNhbGVuZGFyVW5pcXVlSWQrKztcblxuICAgIC8qKiBFdmVudCB0aHJvd24gZXZlcnkgdGltZSBhY3RpdmUgdmlldyBpcyBjaGFuZ2VkICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIHJlYWRvbmx5IGFjdGl2ZVZpZXdDaGFuZ2U6IEV2ZW50RW1pdHRlcjxGZENhbGVuZGFyVmlldz4gPSBuZXcgRXZlbnRFbWl0dGVyPEZkQ2FsZW5kYXJWaWV3PigpO1xuXG4gICAgLyoqIEV2ZW50IHRocm93biBldmVyeSB0aW1lIHNlbGVjdGVkIGRhdGUgaW4gc2luZ2xlIG1vZGUgaXMgY2hhbmdlZCAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyByZWFkb25seSBzZWxlY3RlZERhdGVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxGZERhdGU+ID0gbmV3IEV2ZW50RW1pdHRlcjxGZERhdGU+KCk7XG5cbiAgICAvKiogRXZlbnQgdGhyb3duIGV2ZXJ5IHRpbWUgc2VsZWN0ZWQgZmlyc3Qgb3IgbGFzdCBkYXRlIGluIHJhbmdlIG1vZGUgaXMgY2hhbmdlZCAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyByZWFkb25seSBzZWxlY3RlZFJhbmdlRGF0ZUNoYW5nZTogRXZlbnRFbWl0dGVyPEZkUmFuZ2VEYXRlPiA9IG5ldyBFdmVudEVtaXR0ZXI8RmRSYW5nZURhdGU+KCk7XG5cbiAgICAvKiogRXZlbnQgdGhyb3duIGV2ZXJ5IHRpbWUgd2hlbiB2YWx1ZSBpcyBvdmVyd3JpdHRlbiBmcm9tIG91dHNpZGUgYW5kIHRocm93IGJhY2sgaXNWYWxpZCAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyByZWFkb25seSBpc1ZhbGlkRGF0ZUNoYW5nZTogRXZlbnRFbWl0dGVyPGJvb2xlYW4+ID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuXG4gICAgLyoqIEV2ZW50IHRocm93biBldmVyeSB0aW1lIHdoZW4gY2FsZW5kYXIgc2hvdWxkIGJlIGNsb3NlZCAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyByZWFkb25seSBjbG9zZUNhbGVuZGFyOiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIG9uQ2hhbmdlOiBGdW5jdGlvbiA9ICgpID0+IHtcbiAgICB9O1xuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBvblRvdWNoZWQ6IEZ1bmN0aW9uID0gKCkgPT4ge1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB1c2VkIHRvIGRpc2FibGUgY2VydGFpbiBkYXRlcyBpbiB0aGUgY2FsZW5kYXIuXG4gICAgICogQHBhcmFtIGZkRGF0ZSBGZERhdGVcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGRpc2FibGVGdW5jdGlvbiA9IGZ1bmN0aW9uKGZkRGF0ZTogRmREYXRlKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gdXNlZCB0byBkaXNhYmxlIGNlcnRhaW4gZGF0ZXMgaW4gdGhlIGNhbGVuZGFyIGZvciB0aGUgcmFuZ2Ugc3RhcnQgc2VsZWN0aW9uLlxuICAgICAqIEBwYXJhbSBmZERhdGUgRmREYXRlXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBkaXNhYmxlUmFuZ2VTdGFydEZ1bmN0aW9uID0gZnVuY3Rpb24oZmREYXRlOiBGZERhdGUpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB1c2VkIHRvIGRpc2FibGUgY2VydGFpbiBkYXRlcyBpbiB0aGUgY2FsZW5kYXIgZm9yIHRoZSByYW5nZSBlbmQgc2VsZWN0aW9uLlxuICAgICAqIEBwYXJhbSBmZERhdGUgRmREYXRlXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBkaXNhYmxlUmFuZ2VFbmRGdW5jdGlvbiA9IGZ1bmN0aW9uKGZkRGF0ZTogRmREYXRlKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gdXNlZCB0byBibG9jayBjZXJ0YWluIGRhdGVzIGluIHRoZSBjYWxlbmRhciBmb3IgdGhlIHJhbmdlIHN0YXJ0IHNlbGVjdGlvbi5cbiAgICAgKiBAcGFyYW0gZmREYXRlIEZkRGF0ZVxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgYmxvY2tSYW5nZVN0YXJ0RnVuY3Rpb24gPSBmdW5jdGlvbihmZERhdGU6IEZkRGF0ZSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHVzZWQgdG8gYmxvY2sgY2VydGFpbiBkYXRlcyBpbiB0aGUgY2FsZW5kYXIgZm9yIHRoZSByYW5nZSBlbmQgc2VsZWN0aW9uLlxuICAgICAqIEBwYXJhbSBmZERhdGUgRmREYXRlXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBibG9ja1JhbmdlRW5kRnVuY3Rpb24gPSBmdW5jdGlvbihmZERhdGU6IEZkRGF0ZSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHVzZWQgdG8gYmxvY2sgY2VydGFpbiBkYXRlcyBpbiB0aGUgY2FsZW5kYXIuXG4gICAgICogQHBhcmFtIGZkRGF0ZSBGZERhdGVcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGJsb2NrRnVuY3Rpb24gPSBmdW5jdGlvbihmZERhdGU6IEZkRGF0ZSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIC8qKiBUaGF0IGFsbG93cyB0byBkZWZpbmUgZnVuY3Rpb24gdGhhdCBzaG91bGQgaGFwcGVuLCB3aGVuIGZvY3VzIHNob3VsZCBub3JtYWxseSBlc2NhcGUgb2YgY29tcG9uZW50ICovXG4gICAgQElucHV0KClcbiAgICBlc2NhcGVGb2N1c0Z1bmN0aW9uOiBGdW5jdGlvbiA9ICgpOiB2b2lkID0+IHtcbiAgICAgICAgaWYgKGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKHRoaXMuaWQgKyAnLWxlZnQtYXJyb3cnKSkge1xuICAgICAgICAgICAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQodGhpcy5pZCArICctbGVmdC1hcnJvdycpLmZvY3VzKCk7XG4gICAgICAgIH1cbiAgICB9O1xuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHVibGljIGNhbGVuZGFySTE4bjogQ2FsZW5kYXJJMThuLFxuICAgICAgICBwcml2YXRlIGNoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZlxuICAgICkge31cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMucHJlcGFyZURpc3BsYXllZFZpZXcoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogRnVuY3Rpb24gdGhhdCBwcm92aWRlcyBzdXBwb3J0IGZvciBDb250cm9sVmFsdWVBY2Nlc3NvciB0aGF0IGFsbG93cyB0byB1c2UgWyhuZ01vZGVsKV0gb3IgZm9ybXMuXG4gICAgICovXG4gICAgd3JpdGVWYWx1ZShzZWxlY3RlZDogRmRSYW5nZURhdGUgfCBGZERhdGUpOiB2b2lkIHtcbiAgICAgICAgbGV0IHZhbGlkOiBib29sZWFuID0gdHJ1ZTtcbiAgICAgICAgaWYgKHNlbGVjdGVkKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5jYWxUeXBlID09PSAnc2luZ2xlJykge1xuICAgICAgICAgICAgICAgIHNlbGVjdGVkID0gPEZkRGF0ZT5zZWxlY3RlZDtcblxuICAgICAgICAgICAgICAgIHZhbGlkID0gc2VsZWN0ZWQuaXNEYXRlVmFsaWQoKTtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkRGF0ZSA9IHNlbGVjdGVkO1xuXG4gICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkLmlzRGF0ZVZhbGlkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmVwYXJlRGlzcGxheWVkVmlldygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5jYWxUeXBlID09PSAncmFuZ2UnKSB7XG4gICAgICAgICAgICAgICAgc2VsZWN0ZWQgPSA8RmRSYW5nZURhdGU+c2VsZWN0ZWQ7XG5cbiAgICAgICAgICAgICAgICBpZiAoIXNlbGVjdGVkLnN0YXJ0IHx8ICFzZWxlY3RlZC5lbmQpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFsaWQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkLnN0YXJ0ICYmICFzZWxlY3RlZC5zdGFydC5pc0RhdGVWYWxpZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChzZWxlY3RlZC5lbmQgJiYgIXNlbGVjdGVkLmVuZC5pc0RhdGVWYWxpZCgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhbGlkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRSYW5nZURhdGUgPSB7IHN0YXJ0OiBzZWxlY3RlZC5zdGFydCwgZW5kOiBzZWxlY3RlZC5lbmQgfTtcbiAgICAgICAgICAgICAgICBpZiAodmFsaWQpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wcmVwYXJlRGlzcGxheWVkVmlldygpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB0aGlzLmlzVmFsaWREYXRlQ2hhbmdlLmVtaXQodmFsaWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKiBGdW5jdGlvbiB0aGF0IGltcGxlbWVudHMgVmFsaWRhdG9yIEludGVyZmFjZSwgYWRkcyB2YWxpZGF0aW9uIHN1cHBvcnQgZm9yIGZvcm1zXG4gICAgICovXG4gICAgdmFsaWRhdGUoY29udHJvbDogQWJzdHJhY3RDb250cm9sKToge1xuICAgICAgICBba2V5OiBzdHJpbmddOiBhbnlcbiAgICB9IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNNb2RlbFZhbGlkKCkgPyBudWxsIDoge1xuICAgICAgICAgICAgZGF0ZVZhbGlkYXRpb246IHtcbiAgICAgICAgICAgICAgICB2YWxpZDogZmFsc2VcbiAgICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIHJlZ2lzdGVyT25DaGFuZ2UoZm46IGFueSk6IHZvaWQge1xuICAgICAgICB0aGlzLm9uQ2hhbmdlID0gZm47XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XG4gICAgICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBzZXREaXNhYmxlZFN0YXRlPyhpc0Rpc2FibGVkOiBib29sZWFuKTogdm9pZCB7XG4gICAgICAgIC8vIE5vdCBuZWVkZWRcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNZXRob2QgdGhhdCBoYW5kbGUgYWN0aXZlIHZpZXcgY2hhbmdlIGFuZCB0aHJvd3MgZXZlbnQuXG4gICAgICovXG4gICAgcHVibGljIGhhbmRsZUFjdGl2ZVZpZXdDaGFuZ2UoYWN0aXZlVmlldzogRmRDYWxlbmRhclZpZXcpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5hY3RpdmVWaWV3ID0gYWN0aXZlVmlldztcbiAgICAgICAgdGhpcy5hY3RpdmVWaWV3Q2hhbmdlLmVtaXQoYWN0aXZlVmlldyk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqIE1ldGhvZCB0aGF0IGlzIHRyaWdnZXJlZCBieSBldmVudHMgZnJvbSBkYXkgdmlldyBjb21wb25lbnQsIHdoZW4gdGhlcmUgaXMgc2VsZWN0ZWQgc2luZ2xlIGRhdGUgY2hhbmdlZFxuICAgICAqL1xuICAgIHNlbGVjdGVkRGF0ZUNoYW5nZWQoZGF0ZTogRmREYXRlKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gZGF0ZTtcbiAgICAgICAgdGhpcy5vbkNoYW5nZShkYXRlKTtcbiAgICAgICAgdGhpcy5vblRvdWNoZWQoKTtcbiAgICAgICAgdGhpcy5zZWxlY3RlZERhdGVDaGFuZ2UuZW1pdChkYXRlKTtcbiAgICAgICAgdGhpcy5jbG9zZUNhbGVuZGFyLmVtaXQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogTWV0aG9kIHRoYXQgaXMgdHJpZ2dlcmVkIGJ5IGV2ZW50cyBmcm9tIGRheSB2aWV3IGNvbXBvbmVudCwgd2hlbiB0aGVyZSBpcyBzZWxlY3RlZCByYW5nZSBkYXRlIGNoYW5nZWRcbiAgICAgKi9cbiAgICBwdWJsaWMgc2VsZWN0ZWRSYW5nZURhdGVDaGFuZ2VkKGRhdGVzOiBGZFJhbmdlRGF0ZSk6IHZvaWQge1xuICAgICAgICBpZiAoZGF0ZXMpIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRSYW5nZURhdGUgPSB7IHN0YXJ0OiBkYXRlcy5zdGFydCwgZW5kOiBkYXRlcy5lbmQgPyBkYXRlcy5lbmQgOiBkYXRlcy5zdGFydCB9O1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFJhbmdlRGF0ZUNoYW5nZS5lbWl0KHRoaXMuc2VsZWN0ZWRSYW5nZURhdGUpO1xuICAgICAgICAgICAgdGhpcy5vbkNoYW5nZSh0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlKTtcbiAgICAgICAgICAgIHRoaXMub25Ub3VjaGVkKCk7XG4gICAgICAgICAgICB0aGlzLmNsb3NlQ2FsZW5kYXIuZW1pdCgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIEZ1bmN0aW9uIHRoYXQgaGFuZGxlcyBuZXh0IGFycm93IGljb24gY2xpY2ssIGRlcGVuZGluZyBvbiBjdXJyZW50IHZpZXcgaXQgY2hhbmdlcyBtb250aCwgeWVhciBvciBsaXN0IG9mIHllYXJzICovXG4gICAgcHVibGljIGhhbmRsZU5leHRBcnJvd0NsaWNrKCk6IHZvaWQge1xuICAgICAgICBzd2l0Y2ggKHRoaXMuYWN0aXZlVmlldykge1xuICAgICAgICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3BsYXlOZXh0TW9udGgoKTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ21vbnRoJzpcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3BsYXlOZXh0WWVhcigpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAneWVhcic6XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5TmV4dFllYXJMaXN0KCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vblRvdWNoZWQoKTtcbiAgICB9XG5cbiAgICAvKiogRnVuY3Rpb24gdGhhdCBoYW5kbGVzIHByZXZpb3VzIGFycm93IGljb24gY2xpY2ssIGRlcGVuZGluZyBvbiBjdXJyZW50IHZpZXcgaXQgY2hhbmdlcyBtb250aCwgeWVhciBvciBsaXN0IG9mIHllYXJzICovXG4gICAgcHVibGljIGhhbmRsZVByZXZpb3VzQXJyb3dDbGljaygpOiB2b2lkIHtcbiAgICAgICAgc3dpdGNoICh0aGlzLmFjdGl2ZVZpZXcpIHtcbiAgICAgICAgICAgIGNhc2UgJ2RheSc6XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5UHJldmlvdXNNb250aCgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAnbW9udGgnOlxuICAgICAgICAgICAgICAgIHRoaXMuZGlzcGxheVByZXZpb3VzWWVhcigpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAneWVhcic6XG4gICAgICAgICAgICAgICAgdGhpcy5kaXNwbGF5UHJldmlvdXNZZW