UNPKG

fundamental-ngx

Version:

SAP Fundamentals, implemented in Angular

740 lines 58.6 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, EventEmitter, forwardRef, Input, Output, ViewChild, ViewEncapsulation } from '@angular/core'; import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms'; import { FdDate } from '../calendar/models/fd-date'; import { CalendarService } from '../calendar/calendar.service'; import { CalendarComponent } from '../calendar/calendar.component'; import { DateFormatParser } from './format/date-parser'; var DatePickerComponent = /** @class */ (function () { /** @hidden */ function DatePickerComponent(dateAdapter) { 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; /** * 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 FdDates model start and end in range mode. */ this.selectedRangeDate = { start: null, end: null }; /** * 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; /** * Whether to validate the date picker input. */ this.useValidation = 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; /** * Actually shown active view one of 'day' | 'month' | 'year' in calendar component */ this.activeView = 'day'; /** * 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'; /** * Fired when a new date is selected. */ 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 calendar active view is changed */ this.activeViewChange = new EventEmitter(); /** * @hidden */ this.onChange = (/** * @param {?} selected * @return {?} */ function (selected) { }); /** * @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; }); } /** * Method that handle calendar active view change and throws event. */ /** * Method that handle calendar active view change and throws event. * @param {?} activeView * @return {?} */ DatePickerComponent.prototype.handleCalendarActiveViewChange = /** * Method that handle calendar active view change and throws event. * @param {?} activeView * @return {?} */ function (activeView) { this.activeViewChange.emit(activeView); }; /** @hidden */ /** * @hidden * @return {?} */ DatePickerComponent.prototype.closeFromCalendar = /** * @hidden * @return {?} */ function () { if (this.type === 'single') { this.closeCalendar(); } }; /** Opens the calendar */ /** * Opens the calendar * @return {?} */ DatePickerComponent.prototype.openCalendar = /** * Opens the calendar * @return {?} */ function () { if (!this.disabled) { this.onTouched(); this.isOpen = true; } }; /** Toggles the calendar open or closed */ /** * Toggles the calendar open or closed * @return {?} */ DatePickerComponent.prototype.toggleCalendar = /** * Toggles the calendar open or closed * @return {?} */ function () { this.onTouched(); this.isOpen = !this.isOpen; }; /** 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 * Method that is triggered by events from calendar component, when there is selected single date changed */ /** * @hidden * Method that is triggered by events from calendar component, when there is selected single date changed * @param {?} date * @return {?} */ DatePickerComponent.prototype.handleSingleDateChange = /** * @hidden * Method that is triggered by events from calendar component, when there is selected single date changed * @param {?} date * @return {?} */ function (date) { if (date) { this.inputFieldDate = this.dateAdapter.format(date); this.selectedDate = date; this.selectedDateChange.emit(date); this.onChange(date); } }; /** * @hidden * Method that is triggered by events from calendar component, when there is selected range date changed */ /** * @hidden * Method that is triggered by events from calendar component, when there is selected range date changed * @param {?} dates * @return {?} */ DatePickerComponent.prototype.handleRangeDateChange = /** * @hidden * Method that is triggered by events from calendar component, when there is selected range date changed * @param {?} dates * @return {?} */ function (dates) { if (dates && (!CalendarService.datesEqual(this.selectedRangeDate.start, dates.start) || !CalendarService.datesEqual(this.selectedRangeDate.end, dates.end))) { this.inputFieldDate = this.dateAdapter.format(dates.start) + this.dateAdapter.rangeDelimiter + this.dateAdapter.format(dates.end); this.selectedRangeDate = { start: dates.start, end: dates.end }; this.selectedRangeDateChange.emit(this.selectedRangeDate); this.onChange(this.selectedRangeDate); } }; /** * @hidden * Method that is triggered when the text input is confirmed to ba changed, by clicking enter, or blur */ /** * @hidden * Method that is triggered when the text input is confirmed to ba changed, by clicking enter, or blur * @param {?} strDate * @return {?} */ DatePickerComponent.prototype.handleInputChange = /** * @hidden * Method that is triggered when the text input is confirmed to ba changed, by clicking enter, or blur * @param {?} strDate * @return {?} */ function (strDate) { this.dateStringUpdate(strDate); }; /** * @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 {?} */ DatePickerComponent.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 {?} */ 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 * 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 {?} */ DatePickerComponent.prototype.writeValue = /** * @hidden * Function that provides support for ControlValueAccessor that allows to use [(ngModel)] or forms * @param {?} selected * @return {?} */ function (selected) { /** If written value is not defined, null, empty string */ if (!selected) { this.inputFieldDate = ''; return; } if (this.type === 'single') { /** * For single mode, if the date is invalid, model is changed, it refresh currently * input field text, but it does not refresh currently displayed day */ selected = (/** @type {?} */ (selected)); this.selectedDate = selected; this.inputFieldDate = this.dateAdapter.format(selected); if (this.isModelValid()) { this.calendarComponent.setCurrentlyDisplayed(this.selectedDate); } } else { /** * For range mode, if the date is invalid, model is changed, but it does not refresh currently * displayed day view, or input field text */ selected = (/** @type {?} */ (selected)); if (selected.start) { this.selectedRangeDate = { start: selected.start, end: selected.end }; if (this.isModelValid()) { this.calendarComponent.setCurrentlyDisplayed(this.selectedRangeDate.start); this.inputFieldDate = this.dateAdapter.format(selected.start) + this.dateAdapter.rangeDelimiter + this.dateAdapter.format(selected.end); } } else { this.inputFieldDate = ''; } } this.isInvalidDateInput = !this.isModelValid(); }; /** * @hidden * Method, which is responsible for transforming string to date, depending on type or * validation the results are different. It also changes to state of isInvalidDateInput */ /** * @hidden * Method, which is responsible for transforming string to date, depending on type or * validation the results are different. It also changes to state of isInvalidDateInput * @param {?} date * @return {?} */ DatePickerComponent.prototype.dateStringUpdate = /** * @hidden * Method, which is responsible for transforming string to date, depending on type or * validation the results are different. It also changes to state of isInvalidDateInput * @param {?} date * @return {?} */ function (date) { /** Case when there is single mode */ if (this.type === 'single') { /** @type {?} */ var fdDate = this.dateAdapter.parse(date); /** * Check if dates are equal, if dates are the same there is no need to make any changes * Date in model is changed no matter if the parsed date fro string is valid or not. */ if (!CalendarService.datesEqual(fdDate, this.selectedDate)) { this.isInvalidDateInput = !fdDate.isDateValid(); this.selectedDate = fdDate; this.onChange(this.selectedDate); this.selectedDateChange.emit(this.selectedDate); /** Check if date is valid, if it's not, there is no need to refresh calendar */ if (!this.isInvalidDateInput) { this.calendarComponent.setCurrentlyDisplayed(fdDate); } } /** Case when there is range mode */ } else { /** @type {?} */ var currentDates = date.split(this.dateAdapter.rangeDelimiter); /** @type {?} */ var firstDate = this.dateAdapter.parse(currentDates[0]); /** @type {?} */ var secondDate = this.dateAdapter.parse(currentDates[1]); /** * Check if dates are equal, if dates are the same there is no need to make any changes * Date in model is changed no matter if the parsed dates from string are valid or not. */ if (!CalendarService.datesEqual(firstDate, this.selectedRangeDate.start) || !CalendarService.datesEqual(secondDate, this.selectedRangeDate.end)) { this.isInvalidDateInput = !firstDate.isDateValid() || !secondDate.isDateValid(); /** If the end date is before the start date, there is need to replace them */ if ((firstDate.getTimeStamp() > secondDate.getTimeStamp()) && secondDate.isDateValid()) { this.selectedRangeDate = { start: secondDate, end: firstDate }; } else { this.selectedRangeDate = { start: firstDate, end: secondDate }; } this.selectedRangeDateChange.emit(this.selectedRangeDate); this.onChange({ start: this.selectedRangeDate.start, end: this.selectedRangeDate.end }); /** Check if dates are valid, if it's not, there is no need o refresh calendar */ if (!this.isInvalidDateInput) { this.calendarComponent.setCurrentlyDisplayed(this.selectedRangeDate.start); } } } if (!date && this.allowNull) { this.isInvalidDateInput = false; } }; /** 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 {?} */ DatePickerComponent.prototype.isModelValid = /** * Method that provides information if model selected date/dates have properly types and are valid * @return {?} */ function () { if (this.type === '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.end.isDateValid()); } }; DatePickerComponent.decorators = [ { type: Component, args: [{ selector: 'fd-date-picker', template: "<fd-popover [(isOpen)]=\"isOpen\"\n (isOpenChange)=\"handleInputChange(datePicker.value)\"\n [triggers]=\"[]\"\n [placement]=\"placement\"\n [closeOnEscapeKey]=\"true\"\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)=\"handleInputChange(datePicker.value)\"\n (click)=\"openCalendar()\"\n [disabled]=\"disabled\"\n [ngClass]=\"{ 'fd-input--compact': compact, 'is-invalid': isInvalidDateInput && useValidation }\">\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()\" [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)=\"closeFromCalendar()\"\n [activeView]=\"activeView\"\n (activeViewChange)=\"handleCalendarActiveViewChange($event)\"\n [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 [selectedDate]=\"selectedDate\"\n [selectedRangeDate]=\"selectedRangeDate\"\n (selectedRangeDateChange)=\"handleRangeDateChange($event)\"\n (selectedDateChange)=\"handleSingleDateChange($event)\"\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 }, { provide: NG_VALIDATORS, 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: DateFormatParser } ]; }; DatePickerComponent.propDecorators = { calendarComponent: [{ type: ViewChild, args: [CalendarComponent,] }], type: [{ type: Input }], placeholder: [{ type: Input }], compact: [{ type: Input }], selectedDate: [{ type: Input }], selectedRangeDate: [{ type: Input }], startingDayOfWeek: [{ type: Input }], useValidation: [{ type: Input }], dateInputLabel: [{ type: Input }], displayCalendarToggleLabel: [{ type: Input }], allowNull: [{ type: Input }], activeView: [{ type: Input }], placement: [{ type: Input }], disabled: [{ type: Input }], selectedDateChange: [{ type: Output }], selectedRangeDateChange: [{ type: Output }], activeViewChange: [{ type: Output }], disableFunction: [{ type: Input }], disableRangeStartFunction: [{ type: Input }], disableRangeEndFunction: [{ type: Input }], blockRangeStartFunction: [{ type: Input }], blockRangeEndFunction: [{ type: Input }], blockFunction: [{ type: Input }] }; 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 * @type {?} */ DatePickerComponent.prototype.calendarComponent; /** * 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.selectedDate; /** * The currently selected FdDates model start and end in range mode. * @type {?} */ DatePickerComponent.prototype.selectedRangeDate; /** * The day of the week the calendar should start on. 1 represents Sunday, 2 is Monday, 3 is Tuesday, and so on. * @type {?} */ DatePickerComponent.prototype.startingDayOfWeek; /** * Whether to validate the date picker input. * @type {?} */ DatePickerComponent.prototype.useValidation; /** * 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; /** * Actually shown active view one of 'day' | 'month' | 'year' in calendar component * @type {?} */ DatePickerComponent.prototype.activeView; /** * 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; /** * Fired when a new date is selected. * @type {?} */ DatePickerComponent.prototype.selectedDateChange; /** * Event thrown every time selected first or last date in range mode is changed * @type {?} */ DatePickerComponent.prototype.selectedRangeDateChange; /** * Event thrown every time calendar active view is changed * @type {?} */ DatePickerComponent.prototype.activeViewChange; /** * @hidden * @type {?} */ DatePickerComponent.prototype.onChange; /** * @hidden * @type {?} */ DatePickerComponent.prototype.onTouched; /** * Function used to disable certain dates in the calendar. * \@param fdDate FdDate * @type {?} */ DatePickerComponent.prototype.disableFunction; /** * Function used to disable certain dates in the calendar for the range start selection. * \@param fdDate FdDate * @type {?} */ DatePickerComponent.prototype.disableRangeStartFunction; /** * Function used to disable certain dates in the calendar for the range end selection. * \@param fdDate FdDate * @type {?} */ DatePickerComponent.prototype.disableRangeEndFunction; /** * Function used to block certain dates in the calendar for the range start selection. * \@param fdDate FdDate * @type {?} */ DatePickerComponent.prototype.blockRangeStartFunction; /** * Function used to block certain dates in the calendar for the range end selection. * \@param fdDate FdDate * @type {?} */ DatePickerComponent.prototype.blockRangeEndFunction; /** * Function used to block certain dates in the calendar. * \@param fdDate FdDate * @type {?} */ DatePickerComponent.prototype.blockFunction; /** @type {?} */ DatePickerComponent.prototype.dateAdapter; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1waWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vZnVuZGFtZW50YWwtbmd4LyIsInNvdXJjZXMiOlsibGliL2RhdGUtcGlja2VyL2RhdGUtcGlja2VyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUNILFNBQVMsRUFDVCxZQUFZLEVBQ1osVUFBVSxFQUNWLEtBQUssRUFDTCxNQUFNLEVBQUUsU0FBUyxFQUNqQixpQkFBaUIsRUFDcEIsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUF5QyxhQUFhLEVBQUUsaUJBQWlCLEVBQWEsTUFBTSxnQkFBZ0IsQ0FBQztBQUVwSCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQy9ELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRW5FLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRXhEO0lBZ1BJLGNBQWM7SUFDZCw2QkFDVyxXQUE2QjtRQUE3QixnQkFBVyxHQUFYLFdBQVcsQ0FBa0I7Ozs7UUF4TnhDLG1CQUFjLEdBQUcsSUFBSSxDQUFDOzs7O1FBR3RCLHVCQUFrQixHQUFZLEtBQUssQ0FBQzs7OztRQUdwQyxXQUFNLEdBQVksS0FBSyxDQUFDOzs7O1FBT3hCLFNBQUksR0FBaUIsUUFBUSxDQUFDOzs7O1FBSTlCLGdCQUFXLEdBQVcsWUFBWSxDQUFDOzs7O1FBSW5DLFlBQU8sR0FBWSxLQUFLLENBQUM7Ozs7UUFRbEIsc0JBQWlCLEdBQWdCLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsSUFBSSxFQUFFLENBQUM7Ozs7UUFJbkUsc0JBQWlCLEdBQWUsQ0FBQyxDQUFDOzs7O1FBSWxDLGtCQUFhLEdBQVksSUFBSSxDQUFDOzs7O1FBSTlCLG1CQUFjLEdBQVcsWUFB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cUI7Ozs7O0lBR3JCLGdEQUNtRTs7Ozs7SUFHbkUsZ0RBQ2tDOzs7OztJQUdsQyw0Q0FDOEI7Ozs7O0lBRzlCLDZDQUNzQzs7Ozs7SUFHdEMseURBQytEOzs7OztJQUcvRCx3Q0FDMEI7Ozs7O0lBRzFCLHlDQUMwQzs7Ozs7O0lBTTFDLHdDQUNzQzs7Ozs7SUFHdEMsdUNBQ2tCOzs7OztJQUdsQixpREFDc0Y7Ozs7O0lBR3RGLHNEQUNxRzs7Ozs7SUFHckcsK0NBQ29HOzs7OztJQUdwRyx1Q0FDRTs7Ozs7SUFHRix3Q0FDRTs7Ozs7O0lBTUYsOENBR0U7Ozs7OztJQU1GLHdEQUdFOzs7Ozs7SUFNRixzREFHRTs7Ozs7O0lBTUYsc0RBR0U7Ozs7OztJQU1GLG9EQUdFOzs7Ozs7SUFNRiw0Q0FHRTs7SUE4RUUsMENBQW9DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBDb21wb25lbnQsXG4gICAgRXZlbnRFbWl0dGVyLFxuICAgIGZvcndhcmRSZWYsXG4gICAgSW5wdXQsXG4gICAgT3V0cHV0LCBWaWV3Q2hpbGQsXG4gICAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDYWxlbmRhclR5cGUsIERheXNPZldlZWssIEZkQ2FsZW5kYXJWaWV3IH0gZnJvbSAnLi4vY2FsZW5kYXIvY2FsZW5kYXIuY29tcG9uZW50JztcbmltcG9ydCB7IEFic3RyYWN0Q29udHJvbCwgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5HX1ZBTElEQVRPUlMsIE5HX1ZBTFVFX0FDQ0VTU09SLCBWYWxpZGF0b3IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBQbGFjZW1lbnQgfSBmcm9tICdwb3BwZXIuanMnO1xuaW1wb3J0IHsgRmREYXRlIH0gZnJvbSAnLi4vY2FsZW5kYXIvbW9kZWxzL2ZkLWRhdGUnO1xuaW1wb3J0IHsgQ2FsZW5kYXJTZXJ2aWNlIH0gZnJvbSAnLi4vY2FsZW5kYXIvY2FsZW5kYXIuc2VydmljZSc7XG5pbXBvcnQgeyBDYWxlbmRhckNvbXBvbmVudCB9IGZyb20gJy4uL2NhbGVuZGFyL2NhbGVuZGFyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBGZFJhbmdlRGF0ZSB9IGZyb20gJy4uL2NhbGVuZGFyL21vZGVscy9mZC1yYW5nZS1kYXRlJztcbmltcG9ydCB7IERhdGVGb3JtYXRQYXJzZXIgfSBmcm9tICcuL2Zvcm1hdC9kYXRlLXBhcnNlcic7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnZmQtZGF0ZS1waWNrZXInLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9kYXRlLXBpY2tlci5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vZGF0ZS1waWNrZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgICBob3N0OiB7XG4gICAgICAgICcoYmx1ciknOiAnb25Ub3VjaGVkKCknLFxuICAgICAgICAnW2NsYXNzLmZkLWRhdGUtcGlja2VyXSc6ICd0cnVlJyxcbiAgICAgICAgJ1tjbGFzcy5mZC1kYXRlLXBpY2tlci1jdXN0b21dJzogJ3RydWUnXG4gICAgfSxcbiAgICBwcm92aWRlcnM6IFtcbiAgICAgICAge1xuICAgICAgICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICAgICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBEYXRlUGlja2VyQ29tcG9uZW50KSxcbiAgICAgICAgICAgIG11bHRpOiB0cnVlXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICAgIHByb3ZpZGU6IE5HX1ZBTElEQVRPUlMsXG4gICAgICAgICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBEYXRlUGlja2VyQ29tcG9uZW50KSxcbiAgICAgICAgICAgIG11bHRpOiB0cnVlXG4gICAgICAgIH1cbiAgICBdLFxuICAgIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmVcbn0pXG5leHBvcnQgY2xhc3MgRGF0ZVBpY2tlckNvbXBvbmVudCBpbXBsZW1lbnRzIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBWYWxpZGF0b3Ige1xuXG4gICAgLyoqIEBoaWRkZW4gVGhlIHZhbHVlIG9mIHRoZSBpbnB1dCAqL1xuICAgIGlucHV0RmllbGREYXRlID0gbnVsbDtcblxuICAgIC8qKiBAaGlkZGVuIFdoZXRoZXIgdGhlIGRhdGUgaW5wdXQgaXMgaW52YWxpZCAqL1xuICAgIGlzSW52YWxpZERhdGVJbnB1dDogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgLyoqIEBoaWRkZW4gV2hldGhlciB0aGUgZGF0ZSBwaWNrZXIgaXMgb3BlbiAqL1xuICAgIGlzT3BlbjogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBAVmlld0NoaWxkKENhbGVuZGFyQ29tcG9uZW50KSBjYWxlbmRhckNvbXBvbmVudDogQ2FsZW5kYXJDb21wb25lbnQ7XG5cbiAgICAvKiogVGhlIHR5cGUgb2YgY2FsZW5kYXIsICdzaW5nbGUnIGZvciBzaW5nbGUgZGF0ZSBzZWxlY3Rpb24gb3IgJ3JhbmdlJyBmb3IgYSByYW5nZSBvZiBkYXRlcy4gKi9cbiAgICBASW5wdXQoKVxuICAgIHR5cGU6IENhbGVuZGFyVHlwZSA9ICdzaW5nbGUnO1xuXG4gICAgLyoqIERhdGUgcGlja2VyIGlucHV0IHBsYWNlaG9sZGVyIHN0cmluZyAqL1xuICAgIEBJbnB1dCgpXG4gICAgcGxhY2Vob2xkZXI6IHN0cmluZyA9ICdtbS9kZC95eXl5JztcblxuICAgIC8qKiBXaGV0aGVyIHRoaXMgaXMgdGhlIGNvbXBhY3QgaW5wdXQgZGF0ZSBwaWNrZXIgKi9cbiAgICBASW5wdXQoKVxuICAgIGNvbXBhY3Q6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKiBUaGUgY3VycmVudGx5IHNlbGVjdGVkIENhbGVuZGFyRGF5IG1vZGVsICovXG4gICAgQElucHV0KClcbiAgICBzZWxlY3RlZERhdGU6IEZkRGF0ZTtcblxuICAgIC8qKiBUaGUgY3VycmVudGx5IHNlbGVjdGVkIEZkRGF0ZXMgbW9kZWwgc3RhcnQgYW5kIGVuZCBpbiByYW5nZSBtb2RlLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIHNlbGVjdGVkUmFuZ2VEYXRlOiBGZFJhbmdlRGF0ZSA9IHsgc3RhcnQ6IG51bGwsIGVuZDogbnVsbCB9O1xuXG4gICAgLyoqIFRoZSBkYXkgb2YgdGhlIHdlZWsgdGhlIGNhbGVuZGFyIHNob3VsZCBzdGFydCBvbi4gMSByZXByZXNlbnRzIFN1bmRheSwgMiBpcyBNb25kYXksIDMgaXMgVHVlc2RheSwgYW5kIHNvIG9uLiAqL1xuICAgIEBJbnB1dCgpXG4gICAgc3RhcnRpbmdEYXlPZldlZWs6IERheXNPZldlZWsgPSAxO1xuXG4gICAgLyoqIFdoZXRoZXIgdG8gdmFsaWRhdGUgdGhlIGRhdGUgcGlja2VyIGlucHV0LiAqL1xuICAgIEBJbnB1dCgpXG4gICAgdXNlVmFsaWRhdGlvbjogYm9vbGVhbiA9IHRydWU7XG5cbiAgICAvKiogQXJpYSBsYWJlbCBmb3IgdGhlIGRhdGVwaWNrZXIgaW5wdXQuICovXG4gICAgQElucHV0KClcbiAgICBkYXRlSW5wdXRMYWJlbDogc3RyaW5nID0gJ0RhdGUgaW5wdXQnO1xuXG4gICAgLyoqIEFyaWEgbGFiZWwgZm9yIHRoZSBidXR0b24gdG8gc2hvdy9oaWRlIHRoZSBjYWxlbmRhci4gKi9cbiAgICBASW5wdXQoKVxuICAgIGRpc3BsYXlDYWxlbmRhclRvZ2dsZUxhYmVsOiBzdHJpbmcgPSAnRGlzcGxheSBjYWxlbmRhciB0b2dnbGUnO1xuXG4gICAgLyoqIFdoZXRoZXIgYSBudWxsIGlucHV0IGlzIGNvbnNpZGVyZWQgdmFsaWQuICovXG4gICAgQElucHV0KClcbiAgICBhbGxvd051bGw6IGJvb2xlYW4gPSB0cnVlO1xuXG4gICAgLyoqIEFjdHVhbGx5IHNob3duIGFjdGl2ZSB2aWV3IG9uZSBvZiAnZGF5JyB8ICdtb250aCcgfCAneWVhcicgaW4gY2FsZW5kYXIgY29tcG9uZW50Ki9cbiAgICBASW5wdXQoKVxuICAgIHB1YmxpYyBhY3RpdmVWaWV3OiBGZENhbGVuZGFyVmlldyA9ICdkYXknO1xuXG4gICAgLyoqXG4gICAgICogIFRoZSBwbGFjZW1lbnQgb2YgdGhlIHBvcG92ZXIuIEl0IGNhbiBiZSBvbmUgb2Y6IHRvcCwgdG9wLXN0YXJ0LCB0b3AtZW5kLCBib3R0b20sXG4gICAgICogIGJvdHRvbS1zdGFydCwgYm90dG9tLWVuZCwgcmlnaHQsIHJpZ2h0LXN0YXJ0LCByaWdodC1lbmQsIGxlZnQsIGxlZnQtc3RhcnQsIGxlZnQtZW5kLlxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcGxhY2VtZW50OiBQbGFjZW1lbnQgPSAnYm90dG9tLXN0YXJ0JztcblxuICAgIC8qKiBXaGV0aGVyIHRoZSBkYXRlIHBpY2tlciBpcyBkaXNhYmxlZC4gKi9cbiAgICBASW5wdXQoKVxuICAgIGRpc2FibGVkOiBib29sZWFuO1xuXG4gICAgLyoqIEZpcmVkIHdoZW4gYSBuZXcgZGF0ZSBpcyBzZWxlY3RlZC4gKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgcmVhZG9ubHkgc2VsZWN0ZWREYXRlQ2hhbmdlOiBFdmVudEVtaXR0ZXI8RmREYXRlPiA9IG5ldyBFdmVudEVtaXR0ZXI8RmREYXRlPigpO1xuXG4gICAgLyoqIEV2ZW50IHRocm93biBldmVyeSB0aW1lIHNlbGVjdGVkIGZpcnN0IG9yIGxhc3QgZGF0ZSBpbiByYW5nZSBtb2RlIGlzIGNoYW5nZWQgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgcmVhZG9ubHkgc2VsZWN0ZWRSYW5nZURhdGVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxGZFJhbmdlRGF0ZT4gPSBuZXcgRXZlbnRFbWl0dGVyPEZkUmFuZ2VEYXRlPigpO1xuXG4gICAgLyoqIEV2ZW50IHRocm93biBldmVyeSB0aW1lIGNhbGVuZGFyIGFjdGl2ZSB2aWV3IGlzIGNoYW5nZWQgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgcmVhZG9ubHkgYWN0aXZlVmlld0NoYW5nZTogRXZlbnRFbWl0dGVyPEZkQ2FsZW5kYXJWaWV3PiA9IG5ldyBFdmVudEVtaXR0ZXI8RmRDYWxlbmRhclZpZXc+KCk7XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIG9uQ2hhbmdlOiBhbnkgPSAoc2VsZWN0ZWQ6IGFueSkgPT4ge1xuICAgIH07XG5cbiAgICAvKiogQGhpZGRlbiAqL1xuICAgIG9uVG91Y2hlZDogYW55ID0gKCkgPT4ge1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB1c2VkIHRvIGRpc2FibGUgY2VydGFpbiBkYXRlcyBpbiB0aGUgY2FsZW5kYXIuXG4gICAgICogQHBhcmFtIGZkRGF0ZSBGZERhdGVcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGRpc2FibGVGdW5jdGlvbiA9IGZ1bmN0aW9uKGZkRGF0ZTogRmREYXRlKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gdXNlZCB0byBkaXNhYmxlIGNlcnRhaW4gZGF0ZXMgaW4gdGhlIGNhbGVuZGFyIGZvciB0aGUgcmFuZ2Ugc3RhcnQgc2VsZWN0aW9uLlxuICAgICAqIEBwYXJhbSBmZERhdGUgRmREYXRlXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBkaXNhYmxlUmFuZ2VTdGFydEZ1bmN0aW9uID0gZnVuY3Rpb24oZmREYXRlOiBGZERhdGUpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBGdW5jdGlvbiB1c2VkIHRvIGRpc2FibGUgY2VydGFpbiBkYXRlcyBpbiB0aGUgY2FsZW5kYXIgZm9yIHRoZSByYW5nZSBlbmQgc2VsZWN0aW9uLlxuICAgICAqIEBwYXJhbSBmZERhdGUgRmREYXRlXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBkaXNhYmxlUmFuZ2VFbmRGdW5jdGlvbiA9IGZ1bmN0aW9uKGZkRGF0ZTogRmREYXRlKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogRnVuY3Rpb24gdXNlZCB0byBibG9jayBjZXJ0YWluIGRhdGVzIGluIHRoZSBjYWxlbmRhciBmb3IgdGhlIHJhbmdlIHN0YXJ0IHNlbGVjdGlvbi5cbiAgICAgKiBAcGFyYW0gZmREYXRlIEZkRGF0ZVxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgYmxvY2tSYW5nZVN0YXJ0RnVuY3Rpb24gPSBmdW5jdGlvbihmZERhdGU6IEZkRGF0ZSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHVzZWQgdG8gYmxvY2sgY2VydGFpbiBkYXRlcyBpbiB0aGUgY2FsZW5kYXIgZm9yIHRoZSByYW5nZSBlbmQgc2VsZWN0aW9uLlxuICAgICAqIEBwYXJhbSBmZERhdGUgRmREYXRlXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBibG9ja1JhbmdlRW5kRnVuY3Rpb24gPSBmdW5jdGlvbihmZERhdGU6IEZkRGF0ZSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIEZ1bmN0aW9uIHVzZWQgdG8gYmxvY2sgY2VydGFpbiBkYXRlcyBpbiB0aGUgY2FsZW5kYXIuXG4gICAgICogQHBhcmFtIGZkRGF0ZSBGZERhdGVcbiAgICAgKi9cbiAgICBASW5wdXQoKVxuICAgIGJsb2NrRnVuY3Rpb24gPSBmdW5jdGlvbihmZERhdGU6IEZkRGF0ZSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfTtcblxuICAgIC8qKlxuICAgICAqIE1ldGhvZCB0aGF0IGhhbmRsZSBjYWxlbmRhciBhY3RpdmUgdmlldyBjaGFuZ2UgYW5kIHRocm93cyBldmVudC5cbiAgICAgKi9cbiAgICBwdWJsaWMgaGFuZGxlQ2FsZW5kYXJBY3RpdmVWaWV3Q2hhbmdlKGFjdGl2ZVZpZXc6IEZkQ2FsZW5kYXJWaWV3KTogdm9pZCB7XG4gICAgICAgIHRoaXMuYWN0aXZlVmlld0NoYW5nZS5lbWl0KGFjdGl2ZVZpZXcpO1xuICAgIH1cblxuICAgIC8qKiBAaGlkZGVuICovXG4gICAgcHVibGljIGNsb3NlRnJvbUNhbGVuZGFyKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy50eXBlID09PSAnc2luZ2xlJykge1xuICAgICAgICAgICAgdGhpcy5jbG9zZUNhbGVuZGFyKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogT3BlbnMgdGhlIGNhbGVuZGFyICovXG4gICAgb3BlbkNhbGVuZGFyKCk6IHZvaWQge1xuICAgICAgICBpZiAoIXRoaXMuZGlzYWJsZWQpIHtcbiAgICAgICAgICAgIHRoaXMub25Ub3VjaGVkKCk7XG4gICAgICAgICAgICB0aGlzLmlzT3BlbiA9IHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogVG9nZ2xlcyB0aGUgY2FsZW5kYXIgb3BlbiBvciBjbG9zZWQgKi9cbiAgICBwdWJsaWMgdG9nZ2xlQ2FsZW5kYXIoKTogdm9pZCB7XG4gICAgICAgIHRoaXMub25Ub3VjaGVkKCk7XG4gICAgICAgIHRoaXMuaXNPcGVuID0gIXRoaXMuaXNPcGVuO1xuICAgIH1cblxuICAgIC8qKiBDbG9zZXMgdGhlIGNhbGVuZGFyIGlmIGl0IGlzIG9wZW4gKi9cbiAgICBwdWJsaWMgY2xvc2VDYWxlbmRhcigpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuaXNPcGVuKSB7XG4gICAgICAgICAgICB0aGlzLmlzT3BlbiA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqIE1ldGhvZCB0aGF0IGlzIHRyaWdnZXJlZCBieSBldmVudHMgZnJvbSBjYWxlbmRhciBjb21wb25lbnQsIHdoZW4gdGhlcmUgaXMgc2VsZWN0ZWQgc2luZ2xlIGRhdGUgY2hhbmdlZFxuICAgICAqL1xuICAgIHB1YmxpYyBoYW5kbGVTaW5nbGVEYXRlQ2hhbmdlKGRhdGU6IEZkRGF0ZSk6IHZvaWQge1xuICAgICAgICBpZiAoZGF0ZSkge1xuICAgICAgICAgICAgdGhpcy5pbnB1dEZpZWxkRGF0ZSA9IHRoaXMuZGF0ZUFkYXB0ZXIuZm9ybWF0KGRhdGUpO1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZERhdGUgPSBkYXRlO1xuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZERhdGVDaGFuZ2UuZW1pdChkYXRlKTtcbiAgICAgICAgICAgIHRoaXMub25DaGFuZ2UoZGF0ZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICogTWV0aG9kIHRoYXQgaXMgdHJpZ2dlcmVkIGJ5IGV2ZW50cyBmcm9tIGNhbGVuZGFyIGNvbXBvbmVudCwgd2hlbiB0aGVyZSBpcyBzZWxlY3RlZCByYW5nZSBkYXRlIGNoYW5nZWRcbiAgICAgKi9cbiAgICBwdWJsaWMgaGFuZGxlUmFuZ2VEYXRlQ2hhbmdlKGRhdGVzOiBGZFJhbmdlRGF0ZSk6IHZvaWQge1xuICAgICAgICBpZiAoZGF0ZXMgJiZcbiAgICAgICAgICAgICghQ2FsZW5kYXJTZXJ2aWNlLmRhdGVzRXF1YWwodGhpcy5zZWxlY3RlZFJhbmdlRGF0ZS5zdGFydCwgZGF0ZXMuc3RhcnQpIHx8XG4gICAgICAgICAgICAgICAgIUNhbGVuZGFyU2VydmljZS5kYXRlc0VxdWFsKHRoaXMuc2VsZWN0ZWRSYW5nZURhdGUuZW5kLCBkYXRlcy5lbmQpKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXMuaW5wdXRGaWVsZERhdGUgPSB0aGlzLmRhdGVBZGFwdGVyLmZvcm1hdChkYXRlcy5zdGFydCkgKyB0aGlzLmRhdGVBZGFwdGVyLnJhbmdlRGVsaW1pdGVyXG4gICAgICAgICAgICAgICAgKyB0aGlzLmRhdGVBZGFwdGVyLmZvcm1hdChkYXRlcy5lbmQpXG4gICAgICAgICAgICA7XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlID0geyBzdGFydDogZGF0ZXMuc3RhcnQsIGVuZDogZGF0ZXMuZW5kIH07XG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlQ2hhbmdlLmVtaXQodGhpcy5zZWxlY3RlZFJhbmdlRGF0ZSk7XG4gICAgICAgICAgICB0aGlzLm9uQ2hhbmdlKHRoaXMuc2VsZWN0ZWRSYW5nZURhdGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqIE1ldGhvZCB0aGF0IGlzIHRyaWdnZXJlZCB3aGVuIHRoZSB0ZXh0IGlucHV0IGlzIGNvbmZpcm1lZCB0byBiYSBjaGFuZ2VkLCBieSBjbGlja2luZyBlbnRlciwgb3IgYmx1clxuICAgICAqL1xuICAgIHB1YmxpYyBoYW5kbGVJbnB1dENoYW5nZShzdHJEYXRlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5kYXRlU3RyaW5nVXBkYXRlKHN0ckRhdGUpO1xuICAgIH1cblxuICAgIC8qK