@hxui/angular
Version:
This README includes the steps that are necessary to import the HxUi-angular into a project or to contribute with development.
421 lines (420 loc) • 35.9 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
import { Component, Input, Output, ElementRef, HostListener, EventEmitter, forwardRef } from '@angular/core';
import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
var DatepickerFormComponent = /** @class */ (function () {
function DatepickerFormComponent(element) {
this.element = element;
this.disabled = false;
this.readonly = false;
this.required = false;
this.defaultToPresentDate = true;
this.allowPreviousDates = true;
this.allowFutureDates = true;
this.dateFormat = "dd/MM/y";
this.placeholder = "Date";
this.align = "bottom";
this.from = '';
this.to = '';
this.onDateChange = new EventEmitter();
this.visible = false;
this.dateValidators = new Array();
this.onChanged = new Array();
this.onTouched = new Array();
}
/**
* @return {?}
*/
DatepickerFormComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
var _this = this;
var /** @type {?} */ date = new Date();
this.presentDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
if (this.defaultToPresentDate) {
setTimeout(function () {
_this.setDate(_this.presentDate);
});
}
// Close to the minimum and maxium possible dates, but still normalisable
// http://ecma-international.org/ecma-262/5.1/#sec-15.9.1.1
var /** @type {?} */ from = this.parseDate(this.from) || new Date(-8630000000000000);
var /** @type {?} */ to = this.parseDate(this.to) || new Date(8630000000000000);
if (!!this.from || !!this.to) {
this.validateDateRange = this.createDateRangeValidator(from, to);
this.dateValidators.push(this.validateDateRange.bind(this));
}
if (!this.allowPreviousDates)
this.dateValidators.push(this.validateIsNotBeforeDate.bind(this));
if (!this.allowFutureDates)
this.dateValidators.push(this.validateIsNotAfterDate.bind(this));
};
/**
* @param {?} date
* @return {?}
*/
DatepickerFormComponent.prototype.setDate = /**
* @param {?} date
* @return {?}
*/
function (date) {
this.date = date;
this.onDateChange.emit(date);
this.propogateChange(date);
};
/**
* @return {?}
*/
DatepickerFormComponent.prototype.setVisible = /**
* @return {?}
*/
function () {
this.visible = true;
};
/**
* @return {?}
*/
DatepickerFormComponent.prototype.unsetVisible = /**
* @return {?}
*/
function () {
this.visible = false;
};
/**
* @param {?} targetElement
* @return {?}
*/
DatepickerFormComponent.prototype.onClickOutsideComponent = /**
* @param {?} targetElement
* @return {?}
*/
function (targetElement) {
if (!this.element.nativeElement.firstChild.contains(targetElement)) {
this.unsetVisible();
}
};
/**
* @param {?} inputDate
* @return {?}
*/
DatepickerFormComponent.prototype.onDateSelectEvent = /**
* @param {?} inputDate
* @return {?}
*/
function (inputDate) {
this.unsetVisible();
this.setDate(inputDate);
};
/**
* @param {?} inputDate
* @return {?}
*/
DatepickerFormComponent.prototype.onChange = /**
* @param {?} inputDate
* @return {?}
*/
function (inputDate) {
var /** @type {?} */ date = this.parseDate(inputDate);
if (inputDate == "") {
this.setDate(null);
}
else if (!!date) {
this.setDate(date);
}
else {
this.propogateChange(inputDate);
}
};
/**
* @return {?}
*/
DatepickerFormComponent.prototype.onFocus = /**
* @return {?}
*/
function () {
this.setVisible();
this.propogateTouched();
};
/**
* @param {?} inputDate
* @return {?}
*/
DatepickerFormComponent.prototype.onTab = /**
* @param {?} inputDate
* @return {?}
*/
function (inputDate) {
this.onChange(inputDate);
this.unsetVisible();
this.propogateTouched();
};
/**
* @param {?} inputDate
* @return {?}
*/
DatepickerFormComponent.prototype.parseDate = /**
* @param {?} inputDate
* @return {?}
*/
function (inputDate) {
// Since Date.Parse() only acceps m/d/y dates, we have to swap the day and month
var /** @type {?} */ dateArray = inputDate.split(/[.,\/ -]/);
if (dateArray.length == 3 && dateArray[2].length != 0) {
var /** @type {?} */ day = dateArray.shift();
dateArray.splice(1, 0, day);
var /** @type {?} */ parseInput = Date.parse(dateArray.join("/"));
if (!isNaN(parseInput)) {
return new Date(parseInput);
}
}
return null;
};
/**
* @param {?} date
* @return {?}
*/
DatepickerFormComponent.prototype.validateIsNotBeforeDate = /**
* @param {?} date
* @return {?}
*/
function (date) {
var /** @type {?} */ normalisedDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
return normalisedDate.getTime() < this.presentDate.getTime();
};
/**
* @param {?} date
* @return {?}
*/
DatepickerFormComponent.prototype.validateIsNotAfterDate = /**
* @param {?} date
* @return {?}
*/
function (date) {
var /** @type {?} */ normalisedDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
return normalisedDate.getTime() > this.presentDate.getTime();
};
/**
* @param {?} from
* @param {?} to
* @return {?}
*/
DatepickerFormComponent.prototype.createDateRangeValidator = /**
* @param {?} from
* @param {?} to
* @return {?}
*/
function (from, to) {
var /** @type {?} */ normalisedFromDate = new Date(from.getFullYear(), from.getMonth(), from.getDate());
var /** @type {?} */ normalisedToDate = new Date(to.getFullYear(), to.getMonth(), to.getDate());
return function (date) {
var /** @type {?} */ normalisedDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
return !(normalisedFromDate.getTime() <= normalisedDate.getTime() &&
normalisedDate.getTime() <= normalisedToDate.getTime());
};
};
/**
* @param {?} value
* @return {?}
*/
DatepickerFormComponent.prototype.writeValue = /**
* @param {?} value
* @return {?}
*/
function (value) {
this.setDate(value);
};
/**
* @param {?} fn
* @return {?}
*/
DatepickerFormComponent.prototype.registerOnChange = /**
* @param {?} fn
* @return {?}
*/
function (fn) {
this.onChanged.push(fn);
};
/**
* @param {?} fn
* @return {?}
*/
DatepickerFormComponent.prototype.registerOnTouched = /**
* @param {?} fn
* @return {?}
*/
function (fn) {
this.onTouched.push(fn);
};
/**
* @return {?}
*/
DatepickerFormComponent.prototype.propogateTouched = /**
* @return {?}
*/
function () {
this.onTouched.forEach(function (fn) { return fn(); });
};
/**
* @param {?} value
* @return {?}
*/
DatepickerFormComponent.prototype.propogateChange = /**
* @param {?} value
* @return {?}
*/
function (value) {
this.onChanged.forEach(function (fn) { return fn(value); });
};
/**
* @param {?} control
* @return {?}
*/
DatepickerFormComponent.prototype.validate = /**
* @param {?} control
* @return {?}
*/
function (control) {
var /** @type {?} */ date = Date.parse(control.value);
if (!this.required && (control.value === null || control.value === undefined)) {
this.isValid = true;
return null;
}
if (isNaN(date)) {
this.isValid = false;
return {
dateParseError: {
valid: false
}
};
}
if (!this.allowPreviousDates && this.validateIsNotBeforeDate(this.date)) {
this.isValid = false;
return {
previousDateError: {
valid: false
}
};
}
if (!this.allowFutureDates && this.validateIsNotAfterDate(this.date)) {
this.isValid = false;
return {
futureDateError: {
valid: false
}
};
}
if (this.validateDateRange && this.validateDateRange(this.date)) {
this.isValid = false;
return {
dateRangeError: {
valid: false
}
};
}
if (this.required && !this.date) {
this.isValid = false;
return {
dateRequiredError: {
valid: false
}
};
}
this.isValid = true;
return null;
};
DatepickerFormComponent.decorators = [
{ type: Component, args: [{
selector: 'hxa-datepicker-input, hxa-datepicker-form',
template: "<div class=\"hx-input-group hxa-datepicker-form\">\n <div class=\"hx-input-control\" [ngClass]=\"{'is-danger': !isValid && datePickerForm.touched}\">\n <input class=\"hx-input\" type=\"text\" #datePickerForm=\"ngModel\"\n [required]=\"required ? true : null\"\n [disabled]=\"disabled\"\n [readonly]=\"readonly ? true : null\"\n [ngModel]=\"date | date:dateFormat\"\n (change)=\"onChange(datePickerForm.value)\"\n (focus)=\"onFocus()\"\n (keydown.Tab)=\"onTab(datePickerForm.value)\">\n <label class=\"hx-label\" *ngIf=\"placeholder\">{{placeholder}} <sup *ngIf=\"required\">*</sup></label>\n <div class=\"hx-help\"></div>\n <div class=\"hxa-datepicker-help\">Please select a date</div>\n </div>\n <i class=\"hx-icon icon-calendar\"></i>\n <hxa-datepicker class=\"hxa-datepicker-calendar\" *ngIf=\"visible\" \n [selectedDate]=\"date\"\n [validators]=\"dateValidators\"\n (onDateSelected)=\"onDateSelectEvent($event)\"\n [ngClass]=\"{'hxa-datepicker-calendar-top': align == 'top', 'hxa-datepicker-calendar-bottom': align == 'bottom'}\"></hxa-datepicker>\n</div>\n",
styles: [".hxa-datepicker-form{position:relative;max-width:21rem}.hxa-datepicker-calendar{position:absolute;z-index:99;left:0}.hxa-datepicker-calendar-top{bottom:100%}.hxa-datepicker-calendar-bottom{top:70%}.hxa-datepicker-help{font-size:.75rem;margin-top:.25rem;color:#63605f}.hxa-datepicker-form input[readonly]~.hx-label{top:-.5rem;font-size:.75rem;color:#41b987}"],
providers: [{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(function () { return DatepickerFormComponent; }),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(function () { return DatepickerFormComponent; }),
multi: true,
}]
},] },
];
/** @nocollapse */
DatepickerFormComponent.ctorParameters = function () { return [
{ type: ElementRef, },
]; };
DatepickerFormComponent.propDecorators = {
"disabled": [{ type: Input },],
"readonly": [{ type: Input },],
"required": [{ type: Input },],
"defaultToPresentDate": [{ type: Input },],
"allowPreviousDates": [{ type: Input },],
"allowFutureDates": [{ type: Input },],
"dateFormat": [{ type: Input },],
"placeholder": [{ type: Input },],
"align": [{ type: Input },],
"from": [{ type: Input },],
"to": [{ type: Input },],
"onDateChange": [{ type: Output },],
"onClickOutsideComponent": [{ type: HostListener, args: ['document:click', ['$event.target'],] },],
};
return DatepickerFormComponent;
}());
export { DatepickerFormComponent };
function DatepickerFormComponent_tsickle_Closure_declarations() {
/** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */
DatepickerFormComponent.decorators;
/**
* @nocollapse
* @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>}
*/
DatepickerFormComponent.ctorParameters;
/** @type {!Object<string,!Array<{type: !Function, args: (undefined|!Array<?>)}>>} */
DatepickerFormComponent.propDecorators;
/** @type {?} */
DatepickerFormComponent.prototype.disabled;
/** @type {?} */
DatepickerFormComponent.prototype.readonly;
/** @type {?} */
DatepickerFormComponent.prototype.required;
/** @type {?} */
DatepickerFormComponent.prototype.defaultToPresentDate;
/** @type {?} */
DatepickerFormComponent.prototype.allowPreviousDates;
/** @type {?} */
DatepickerFormComponent.prototype.allowFutureDates;
/** @type {?} */
DatepickerFormComponent.prototype.dateFormat;
/** @type {?} */
DatepickerFormComponent.prototype.placeholder;
/** @type {?} */
DatepickerFormComponent.prototype.align;
/** @type {?} */
DatepickerFormComponent.prototype.from;
/** @type {?} */
DatepickerFormComponent.prototype.to;
/** @type {?} */
DatepickerFormComponent.prototype.onDateChange;
/** @type {?} */
DatepickerFormComponent.prototype.date;
/** @type {?} */
DatepickerFormComponent.prototype.visible;
/** @type {?} */
DatepickerFormComponent.prototype.presentDate;
/** @type {?} */
DatepickerFormComponent.prototype.isValid;
/** @type {?} */
DatepickerFormComponent.prototype.dateValidators;
/** @type {?} */
DatepickerFormComponent.prototype.onChanged;
/** @type {?} */
DatepickerFormComponent.prototype.onTouched;
/** @type {?} */
DatepickerFormComponent.prototype.validateDateRange;
/** @type {?} */
DatepickerFormComponent.prototype.element;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXBpY2tlci1mb3JtLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BoeHVpL2FuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvZGF0ZXBpY2tlci9kYXRlcGlja2VyLWZvcm0uY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQVUsVUFBVSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3JILE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxhQUFhLEVBQW9ELE1BQU0sZ0JBQWdCLENBQUM7O0lBK0RsSCxpQ0FBb0IsT0FBbUI7UUFBbkIsWUFBTyxHQUFQLE9BQU8sQ0FBWTt3QkF4Qm5CLEtBQUs7d0JBQ0wsS0FBSzt3QkFDTCxLQUFLO29DQUNPLElBQUk7a0NBQ04sSUFBSTtnQ0FDTixJQUFJOzBCQUNWLFNBQVM7MkJBQ1IsTUFBTTtxQkFDTSxRQUFRO29CQUMzQixFQUFFO2tCQUNKLEVBQUU7NEJBRTZCLElBQUksWUFBWSxFQUFRO3VCQUczQyxLQUFLOzhCQUdQLElBQUksS0FBSyxFQUEyQjt5QkFDeEMsSUFBSSxLQUFLLEVBQXlCO3lCQUNsQyxJQUFJLEtBQUssRUFBYztLQUlDOzs7O0lBRTVDLDBDQUFROzs7SUFBUjtRQUFBLGlCQXdCQztRQXZCQyxxQkFBTSxJQUFJLEdBQVMsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUM5QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFFakYsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQztZQUM5QixVQUFVLENBQUM7Z0JBQ1QsS0FBSSxDQUFDLE9BQU8sQ0FBQyxLQUFJ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LGlCQUFpQjs0QkFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxjQUFNLE9BQUEsdUJBQXVCLEVBQXZCLENBQXVCLENBQUM7NEJBQ3RELEtBQUssRUFBRSxJQUFJO3lCQUNaO3dCQUNEOzRCQUNFLE9BQU8sRUFBRSxhQUFhOzRCQUN0QixXQUFXLEVBQUUsVUFBVSxDQUFDLGNBQU0sT0FBQSx1QkFBdUIsRUFBdkIsQ0FBdUIsQ0FBQzs0QkFDdEQsS0FBSyxFQUFFLElBQUk7eUJBQ1osQ0FBQztpQkFDSDs7OztnQkF0QzBDLFVBQVU7Ozs2QkF3Q2xELEtBQUs7NkJBQ0wsS0FBSzs2QkFDTCxLQUFLO3lDQUNMLEtBQUs7dUNBQ0wsS0FBSztxQ0FDTCxLQUFLOytCQUNMLEtBQUs7Z0NBQ0wsS0FBSzswQkFDTCxLQUFLO3lCQUNMLEtBQUs7dUJBQ0wsS0FBSztpQ0FFTCxNQUFNOzRDQXNETixZQUFZLFNBQUMsZ0JBQWdCLEVBQUUsQ0FBQyxlQUFlLENBQUM7O2tDQTFHbkQ7O1NBdUNhLHVCQUF1QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIE91dHB1dCwgT25Jbml0LCBFbGVtZW50UmVmLCBIb3N0TGlzdGVuZXIsIEV2ZW50RW1pdHRlciwgZm9yd2FyZFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBOR19WQUxVRV9BQ0NFU1NPUiwgTkdfVkFMSURBVE9SUywgQ29udHJvbFZhbHVlQWNjZXNzb3IsIFZhbGlkYXRvciwgQWJzdHJhY3RDb250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdoeGEtZGF0ZXBpY2tlci1pbnB1dCwgaHhhLWRhdGVwaWNrZXItZm9ybScsXHJcbiAgdGVtcGxhdGU6IGA8ZGl2IGNsYXNzPVwiaHgtaW5wdXQtZ3JvdXAgaHhhLWRhdGVwaWNrZXItZm9ybVwiPlxyXG4gIDxkaXYgY2xhc3M9XCJoeC1pbnB1dC1jb250cm9sXCIgW25nQ2xhc3NdPVwieydpcy1kYW5nZXInOiAhaXNWYWxpZCAmJiBkYXRlUGlja2VyRm9ybS50b3VjaGVkfVwiPlxyXG4gICAgPGlucHV0IGNsYXNzPVwiaHgtaW5wdXRcIiB0eXBlPVwidGV4dFwiICNkYXRlUGlja2VyRm9ybT1cIm5nTW9kZWxcIlxyXG4gICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWQgPyB0cnVlIDogbnVsbFwiXHJcbiAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXHJcbiAgICAgIFtyZWFkb25seV09XCJyZWFkb25seSA/IHRydWUgOiBudWxsXCJcclxuICAgICAgW25nTW9kZWxdPVwiZGF0ZSB8IGRhdGU6ZGF0ZUZvcm1hdFwiXHJcbiAgICAgIChjaGFuZ2UpPVwib25DaGFuZ2UoZGF0ZVBpY2tlckZvcm0udmFsdWUpXCJcclxuICAgICAgKGZvY3VzKT1cIm9uRm9jdXMoKVwiXHJcbiAgICAgIChrZXlkb3duLlRhYik9XCJvblRhYihkYXRlUGlja2VyRm9ybS52YWx1ZSlcIj5cclxuICAgIDxsYWJlbCBjbGFzcz1cImh4LWxhYmVsXCIgKm5nSWY9XCJwbGFjZWhvbGRlclwiPnt7cGxhY2Vob2xkZXJ9fSA8c3VwICpuZ0lmPVwicmVxdWlyZWRcIj4qPC9zdXA+PC9sYWJlbD5cclxuICAgIDxkaXYgY2xhc3M9XCJoeC1oZWxwXCI+PC9kaXY+XHJcbiAgICA8ZGl2IGNsYXNzPVwiaHhhLWRhdGVwaWNrZXItaGVscFwiPlBsZWFzZSBzZWxlY3QgYSBkYXRlPC9kaXY+XHJcbiAgPC9kaXY+XHJcbiAgPGkgY2xhc3M9XCJoeC1pY29uIGljb24tY2FsZW5kYXJcIj48L2k+XHJcbiAgPGh4YS1kYXRlcGlja2VyIGNsYXNzPVwiaHhhLWRhdGVwaWNrZXItY2FsZW5kYXJcIiAqbmdJZj1cInZpc2libGVcIiBcclxuICAgIFtzZWxlY3RlZERhdGVdPVwiZGF0ZVwiXHJcbiAgICBbdmFsaWRhdG9yc109XCJkYXRlVmFsaWRhdG9yc1wiXHJcbiAgICAob25EYXRlU2VsZWN0ZWQpPVwib25EYXRlU2VsZWN0RXZlbnQoJGV2ZW50KVwiXHJcbiAgICBbbmdDbGFzc109XCJ7J2h4YS1kYXRlcGlja2VyLWNhbGVuZGFyLXRvcCc6IGFsaWduID09ICd0b3AnLCAnaHhhLWRhdGVwaWNrZXItY2FsZW5kYXItYm90dG9tJzogYWxpZ24gPT0gJ2JvdHRvbSd9XCI+PC9oeGEtZGF0ZXBpY2tlcj5cclxuPC9kaXY+XHJcbmAsXHJcbiAgc3R5bGVzOiBbYC5oeGEtZGF0ZXBpY2tlci1mb3Jte3Bvc2l0aW9uOnJlbGF0aXZlO21heC13aWR0aDoyMXJlbX0uaHhhLWRhdGVwaWNrZXItY2FsZW5kYXJ7cG9zaXRpb246YWJzb2x1dGU7ei1pbmRleDo5OTtsZWZ0OjB9Lmh4YS1kYXRlcGlja2VyLWNhbGVuZGFyLXRvcHtib3R0b206MTAwJX0uaHhhLWRhdGVwaWNrZXItY2FsZW5kYXItYm90dG9te3RvcDo3MCV9Lmh4YS1kYXRlcGlja2VyLWhlbHB7Zm9udC1zaXplOi43NXJlbTttYXJnaW4tdG9wOi4yNXJlbTtjb2xvcjojNjM2MDVmfS5oeGEtZGF0ZXBpY2tlci1mb3JtIGlucHV0W3JlYWRvbmx5XX4uaHgtbGFiZWx7dG9wOi0uNXJlbTtmb250LXNpemU6Ljc1cmVtO2NvbG9yOiM0MWI5ODd9YF0sXHJcbiAgcHJvdmlkZXJzOiBbe1xyXG4gICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBEYXRlcGlja2VyRm9ybUNvbXBvbmVudCksXHJcbiAgICBtdWx0aTogdHJ1ZVxyXG4gIH0sXHJcbiAge1xyXG4gICAgcHJvdmlkZTogTkdfVkFMSURBVE9SUyxcclxuICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IERhdGVwaWNrZXJGb3JtQ29tcG9uZW50KSxcclxuICAgIG11bHRpOiB0cnVlLFxyXG4gIH1dXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBEYXRlcGlja2VyRm9ybUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQ29udHJvbFZhbHVlQWNjZXNzb3IsIFZhbGlkYXRvciB7XHJcbiAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcclxuICBASW5wdXQoKSByZWFkb25seSA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIHJlcXVpcmVkID0gZmFsc2U7XHJcbiAgQElucHV0KCkgZGVmYXVsdFRvUHJlc2VudERhdGUgPSB0cnVlO1xyXG4gIEBJbnB1dCgpIGFsbG93UHJldmlvdXNEYXRlcyA9IHRydWU7XHJcbiAgQElucHV0KCkgYWxsb3dGdXR1cmVEYXRlcyA9IHRydWU7XHJcbiAgQElucHV0KCkgZGF0ZUZvcm1hdCA9IFwiZGQvTU0veVwiO1xyXG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyID0gXCJEYXRlXCI7XHJcbiAgQElucHV0KCkgYWxpZ246IFwidG9wXCIgfCBcImJvdHRvbVwiID0gXCJib3R0b21cIjtcclxuICBASW5wdXQoKSBmcm9tID0gJyc7XHJcbiAgQElucHV0KCkgdG8gPSAnJztcclxuXHJcbiAgQE91dHB1dCgpIG9uRGF0ZUNoYW5nZTogRXZlbnRFbWl0dGVyPERhdGU+ID0gbmV3IEV2ZW50RW1pdHRlcjxEYXRlPigpO1xyXG5cclxuICBwdWJsaWMgZGF0ZTogRGF0ZTtcclxuICBwdWJsaWMgdmlzaWJsZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIHB1YmxpYyBwcmVzZW50RGF0ZTogRGF0ZTtcclxuICBwdWJsaWMgaXNWYWxpZDogYm9vbGVhbjtcclxuICBwdWJsaWMgZGF0ZVZhbGlkYXRvcnMgPSBuZXcgQXJyYXk8KGRhdGU6IERhdGUpID0+IGJvb2xlYW4+KCk7XHJcbiAgcHJpdmF0ZSBvbkNoYW5nZWQgPSBuZXcgQXJyYXk8KHZhbHVlOiBEYXRlKSA9PiB2b2lkPigpO1xyXG4gIHByaXZhdGUgb25Ub3VjaGVkID0gbmV3IEFycmF5PCgpID0+IHZvaWQ+KCk7XHJcblxyXG4gIHByaXZhdGUgdmFsaWRhdGVEYXRlUmFuZ2U6IChkYXRlOiBEYXRlKSA9PiBib29sZWFuO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGVsZW1lbnQ6IEVsZW1lbnRSZWYpIHsgfVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIGNvbnN0IGRhdGU6IERhdGUgPSBuZXcgRGF0ZSgpO1xyXG4gICAgdGhpcy5wcmVzZW50RGF0ZSA9IG5ldyBEYXRlKGRhdGUuZ2V0RnVsbFllYXIoKSwgZGF0ZS5nZXRNb250aCgpLCBkYXRlLmdldERhdGUoKSk7XHJcblxyXG4gICAgaWYgKHRoaXMuZGVmYXVsdFRvUHJlc2VudERhdGUpIHtcclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5zZXREYXRlKHRoaXMucHJlc2VudERhdGUpO1xyXG4gICAgICB9KTtcclxuICAgIH0gICAgXHJcblxyXG4gICAgLy8gQ2xvc2UgdG8gdGhlIG1pbmltdW0gYW5kIG1heGl1bSBwb3NzaWJsZSBkYXRlcywgYnV0IHN0aWxsIG5vcm1hbGlzYWJsZVxyXG4gICAgLy8gaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNS4xLyNzZWMtMTUuOS4xLjFcclxuICAgIGNvbnN0IGZyb20gPSB0aGlzLnBhcnNlRGF0ZSh0aGlzLmZyb20pIHx8IG5ldyBEYXRlKC04NjMwMDAwMDAwMDAwMDAwKTtcclxuICAgIGNvbnN0IHRvID0gdGhpcy5wYXJzZURhdGUodGhpcy50bykgfHwgbmV3IERhdGUoODYzMDAwMDAwMDAwMDAwMCk7XHJcblxyXG4gICAgaWYgKCEhdGhpcy5mcm9tIHx8ICEhdGhpcy50bykge1xyXG4gICAgICB0aGlzLnZhbGlkYXRlRGF0ZVJhbmdlID0gdGhpcy5jcmVhdGVEYXRlUmFuZ2VWYWxpZGF0b3IoZnJvbSwgdG8pO1xyXG4gICAgICB0aGlzLmRhdGVWYWxpZGF0b3JzLnB1c2godGhpcy52YWxpZGF0ZURhdGVSYW5nZS5iaW5kKHRoaXMpKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXRoaXMuYWxsb3dQcmV2aW91c0RhdGVzKVxyXG4gICAgICB0aGlzLmRhdGVWYWxpZGF0b3JzLnB1c2godGhpcy52YWxpZGF0ZUlzTm90QmVmb3JlRGF0ZS5iaW5kKHRoaXMpKTtcclxuICAgIGlmICghdGhpcy5hbGxvd0Z1dHVyZURhdGVzKVxyXG4gICAgICB0aGlzLmRhdGVWYWxpZGF0b3JzLnB1c2godGhpcy52YWxpZGF0ZUlzTm90QWZ0ZXJEYXRlLmJpbmQodGhpcykpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHNldERhdGUoZGF0ZTogRGF0ZSk6IHZvaWQge1xyXG4gICAgdGhpcy5kYXRlID0gZGF0ZTtcclxuICAgIHRoaXMub25EYXRlQ2hhbmdlLmVtaXQoZGF0ZSk7XHJcbiAgICB0aGlzLnByb3BvZ2F0ZUNoYW5nZShkYXRlKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZXRWaXNpYmxlKCk6IHZvaWQge1xyXG4gICAgdGhpcy52aXNpYmxlID0gdHJ1ZTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyB1bnNldFZpc2libGUoKTogdm9pZCB7XHJcbiAgICB0aGlzLnZpc2libGUgPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQudGFyZ2V0J10pXHJcbiAgcHVibGljIG9uQ2xpY2tPdXRzaWRlQ29tcG9uZW50KHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50KTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50LmZpcnN0Q2hpbGQuY29udGFpbnModGFyZ2V0RWxlbWVudCkpIHtcclxuICAgICAgdGhpcy51bnNldFZpc2libGUoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBvbkRhdGVTZWxlY3RFdmVudChpbnB1dERhdGU6IERhdGUpOiB2b2lkIHtcclxuICAgIHRoaXMudW5zZXRWaXNpYmxlKCk7XHJcbiAgICB0aGlzLnNldERhdGUoaW5wdXREYXRlKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBvbkNoYW5nZShpbnB1dERhdGU6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgY29uc3QgZGF0ZTogRGF0ZSA9IHRoaXMucGFyc2VEYXRlKGlucHV0RGF0ZSk7XHJcblxyXG4gICAgaWYgKGlucHV0RGF0ZSA9PSBcIlwiKSB7XHJcbiAgICAgIHRoaXMuc2V0RGF0ZShudWxsKTtcclxuICAgIH0gZWxzZSBpZiAoISFkYXRlKSB7XHJcbiAgICAgIHRoaXMuc2V0RGF0ZShkYXRlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMucHJvcG9nYXRlQ2hhbmdlKGlucHV0RGF0ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25Gb2N1cygpOiB2b2lkIHtcclxuICAgIHRoaXMuc2V0VmlzaWJsZSgpO1xyXG4gICAgdGhpcy5wcm9wb2dhdGVUb3VjaGVkKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25UYWIoaW5wdXREYXRlOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIHRoaXMub25DaGFuZ2UoaW5wdXREYXRlKTtcclxuICAgIHRoaXMudW5zZXRWaXNpYmxlKCk7XHJcbiAgICB0aGlzLnByb3BvZ2F0ZVRvdWNoZWQoKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBwYXJzZURhdGUoaW5wdXREYXRlOiBzdHJpbmcpOiBEYXRlIHtcclxuICAgIC8vIFNpbmNlIERhdGUuUGFyc2UoKSBvbmx5IGFjY2VwcyBtL2QveSBkYXRlcywgd2UgaGF2ZSB0byBzd2FwIHRoZSBkYXkgYW5kIG1vbnRoXHJcbiAgICBsZXQgZGF0ZUFycmF5ID0gaW5wdXREYXRlLnNwbGl0KC9bLixcXC8gLV0vKTtcclxuICAgIGlmIChkYXRlQXJyYXkubGVuZ3RoID09IDMgJiYgZGF0ZUFycmF5WzJdLmxlbmd0aCAhPSAwKSB7XHJcbiAgICAgIGxldCBkYXk6IHN0cmluZyA9IGRhdGVBcnJheS5zaGlmdCgpO1xyXG4gICAgICBkYXRlQXJyYXkuc3BsaWNlKDEsIDAsIGRheSk7XHJcblxyXG4gICAgICBsZXQgcGFyc2VJbnB1dDogbnVtYmVyID0gRGF0ZS5wYXJzZShkYXRlQXJyYXkuam9pbihcIi9cIikpO1xyXG4gICAgICBpZiAoIWlzTmFOKHBhcnNlSW5wdXQpKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRlKHBhcnNlSW5wdXQpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyB2YWxpZGF0ZUlzTm90QmVmb3JlRGF0ZShkYXRlOiBEYXRlKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCBub3JtYWxpc2VkRGF0ZSA9IG5ldyBEYXRlKGRhdGUuZ2V0RnVsbFllYXIoKSwgZGF0ZS5nZXRNb250aCgpLCBkYXRlLmdldERhdGUoKSk7XHJcblxyXG4gICAgcmV0dXJuIG5vcm1hbGlzZWREYXRlLmdldFRpbWUoKSA8IHRoaXMucHJlc2VudERhdGUuZ2V0VGltZSgpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHZhbGlkYXRlSXNOb3RBZnRlckRhdGUoZGF0ZTogRGF0ZSk6IGJvb2xlYW4ge1xyXG4gICAgY29uc3Qgbm9ybWFsaXNlZERhdGUgPSBuZXcgRGF0ZShkYXRlLmdldEZ1bGxZZWFyKCksIGRhdGUuZ2V0TW9udGgoKSwgZGF0ZS5nZXREYXRlKCkpO1xyXG5cclxuICAgIHJldHVybiBub3JtYWxpc2VkRGF0ZS5nZXRUaW1lKCkgPiB0aGlzLnByZXNlbnREYXRlLmdldFRpbWUoKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBjcmVhdGVEYXRlUmFuZ2VWYWxpZGF0b3IoZnJvbTogRGF0ZSwgdG86IERhdGUpOiAoZGF0ZTogRGF0ZSkgPT4gYm9vbGVhbiB7XHJcbiAgICBjb25zdCBub3JtYWxpc2VkRnJvbURhdGUgPSBuZXcgRGF0ZShmcm9tLmdldEZ1bGxZZWFyKCksIGZyb20uZ2V0TW9udGgoKSwgZnJvbS5nZXREYXRlKCkpO1xyXG4gICAgY29uc3Qgbm9ybWFsaXNlZFRvRGF0ZSA9IG5ldyBEYXRlKHRvLmdldEZ1bGxZZWFyKCksIHRvLmdldE1vbnRoKCksIHRvLmdldERhdGUoKSk7XHJcblxyXG4gICAgcmV0dXJuIChkYXRlOiBEYXRlKSA9PiB7XHJcbiAgICAgIGNvbnN0IG5vcm1hbGlzZWREYXRlID0gbmV3IERhdGUoZGF0ZS5nZXRGdWxsWWVhcigpLCBkYXRlLmdldE1vbnRoKCksIGRhdGUuZ2V0RGF0ZSgpKTtcclxuICAgICAgcmV0dXJuICEobm9ybWFsaXNlZEZyb21EYXRlLmdldFRpbWUoKSA8PSBub3JtYWxpc2VkRGF0ZS5nZXRUaW1lKCkgJiZcclxuICAgICAgICBub3JtYWxpc2VkRGF0ZS5nZXRUaW1lKCkgPD0gbm9ybWFsaXNlZFRvRGF0ZS5nZXRUaW1lKCkpO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyB3cml0ZVZhbHVlKHZhbHVlOiBEYXRlKTogdm9pZCB7XHJcbiAgICB0aGlzLnNldERhdGUodmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHJlZ2lzdGVyT25DaGFuZ2UoZm46ICh2YWx1ZTogRGF0ZSkgPT4gdm9pZCk6IHZvaWQge1xyXG4gICAgdGhpcy5vbkNoYW5nZWQucHVzaChmbik7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgcmVnaXN0ZXJPblRvdWNoZWQoZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcclxuICAgIHRoaXMub25Ub3VjaGVkLnB1c2goZm4pO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHByb3BvZ2F0ZVRvdWNoZWQoKTogdm9pZCB7XHJcbiAgICB0aGlzLm9uVG91Y2hlZC5mb3JFYWNoKGZuID0+IGZuKCkpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHByb3BvZ2F0ZUNoYW5nZSh2YWx1ZSk6IHZvaWQge1xyXG4gICAgdGhpcy5vbkNoYW5nZWQuZm9yRWFjaChmbiA9PiBmbih2YWx1ZSkpO1xyXG4gIH1cclxuXHJcbiAgdmFsaWRhdGUoY29udHJvbDogQWJzdHJhY3RDb250cm9sKTogeyBba2V5OiBzdHJpbmddOiBhbnk7IH0ge1xyXG4gICAgY29uc3QgZGF0ZSA9IERhdGUucGFyc2UoY29udHJvbC52YWx1ZSk7XHJcblxyXG4gICAgaWYgKCF0aGlzLnJlcXVpcmVkICYmIChjb250cm9sLnZhbHVlID09PSBudWxsIHx8IGNvbnRyb2wudmFsdWUgPT09IHVuZGVmaW5lZCkpIHtcclxuICAgICAgdGhpcy5pc1ZhbGlkID0gdHJ1ZTtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGlzTmFOKGRhdGUpKSB7XHJcbiAgICAgIHRoaXMuaXNWYWxpZCA9IGZhbHNlO1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGRhdGVQYXJzZUVycm9yOiB7XHJcbiAgICAgICAgICB2YWxpZDogZmFsc2VcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXRoaXMuYWxsb3dQcmV2aW91c0RhdGVzICYmIHRoaXMudmFsaWRhdGVJc05vdEJlZm9yZURhdGUodGhpcy5kYXRlKSkge1xyXG4gICAgICB0aGlzLmlzVmFsaWQgPSBmYWxzZTtcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBwcmV2aW91c0RhdGVFcnJvcjoge1xyXG4gICAgICAgICAgdmFsaWQ6IGZhbHNlXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCF0aGlzLmFsbG93RnV0dXJlRGF0ZXMgJiYgdGhpcy52YWxpZGF0ZUlzTm90QWZ0ZXJEYXRlKHRoaXMuZGF0ZSkpIHtcclxuICAgICAgdGhpcy5pc1ZhbGlkID0gZmFsc2U7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgZnV0dXJlRGF0ZUVycm9yOiB7XHJcbiAgICAgICAgICB2YWxpZDogZmFsc2VcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy52YWxpZGF0ZURhdGVSYW5nZSAmJiB0aGlzLnZhbGlkYXRlRGF0ZVJhbmdlKHRoaXMuZGF0ZSkpIHtcclxuICAgICAgdGhpcy5pc1ZhbGlkID0gZmFsc2U7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgZGF0ZVJhbmdlRXJyb3I6IHtcclxuICAgICAgICAgIHZhbGlkOiBmYWxzZVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLnJlcXVpcmVkICYmICF0aGlzLmRhdGUpIHtcclxuICAgICAgdGhpcy5pc1ZhbGlkID0gZmFsc2U7XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgZGF0ZVJlcXVpcmVkRXJyb3I6IHtcclxuICAgICAgICAgIHZhbGlkOiBmYWxzZVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuaXNWYWxpZCA9IHRydWU7XHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9XHJcbn1cclxuIl19