@kushki/ng-suka
Version:
<p align="center"> <h1 align="center">Suka Components Angular</h1> <p align="center"> An Angular implementation of the Suka Design System </p> </p>
583 lines • 49.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Component, Input, Output, EventEmitter, ViewEncapsulation, ElementRef, HostListener } from '@angular/core';
import rangePlugin from 'flatpickr/dist/plugins/rangePlugin';
import flatpickr from 'flatpickr';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { sukaFlatpickrMonthSelectPlugin } from './sukaFlatpickrMonthSelectPlugin';
var DatePicker = /** @class */ (function () {
function DatePicker(elementRef) {
var _this = this;
this.elementRef = elementRef;
/**
* Select calendar range mode
*/
this.range = false;
/**
* Format of date
*
* For reference: https://flatpickr.js.org/formatting/
*/
this.dateFormat = 'd/m/Y';
this.placeholder = 'dd/mm/yyyy';
this.pattern = '^\\d{1,2}/\\d{1,2}/\\d{4}$';
this.id = "datepicker-" + DatePicker.datePickerCount++;
this.disabled = false;
this.invalid = false;
this.skeleton = false;
this.plugins = [];
this.valueChange = new EventEmitter();
this._value = [];
this._flatpickrOptions = {
allowInput: true
};
this.flatpickrBaseOptions = {
mode: 'single',
dateFormat: 'd/m/Y',
plugins: this.plugins,
onOpen: (/**
* @return {?}
*/
function () { _this.updateClassNames(); }),
value: this.value
};
this.flatpickrInstance = null;
this.onTouched = (/**
* @return {?}
*/
function () { });
this.propagateChange = (/**
* @param {?} _
* @return {?}
*/
function (_) { });
}
Object.defineProperty(DatePicker.prototype, "value", {
get: /**
* @return {?}
*/
function () {
return this._value;
},
set: /**
* @param {?} v
* @return {?}
*/
function (v) {
if (!v) {
v = [];
}
this._value = v;
},
enumerable: true,
configurable: true
});
Object.defineProperty(DatePicker.prototype, "flatpickrOptions", {
get: /**
* @return {?}
*/
function () {
/** @type {?} */
var plugins = tslib_1.__spread(this.plugins, [sukaFlatpickrMonthSelectPlugin]);
if (this.range) {
plugins.push(rangePlugin({ input: "#" + this.id + "-rangeInput", position: 'left' }));
}
return Object.assign({}, this._flatpickrOptions, this.flatpickrBaseOptions, {
mode: this.range ? 'range' : 'single',
plugins: plugins,
dateFormat: this.dateFormat
});
},
set: /**
* @param {?} options
* @return {?}
*/
function (options) {
this._flatpickrOptions = Object.assign({}, this._flatpickrOptions, options);
},
enumerable: true,
configurable: true
});
Object.defineProperty(DatePicker.prototype, "flatpickrOptionsRange", {
get: /**
* @return {?}
*/
function () {
console.warn('flatpickrOptionsRange is deprecated, use flatpickrOptions and set the range to true instead');
return this.flatpickrOptions;
},
set: /**
* @param {?} options
* @return {?}
*/
function (options) {
console.warn('flatpickrOptionsRange is deprecated, use flatpickrOptions and set the range to true instead');
this.range = true;
this.flatpickrOptions = options;
},
enumerable: true,
configurable: true
});
/**
* @param {?} changes
* @return {?}
*/
DatePicker.prototype.ngOnChanges = /**
* @param {?} changes
* @return {?}
*/
function (changes) {
if (this.isFlatpickrLoaded()) {
/** @type {?} */
var dates = this.flatpickrInstance.selectedDates;
if (changes.value && this.didDateValueChange(changes.value.currentValue, changes.value.previousValue)) {
dates = changes.value.currentValue;
}
// only reset the flatpickr instance on Input changes
this.flatpickrInstance = flatpickr("#" + this.id, this.flatpickrOptions);
this.setDateValues(dates);
}
};
// because the actual view may be delayed in loading (think projection into a tab pane)
// and because we rely on a library that operates outside the Angular view of the world
// we need to keep trying to load the library, until the relevant DOM is actually live
// because the actual view may be delayed in loading (think projection into a tab pane)
// and because we rely on a library that operates outside the Angular view of the world
// we need to keep trying to load the library, until the relevant DOM is actually live
/**
* @return {?}
*/
DatePicker.prototype.ngAfterViewChecked =
// because the actual view may be delayed in loading (think projection into a tab pane)
// and because we rely on a library that operates outside the Angular view of the world
// we need to keep trying to load the library, until the relevant DOM is actually live
/**
* @return {?}
*/
function () {
if (!this.isFlatpickrLoaded()) {
this.flatpickrInstance = flatpickr("#" + this.id, this.flatpickrOptions);
// if (and only if) the initialization succeeded, we can set the date values
if (this.isFlatpickrLoaded()) {
if (this.value.length > 0) {
this.setDateValues(this.value);
}
}
}
};
/**
* @return {?}
*/
DatePicker.prototype.onFocus = /**
* @return {?}
*/
function () {
this.onTouched();
};
/**
* Writes a value from the model to the component. Expects the value to be `null` or `(Date | string)[]`
* @param value value received from the model
*/
/**
* Writes a value from the model to the component. Expects the value to be `null` or `(Date | string)[]`
* @param {?} value value received from the model
* @return {?}
*/
DatePicker.prototype.writeValue = /**
* Writes a value from the model to the component. Expects the value to be `null` or `(Date | string)[]`
* @param {?} value value received from the model
* @return {?}
*/
function (value) {
this.value = value;
if (this.isFlatpickrLoaded() && this.flatpickrInstance.config) {
this.setDateValues(this.value);
}
};
/**
* @param {?} fn
* @return {?}
*/
DatePicker.prototype.registerOnChange = /**
* @param {?} fn
* @return {?}
*/
function (fn) {
this.propagateChange = fn;
};
/**
* @param {?} fn
* @return {?}
*/
DatePicker.prototype.registerOnTouched = /**
* @param {?} fn
* @return {?}
*/
function (fn) {
this.onTouched = fn;
};
/**
* Cleans up our flatpickr instance
*/
/**
* Cleans up our flatpickr instance
* @return {?}
*/
DatePicker.prototype.ngOnDestroy = /**
* Cleans up our flatpickr instance
* @return {?}
*/
function () {
if (!this.isFlatpickrLoaded()) {
return;
}
this.flatpickrInstance.destroy();
};
/**
* Handles the `valueChange` event from the primary/single input
*/
/**
* Handles the `valueChange` event from the primary/single input
* @param {?} event
* @return {?}
*/
DatePicker.prototype.onValueChange = /**
* Handles the `valueChange` event from the primary/single input
* @param {?} event
* @return {?}
*/
function (event) {
if (this.isFlatpickrLoaded()) {
/** @type {?} */
var date = this.flatpickrInstance.parseDate(event, this.dateFormat);
if (this.range) {
this.setDateValues([date, this.flatpickrInstance.selectedDates[1]]);
}
else {
this.setDateValues([date]);
}
this.doSelect(this.flatpickrInstance.selectedDates);
}
};
/**
* Handles the `valueChange` event from the range input
*/
/**
* Handles the `valueChange` event from the range input
* @param {?} event
* @return {?}
*/
DatePicker.prototype.onRangeValueChange = /**
* Handles the `valueChange` event from the range input
* @param {?} event
* @return {?}
*/
function (event) {
if (this.isFlatpickrLoaded()) {
/** @type {?} */
var date = this.flatpickrInstance.parseDate(event, this.dateFormat);
this.setDateValues([this.flatpickrInstance.selectedDates[0], date]);
this.doSelect(this.flatpickrInstance.selectedDates);
}
};
/**
* Carbon uses a number of specific classnames for parts of the flatpickr - this idempotent method applies them if needed.
*/
/**
* Carbon uses a number of specific classnames for parts of the flatpickr - this idempotent method applies them if needed.
* @protected
* @return {?}
*/
DatePicker.prototype.updateClassNames = /**
* Carbon uses a number of specific classnames for parts of the flatpickr - this idempotent method applies them if needed.
* @protected
* @return {?}
*/
function () {
var _this = this;
if (!this.elementRef) {
return;
}
// get all the possible flatpickrs in the document - we need to add classes to (potentially) all of them
/** @type {?} */
var calendarContainer = document.querySelectorAll('.flatpickr-calendar');
/** @type {?} */
var monthContainer = document.querySelectorAll('.flatpickr-month');
/** @type {?} */
var weekdaysContainer = document.querySelectorAll('.flatpickr-weekdays');
/** @type {?} */
var weekdayContainer = document.querySelectorAll('.flatpickr-weekday');
/** @type {?} */
var daysContainer = document.querySelectorAll('.flatpickr-days');
/** @type {?} */
var dayContainer = document.querySelectorAll('.flatpickr-day');
// add classes to lists of elements
/** @type {?} */
var addClassIfNotExists = (/**
* @param {?} classname
* @param {?} elementList
* @return {?}
*/
function (classname, elementList) {
Array.from(elementList).forEach((/**
* @param {?} element
* @return {?}
*/
function (element) {
if (!element.classList.contains(classname)) {
element.classList.add(classname);
}
}));
});
// add classes (but only if they don't exist, small perf win)
addClassIfNotExists('date-picker__calendar', calendarContainer);
addClassIfNotExists('date-picker__month', monthContainer);
addClassIfNotExists('date-picker__weekdays', weekdaysContainer);
addClassIfNotExists('date-picker__days', daysContainer);
// add weekday classes and format the text
Array.from(weekdayContainer).forEach((/**
* @param {?} element
* @return {?}
*/
function (element) {
element.innerHTML = element.innerHTML.replace(/\s+/g, '');
element.classList.add('date-picker__weekday');
}));
// add day classes and special case the "today" element based on `this.value`
Array.from(dayContainer).forEach((/**
* @param {?} element
* @return {?}
*/
function (element) {
element.classList.add('date-picker__day');
if (!_this.value) {
return;
}
if (element.classList.contains('today') && _this.value.length > 0) {
element.classList.add('no-border');
}
else if (element.classList.contains('today') && _this.value.length === 0) {
element.classList.remove('no-border');
}
}));
};
/**
* Applies the given date value array to both the flatpickr instance and the `input`(s)
* @param dates the date values to apply
*/
/**
* Applies the given date value array to both the flatpickr instance and the `input`(s)
* @protected
* @param {?} dates the date values to apply
* @return {?}
*/
DatePicker.prototype.setDateValues = /**
* Applies the given date value array to both the flatpickr instance and the `input`(s)
* @protected
* @param {?} dates the date values to apply
* @return {?}
*/
function (dates) {
if (this.isFlatpickrLoaded()) {
/** @type {?} */
var singleInput_1 = this.elementRef.nativeElement.querySelector("#" + this.id);
/** @type {?} */
var rangeInput_1 = this.elementRef.nativeElement.querySelector("#" + this.id + "-rangeInput");
// set the date on the instance
this.flatpickrInstance.setDate(dates);
// we can either set a date value or an empty string, so we start with an empty string
/** @type {?} */
var singleDate_1 = '';
// if date is a string, parse and format
if (typeof this.flatpickrInstance.selectedDates[0] === 'string') {
singleDate_1 = this.flatpickrInstance.parseDate(this.flatpickrInstance.selectedDates[0], this.dateFormat);
singleDate_1 = this.flatpickrInstance.formatDate(singleDate_1, this.dateFormat);
// if date is not a string we can assume it's a Date and we should format
}
else if (!!this.flatpickrInstance.selectedDates[0]) {
singleDate_1 = this.flatpickrInstance.formatDate(this.flatpickrInstance.selectedDates[0], this.dateFormat);
}
if (rangeInput_1) {
// we can either set a date value or an empty string, so we start with an empty string
/** @type {?} */
var rangeDate_1 = '';
// if date is a string, parse and format
if (typeof this.flatpickrInstance.selectedDates[1] === 'string') {
rangeDate_1 = this.flatpickrInstance.parseDate(this.flatpickrInstance.selectedDates[1].toString(), this.dateFormat);
rangeDate_1 = this.flatpickrInstance.formatDate(rangeDate_1, this.dateFormat);
// if date is not a string we can assume it's a Date and we should format
}
else if (!!this.flatpickrInstance.selectedDates[1]) {
rangeDate_1 = this.flatpickrInstance.formatDate(this.flatpickrInstance.selectedDates[1], this.dateFormat);
}
setTimeout((/**
* @return {?}
*/
function () {
// apply the values
rangeInput_1.value = rangeDate_1;
singleInput_1.value = singleDate_1;
}));
}
}
};
/**
* @protected
* @param {?} selectedValue
* @return {?}
*/
DatePicker.prototype.doSelect = /**
* @protected
* @param {?} selectedValue
* @return {?}
*/
function (selectedValue) {
this.valueChange.emit(selectedValue);
this.propagateChange(selectedValue);
};
/**
* @protected
* @param {?} currentValue
* @param {?} previousValue
* @return {?}
*/
DatePicker.prototype.didDateValueChange = /**
* @protected
* @param {?} currentValue
* @param {?} previousValue
* @return {?}
*/
function (currentValue, previousValue) {
return currentValue[0] !== previousValue[0] || currentValue[1] !== previousValue[1];
};
/**
* More advanced checking of the loaded state of flatpickr
*/
/**
* More advanced checking of the loaded state of flatpickr
* @protected
* @return {?}
*/
DatePicker.prototype.isFlatpickrLoaded = /**
* More advanced checking of the loaded state of flatpickr
* @protected
* @return {?}
*/
function () {
// cast the instance to a boolean, and some method that has to exist for the library to be loaded in this case `setDate`
return !!this.flatpickrInstance && !!this.flatpickrInstance.setDate;
};
DatePicker.datePickerCount = 0;
DatePicker.decorators = [
{ type: Component, args: [{
selector: 'suka-date-picker',
template: "\n <div class=\"form-item\">\n <div\n class=\"date-picker\"\n [ngClass]=\"{\n 'date-picker--range' : range,\n 'date-picker--single' : !range,\n 'skeleton' : skeleton\n }\">\n <div class=\"date-picker-container\">\n <suka-date-picker-input\n [label]=\"label\"\n [placeholder]=\"placeholder\"\n [pattern]=\"pattern\"\n [id]=\"id\"\n [type]=\"(range ? 'range' : 'single')\"\n [hasIcon]=\"(range ? false : true)\"\n [disabled]=\"disabled\"\n [invalid]=\"invalid\"\n [invalidText]=\"invalidText\"\n [skeleton]=\"skeleton\"\n (valueChange)=\"onValueChange($event)\">\n </suka-date-picker-input>\n </div>\n <div *ngIf=\"range\" class=\"date-picker-container\">\n <suka-date-picker-input\n [label]=\"rangeLabel\"\n [placeholder]=\"placeholder\"\n [pattern]=\"pattern\"\n [id]=\"id + '-rangeInput'\"\n [type]=\"(range ? 'range' : 'single')\"\n [hasIcon]=\"(range ? true : null)\"\n [disabled]=\"disabled\"\n [invalid]=\"invalid\"\n [invalidText]=\"invalidText\"\n [skeleton]=\"skeleton\"\n (valueChange)=\"onRangeValueChange($event)\">\n </suka-date-picker-input>\n </div>\n </div>\n </div>\n ",
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: DatePicker,
multi: true
}
],
encapsulation: ViewEncapsulation.None
}] }
];
/** @nocollapse */
DatePicker.ctorParameters = function () { return [
{ type: ElementRef }
]; };
DatePicker.propDecorators = {
range: [{ type: Input }],
dateFormat: [{ type: Input }],
label: [{ type: Input }],
rangeLabel: [{ type: Input }],
placeholder: [{ type: Input }],
pattern: [{ type: Input }],
id: [{ type: Input }],
value: [{ type: Input }],
disabled: [{ type: Input }],
invalid: [{ type: Input }],
invalidText: [{ type: Input }],
skeleton: [{ type: Input }],
plugins: [{ type: Input }],
flatpickrOptions: [{ type: Input }],
valueChange: [{ type: Output }],
onFocus: [{ type: HostListener, args: ['focusin',] }]
};
return DatePicker;
}());
export { DatePicker };
if (false) {
/**
* @type {?}
* @private
*/
DatePicker.datePickerCount;
/**
* Select calendar range mode
* @type {?}
*/
DatePicker.prototype.range;
/**
* Format of date
*
* For reference: https://flatpickr.js.org/formatting/
* @type {?}
*/
DatePicker.prototype.dateFormat;
/** @type {?} */
DatePicker.prototype.label;
/** @type {?} */
DatePicker.prototype.rangeLabel;
/** @type {?} */
DatePicker.prototype.placeholder;
/** @type {?} */
DatePicker.prototype.pattern;
/** @type {?} */
DatePicker.prototype.id;
/** @type {?} */
DatePicker.prototype.disabled;
/** @type {?} */
DatePicker.prototype.invalid;
/** @type {?} */
DatePicker.prototype.invalidText;
/** @type {?} */
DatePicker.prototype.skeleton;
/** @type {?} */
DatePicker.prototype.plugins;
/** @type {?} */
DatePicker.prototype.valueChange;
/**
* @type {?}
* @protected
*/
DatePicker.prototype._value;
/**
* @type {?}
* @protected
*/
DatePicker.prototype._flatpickrOptions;
/**
* @type {?}
* @protected
*/
DatePicker.prototype.flatpickrBaseOptions;
/**
* @type {?}
* @protected
*/
DatePicker.prototype.flatpickrInstance;
/** @type {?} */
DatePicker.prototype.onTouched;
/** @type {?} */
DatePicker.prototype.propagateChange;
/**
* @type {?}
* @protected
*/
DatePicker.prototype.elementRef;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXBpY2tlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9Aa3VzaGtpL25nLXN1a2EvIiwic291cmNlcyI6WyJsaWIvZGF0ZXBpY2tlci9kYXRlcGlja2VyLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBQ1osaUJBQWlCLEVBQ2pCLFVBQVUsRUFFVixZQUFZLEVBS2IsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxXQUFXLE1BQU0sb0NBQW9DLENBQUM7QUFDN0QsT0FBTyxTQUFTLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ25ELE9BQU8sRUFBRSw4QkFBOEIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBR2xGO0lBK0lFLG9CQUFzQixVQUFzQjtRQUE1QyxpQkFBaUQ7UUFBM0IsZUFBVSxHQUFWLFVBQVUsQ0FBWTs7OztRQXBGbkMsVUFBSyxHQUFHLEtBQUssQ0FBQzs7Ozs7O1FBT2QsZUFBVSxHQUFHLE9BQU8sQ0FBQztRQU1yQixnQkFBVyxHQUFHLFlBQVksQ0FBQztRQUUzQixZQUFPLEdBQUcsNEJBQTRCLENBQUM7UUFFdkMsT0FBRSxHQUFHLGdCQUFjLFVBQVUsQ0FBQyxlQUFlLEVBQUksQ0FBQztRQWFsRCxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBRWpCLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFJaEIsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUVqQixZQUFPLEdBQUcsRUFBRSxDQUFDO1FBNEJaLGdCQUFXLEdBQXNCLElBQUksWUFBWSxFQUFFLENBQUM7UUFFcEQsV0FBTSxHQUFHLEVBQUUsQ0FBQztRQUVaLHNCQUFpQixHQUFHO1lBQzVCLFVBQVUsRUFBRSxJQUFJO1NBQ2pCLENBQUM7UUFFUSx5QkFBb0IsR0FBRztZQUMvQixJQUFJLEVBQUUsUUFB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QUN0RSxDQUFDO0lBaFNjLDBCQUFlLEdBQUcsQ0FBQyxDQUFDOztnQkF0RHBDLFNBQVMsU0FBQztvQkFDVCxRQUFRLEVBQUUsa0JBQWtCO29CQUM1QixRQUFRLEVBQUUsaTdDQXlDVDtvQkFDRCxTQUFTLEVBQUU7d0JBQ1Q7NEJBQ0UsT0FBTyxFQUFFLGlCQUFpQjs0QkFDMUIsV0FBVyxFQUFFLFVBQVU7NEJBQ3ZCLEtBQUssRUFBRSxJQUFJO3lCQUNaO3FCQUNGO29CQUNELGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJO2lCQUN0Qzs7OztnQkFsRUMsVUFBVTs7O3dCQXlFVCxLQUFLOzZCQU9MLEtBQUs7d0JBRUwsS0FBSzs2QkFFTCxLQUFLOzhCQUVMLEtBQUs7MEJBRUwsS0FBSztxQkFFTCxLQUFLO3dCQUVMLEtBQUs7MkJBV0wsS0FBSzswQkFFTCxLQUFLOzhCQUVMLEtBQUs7MkJBRUwsS0FBSzswQkFFTCxLQUFLO21DQUVMLEtBQUs7OEJBMEJMLE1BQU07MEJBZ0ROLFlBQVksU0FBQyxTQUFTOztJQTBLekIsaUJBQUM7Q0FBQSxBQXZWRCxJQXVWQztTQWxTWSxVQUFVOzs7Ozs7SUFDckIsMkJBQW1DOzs7OztJQUtuQywyQkFBdUI7Ozs7Ozs7SUFPdkIsZ0NBQThCOztJQUU5QiwyQkFBMEM7O0lBRTFDLGdDQUE0Qjs7SUFFNUIsaUNBQW9DOztJQUVwQyw2QkFBZ0Q7O0lBRWhELHdCQUEyRDs7SUFhM0QsOEJBQTBCOztJQUUxQiw2QkFBeUI7O0lBRXpCLGlDQUFnRDs7SUFFaEQsOEJBQTBCOztJQUUxQiw2QkFBc0I7O0lBNEJ0QixpQ0FBOEQ7Ozs7O0lBRTlELDRCQUFzQjs7Ozs7SUFFdEIsdUNBRUU7Ozs7O0lBRUYsMENBTUU7Ozs7O0lBRUYsdUNBQW1DOztJQXdEbkMsK0JBQWlDOztJQUVqQyxxQ0FBa0M7Ozs7O0lBeER0QixnQ0FBZ0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIElucHV0LFxuICBPdXRwdXQsXG4gIEV2ZW50RW1pdHRlcixcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIEVsZW1lbnRSZWYsXG4gIE9uRGVzdHJveSxcbiAgSG9zdExpc3RlbmVyLFxuICBUZW1wbGF0ZVJlZixcbiAgT25DaGFuZ2VzLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBBZnRlclZpZXdDaGVja2VkXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHJhbmdlUGx1Z2luIGZyb20gJ2ZsYXRwaWNrci9kaXN0L3BsdWdpbnMvcmFuZ2VQbHVnaW4nO1xuaW1wb3J0IGZsYXRwaWNrciBmcm9tICdmbGF0cGlja3InO1xuaW1wb3J0IHsgTkdfVkFMVUVfQUNDRVNTT1IgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBzdWthRmxhdHBpY2tyTW9udGhTZWxlY3RQbHVnaW4gfSBmcm9tICcuL3N1a2FGbGF0cGlja3JNb250aFNlbGVjdFBsdWdpbic7XG5cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc3VrYS1kYXRlLXBpY2tlcicsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiBjbGFzcz1cImZvcm0taXRlbVwiPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cImRhdGUtcGlja2VyXCJcbiAgICAgICAgW25nQ2xhc3NdPVwie1xuICAgICAgICAgICdkYXRlLXBpY2tlci0tcmFuZ2UnIDogcmFuZ2UsXG4gICAgICAgICAgJ2RhdGUtcGlja2VyLS1zaW5nbGUnIDogIXJhbmdlLFxuICAgICAgICAgICdza2VsZXRvbicgOiBza2VsZXRvblxuICAgICAgICB9XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJkYXRlLXBpY2tlci1jb250YWluZXJcIj5cbiAgICAgICAgICA8c3VrYS1kYXRlLXBpY2tlci1pbnB1dFxuICAgICAgICAgICAgW2xhYmVsXT1cImxhYmVsXCJcbiAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlclwiXG4gICAgICAgICAgICBbcGF0dGVybl09XCJwYXR0ZXJuXCJcbiAgICAgICAgICAgIFtpZF09XCJpZFwiXG4gICAgICAgICAgICBbdHlwZV09XCIocmFuZ2UgPyAncmFuZ2UnIDogJ3NpbmdsZScpXCJcbiAgICAgICAgICAgIFtoYXNJY29uXT1cIihyYW5nZSA/IGZhbHNlIDogdHJ1ZSlcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgICAgIFtpbnZhbGlkXT1cImludmFsaWRcIlxuICAgICAgICAgICAgW2ludmFsaWRUZXh0XT1cImludmFsaWRUZXh0XCJcbiAgICAgICAgICAgIFtza2VsZXRvbl09XCJza2VsZXRvblwiXG4gICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwib25WYWx1ZUNoYW5nZSgkZXZlbnQpXCI+XG4gICAgICAgICAgPC9zdWthLWRhdGUtcGlja2VyLWlucHV0PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiAqbmdJZj1cInJhbmdlXCIgY2xhc3M9XCJkYXRlLXBpY2tlci1jb250YWluZXJcIj5cbiAgICAgICAgICA8c3VrYS1kYXRlLXBpY2tlci1pbnB1dFxuICAgICAgICAgICAgW2xhYmVsXT1cInJhbmdlTGFiZWxcIlxuICAgICAgICAgICAgW3BsYWNlaG9sZGVyXT1cInBsYWNlaG9sZGVyXCJcbiAgICAgICAgICAgIFtwYXR0ZXJuXT1cInBhdHRlcm5cIlxuICAgICAgICAgICAgW2lkXT1cImlkICsgJy1yYW5nZUlucHV0J1wiXG4gICAgICAgICAgICBbdHlwZV09XCIocmFuZ2UgPyAncmFuZ2UnIDogJ3NpbmdsZScpXCJcbiAgICAgICAgICAgIFtoYXNJY29uXT1cIihyYW5nZSA/IHRydWUgOiBudWxsKVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgICAgICAgW2ludmFsaWRdPVwiaW52YWxpZFwiXG4gICAgICAgICAgICBbaW52YWxpZFRleHRdPVwiaW52YWxpZFRleHRcIlxuICAgICAgICAgICAgW3NrZWxldG9uXT1cInNrZWxldG9uXCJcbiAgICAgICAgICAgICh2YWx1ZUNoYW5nZSk9XCJvblJhbmdlVmFsdWVDaGFuZ2UoJGV2ZW50KVwiPlxuICAgICAgICAgIDwvc3VrYS1kYXRlLXBpY2tlci1pbnB1dD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgcHJvdmlkZXJzOiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogRGF0ZVBpY2tlcixcbiAgICAgIG11bHRpOiB0cnVlXG4gICAgfVxuICBdLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lXG59KVxuZXhwb3J0IGNsYXNzIERhdGVQaWNrZXIgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3Q2hlY2tlZCB7XG4gIHByaXZhdGUgc3RhdGljIGRhdGVQaWNrZXJDb3VudCA9IDA7XG5cbiAgLyoqXG4gICAqIFNlbGVjdCBjYWxlbmRhciByYW5nZSBtb2RlXG4gICAqL1xuICBASW5wdXQoKSByYW5nZSA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBGb3JtYXQgb2YgZGF0ZVxuICAgKlxuICAgKiBGb3IgcmVmZXJlbmNlOiBodHRwczovL2ZsYXRwaWNrci5qcy5vcmcvZm9ybWF0dGluZy9cbiAgICovXG4gIEBJbnB1dCgpIGRhdGVGb3JtYXQgPSAnZC9tL1knO1xuXG4gIEBJbnB1dCgpIGxhYmVsOiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gIEBJbnB1dCgpIHJhbmdlTGFiZWw6IHN0cmluZztcblxuICBASW5wdXQoKSBwbGFjZWhvbGRlciA9ICdkZC9tbS95eXl5JztcblxuICBASW5wdXQoKSBwYXR0ZXJuID0gJ15cXFxcZHsxLDJ9L1xcXFxkezEsMn0vXFxcXGR7NH0kJztcblxuICBASW5wdXQoKSBpZCA9IGBkYXRlcGlja2VyLSR7RGF0ZVBpY2tlci5kYXRlUGlja2VyQ291bnQrK31gO1xuXG4gIEBJbnB1dCgpIHNldCB2YWx1ZSh2OiAoRGF0ZSB8IHN0cmluZylbXSkge1xuICAgIGlmICghdikge1xuICAgICAgdiA9IFtdO1xuICAgIH1cbiAgICB0aGlzLl92YWx1ZSA9IHY7XG4gIH1cblxuICBnZXQgdmFsdWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3ZhbHVlO1xuICB9XG5cbiAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcblxuICBASW5wdXQoKSBpbnZhbGlkID0gZmFsc2U7XG5cbiAgQElucHV0KCkgaW52YWxpZFRleHQ6IHN0cmluZyB8IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgQElucHV0KCkgc2tlbGV0b24gPSBmYWxzZTtcblxuICBASW5wdXQoKSBwbHVnaW5zID0gW107XG5cbiAgQElucHV0KClcbiAgc2V0IGZsYXRwaWNrck9wdGlvbnMob3B0aW9ucykge1xuICAgIHRoaXMuX2ZsYXRwaWNrck9wdGlvbnMgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLl9mbGF0cGlja3JPcHRpb25zLCBvcHRpb25zKTtcbiAgfVxuICBnZXQgZmxhdHBpY2tyT3B0aW9ucygpIHtcbiAgICBjb25zdCBwbHVnaW5zID0gWy4uLnRoaXMucGx1Z2lucywgc3VrYUZsYXRwaWNrck1vbnRoU2VsZWN0UGx1Z2luXTtcbiAgICBpZiAodGhpcy5yYW5nZSkge1xuICAgICAgcGx1Z2lucy5wdXNoKHJhbmdlUGx1Z2luKHsgaW5wdXQ6IGAjJHt0aGlzLmlkfS1yYW5nZUlucHV0YCwgcG9zaXRpb246ICdsZWZ0JyB9KSk7XG4gICAgfVxuICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCB0aGlzLl9mbGF0cGlja3JPcHRpb25zLCB0aGlzLmZsYXRwaWNrckJhc2VPcHRpb25zLCB7XG4gICAgICBtb2RlOiB0aGlzLnJhbmdlID8gJ3JhbmdlJyA6ICdzaW5nbGUnLFxuICAgICAgcGx1Z2lucyxcbiAgICAgIGRhdGVGb3JtYXQ6IHRoaXMuZGF0ZUZvcm1hdFxuICAgIH0pO1xuICB9XG5cbiAgc2V0IGZsYXRwaWNrck9wdGlvbnNSYW5nZShvcHRpb25zKSB7XG4gICAgY29uc29sZS53YXJuKCdmbGF0cGlja3JPcHRpb25zUmFuZ2UgaXMgZGVwcmVjYXRlZCwgdXNlIGZsYXRwaWNrck9wdGlvbnMgYW5kIHNldCB0aGUgcmFuZ2UgdG8gdHJ1ZSBpbnN0ZWFkJyk7XG4gICAgdGhpcy5yYW5nZSA9IHRydWU7XG4gICAgdGhpcy5mbGF0cGlja3JPcHRpb25zID0gb3B0aW9ucztcbiAgfVxuICBnZXQgZmxhdHBpY2tyT3B0aW9uc1JhbmdlKCkge1xuICAgIGNvbnNvbGUud2FybignZmxhdHBpY2tyT3B0aW9uc1JhbmdlIGlzIGRlcHJlY2F0ZWQsIHVzZSBmbGF0cGlja3JPcHRpb25zIGFuZCBzZXQgdGhlIHJhbmdlIHRvIHRydWUgaW5zdGVhZCcpO1xuICAgIHJldHVybiB0aGlzLmZsYXRwaWNrck9wdGlvbnM7XG4gIH1cblxuICBAT3V0cHV0KCkgdmFsdWVDaGFuZ2U6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIHByb3RlY3RlZCBfdmFsdWUgPSBbXTtcblxuICBwcm90ZWN0ZWQgX2ZsYXRwaWNrck9wdGlvbnMgPSB7XG4gICAgYWxsb3dJbnB1dDogdHJ1ZVxuICB9O1xuXG4gIHByb3RlY3RlZCBmbGF0cGlja3JCYXNlT3B0aW9ucyA9IHtcbiAgICBtb2RlOiAnc2luZ2xlJyxcbiAgICBkYXRlRm9ybWF0OiAnZC9tL1knLFxuICAgIHBsdWdpbnM6IHRoaXMucGx1Z2lucyxcbiAgICBvbk9wZW46ICgpID0+IHsgdGhpcy51cGRhdGVDbGFzc05hbWVzKCk7IH0sXG4gICAgdmFsdWU6IHRoaXMudmFsdWVcbiAgfTtcblxuICBwcm90ZWN0ZWQgZmxhdHBpY2tySW5zdGFuY2UgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKHByb3RlY3RlZCBlbGVtZW50UmVmOiBFbGVtZW50UmVmKSB7IH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKSB7XG4gICAgaWYgKHRoaXMuaXNGbGF0cGlja3JMb2FkZWQoKSkge1xuICAgICAgbGV0IGRhdGVzID0gdGhpcy5mbGF0cGlja3JJbnN0YW5jZS5zZWxlY3RlZERhdGVzO1xuICAgICAgaWYgKGNoYW5nZXMudmFsdWUgJiYgdGhpcy5kaWREYXRlVmFsdWVDaGFuZ2UoY2hhbmdlcy52YWx1ZS5jdXJyZW50VmFsdWUsIGNoYW5nZXMudmFsdWUucHJldmlvdXNWYWx1ZSkpIHtcbiAgICAgICAgZGF0ZXMgPSBjaGFuZ2VzLnZhbHVlLmN1cnJlbnRWYWx1ZTtcbiAgICAgIH1cbiAgICAgIC8vIG9ubHkgcmVzZXQgdGhlIGZsYXRwaWNrciBpbnN0YW5jZSBvbiBJbnB1dCBjaGFuZ2VzXG4gICAgICB0aGlzLmZsYXRwaWNrckluc3RhbmNlID0gZmxhdHBpY2tyKGAjJHt0aGlzLmlkfWAsIHRoaXMuZmxhdHBpY2tyT3B0aW9ucyk7XG4gICAgICB0aGlzLnNldERhdGVWYWx1ZXMoZGF0ZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGJlY2F1c2UgdGhlIGFjdHVhbCB2aWV3IG1heSBiZSBkZWxheWVkIGluIGxvYWRpbmcgKHRoaW5rIHByb2plY3Rpb24gaW50byBhIHRhYiBwYW5lKVxuICAvLyBhbmQgYmVjYXVzZSB3ZSByZWx5IG9uIGEgbGlicmFyeSB0aGF0IG9wZXJhdGVzIG91dHNpZGUgdGhlIEFuZ3VsYXIgdmlldyBvZiB0aGUgd29ybGRcbiAgLy8gd2UgbmVlZCB0byBrZWVwIHRyeWluZyB0byBsb2FkIHRoZSBsaWJyYXJ5LCB1bnRpbCB0aGUgcmVsZXZhbnQgRE9NIGlzIGFjdHVhbGx5IGxpdmVcbiAgbmdBZnRlclZpZXdDaGVja2VkKCkge1xuICAgIGlmICghdGhpcy5pc0ZsYXRwaWNrckxvYWRlZCgpKSB7XG4gICAgICB0aGlzLmZsYXRwaWNrckluc3RhbmNlID0gZmxhdHBpY2tyKGAjJHt0aGlzLmlkfWAsIHRoaXMuZmxhdHBpY2tyT3B0aW9ucyk7XG5cbiAgICAgIC8vIGlmIChhbmQgb25seSBpZikgdGhlIGluaXRpYWxpemF0aW9uIHN1Y2NlZWRlZCwgd2UgY2FuIHNldCB0aGUgZGF0ZSB2YWx1ZXNcbiAgICAgIGlmICh0aGlzLmlzRmxhdHBpY2tyTG9hZGVkKCkpIHtcbiAgICAgICAgaWYgKHRoaXMudmFsdWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgIHRoaXMuc2V0RGF0ZVZhbHVlcyh0aGlzLnZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2ZvY3VzaW4nKVxuICBvbkZvY3VzKCkge1xuICAgIHRoaXMub25Ub3VjaGVkKCk7XG4gIH1cblxuICAvKipcbiAgICogV3JpdGVzIGEgdmFsdWUgZnJvbSB0aGUgbW9kZWwgdG8gdGhlIGNvbXBvbmVudC4gRXhwZWN0cyB0aGUgdmFsdWUgdG8gYmUgYG51bGxgIG9yIGAoRGF0ZSB8IHN0cmluZylbXWBcbiAgICogQHBhcmFtIHZhbHVlIHZhbHVlIHJlY2VpdmVkIGZyb20gdGhlIG1vZGVsXG4gICAqL1xuICB3cml0ZVZhbHVlKHZhbHVlOiAoRGF0ZSB8IHN0cmluZylbXSkge1xuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbiAgICBpZiAodGhpcy5pc0ZsYXRwaWNrckxvYWRlZCgpICYmIHRoaXMuZmxhdHBpY2tySW5zdGFuY2UuY29uZmlnKSB7XG4gICAgICB0aGlzLnNldERhdGVWYWx1ZXModGhpcy52YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KSB7XG4gICAgdGhpcy5wcm9wYWdhdGVDaGFuZ2UgPSBmbjtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpIHtcbiAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xuICB9XG5cbiAgb25Ub3VjaGVkOiAoKSA9PiBhbnkgPSAoKSA9PiB7IH07XG5cbiAgcHJvcGFnYXRlQ2hhbmdlID0gKF86IGFueSkgPT4geyB9O1xuXG4gIC8qKlxuICAgKiBDbGVhbnMgdXAgb3VyIGZsYXRwaWNrciBpbnN0YW5jZVxuICAgKi9cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgaWYgKCF0aGlzLmlzRmxhdHBpY2tyTG9hZGVkKCkpIHsgcmV0dXJuOyB9XG4gICAgdGhpcy5mbGF0cGlja3JJbnN0YW5jZS5kZXN0cm95KCk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyB0aGUgYHZhbHVlQ2hhbmdlYCBldmVudCBmcm9tIHRoZSBwcmltYXJ5L3NpbmdsZSBpbnB1dFxuICAgKi9cbiAgb25WYWx1ZUNoYW5nZShldmVudDogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuaXNGbGF0cGlja3JMb2FkZWQoKSkge1xuICAgICAgY29uc3QgZGF0ZSA9IHRoaXMuZmxhdHBpY2tySW5zdGFuY2UucGFyc2VEYXRlKGV2ZW50LCB0aGlzLmRhdGVGb3JtYXQpO1xuICAgICAgaWYgKHRoaXMucmFuZ2UpIHtcbiAgICAgICAgdGhpcy5zZXREYXRlVmFsdWVzKFtkYXRlLCB0aGlzLmZsYXRwaWNrckluc3RhbmNlLnNlbGVjdGVkRGF0ZXNbMV1dKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc2V0RGF0ZVZhbHVlcyhbZGF0ZV0pO1xuICAgICAgfVxuICAgICAgdGhpcy5kb1NlbGVjdCh0aGlzLmZsYXRwaWNrckluc3RhbmNlLnNlbGVjdGVkRGF0ZXMpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGVzIHRoZSBgdmFsdWVDaGFuZ2VgIGV2ZW50IGZyb20gdGhlIHJhbmdlIGlucHV0XG4gICAqL1xuICBvblJhbmdlVmFsdWVDaGFuZ2UoZXZlbnQ6IHN0cmluZykge1xuICAgIGlmICh0aGlzLmlzRmxhdHBpY2tyTG9hZGVkKCkpIHtcbiAgICAgIGNvbnN0IGRhdGUgPSB0aGlzLmZsYXRwaWNrckluc3RhbmNlLnBhcnNlRGF0ZShldmVudCwgdGhpcy5kYXRlRm9ybWF0KTtcbiAgICAgIHRoaXMuc2V0RGF0ZVZhbHVlcyhbdGhpcy5mbGF0cGlja3JJbnN0YW5jZS5zZWxlY3RlZERhdGVzWzBdLCBkYXRlXSk7XG4gICAgICB0aGlzLmRvU2VsZWN0KHRoaXMuZmxhdHBpY2tySW5zdGFuY2Uuc2VsZWN0ZWREYXRlcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENhcmJvbiB1c2VzIGEgbnVtYmVyIG9mIHNwZWNpZmljIGNsYXNzbmFtZXMgZm9yIHBhcnRzIG9mIHRoZSBmbGF0cGlja3IgLSB0aGlzIGlkZW1wb3RlbnQgbWV0aG9kIGFwcGxpZXMgdGhlbSBpZiBuZWVkZWQuXG4gICAqL1xuICBwcm90ZWN0ZWQgdXBkYXRlQ2xhc3NOYW1lcygpIHtcbiAgICBpZiAoIXRoaXMuZWxlbWVudFJlZikgeyByZXR1cm47IH1cblxuICAgIC8vIGdldCBhbGwgdGhlIHBvc3NpYmxlIGZsYXRwaWNrcnMgaW4gdGhlIGRvY3VtZW50IC0gd2UgbmVlZCB0byBhZGQgY2xhc3NlcyB0byAocG90ZW50aWFsbHkpIGFsbCBvZiB0aGVtXG4gICAgY29uc3QgY2FsZW5kYXJDb250YWluZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZmxhdHBpY2tyLWNhbGVuZGFyJyk7XG4gICAgY29uc3QgbW9udGhDb250YWluZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZmxhdHBpY2tyLW1vbnRoJyk7XG4gICAgY29uc3Qgd2Vla2RheXNDb250YWluZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZmxhdHBpY2tyLXdlZWtkYXlzJyk7XG4gICAgY29uc3Qgd2Vla2RheUNvbnRhaW5lciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5mbGF0cGlja3Itd2Vla2RheScpO1xuICAgIGNvbnN0IGRheXNDb250YWluZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZmxhdHBpY2tyLWRheXMnKTtcbiAgICBjb25zdCBkYXlDb250YWluZXIgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKCcuZmxhdHBpY2tyLWRheScpO1xuXG4gICAgLy8gYWRkIGNsYXNzZXMgdG8gbGlzdHMgb2YgZWxlbWVudHNcbiAgICBjb25zdCBhZGRDbGFzc0lmTm90RXhpc3RzID0gKGNsYXNzbmFtZTogc3RyaW5nLCBlbGVtZW50TGlzdDogTm9kZUxpc3RPZjxFbGVtZW50PikgPT4ge1xuICAgICAgQXJyYXkuZnJvbShlbGVtZW50TGlzdCkuZm9yRWFjaChlbGVtZW50ID0+IHtcbiAgICAgICAgaWYgKCFlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhjbGFzc25hbWUpKSB7XG4gICAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QuYWRkKGNsYXNzbmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH07XG5cbiAgICAvLyBhZGQgY2xhc3NlcyAoYnV0IG9ubHkgaWYgdGhleSBkb24ndCBleGlzdCwgc21hbGwgcGVyZiB3aW4pXG4gICAgYWRkQ2xhc3NJZk5vdEV4aXN0cygnZGF0ZS1waWNrZXJfX2NhbGVuZGFyJywgY2FsZW5kYXJDb250YWluZXIpO1xuICAgIGFkZENsYXNzSWZOb3RFeGlzdHMoJ2RhdGUtcGlja2VyX19tb250aCcsIG1vbnRoQ29udGFpbmVyKTtcbiAgICBhZGRDbGFzc0lmTm90RXhpc3RzKCdkYXRlLXBpY2tlcl9fd2Vla2RheXMnLCB3ZWVrZGF5c0NvbnRhaW5lcik7XG4gICAgYWRkQ2xhc3NJZk5vdEV4aXN0cygnZGF0ZS1waWNrZXJfX2RheXMnLCBkYXlzQ29udGFpbmVyKTtcblxuICAgIC8vIGFkZCB3ZWVrZGF5IGNsYXNzZXMgYW5kIGZvcm1hdCB0aGUgdGV4dFxuICAgIEFycmF5LmZyb20od2Vla2RheUNvbnRhaW5lcikuZm9yRWFjaChlbGVtZW50ID0+IHtcbiAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gZWxlbWVudC5pbm5lckhUTUwucmVwbGFjZSgvXFxzKy9nLCAnJyk7XG4gICAgICBlbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2RhdGUtcGlja2VyX193ZWVrZGF5Jyk7XG4gICAgfSk7XG5cbiAgICAvLyBhZGQgZGF5IGNsYXNzZXMgYW5kIHNwZWNpYWwgY2FzZSB0aGUgXCJ0b2RheVwiIGVsZW1lbnQgYmFzZWQgb24gYHRoaXMudmFsdWVgXG4gICAgQXJyYXkuZnJvbShkYXlDb250YWluZXIpLmZvckVhY2goZWxlbWVudCA9PiB7XG4gICAgICBlbGVtZW50LmNsYXNzTGlzdC5hZGQoJ2RhdGUtcGlja2VyX19kYXknKTtcbiAgICAgIGlmICghdGhpcy52YWx1ZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoJ3RvZGF5JykgJiYgdGhpcy52YWx1ZS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZCgnbm8tYm9yZGVyJyk7XG4gICAgICB9IGVsc2UgaWYgKGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKCd0b2RheScpICYmIHRoaXMudmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZSgnbm8tYm9yZGVyJyk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQXBwbGllcyB0aGUgZ2l2ZW4gZGF0ZSB2YWx1ZSBhcnJheSB0byBib3RoIHRoZSBmbGF0cGlja3IgaW5zdGFuY2UgYW5kIHRoZSBgaW5wdXRgKHMpXG4gICAqIEBwYXJhbSBkYXRlcyB0aGUgZGF0ZSB2YWx1ZXMgdG8gYXBwbHlcbiAgICovXG4gIHByb3RlY3RlZCBzZXREYXRlVmFsdWVzKGRhdGVzOiAoRGF0ZSB8IHN0cmluZylbXSkge1xuICAgIGlmICh0aGlzLmlzRmxhdHBpY2tyTG9hZGVkKCkpIHtcbiAgICAgIGNvbnN0IHNpbmdsZUlucHV0ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihgIyR7dGhpcy5pZH1gKTtcbiAgICAgIGNvbnN0IHJhbmdlSW5wdXQgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKGAjJHt0aGlzLmlkfS1yYW5nZUlucHV0YCk7XG5cbiAgICAgIC8vIHNldCB0aGUgZGF0ZSBvbiB0aGUgaW5zdGFuY2VcbiAgICAgIHRoaXMuZmxhdHBpY2tySW5zdGFuY2Uuc2V0RGF0ZShkYXRlcyk7XG5cbiAgICAgIC8vIHdlIGNhbiBlaXRoZXIgc2V0IGEgZGF0ZSB2YWx1ZSBvciBhbiBlbXB0eSBzdHJpbmcsIHNvIHdlIHN0YXJ0IHdpdGggYW4gZW1wdHkgc3RyaW5nXG4gICAgICBsZXQgc2luZ2xlRGF0ZSA9ICcnO1xuICAgICAgLy8gaWYgZGF0ZSBpcyBhIHN0cmluZywgcGFyc2UgYW5kIGZvcm1hdFxuICAgICAgaWYgKHR5cGVvZiB0aGlzLmZsYXRwaWNrckluc3RhbmNlLnNlbGVjdGVkRGF0ZXNbMF0gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHNpbmdsZURhdGUgPSB0aGlzLmZsYXRwaWNrckluc3RhbmNlLnBhcnNlRGF0ZSh0aGlzLmZsYXRwaWNrckluc3RhbmNlLnNlbGVjdGVkRGF0ZXNbMF0sIHRoaXMuZGF0ZUZvcm1hdCk7XG4gICAgICAgIHNpbmdsZURhdGUgPSB0aGlzLmZsYXRwaWNrckluc3RhbmNlLmZvcm1hdERhdGUoc2luZ2xlRGF0ZSwgdGhpcy5kYXRlRm9ybWF0KTtcbiAgICAgICAgLy8gaWYgZGF0ZSBpcyBub3QgYSBzdHJpbmcgd2UgY2FuIGFzc3VtZSBpdCdzIGEgRGF0ZSBhbmQgd2Ugc2hvdWxkIGZvcm1hdFxuICAgICAgfSBlbHNlIGlmICghIXRoaXMuZmxhdHBpY2tySW5zdGFuY2Uuc2VsZWN0ZWREYXRlc1swXSkge1xuICAgICAgICBzaW5nbGVEYXRlID0gdGhpcy5mbGF0cGlja3JJbnN0YW5jZS5mb3JtYXREYXRlKHRoaXMuZmxhdHBpY2tySW5zdGFuY2Uuc2VsZWN0ZWREYXRlc1swXSwgdGhpcy5kYXRlRm9ybWF0KTtcbiAgICAgIH1cblxuICAgICAgaWYgKHJhbmdlSW5wdXQpIHtcbiAgICAgICAgLy8gd2UgY2FuIGVpdGhlciBzZXQgYSBkYXRlIHZhbHVlIG9yIGFuIGVtcHR5IHN0cmluZywgc28gd2Ugc3RhcnQgd2l0aCBhbiBlbXB0eSBzdHJpbmdcbiAgICAgICAgbGV0IHJhbmdlRGF0ZSA9ICcnO1xuICAgICAgICAvLyBpZiBkYXRlIGlzIGEgc3RyaW5nLCBwYXJzZSBhbmQgZm9ybWF0XG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5mbGF0cGlja3JJbnN0YW5jZS5zZWxlY3RlZERhdGVzWzFdID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIHJhbmdlRGF0ZSA9IHRoaXMuZmxhdHBpY2tySW5zdGFuY2UucGFyc2VEYXRlKHRoaXMuZmxhdHBpY2tySW5zdGFuY2Uuc2VsZWN0ZWREYXRlc1sxXS50b1N0cmluZygpLCB0aGlzLmRhdGVGb3JtYXQpO1xuICAgICAgICAgIHJhbmdlRGF0ZSA9IHRoaXMuZmxhdHBpY2tySW5zdGFuY2UuZm9ybWF0RGF0ZShyYW5nZURhdGUsIHRoaXMuZGF0ZUZvcm1hdCk7XG4gICAgICAgICAgLy8gaWYgZGF0ZSBpcyBub3QgYSBzdHJpbmcgd2UgY2FuIGFzc3VtZSBpdCdzIGEgRGF0ZSBhbmQgd2Ugc2hvdWxkIGZvcm1hdFxuICAgICAgICB9IGVsc2UgaWYgKCEhdGhpcy5mbGF0cGlja3JJbnN0YW5jZS5zZWxlY3RlZERhdGVzWzFdKSB7XG4gICAgICAgICAgcmFuZ2VEYXRlID0gdGhpcy5mbGF0cGlja3JJbnN0YW5jZS5mb3JtYXREYXRlKHRoaXMuZmxhdHBpY2tySW5zdGFuY2Uuc2VsZWN0ZWREYXRlc1sxXSwgdGhpcy5kYXRlRm9ybWF0KTtcbiAgICAgICAgfVxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAvLyBhcHBseSB0aGUgdmFsdWVzXG4gICAgICAgICAgcmFuZ2VJbnB1dC52YWx1ZSA9IHJhbmdlRGF0ZTtcbiAgICAgICAgICBzaW5nbGVJbnB1dC52YWx1ZSA9IHNpbmdsZURhdGU7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBkb1NlbGVjdChzZWxlY3RlZFZhbHVlOiAoRGF0ZSB8IHN0cmluZylbXSkge1xuICAgIHRoaXMudmFsdWVDaGFuZ2UuZW1pdChzZWxlY3RlZFZhbHVlKTtcbiAgICB0aGlzLnByb3BhZ2F0ZUNoYW5nZShzZWxlY3RlZFZhbHVlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBkaWREYXRlVmFsdWVDaGFuZ2UoY3VycmVudFZhbHVlLCBwcmV2aW91c1ZhbHVlKSB7XG4gICAgcmV0dXJuIGN1cnJlbnRWYWx1ZVswXSAhPT0gcHJldmlvdXNWYWx1ZVswXSB8fCBjdXJyZW50VmFsdWVbMV0gIT09IHByZXZpb3VzVmFsdWVbMV07XG4gIH1cblxuICAvKipcbiAgICogTW9yZSBhZHZhbmNlZCBjaGVja2luZyBvZiB0aGUgbG9hZGVkIHN0YXRlIG9mIGZsYXRwaWNrclxuICAgKi9cbiAgcHJvdGVjdGVkIGlzRmxhdHBpY2tyTG9hZGVkKCkge1xuICAgIC8vIGNhc3QgdGhlIGluc3RhbmNlIHRvIGEgYm9vbGVhbiwgYW5kIHNvbWUgbWV0aG9kIHRoYXQgaGFzIHRvIGV4aXN0IGZvciB0aGUgbGlicmFyeSB0byBiZSBsb2FkZWQgaW4gdGhpcyBjYXNlIGBzZXREYXRlYFxuICAgIHJldHVybiAhIXRoaXMuZmxhdHBpY2tySW5zdGFuY2UgJiYgISF0aGlzLmZsYXRwaWNrckluc3RhbmNlLnNldERhdGU7XG4gIH1cbn1cbiJdfQ==