fundamental-ngx
Version:
SAP Fiori Fundamentals, implemented in Angular
666 lines • 45.9 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, ElementRef, EventEmitter, forwardRef, HostListener, Input, Output, ViewEncapsulation } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { Subject } from 'rxjs';
import { DateFormatParser } from '../calendar/format/date-parser';
var DatePickerComponent = /** @class */ (function () {
function DatePickerComponent(eRef, dateAdapter) {
this.eRef = eRef;
this.dateAdapter = dateAdapter;
/**
* @hidden The value of the input
*/
this.inputFieldDate = null;
/**
* @hidden Whether the date input is invalid
*/
this.isInvalidDateInput = false;
/**
* @hidden Whether the date picker is open
*/
this.isOpen = false;
/**
* @hidden Subject the calendar subscribes to when the date value from the datePicker component changes. For internal use.
*/
this.dateFromDatePicker = new Subject();
/**
* The type of calendar, 'single' for single date selection or 'range' for a range of dates.
*/
this.type = 'single';
/**
* Date picker input placeholder string
*/
this.placeholder = 'mm/dd/yyyy';
/**
* Whether this is the compact input date picker
*/
this.compact = false;
/**
* The currently selected CalendarDay model
*/
this.selectedDay = {
date: null
};
/**
* Fired when a new date is selected.
*/
this.selectedDayChange = new EventEmitter();
/**
* The currently selected first CalendarDay in a range type calendar.
*/
this.selectedRangeFirst = {
date: null
};
/**
* Fired when the user selects a new first date in a range of dates is selected.
*/
this.selectedRangeFirstChange = new EventEmitter();
/**
* The currently selected last CalendarDay in a range type calendar.
*/
this.selectedRangeLast = {
date: null
};
/**
* Fired when the user selects a new last date in a range of dates is selected.
*/
this.selectedRangeLastChange = new EventEmitter();
/**
* The day of the week the calendar should start on. 0 represents Sunday, 1 is Monday, 2 is Tuesday, and so on.
*/
this.startingDayOfWeek = 0;
/**
* Whether to validate the date picker input.
*/
this.validate = true;
/**
* Aria label for the datepicker input.
*/
this.dateInputLabel = 'Date input';
/**
* Aria label for the button to show/hide the calendar.
*/
this.displayCalendarToggleLabel = 'Display calendar toggle';
/**
* Whether a null input is considered valid.
*/
this.allowNull = true;
/**
* The placement of the popover. It can be one of: top, top-start, top-end, bottom,
* bottom-start, bottom-end, right, right-start, right-end, left, left-start, left-end.
*/
this.placement = 'bottom-start';
/**
* Function used to disable certain dates in the calendar.
* @param d Date
*/
this.disableFunction = (/**
* @param {?} d
* @return {?}
*/
function (d) {
return false;
});
/**
* Function used to block certain dates in the calendar.
* @param d Date
*/
this.blockFunction = (/**
* @param {?} d
* @return {?}
*/
function (d) {
return false;
});
/**
* Function used to disable certain dates in the calendar for the range start selection.
* @param d Date
*/
this.disableRangeStartFunction = (/**
* @param {?} d
* @return {?}
*/
function (d) {
return false;
});
/**
* Function used to disable certain dates in the calendar for the range end selection.
* @param d Date
*/
this.disableRangeEndFunction = (/**
* @param {?} d
* @return {?}
*/
function (d) {
return false;
});
/**
* Function used to block certain dates in the calendar for the range start selection.
* @param d Date
*/
this.blockRangeStartFunction = (/**
* @param {?} d
* @return {?}
*/
function (d) {
return false;
});
/**
* Function used to block certain dates in the calendar for the range end selection.
* @param d Date
*/
this.blockRangeEndFunction = (/**
* @param {?} d
* @return {?}
*/
function (d) {
return false;
});
/**
* @hidden
*/
this.onChange = (/**
* @param {?} selected
* @return {?}
*/
function (selected) { });
/**
* @hidden
*/
this.onTouched = (/**
* @return {?}
*/
function () { });
}
/** Opens the calendar */
/**
* Opens the calendar
* @param {?} e
* @return {?}
*/
DatePickerComponent.prototype.openCalendar = /**
* Opens the calendar
* @param {?} e
* @return {?}
*/
function (e) {
if (!this.disabled) {
this.onTouched({ date: this.selectedDay.date });
this.isOpen = true;
this.getInputValue(e);
}
};
/** Toggles the calendar open or closed */
/**
* Toggles the calendar open or closed
* @param {?} e
* @return {?}
*/
DatePickerComponent.prototype.toggleCalendar = /**
* Toggles the calendar open or closed
* @param {?} e
* @return {?}
*/
function (e) {
this.onTouched({ date: this.selectedDay.date });
this.isOpen = !this.isOpen;
this.getInputValue(e);
};
/** Closes the calendar if it is open */
/**
* Closes the calendar if it is open
* @return {?}
*/
DatePickerComponent.prototype.closeCalendar = /**
* Closes the calendar if it is open
* @return {?}
*/
function () {
if (this.isOpen) {
this.isOpen = false;
}
};
/** @hidden */
/**
* @hidden
* @param {?} d
* @return {?}
*/
DatePickerComponent.prototype.updateDatePickerInputHandler = /**
* @hidden
* @param {?} d
* @return {?}
*/
function (d) {
if (this.type === 'single') {
if (d.selectedDay.date) {
/** @type {?} */
var newInputDate = this.dateAdapter.format(d.selectedDay.date);
if (this.inputFieldDate !== newInputDate) {
this.inputFieldDate = newInputDate;
this.selectedDay = d.selectedDay;
this.selectedDayChange.emit(this.selectedDay);
this.onChange({ date: this.selectedDay.date });
}
}
}
else {
if (d.selectedFirstDay.date) {
/** @type {?} */
var newInputDates = this.dateAdapter.format(d.selectedFirstDay.date) + this.dateAdapter.rangeDelimiter
+ this.dateAdapter.format(d.selectedLastDay.date);
if (this.inputFieldDate !== newInputDates) {
this.inputFieldDate = newInputDates;
this.selectedRangeFirst = d.selectedFirstDay;
this.selectedRangeLast = d.selectedLastDay;
this.selectedRangeFirstChange.emit(this.selectedRangeFirst);
this.selectedRangeLastChange.emit(this.selectedRangeLast);
this.onChange({ date: this.selectedRangeFirst.date, rangeEnd: this.selectedRangeLast.date });
}
}
}
};
/** @hidden */
/**
* @hidden
* @param {?} e
* @return {?}
*/
DatePickerComponent.prototype.isInvalidDateInputHandler = /**
* @hidden
* @param {?} e
* @return {?}
*/
function (e) {
this.isInvalidDateInput = e;
};
/** @hidden */
/**
* @hidden
* @param {?} e
* @return {?}
*/
DatePickerComponent.prototype.getInputValue = /**
* @hidden
* @param {?} e
* @return {?}
*/
function (e) {
this.dateFromDatePicker.next(e);
};
/** @hidden */
/**
* @hidden
* @return {?}
*/
DatePickerComponent.prototype.onEscapeKeydownHandler = /**
* @hidden
* @return {?}
*/
function () {
this.closeCalendar();
};
/** @hidden */
/**
* @hidden
* @param {?} event
* @return {?}
*/
DatePickerComponent.prototype.onGlobalClick = /**
* @hidden
* @param {?} event
* @return {?}
*/
function (event) {
if (!this.eRef.nativeElement.contains(event.target)) {
this.closeCalendar();
}
};
/** @hidden */
/**
* @hidden
* @return {?}
*/
DatePickerComponent.prototype.ngOnInit = /**
* @hidden
* @return {?}
*/
function () {
var _this = this;
if (this.dateFromDatePicker) {
this.dateFromDatePicker.subscribe((/**
* @param {?} date
* @return {?}
*/
function (date) {
if (date && typeof date === 'object') {
_this.updateDatePickerInputHandler(date);
}
else if (date === '' && _this.allowNull) {
_this.isInvalidDateInput = false;
if (_this.type === 'single') {
_this.selectedDay.date = null;
_this.selectedDay.selected = null;
}
else {
_this.selectedRangeFirst.date = null;
_this.selectedRangeFirst.selected = null;
_this.selectedRangeLast.date = null;
_this.selectedRangeLast.selected = null;
}
}
else {
_this.isInvalidDateInput = true;
}
}));
}
};
/** @hidden */
/**
* @hidden
* @return {?}
*/
DatePickerComponent.prototype.ngOnDestroy = /**
* @hidden
* @return {?}
*/
function () {
if (this.dateFromDatePicker) {
this.dateFromDatePicker.unsubscribe();
}
};
/** @hidden */
/**
* @hidden
* @param {?} fn
* @return {?}
*/
DatePickerComponent.prototype.registerOnChange = /**
* @hidden
* @param {?} fn
* @return {?}
*/
function (fn) {
this.onChange = fn;
};
/** @hidden */
/**
* @hidden
* @param {?} fn
* @return {?}
*/
DatePickerComponent.prototype.registerOnTouched = /**
* @hidden
* @param {?} fn
* @return {?}
*/
function (fn) {
this.onTouched = fn;
};
/** @hidden */
/**
* @hidden
* @param {?} isDisabled
* @return {?}
*/
DatePickerComponent.prototype.setDisabledState = /**
* @hidden
* @param {?} isDisabled
* @return {?}
*/
function (isDisabled) {
this.disabled = isDisabled;
};
/** @hidden */
/**
* @hidden
* @param {?} selected
* @return {?}
*/
DatePickerComponent.prototype.writeValue = /**
* @hidden
* @param {?} selected
* @return {?}
*/
function (selected) {
if (!selected) {
return;
}
if (this.type.toLocaleLowerCase() === 'single') {
this.selectedDay.date = selected.date;
if (selected.date !== null) {
this.inputFieldDate = this.dateAdapter.format(selected.date);
}
else {
this.inputFieldDate = '';
}
}
else {
this.selectedRangeFirst.date = selected.date;
this.selectedRangeLast.date = selected.rangeEnd;
if (selected.date !== null) {
this.inputFieldDate = this.dateAdapter.format(selected.date) +
this.dateAdapter.rangeDelimiter + this.dateAdapter.format(selected.rangeEnd);
}
else {
this.inputFieldDate = '';
}
}
};
DatePickerComponent.decorators = [
{ type: Component, args: [{
selector: 'fd-date-picker',
template: "<fd-popover [(isOpen)]=\"isOpen\"\n [triggers]=\"[]\"\n [placement]=\"placement\"\n [disabled]=\"disabled\">\n <fd-popover-control>\n <div class=\"fd-input-group fd-input-group--after\"\n [ngClass]=\"{'fd-input-group--compact' : compact}\">\n <input #datePicker\n type=\"text\"\n [attr.aria-label]=\"dateInputLabel\"\n [value]=\"inputFieldDate\"\n [placeholder]=\"placeholder\"\n (keyup.enter)=\"getInputValue(datePicker.value)\"\n (blur)=\"getInputValue(datePicker.value)\"\n (click)=\"openCalendar(datePicker.value)\"\n [disabled]=\"disabled\"\n [ngClass]=\"{ 'fd-input--compact': compact, 'is-invalid': isInvalidDateInput && validate }\">\n <span class=\"fd-input-group__addon fd-input-group__addon--after fd-input-group__addon--button\">\n <button [disabled]=\"disabled\" class=\"fd-popover__control fd-button--icon fd-button--light sap-icon--calendar\"\n (click)=\"toggleCalendar(datePicker.value)\" [attr.aria-label]=\"displayCalendarToggleLabel\"\n [attr.aria-expanded]=\"isOpen\" type=\"button\"></button>\n </span>\n </div>\n </fd-popover-control>\n <fd-popover-body\n [style.display]=\"'block'\"\n [attr.aria-expanded]=\"isOpen\"\n [attr.aria-hidden]=\"!isOpen\">\n <fd-calendar (closeCalendar)=\"isOpen = false;\" [calType]=\"type\"\n [disableFunction]=\"disableFunction ? disableFunction : null\"\n [blockFunction]=\"blockFunction ? blockFunction : null\"\n [disableRangeStartFunction]=\"disableRangeStartFunction ? disableRangeStartFunction : null\"\n [disableRangeEndFunction]=\"disableRangeEndFunction ? disableRangeEndFunction : null\"\n [blockRangeStartFunction]=\"blockRangeStartFunction ? blockRangeStartFunction : null\"\n [blockRangeEndFunction]=\"blockRangeEndFunction ? blockRangeEndFunction : null\"\n [(selectedDay)]=\"selectedDay\"\n [(selectedRangeFirst)]=\"selectedRangeFirst\"\n [(selectedRangeLast)]=\"selectedRangeLast\"\n (isInvalidDateInput)=\"isInvalidDateInputHandler($event)\"\n [dateFromDatePicker]=\"dateFromDatePicker\"\n [startingDayOfWeek]=\"startingDayOfWeek\"></fd-calendar>\n </fd-popover-body>\n</fd-popover>\n",
host: {
'(blur)': 'onTouched()',
'[class.fd-date-picker]': 'true',
'[class.fd-date-picker-custom]': 'true'
},
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef((/**
* @return {?}
*/
function () { return DatePickerComponent; })),
multi: true
}
],
encapsulation: ViewEncapsulation.None,
styles: [".fd-date-picker-custom{display:inline-block}.fd-date-picker-custom fd-popover{display:block}"]
}] }
];
/** @nocollapse */
DatePickerComponent.ctorParameters = function () { return [
{ type: ElementRef },
{ type: DateFormatParser }
]; };
DatePickerComponent.propDecorators = {
type: [{ type: Input }],
placeholder: [{ type: Input }],
compact: [{ type: Input }],
selectedDay: [{ type: Input }],
selectedDayChange: [{ type: Output }],
selectedRangeFirst: [{ type: Input }],
selectedRangeFirstChange: [{ type: Output }],
selectedRangeLast: [{ type: Input }],
selectedRangeLastChange: [{ type: Output }],
startingDayOfWeek: [{ type: Input }],
validate: [{ type: Input }],
dateInputLabel: [{ type: Input }],
displayCalendarToggleLabel: [{ type: Input }],
allowNull: [{ type: Input }],
placement: [{ type: Input }],
disabled: [{ type: Input }],
disableFunction: [{ type: Input }],
blockFunction: [{ type: Input }],
disableRangeStartFunction: [{ type: Input }],
disableRangeEndFunction: [{ type: Input }],
blockRangeStartFunction: [{ type: Input }],
blockRangeEndFunction: [{ type: Input }],
onEscapeKeydownHandler: [{ type: HostListener, args: ['document:keydown.escape', [],] }],
onGlobalClick: [{ type: HostListener, args: ['document:click', ['$event'],] }]
};
return DatePickerComponent;
}());
export { DatePickerComponent };
if (false) {
/**
* @hidden The value of the input
* @type {?}
*/
DatePickerComponent.prototype.inputFieldDate;
/**
* @hidden Whether the date input is invalid
* @type {?}
*/
DatePickerComponent.prototype.isInvalidDateInput;
/**
* @hidden Whether the date picker is open
* @type {?}
*/
DatePickerComponent.prototype.isOpen;
/**
* @hidden Subject the calendar subscribes to when the date value from the datePicker component changes. For internal use.
* @type {?}
*/
DatePickerComponent.prototype.dateFromDatePicker;
/**
* The type of calendar, 'single' for single date selection or 'range' for a range of dates.
* @type {?}
*/
DatePickerComponent.prototype.type;
/**
* Date picker input placeholder string
* @type {?}
*/
DatePickerComponent.prototype.placeholder;
/**
* Whether this is the compact input date picker
* @type {?}
*/
DatePickerComponent.prototype.compact;
/**
* The currently selected CalendarDay model
* @type {?}
*/
DatePickerComponent.prototype.selectedDay;
/**
* Fired when a new date is selected.
* @type {?}
*/
DatePickerComponent.prototype.selectedDayChange;
/**
* The currently selected first CalendarDay in a range type calendar.
* @type {?}
*/
DatePickerComponent.prototype.selectedRangeFirst;
/**
* Fired when the user selects a new first date in a range of dates is selected.
* @type {?}
*/
DatePickerComponent.prototype.selectedRangeFirstChange;
/**
* The currently selected last CalendarDay in a range type calendar.
* @type {?}
*/
DatePickerComponent.prototype.selectedRangeLast;
/**
* Fired when the user selects a new last date in a range of dates is selected.
* @type {?}
*/
DatePickerComponent.prototype.selectedRangeLastChange;
/**
* The day of the week the calendar should start on. 0 represents Sunday, 1 is Monday, 2 is Tuesday, and so on.
* @type {?}
*/
DatePickerComponent.prototype.startingDayOfWeek;
/**
* Whether to validate the date picker input.
* @type {?}
*/
DatePickerComponent.prototype.validate;
/**
* Aria label for the datepicker input.
* @type {?}
*/
DatePickerComponent.prototype.dateInputLabel;
/**
* Aria label for the button to show/hide the calendar.
* @type {?}
*/
DatePickerComponent.prototype.displayCalendarToggleLabel;
/**
* Whether a null input is considered valid.
* @type {?}
*/
DatePickerComponent.prototype.allowNull;
/**
* The placement of the popover. It can be one of: top, top-start, top-end, bottom,
* bottom-start, bottom-end, right, right-start, right-end, left, left-start, left-end.
* @type {?}
*/
DatePickerComponent.prototype.placement;
/**
* Whether the date picker is disabled.
* @type {?}
*/
DatePickerComponent.prototype.disabled;
/**
* Function used to disable certain dates in the calendar.
* \@param d Date
* @type {?}
*/
DatePickerComponent.prototype.disableFunction;
/**
* Function used to block certain dates in the calendar.
* \@param d Date
* @type {?}
*/
DatePickerComponent.prototype.blockFunction;
/**
* Function used to disable certain dates in the calendar for the range start selection.
* \@param d Date
* @type {?}
*/
DatePickerComponent.prototype.disableRangeStartFunction;
/**
* Function used to disable certain dates in the calendar for the range end selection.
* \@param d Date
* @type {?}
*/
DatePickerComponent.prototype.disableRangeEndFunction;
/**
* Function used to block certain dates in the calendar for the range start selection.
* \@param d Date
* @type {?}
*/
DatePickerComponent.prototype.blockRangeStartFunction;
/**
* Function used to block certain dates in the calendar for the range end selection.
* \@param d Date
* @type {?}
*/
DatePickerComponent.prototype.blockRangeEndFunction;
/**
* @hidden
* @type {?}
*/
DatePickerComponent.prototype.onChange;
/**
* @hidden
* @type {?}
*/
DatePickerComponent.prototype.onTouched;
/**
* @type {?}
* @private
*/
DatePickerComponent.prototype.eRef;
/** @type {?} */
DatePickerComponent.prototype.dateAdapter;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1waWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vZnVuZGFtZW50YWwtbmd4LyIsInNvdXJjZXMiOlsibGliL2RhdGUtcGlja2VyL2RhdGUtcGlja2VyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUNILFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFFVixZQUFZLEVBQ1osS0FBSyxFQUdMLE1BQU0sRUFDTixpQkFBaUIsRUFDcEIsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3pFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0IsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFHbEU7SUFrUUksNkJBQW9CLElBQWdCLEVBQVMsV0FBNkI7UUFBdEQsU0FBSSxHQUFKLElBQUksQ0FBWTtRQUFTLGdCQUFXLEdBQVgsV0FBVyxDQUFrQjs7OztRQTlPMUUsbUJBQWMsR0FBRyxJQUFJLENBQUM7Ozs7UUFFdEIsdUJBQWtCLEdBQVksS0FBSyxDQUFDOzs7O1FBRXBDLFdBQU0sR0FBWSxLQUFLLENBQUM7Ozs7UUFFeEIsdUJBQWtCLEdBQW9CLElBQUksT0FBTyxFQUFFLENBQUM7Ozs7UUFJcEQsU0FBSSxHQUFpQixRQUFRLENBQUM7Ozs7UUFJOUIsZ0JBQVcsR0FBVyxZQUFZLENBQUM7Ozs7UUFJbkMsWUFBTyxHQUFZLEtBQUssQ0FBQzs7OztRQUl6QixnQkFBVyxHQUFnQjtZQUN2QixJQUFJLEVBQUUsSUFBSTtTQUNiLENBQUM7Ozs7UUFJRixzQkFBaUIsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDOzs7O1FBSXZDLHVCQUFrQixHQUFnQjtZQUM5QixJQUFJLEVBQUUsSUFBSTtTQUNiLENBQUM7Ozs7UUFJRiw2QkFBd0IsR0FBRyxJQUFJLFlBQVksRUFB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QkFJTCxLQUFLO29DQU1MLE1BQU07cUNBSU4sS0FBSzsyQ0FNTCxNQUFNO29DQUlOLEtBQUs7MENBTUwsTUFBTTtvQ0FJTixLQUFLOzJCQUlMLEtBQUs7aUNBR0wsS0FBSzs2Q0FJTCxLQUFLOzRCQUlMLEtBQUs7NEJBS0wsS0FBSzsyQkFJTCxLQUFLO2tDQU9MLEtBQUs7Z0NBUUwsS0FBSzs0Q0FRTCxLQUFLOzBDQVFMLEtBQUs7MENBUUwsS0FBSzt3Q0FRTCxLQUFLO3lDQXdFTCxZQUFZLFNBQUMseUJBQXlCLEVBQUUsRUFBRTtnQ0FNMUMsWUFBWSxTQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDOztJQThFOUMsMEJBQUM7Q0FBQSxBQTFTRCxJQTBTQztTQXhSWSxtQkFBbUI7Ozs7OztJQUU1Qiw2Q0FBc0I7Ozs7O0lBRXRCLGlEQUFvQzs7Ozs7SUFFcEMscUNBQXdCOzs7OztJQUV4QixpREFBb0Q7Ozs7O0lBR3BELG1DQUM4Qjs7Ozs7SUFHOUIsMENBQ21DOzs7OztJQUduQyxzQ0FDeUI7Ozs7O0lBR3pCLDBDQUdFOzs7OztJQUdGLGdEQUN1Qzs7Ozs7SUFHdkMsaURBR0U7Ozs7O0lBR0YsdURBQzhDOzs7OztJQUc5QyxnREFHRTs7Ozs7SUFHRixzREFDNkM7Ozs7O0lBRzdDLGdEQUM4Qjs7Ozs7SUFHOUIsdUNBQWtDOzs7OztJQUdsQyw2Q0FDc0M7Ozs7O0lBR3RDLHlEQUMrRDs7Ozs7SUFHL0Qsd0NBQzBCOzs7Ozs7SUFJMUIsd0NBQ3NDOzs7OztJQUd0Qyx1Q0FDa0I7Ozs7OztJQU1sQiw4Q0FHRTs7Ozs7O0lBS0YsNENBR0U7Ozs7OztJQUtGLHdEQUdFOzs7Ozs7SUFLRixzREFHRTs7Ozs7O0lBS0Ysc0RBR0U7Ozs7OztJQUtGLG9EQUdFOzs7OztJQUdGLHVDQUFzQzs7Ozs7SUFFdEMsd0NBQTBCOzs7OztJQTRHZCxtQ0FBd0I7O0lBQUUsMENBQW9DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBDb21wb25lbnQsXG4gICAgRWxlbWVudFJlZixcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgZm9yd2FyZFJlZixcbiAgICBIb3N0QmluZGluZyxcbiAgICBIb3N0TGlzdGVuZXIsXG4gICAgSW5wdXQsXG4gICAgT25EZXN0cm95LFxuICAgIE9uSW5pdCxcbiAgICBPdXRwdXQsXG4gICAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDYWxlbmRhckRheSwgQ2FsZW5kYXJUeXBlIH0gZnJvbSAnLi4vY2FsZW5kYXIvY2FsZW5kYXIuY29tcG9uZW50JztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IERhdGVGb3JtYXRQYXJzZXIgfSBmcm9tICcuLi9jYWxlbmRhci9mb3JtYXQvZGF0ZS1wYXJzZXInO1xuaW1wb3J0IHsgUGxhY2VtZW50IH0gZnJvbSAncG9wcGVyLmpzJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdmZC1kYXRlLXBpY2tlcicsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2RhdGUtcGlja2VyLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9kYXRlLXBpY2tlci5jb21wb25lbnQuc2NzcyddLFxuICAgIGhvc3Q6IHtcbiAgICAgICAgJyhibHVyKSc6ICdvblRvdWNoZWQoKScsXG4gICAgICAgICdbY2xhc3MuZmQtZGF0ZS1waWNrZXJdJzogJ3RydWUnLFxuICAgICAgICAnW2NsYXNzLmZkLWRhdGUtcGlja2VyLWN1c3RvbV0nOiAndHJ1ZSdcbiAgICB9LFxuICAgIHByb3ZpZGVyczogW1xuICAgICAgICB7XG4gICAgICAgICAgICBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUixcbiAgICAgICAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IERhdGVQaWNrZXJDb21wb25lbnQpLFxuICAgICAgICAgICAgbXVsdGk6IHRydWVcbiAgICAgICAgfVxuICAgIF0sXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZVxufSlcbmV4cG9ydCBjbGFzcyBEYXRlUGlja2VyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcbiAgICAvKiogQGhpZGRlbiBUaGUgdmFsdWUgb2YgdGhlIGlucHV0ICovXG4gICAgaW5wdXRGaWVsZERhdGUgPSBudWxsO1xuICAgIC8qKiBAaGlkZGVuIFdoZXRoZXIgdGhlIGRhdGUgaW5wdXQgaXMgaW52YWxpZCAqL1xuICAgIGlzSW52YWxpZERhdGVJbnB1dDogYm9vbGVhbiA9IGZhbHNlO1xuICAgIC8qKiBAaGlkZGVuIFdoZXRoZXIgdGhlIGRhdGUgcGlja2VyIGlzIG9wZW4gKi9cbiAgICBpc09wZW46IGJvb2xlYW4gPSBmYWxzZTtcbiAgICAvKiogQGhpZGRlbiBTdWJqZWN0IHRoZSBjYWxlbmRhciBzdWJzY3JpYmVzIHRvIHdoZW4gdGhlIGRhdGUgdmFsdWUgZnJvbSB0aGUgZGF0ZVBpY2tlciBjb21wb25lbnQgY2hhbmdlcy4gRm9yIGludGVybmFsIHVzZS4gKi9cbiAgICBkYXRlRnJvbURhdGVQaWNrZXI6IFN1YmplY3Q8c3RyaW5nPiA9IG5ldyBTdWJqZWN0KCk7XG5cbiAgICAvKiogVGhlIHR5cGUgb2YgY2FsZW5kYXIsICdzaW5nbGUnIGZvciBzaW5nbGUgZGF0ZSBzZWxlY3Rpb24gb3IgJ3JhbmdlJyBmb3IgYSByYW5nZSBvZiBkYXRlcy4gKi9cbiAgICBASW5wdXQoKVxuICAgIHR5cGU6IENhbGVuZGFyVHlwZSA9ICdzaW5nbGUnO1xuXG4gICAgLyoqIERhdGUgcGlja2VyIGlucHV0IHBsYWNlaG9sZGVyIHN0cmluZyAqL1xuICAgIEBJbnB1dCgpXG4gICAgcGxhY2Vob2xkZXI6IHN0cmluZyA9ICdtbS9kZC95eXl5JztcblxuICAgIC8qKiBXaGV0aGVyIHRoaXMgaXMgdGhlIGNvbXBhY3QgaW5wdXQgZGF0ZSBwaWNrZXIgKi9cbiAgICBASW5wdXQoKVxuICAgIGNvbXBhY3Q6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKiBUaGUgY3VycmVudGx5IHNlbGVjdGVkIENhbGVuZGFyRGF5IG1vZGVsICovXG4gICAgQElucHV0KClcbiAgICBzZWxlY3RlZERheTogQ2FsZW5kYXJEYXkgPSB7XG4gICAgICAgIGRhdGU6IG51bGxcbiAgICB9O1xuXG4gICAgLyoqIEZpcmVkIHdoZW4gYSBuZXcgZGF0ZSBpcyBzZWxlY3RlZC4gKi9cbiAgICBAT3V0cHV0KClcbiAgICBzZWxlY3RlZERheUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAgIC8qKiBUaGUgY3VycmVudGx5IHNlbGVjdGVkIGZpcnN0IENhbGVuZGFyRGF5IGluIGEgcmFuZ2UgdHlwZSBjYWxlbmRhci4gKi9cbiAgICBASW5wdXQoKVxuICAgIHNlbGVjdGVkUmFuZ2VGaXJzdDogQ2FsZW5kYXJEYXkgPSB7XG4gICAgICAgIGRhdGU6IG51bGxcbiAgICB9O1xuXG4gICAgLyoqIEZpcmVkIHdoZW4gdGhlIHVzZXIgc2VsZWN0cyBhIG5ldyBmaXJzdCBkYXRlIGluIGEgcmFuZ2Ugb2YgZGF0ZXMgaXMgc2VsZWN0ZWQuICovXG4gICAgQE91dHB1dCgpXG4gICAgc2VsZWN0ZWRSYW5nZUZpcnN0Q2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gICAgLyoqIFRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgbGFzdCBDYWxlbmRhckRheSBpbiBhIHJhbmdlIHR5cGUgY2FsZW5kYXIuICovXG4gICAgQElucHV0KClcbiAgICBzZWxlY3RlZFJhbmdlTGFzdDogQ2FsZW5kYXJEYXkgPSB7XG4gICAgICAgIGRhdGU6IG51bGxcbiAgICB9O1xuXG4gICAgLyoqIEZpcmVkIHdoZW4gdGhlIHVzZXIgc2VsZWN0cyBhIG5ldyBsYXN0IGRhdGUgaW4gYSByYW5nZSBvZiBkYXRlcyBpcyBzZWxlY3RlZC4gKi9cbiAgICBAT3V0cHV0KClcbiAgICBzZWxlY3RlZFJhbmdlTGFzdENoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcblxuICAgIC8qKiBUaGUgZGF5IG9mIHRoZSB3ZWVrIHRoZSBjYWxlbmRhciBzaG91bGQgc3RhcnQgb24uIDAgcmVwcmVzZW50cyBTdW5kYXksIDEgaXMgTW9uZGF5LCAyIGlzIFR1ZXNkYXksIGFuZCBzbyBvbi4gKi9cbiAgICBASW5wdXQoKVxuICAgIHN0YXJ0aW5nRGF5T2ZXZWVrOiBudW1iZXIgPSAwO1xuXG4gICAgLyoqIFdoZXRoZXIgdG8gdmFsaWRhdGUgdGhlIGRhdGUgcGlja2VyIGlucHV0LiAqL1xuICAgIEBJbnB1dCgpIHZhbGlkYXRlOiBib29sZWFuID0gdHJ1ZTtcblxuICAgIC8qKiBBcmlhIGxhYmVsIGZvciB0aGUgZGF0ZXBpY2tlciBpbnB1dC4gKi9cbiAgICBASW5wdXQoKVxuICAgIGRhdGVJbnB1dExhYmVsOiBzdHJpbmcgPSAnRGF0ZSBpbnB1dCc7XG5cbiAgICAvKiogQXJpYSBsYWJlbCBmb3IgdGhlIGJ1dHRvbiB0byBzaG93L2hpZGUgdGhlIGNhbGVuZGFyLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgZGlzcGxheUNhbGVuZGFyVG9nZ2xlTGFiZWw6IHN0cmluZyA9ICdEaXNwbGF5IGNhbGVuZGFyIHRvZ2dsZSc7XG5cbiAgICAvKiogV2hldGhlciBhIG51bGwgaW5wdXQgaXMgY29uc2lkZXJlZCB2YWxpZC4gKi9cbiAgICBASW5wdXQoKVxuICAgIGFsbG93TnVsbDogYm9vbGVhbiA9IHRydWU7XG5cbiAgICAvKiogVGhlIHBsYWNlbWVudCBvZiB0aGUgcG9wb3Zlci4gSXQgY2FuIGJlIG9uZSBvZjogdG9wLCB0b3Atc3RhcnQsIHRvcC1lbmQsIGJvdHRvbSxcbiAgICAgKiAgYm90dG9tLXN0YXJ0LCBib3R0b20tZW5kLCByaWdodCwgcmlnaHQtc3RhcnQsIHJpZ2h0LWVuZCwgbGVmdCwgbGVmdC1zdGFydCwgbGVmdC1lbmQuICovXG4gICAgQElucHV0KClcbiAgICBwbGFjZW1lbnQ6IFBsYWNlbWVudCA9ICdib3R0b20tc3RhcnQnO1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIGRhdGUgcGlja2VyIGlzIGRpc2FibGVkLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgZGlzYWJsZWQ6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB1c2VkIHRvIGRpc2FibGUgY2VydGFpbiBkYXRlcyBpbiB0aGUgY2FsZW5kYXIuXG4gICAgICogQHBhcmFtIGQgRGF0ZVxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgZGlzYWJsZUZ1bmN0aW9uID0gZnVuY3Rpb24oZCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB1c2VkIHRvIGJsb2NrIGNlcnRhaW4gZGF0ZXMgaW4gdGhlIGNhbGVuZGFyLlxuICAgICAqIEBwYXJhbSBkIERhdGVcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGJsb2NrRnVuY3Rpb24gPSBmdW5jdGlvbihkKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHVzZWQgdG8gZGlzYWJsZSBjZXJ0YWluIGRhdGVzIGluIHRoZSBjYWxlbmRhciBmb3IgdGhlIHJhbmdlIHN0YXJ0IHNlbGVjdGlvbi5cbiAgICAgKiBAcGFyYW0gZCBEYXRlXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBkaXNhYmxlUmFuZ2VTdGFydEZ1bmN0aW9uID0gZnVuY3Rpb24oZCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB1c2VkIHRvIGRpc2FibGUgY2VydGFpbiBkYXRlcyBpbiB0aGUgY2FsZW5kYXIgZm9yIHRoZSByYW5nZSBlbmQgc2VsZWN0aW9uLlxuICAgICAqIEBwYXJhbSBkIERhdGVcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGRpc2FibGVSYW5nZUVuZEZ1bmN0aW9uID0gZnVuY3Rpb24oZCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB1c2VkIHRvIGJsb2NrIGNlcnRhaW4gZGF0ZXMgaW4gdGhlIGNhbGVuZGFyIGZvciB0aGUgcmFuZ2Ugc3RhcnQgc2VsZWN0aW9uLlxuICAgICAqIEBwYXJhbSBkIERhdGVcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGJsb2NrUmFuZ2VTdGFydEZ1bmN0aW9uID0gZnVuY3Rpb24oZCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB1c2VkIHRvIGJsb2NrIGNlcnRhaW4gZGF0ZXMgaW4gdGhlIGNhbGVuZGFyIGZvciB0aGUgcmFuZ2UgZW5kIHNlbGVjdGlvbi5cbiAgICAgKiBAcGFyYW0gZCBEYXRlXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBibG9ja1JhbmdlRW5kRnVuY3Rpb24gPSBmdW5jdGlvbihkKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBvbkNoYW5nZTogYW55ID0gKHNlbGVjdGVkOiBhbnkpID0+IHt9O1xuICAgIC8qKiBAaGlkZGVuICovXG4gICAgb25Ub3VjaGVkOiBhbnkgPSAoKSA9PiB7fTtcblxuICAgIC8qKiBPcGVucyB0aGUgY2FsZW5kYXIgKi9cbiAgICBvcGVuQ2FsZW5kYXIoZSkge1xuICAgICAgICBpZiAoIXRoaXMuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMub25Ub3VjaGVkKHtkYXRlOiB0aGlzLnNlbGVjdGVkRGF5LmRhdGV9KTtcbiAgICAgICAgICAgIHRoaXMuaXNPcGVuID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuZ2V0SW5wdXRWYWx1ZShlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBUb2dnbGVzIHRoZSBjYWxlbmRhciBvcGVuIG9yIGNsb3NlZCAqL1xuICAgIHRvZ2dsZUNhbGVuZGFyKGUpIHtcbiAgICAgICAgdGhpcy5vblRvdWNoZWQoe2RhdGU6IHRoaXMuc2VsZWN0ZWREYXkuZGF0ZX0pO1xuICAgICAgICB0aGlzLmlzT3BlbiA9ICF0aGlzLmlzT3BlbjtcbiAgICAgICAgdGhpcy5nZXRJbnB1dFZhbHVlKGUpO1xuICAgIH1cblxuICAgIC8qKiBDbG9zZXMgdGhlIGNhbGVuZGFyIGlmIGl0IGlzIG9wZW4gKi9cbiAgICBjbG9zZUNhbGVuZGFyKCkge1xuICAgICAgICBpZiAodGhpcy5pc09wZW4pIHtcbiAgICAgICAgICAgIHRoaXMuaXNPcGVuID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIHVwZGF0ZURhdGVQaWNrZXJJbnB1dEhhbmRsZXIoZCkge1xuICAgICAgICBpZiAodGhpcy50eXBlID09PSAnc2luZ2xlJykge1xuICAgICAgICAgICAgaWYgKGQuc2VsZWN0ZWREYXkuZGF0ZSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IG5ld0lucHV0RGF0ZSA9IHRoaXMuZGF0ZUFkYXB0ZXIuZm9ybWF0KGQuc2VsZWN0ZWREYXkuZGF0ZSk7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaW5wdXRGaWVsZERhdGUgIT09IG5ld0lucHV0RGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmlucHV0RmllbGREYXRlID0gbmV3SW5wdXREYXRlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkRGF5ID0gZC5zZWxlY3RlZERheTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZERheUNoYW5nZS5lbWl0KHRoaXMuc2VsZWN0ZWREYXkpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uQ2hhbmdlKHtkYXRlOiB0aGlzLnNlbGVjdGVkRGF5LmRhdGV9KTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoZC5zZWxlY3RlZEZpcnN0RGF5LmRhdGUpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdJbnB1dERhdGVzID0gdGhpcy5kYXRlQWRhcHRlci5mb3JtYXQoZC5zZWxlY3RlZEZpcnN0RGF5LmRhdGUpICsgdGhpcy5kYXRlQWRhcHRlci5yYW5nZURlbGltaXRlclxuICAgICAgICAgICAgICAgICAgICArIHRoaXMuZGF0ZUFkYXB0ZXIuZm9ybWF0KGQuc2VsZWN0ZWRMYXN0RGF5LmRhdGUpO1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmlucHV0RmllbGREYXRlICE9PSBuZXdJbnB1dERhdGVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRGaWVsZERhdGUgPSBuZXdJbnB1dERhdGVzO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkUmFuZ2VGaXJzdCA9IGQuc2VsZWN0ZWRGaXJzdERheTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFJhbmdlTGFzdCA9IGQuc2VsZWN0ZWRMYXN0RGF5O1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkUmFuZ2VGaXJzdENoYW5nZS5lbWl0KHRoaXMuc2VsZWN0ZWRSYW5nZUZpcnN0KTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFJhbmdlTGFzdENoYW5nZS5lbWl0KHRoaXMuc2VsZWN0ZWRSYW5nZUxhc3QpO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uQ2hhbmdlKHtkYXRlOiB0aGlzLnNlbGVjdGVkUmFuZ2VGaXJzdC5kYXRlLCByYW5nZUVuZDogdGhpcy5zZWxlY3RlZFJhbmdlTGFzdC5kYXRlfSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBpc0ludmFsaWREYXRlSW5wdXRIYW5kbGVyKGUpIHtcbiAgICAgICAgdGhpcy5pc0ludmFsaWREYXRlSW5wdXQgPSBlO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgZ2V0SW5wdXRWYWx1ZShlKSB7XG4gICAgICAgIHRoaXMuZGF0ZUZyb21EYXRlUGlja2VyLm5leHQoZSk7XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDprZXlkb3duLmVzY2FwZScsIFtdKVxuICAgIG9uRXNjYXBlS2V5ZG93bkhhbmRsZXIoKSB7XG4gICAgICAgIHRoaXMuY2xvc2VDYWxlbmRhcigpO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxuICAgIHB1YmxpYyBvbkdsb2JhbENsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgICAgIGlmICghdGhpcy5lUmVmLm5hdGl2ZUVsZW1lbnQuY29udGFpbnMoZXZlbnQudGFyZ2V0KSkge1xuICAgICAgICAgICAgdGhpcy5jbG9zZUNhbGVuZGFyKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIG5nT25Jbml0KCkge1xuICAgICAgICBpZiAodGhpcy5kYXRlRnJvbURhdGVQaWNrZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0ZUZyb21EYXRlUGlja2VyLnN1YnNjcmliZShkYXRlID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZGF0ZSAmJiB0eXBlb2YgZGF0ZSA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVEYXRlUGlja2VySW5wdXRIYW5kbGVyKGRhdGUpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoZGF0ZSA9PT0gJycgJiYgdGhpcy5hbGxvd051bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0ludmFsaWREYXRlSW5wdXQgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudHlwZSA9PT0gJ3NpbmdsZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWREYXkuZGF0ZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkRGF5LnNlbGVjdGVkID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRSYW5nZUZpcnN0LmRhdGUgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFJhbmdlRmlyc3Quc2VsZWN0ZWQgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFJhbmdlTGFzdC5kYXRlID0gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRSYW5nZUxhc3Quc2VsZWN0ZWQgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0ludmFsaWREYXRlSW5wdXQgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICBpZiAodGhpcy5kYXRlRnJvbURhdGVQaWNrZXIpIHtcbiAgICAgICAgICAgIHRoaXMuZGF0ZUZyb21EYXRlUGlja2VyLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVSZWY6IEVsZW1lbnRSZWYsIHB1YmxpYyBkYXRlQWRhcHRlcjogRGF0ZUZvcm1hdFBhcnNlcikge31cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgcmVnaXN0ZXJPbkNoYW5nZShmbjogKHNlbGVjdGVkOiBhbnkpID0+IHt2b2lkfSk6IHZvaWQge1xuICAgICAgICB0aGlzLm9uQ2hhbmdlID0gZm47XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XG4gICAgICAgIHRoaXMub25Ub3VjaGVkID0gZm47XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBzZXREaXNhYmxlZFN0YXRlKGlzRGlzYWJsZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kaXNhYmxlZCA9IGlzRGlzYWJsZWQ7XG4gICAgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICB3cml0ZVZhbHVlKHNlbGVjdGVkOiB7ZGF0ZTogRGF0ZSwgcmFuZ2VFbmQ/OiBEYXRlfSk6IHZvaWQge1xuICAgICAgICBpZiAoIXNlbGVjdGVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMudHlwZS50b0xvY2FsZUxvd2VyQ2FzZSgpID09PSAnc2luZ2xlJykge1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZERheS5kYXRlID0gc2VsZWN0ZWQuZGF0ZTtcbiAgICAgICAgICAgIGlmIChzZWxlY3RlZC5kYXRlICE9PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5pbnB1dEZpZWxkRGF0ZSA9IHRoaXMuZGF0ZUFkYXB0ZXIuZm9ybWF0KHNlbGVjdGVkLmRhdGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlucHV0RmllbGREYXRlID0gJyc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkUmFuZ2VGaXJzdC5kYXRlID0gc2VsZWN0ZWQuZGF0ZTtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRSYW5nZUxhc3QuZGF0ZSA9IHNlbGVjdGVkLnJhbmdlRW5kO1xuICAgICAgICAgICAgaWYgKHNlbGVjdGVkLmRhdGUgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlucHV0RmllbGREYXRlID0gdGhpcy5kYXRlQWRhcHRlci5mb3JtYXQoc2VsZWN0ZWQuZGF0ZSkgK1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmRhdGVBZGFwdGVyLnJhbmdlRGVsaW1pdGVyICsgdGhpcy5kYXRlQWRhcHRlci5mb3JtYXQoc2VsZWN0ZWQucmFuZ2VFbmQpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlucHV0RmllbGREYXRlID0gJyc7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=