@hxui/angular
Version:
An Angular library based on the [HXUI design system](https://hxui.io).
176 lines • 34.4 kB
JavaScript
import { DatePipe } from '@angular/common';
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import { DropdownDirective } from '../dropdown/dropdown.directive';
import { DateRangePickerConfig } from './date-range-picker.config';
import { DateSelectionType, DisplayMode } from './date-range-picker.model';
import { fullIntervalList, IntervalItem } from './interval-option-model';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "./date-range-picker.config";
import * as i3 from "../tabs/tabset.component";
import * as i4 from "./date-range-picker-interval/date-range-picker-interval.component";
import * as i5 from "./date-range-picker-custom/date-range-picker-custom.component";
import * as i6 from "../dropdown/dropdown.directive";
import * as i7 from "../dropdown/dropdown-toggle.directive";
import * as i8 from "../dropdown/dropdown-menu.directive";
import * as i9 from "../tabs/tab.directive";
export class DateRangePickerComponent {
constructor(datePipe, dateRangePickerConfig) {
this.datePipe = datePipe;
this.dateRangePickerConfig = dateRangePickerConfig;
/** This attribute specifies the placeholder value of the components input element. */
this.placeholder = 'Date';
/** Adds the disabled html attribute to the components dropdown element. */
this.disabled = false;
/**
* Indicates that dropdown will be closed on item or document
* click, and after pressing ESC.
*/
this.autoClose = true;
/** Specifies the position the datepicker opens against the input element */
this.placement = 'bottom';
/** Specifies how tab(s) will be displayed. */
this.displayMode = DisplayMode.showTab;
/**
* A JavaScript Date object formatting string, formats the display
* of components current value.
*/
this.dateFormat = 'dd/MM/yyyy';
this.defaultDateRange = {
fromDate: new Date(),
toDate: new Date()
};
/** Specifies whether caret down icon is displayed to right of input */
this.showCaretDown = true;
/**
* Emits a Date Range Object containing fromDate and toDate
* selected from the DateRangePicker.
*/
this.onDateRangeSelected = new EventEmitter();
// import to DateSElectionType into the instance of this class
this.DateSelectionType = DateSelectionType;
this.currentTab = DateSelectionType.interval;
this.fromDate = new Date();
this.toDate = new Date();
this.selectedInterval = new IntervalItem('Today', 'day', 0, 'today');
}
ngOnInit() {
this.setInitialDateRange();
this.showTab = this.displayMode === DisplayMode.showTab;
this.showIntervalOnly = this.displayMode === DisplayMode.showIntervalOnly;
this.showCustomOnly = this.displayMode === DisplayMode.showCustomOnly;
this.generateIntervalOptionItems(this.intervalOptions || []);
}
setInitialDateRange() {
this.defaultDateRange = this.defaultDateRange || {
fromDate: new Date(),
toDate: new Date()
};
this.dateFormat = this.dateFormat || 'dd/MM/yyyy';
this.fromDate = this.defaultDateRange.fromDate;
this.toDate = this.defaultDateRange.toDate;
this._displayRange = this.createDateRange();
}
resetDateRange() {
this.fromDate = new Date();
this.toDate = new Date();
this._displayRange = this.createDateRange();
}
generateIntervalOptionItems(itemList) {
this.intervalList = fullIntervalList.filter(item => itemList.includes(item.displayName));
}
hide(closeDropdown) {
if (closeDropdown) {
this.dropdown.hide();
}
}
toggle() {
this.dropdown.toggle();
}
onCustomDateSelection(newCustomDate) {
// do not update range if undefined, null[], from > to
if (!newCustomDate ||
newCustomDate[0] == null ||
newCustomDate[1] == null ||
newCustomDate[0] > newCustomDate[1]) {
return null;
}
this.fromDate = newCustomDate[0];
this.toDate = newCustomDate[1];
this._displayRange = this.createDateRange();
this.onDateRangeSelected.emit({
fromDate: this.fromDate,
toDate: this.toDate
});
this.currentTab = DateSelectionType.custom;
this.selectedInterval = null;
}
onIntervalSelection(selectedItem) {
if (selectedItem) {
this.selectedInterval = selectedItem;
const today = new Date();
let calculatedDate;
if (selectedItem.unit === 'day') {
calculatedDate = new Date(today.getFullYear(), today.getMonth(), today.getDate() + selectedItem.count);
}
else if (selectedItem.unit === 'month') {
calculatedDate = new Date(today.getFullYear(), today.getMonth() + selectedItem.count, today.getDate());
}
else if (selectedItem.unit === 'year') {
calculatedDate = new Date(today.getFullYear() + selectedItem.count, today.getMonth(), today.getDate());
}
if (calculatedDate >= today) {
this.fromDate = today;
this.toDate = calculatedDate;
}
else {
this.fromDate = calculatedDate;
this.toDate = today;
}
this._displayRange = this.createDateRange();
this.onDateRangeSelected.emit({
fromDate: this.fromDate,
toDate: this.toDate
});
this.currentTab = DateSelectionType.interval;
}
}
createDateRange() {
const fromDateStr = this.datePipe.transform(this.fromDate, this.dateFormat);
const toDateStr = this.datePipe.transform(this.toDate, this.dateFormat);
if (fromDateStr === toDateStr) {
return fromDateStr;
}
return `${fromDateStr} - ${toDateStr}`;
}
}
DateRangePickerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DateRangePickerComponent, deps: [{ token: i1.DatePipe }, { token: i2.DateRangePickerConfig }], target: i0.ɵɵFactoryTarget.Component });
DateRangePickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.3.11", type: DateRangePickerComponent, selector: "hxa-date-range-picker", inputs: { intervalOptions: "intervalOptions", placeholder: "placeholder", disabled: "disabled", autoClose: "autoClose", placement: "placement", displayMode: "displayMode", dateFormat: "dateFormat", defaultDateRange: "defaultDateRange", showCaretDown: "showCaretDown" }, outputs: { onDateRangeSelected: "onDateRangeSelected" }, viewQueries: [{ propertyName: "dropdown", first: true, predicate: ["dropdown"], descendants: true, static: true }], ngImport: i0, template: "<div\r\n class=\"hx-dropdown\"\r\n hxDropdown\r\n #dropdown=\"hx-dropdown\"\r\n [autoClose]=\"autoClose\"\r\n [isDisabled]=\"disabled\"\r\n [placement]=\"placement\"\r\n>\r\n <button class=\"hx-button\" hxDropdownToggle type=\"button\">\r\n <span>\r\n <span class=\"is-text-weight-light\" *ngIf=\"!!placeholder\">\r\n {{ placeholder }}: \r\n </span>\r\n <span class=\"is-text-weight-bolder\">{{ _displayRange }}</span>\r\n </span>\r\n <span class=\"hx-icon-control\" *ngIf=\"showCaretDown\">\r\n <i class=\"icon icon-caret-down\"></i>\r\n </span>\r\n </button>\r\n <div \r\n class=\"hx-dropdown-menu dropdown-menu-wider py-0 px-0\" \r\n *hxDropdownMenu\r\n >\r\n <div class=\"hxa-tabs\" *ngIf=\"showTab\">\r\n <hx-tabset [justified]=\"true\" contentCustomClass=\"pa-0\">\r\n <hx-tab\r\n heading=\"INTERVAL\"\r\n [active]=\"currentTab === DateSelectionType.interval\"\r\n >\r\n <hxa-date-range-picker-interval\r\n [intervalOptionList]=\"intervalList\"\r\n [currentSelectedInterval]=\"selectedInterval\"\r\n (newSelectedInterval)=\"onIntervalSelection($event)\"\r\n (closeDropdown)=\"hide($event)\"\r\n ></hxa-date-range-picker-interval>\r\n </hx-tab>\r\n <hx-tab\r\n heading=\"CUSTOM\"\r\n [active]=\"currentTab === DateSelectionType.custom\"\r\n >\r\n <hxa-date-range-picker-custom\r\n [currentFromDate]=\"fromDate\"\r\n [currentToDate]=\"toDate\"\r\n [dateFormat]=\"dateFormat\"\r\n (newSelectedCustomDate)=\"onCustomDateSelection($event)\"\r\n (closeDropdown)=\"hide($event)\"\r\n ></hxa-date-range-picker-custom>\r\n </hx-tab>\r\n </hx-tabset>\r\n </div>\r\n <div \r\n *ngIf=\"!showTab && showIntervalOnly\" \r\n class=\"internal-custom-tab pa-0\"\r\n >\r\n <hxa-date-range-picker-interval\r\n [intervalOptionList]=\"intervalList\"\r\n [currentSelectedInterval]=\"selectedInterval\"\r\n (newSelectedInterval)=\"onIntervalSelection($event)\"\r\n (closeDropdown)=\"hide($event)\"\r\n ></hxa-date-range-picker-interval>\r\n </div>\r\n <div\r\n *ngIf=\"!showTab && showCustomOnly\"\r\n class=\"internal-custom-tab px-0 pb-0\"\r\n >\r\n <hxa-date-range-picker-custom\r\n [currentFromDate]=\"fromDate\"\r\n [currentToDate]=\"toDate\"\r\n [dateFormat]=\"dateFormat\"\r\n (newSelectedCustomDate)=\"onCustomDateSelection($event)\"\r\n (closeDropdown)=\"hide($event)\"\r\n ></hxa-date-range-picker-custom>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".internal-custom-tab{padding:1rem}.dropdown-menu-wider{width:320px}\n"], components: [{ type: i3.TabsetComponent, selector: "hx-tabset", inputs: ["vertical", "justified", "hasInfo", "type", "contentCustomClass", "stickyHeader", "stickyHeaderOffset", "tag", "changeFn"] }, { type: i4.DateRangePickerIntervalComponent, selector: "hxa-date-range-picker-interval", inputs: ["intervalOptionList", "currentSelectedInterval"], outputs: ["newSelectedInterval", "closeDropdown"] }, { type: i5.DateRangePickerCustomComponent, selector: "hxa-date-range-picker-custom", inputs: ["currentFromDate", "currentToDate", "dateFormat"], outputs: ["newSelectedCustomDate", "closeDropdown"] }], directives: [{ type: i6.DropdownDirective, selector: "[hxaDropdown],[hxDropdown]", inputs: ["placement", "autoClose", "isDisabled", "showDelay", "hideDelay", "maxWidthRelativeTo", "minWidthRelativeTo", "offsetY", "offsetX", "createClipPathMask"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["hx-dropdown", "hxa-dropdown"] }, { type: i7.DropdownToggleDirective, selector: "[hxDropdownToggle],[hxaDropdownToggle]", exportAs: ["hx-dropdown-toggle"] }, { type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i8.DropdownMenuDirective, selector: "[hxDropdownMenu],[hxaDropdownMenu]", exportAs: ["hx-dropdown-menu"] }, { type: i9.TabDirective, selector: "hx-tab, [hx-tab]", inputs: ["heading", "id", "disabled", "removable", "customClass", "active"], outputs: ["select", "deselect", "removed"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.11", ngImport: i0, type: DateRangePickerComponent, decorators: [{
type: Component,
args: [{ selector: 'hxa-date-range-picker', template: "<div\r\n class=\"hx-dropdown\"\r\n hxDropdown\r\n #dropdown=\"hx-dropdown\"\r\n [autoClose]=\"autoClose\"\r\n [isDisabled]=\"disabled\"\r\n [placement]=\"placement\"\r\n>\r\n <button class=\"hx-button\" hxDropdownToggle type=\"button\">\r\n <span>\r\n <span class=\"is-text-weight-light\" *ngIf=\"!!placeholder\">\r\n {{ placeholder }}: \r\n </span>\r\n <span class=\"is-text-weight-bolder\">{{ _displayRange }}</span>\r\n </span>\r\n <span class=\"hx-icon-control\" *ngIf=\"showCaretDown\">\r\n <i class=\"icon icon-caret-down\"></i>\r\n </span>\r\n </button>\r\n <div \r\n class=\"hx-dropdown-menu dropdown-menu-wider py-0 px-0\" \r\n *hxDropdownMenu\r\n >\r\n <div class=\"hxa-tabs\" *ngIf=\"showTab\">\r\n <hx-tabset [justified]=\"true\" contentCustomClass=\"pa-0\">\r\n <hx-tab\r\n heading=\"INTERVAL\"\r\n [active]=\"currentTab === DateSelectionType.interval\"\r\n >\r\n <hxa-date-range-picker-interval\r\n [intervalOptionList]=\"intervalList\"\r\n [currentSelectedInterval]=\"selectedInterval\"\r\n (newSelectedInterval)=\"onIntervalSelection($event)\"\r\n (closeDropdown)=\"hide($event)\"\r\n ></hxa-date-range-picker-interval>\r\n </hx-tab>\r\n <hx-tab\r\n heading=\"CUSTOM\"\r\n [active]=\"currentTab === DateSelectionType.custom\"\r\n >\r\n <hxa-date-range-picker-custom\r\n [currentFromDate]=\"fromDate\"\r\n [currentToDate]=\"toDate\"\r\n [dateFormat]=\"dateFormat\"\r\n (newSelectedCustomDate)=\"onCustomDateSelection($event)\"\r\n (closeDropdown)=\"hide($event)\"\r\n ></hxa-date-range-picker-custom>\r\n </hx-tab>\r\n </hx-tabset>\r\n </div>\r\n <div \r\n *ngIf=\"!showTab && showIntervalOnly\" \r\n class=\"internal-custom-tab pa-0\"\r\n >\r\n <hxa-date-range-picker-interval\r\n [intervalOptionList]=\"intervalList\"\r\n [currentSelectedInterval]=\"selectedInterval\"\r\n (newSelectedInterval)=\"onIntervalSelection($event)\"\r\n (closeDropdown)=\"hide($event)\"\r\n ></hxa-date-range-picker-interval>\r\n </div>\r\n <div\r\n *ngIf=\"!showTab && showCustomOnly\"\r\n class=\"internal-custom-tab px-0 pb-0\"\r\n >\r\n <hxa-date-range-picker-custom\r\n [currentFromDate]=\"fromDate\"\r\n [currentToDate]=\"toDate\"\r\n [dateFormat]=\"dateFormat\"\r\n (newSelectedCustomDate)=\"onCustomDateSelection($event)\"\r\n (closeDropdown)=\"hide($event)\"\r\n ></hxa-date-range-picker-custom>\r\n </div>\r\n </div>\r\n</div>\r\n", styles: [".internal-custom-tab{padding:1rem}.dropdown-menu-wider{width:320px}\n"] }]
}], ctorParameters: function () { return [{ type: i1.DatePipe }, { type: i2.DateRangePickerConfig }]; }, propDecorators: { dropdown: [{
type: ViewChild,
args: ['dropdown', { static: true }]
}], intervalOptions: [{
type: Input
}], placeholder: [{
type: Input
}], disabled: [{
type: Input
}], autoClose: [{
type: Input
}], placement: [{
type: Input
}], displayMode: [{
type: Input
}], dateFormat: [{
type: Input
}], defaultDateRange: [{
type: Input
}], showCaretDown: [{
type: Input
}], onDateRangeSelected: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1yYW5nZS1waWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvaHgtdWkvc3JjL2xpYi9kYXRlLXJhbmdlLXBpY2tlci9kYXRlLXJhbmdlLXBpY2tlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9oeC11aS9zcmMvbGliL2RhdGUtcmFuZ2UtcGlja2VyL2RhdGUtcmFuZ2UtcGlja2VyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMzQyxPQUFPLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBRUwsTUFBTSxFQUNOLFNBQVMsRUFDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNuRSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNuRSxPQUFPLEVBRUwsaUJBQWlCLEVBQ2pCLFdBQVcsRUFDWixNQUFNLDJCQUEyQixDQUFDO0FBQ25DLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQzs7Ozs7Ozs7Ozs7QUFPekUsTUFBTSxPQUFPLHdCQUF3QjtJQTRDbkMsWUFDVSxRQUFrQixFQUNsQixxQkFBNEM7UUFENUMsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQUNsQiwwQkFBcUIsR0FBckIscUJBQXFCLENBQXVCO1FBeEN0RCxzRkFBc0Y7UUFDN0UsZ0JBQVcsR0FBRyxNQUFNLENBQUM7UUFFOUIsMkVBQTJFO1FBQ2xFLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFFMUI7OztXQUdHO1FBQ00sY0FBUyxHQUFHLElBQUksQ0FBQztRQUUxQiw0RUFBNEU7UUFDbkUsY0FBUyxHQUF3QyxRQUFRLENBQUM7UUFFbkUsOENBQThD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VyxDQUFDO1NBQ3BCO1FBQ0QsT0FBTyxHQUFHLFdBQVcsTUFBTSxTQUFTLEVBQUUsQ0FBQztJQUN6QyxDQUFDOztzSEFoTFUsd0JBQXdCOzBHQUF4Qix3QkFBd0Isd2ZDdkJyQyxzckZBMkVBOzRGRHBEYSx3QkFBd0I7a0JBTHBDLFNBQVM7K0JBQ0UsdUJBQXVCO21JQUtRLFFBQVE7c0JBQWhELFNBQVM7dUJBQUMsVUFBVSxFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFHOUIsZUFBZTtzQkFBdkIsS0FBSztnQkFHRyxXQUFXO3NCQUFuQixLQUFLO2dCQUdHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBTUcsU0FBUztzQkFBakIsS0FBSztnQkFHRyxTQUFTO3NCQUFqQixLQUFLO2dCQUdHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBTUcsVUFBVTtzQkFBbEIsS0FBSztnQkFFRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBTUcsYUFBYTtzQkFBckIsS0FBSztnQkFNSSxtQkFBbUI7c0JBQTVCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEYXRlUGlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7XHJcbiAgQ29tcG9uZW50LFxyXG4gIEV2ZW50RW1pdHRlcixcclxuICBJbnB1dCxcclxuICBPbkluaXQsXHJcbiAgT3V0cHV0LFxyXG4gIFZpZXdDaGlsZFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBEcm9wZG93bkRpcmVjdGl2ZSB9IGZyb20gJy4uL2Ryb3Bkb3duL2Ryb3Bkb3duLmRpcmVjdGl2ZSc7XHJcbmltcG9ydCB7IERhdGVSYW5nZVBpY2tlckNvbmZpZyB9IGZyb20gJy4vZGF0ZS1yYW5nZS1waWNrZXIuY29uZmlnJztcclxuaW1wb3J0IHtcclxuICBEYXRlUmFuZ2UsXHJcbiAgRGF0ZVNlbGVjdGlvblR5cGUsXHJcbiAgRGlzcGxheU1vZGVcclxufSBmcm9tICcuL2RhdGUtcmFuZ2UtcGlja2VyLm1vZGVsJztcclxuaW1wb3J0IHsgZnVsbEludGVydmFsTGlzdCwgSW50ZXJ2YWxJdGVtIH0gZnJvbSAnLi9pbnRlcnZhbC1vcHRpb24tbW9kZWwnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdoeGEtZGF0ZS1yYW5nZS1waWNrZXInLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9kYXRlLXJhbmdlLXBpY2tlci5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vZGF0ZS1yYW5nZS1waWNrZXIuY29tcG9uZW50LnNjc3MnXVxyXG59KVxyXG5leHBvcnQgY2xhc3MgRGF0ZVJhbmdlUGlja2VyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcclxuICBAVmlld0NoaWxkKCdkcm9wZG93bicsIHsgc3RhdGljOiB0cnVlIH0pIGRyb3Bkb3duOiBEcm9wZG93bkRpcmVjdGl2ZTtcclxuXHJcbiAgLyoqIFNwZWNpZmllcyBpbnRlcnZhbCBvcHRpb25zIGRpc3BsYXllZCB1bmRlciBpbnRlcnZhbCBzZWxlY3Rpb24gdGFiLiAqL1xyXG4gIEBJbnB1dCgpIGludGVydmFsT3B0aW9uczogc3RyaW5nW107XHJcblxyXG4gIC8qKiBUaGlzIGF0dHJpYnV0ZSBzcGVjaWZpZXMgdGhlIHBsYWNlaG9sZGVyIHZhbHVlIG9mIHRoZSBjb21wb25lbnRzIGlucHV0IGVsZW1lbnQuICovXHJcbiAgQElucHV0KCkgcGxhY2Vob2xkZXIgPSAnRGF0ZSc7XHJcblxyXG4gIC8qKiBBZGRzIHRoZSBkaXNhYmxlZCBodG1sIGF0dHJpYnV0ZSB0byB0aGUgY29tcG9uZW50cyBkcm9wZG93biBlbGVtZW50LiAqL1xyXG4gIEBJbnB1dCgpIGRpc2FibGVkID0gZmFsc2U7XHJcblxyXG4gIC8qKlxyXG4gICAqIEluZGljYXRlcyB0aGF0IGRyb3Bkb3duIHdpbGwgYmUgY2xvc2VkIG9uIGl0ZW0gb3IgZG9jdW1lbnRcclxuICAgKiBjbGljaywgYW5kIGFmdGVyIHByZXNzaW5nIEVTQy5cclxuICAgKi9cclxuICBASW5wdXQoKSBhdXRvQ2xvc2UgPSB0cnVlO1xyXG5cclxuICAvKiogU3BlY2lmaWVzIHRoZSBwb3NpdGlvbiB0aGUgZGF0ZXBpY2tlciBvcGVucyBhZ2FpbnN0IHRoZSBpbnB1dCBlbGVtZW50ICovXHJcbiAgQElucHV0KCkgcGxhY2VtZW50OiAndG9wJyB8ICdib3R0b20nIHwgJ2xlZnQnIHwgJ3JpZ2h0JyA9ICdib3R0b20nO1xyXG5cclxuICAvKiogU3BlY2lmaWVzIGhvdyB0YWIocykgd2lsbCBiZSBkaXNwbGF5ZWQuICovXHJcbiAgQElucHV0KCkgZGlzcGxheU1vZGU6IERpc3BsYXlNb2RlID0gRGlzcGxheU1vZGUuc2hvd1RhYjtcclxuXHJcbiAgLyoqXHJcbiAgICogQSBKYXZhU2NyaXB0IERhdGUgb2JqZWN0IGZvcm1hdHRpbmcgc3RyaW5nLCBmb3JtYXRzIHRoZSBkaXNwbGF5XHJcbiAgICogb2YgY29tcG9uZW50cyBjdXJyZW50IHZhbHVlLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIGRhdGVGb3JtYXQgPSAnZGQvTU0veXl5eSc7XHJcblxyXG4gIEBJbnB1dCgpIGRlZmF1bHREYXRlUmFuZ2U6IERhdGVSYW5nZSA9IHtcclxuICAgIGZyb21EYXRlOiBuZXcgRGF0ZSgpLFxyXG4gICAgdG9EYXRlOiBuZXcgRGF0ZSgpXHJcbiAgfTtcclxuXHJcbiAgLyoqIFNwZWNpZmllcyB3aGV0aGVyIGNhcmV0IGRvd24gaWNvbiBpcyBkaXNwbGF5ZWQgdG8gcmlnaHQgb2YgaW5wdXQgKi9cclxuICBASW5wdXQoKSBzaG93Q2FyZXREb3duID0gdHJ1ZTtcclxuXHJcbiAgLyoqXHJcbiAgICogRW1pdHMgYSBEYXRlIFJhbmdlIE9iamVjdCBjb250YWluaW5nIGZyb21EYXRlIGFuZCB0b0RhdGVcclxuICAgKiBzZWxlY3RlZCBmcm9tIHRoZSBEYXRlUmFuZ2VQaWNrZXIuXHJcbiAgICovXHJcbiAgQE91dHB1dCgpIG9uRGF0ZVJhbmdlU2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPERhdGVSYW5nZT4oKTtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGRhdGVQaXBlOiBEYXRlUGlwZSxcclxuICAgIHByaXZhdGUgZGF0ZVJhbmdlUGlja2VyQ29uZmlnOiBEYXRlUmFuZ2VQaWNrZXJDb25maWdcclxuICApIHt9XHJcblxyXG4gIC8vIGltcG9ydCB0byBEYXRlU0VsZWN0aW9uVHlwZSBpbnRvIHRoZSBpbnN0YW5jZSBvZiB0aGlzIGNsYXNzXHJcbiAgRGF0ZVNlbGVjdGlvblR5cGUgPSBEYXRlU2VsZWN0aW9uVHlwZTtcclxuICBjdXJyZW50VGFiOiBEYXRlU2VsZWN0aW9uVHlwZSA9IERhdGVTZWxlY3Rpb25UeXBlLmludGVydmFsO1xyXG4gIGZyb21EYXRlOiBEYXRlID0gbmV3IERhdGUoKTtcclxuICB0b0RhdGU6IERhdGUgPSBuZXcgRGF0ZSgpO1xyXG4gIF9kaXNwbGF5UmFuZ2U6IHN0cmluZztcclxuXHJcbiAgc2hvd0ludGVydmFsT25seTogYm9vbGVhbjtcclxuICBzaG93Q3VzdG9tT25seTogYm9vbGVhbjtcclxuICBzaG93VGFiOiBib29sZWFuO1xyXG5cclxuICBzZWxlY3RlZEludGVydmFsID0gbmV3IEludGVydmFsSXRlbSgnVG9kYXknLCAnZGF5JywgMCwgJ3RvZGF5Jyk7XHJcblxyXG4gIGludGVydmFsTGlzdDogSW50ZXJ2YWxJdGVtW107XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgdGhpcy5zZXRJbml0aWFsRGF0ZVJhbmdlKCk7XHJcbiAgICB0aGlzLnNob3dUYWIgPSB0aGlzLmRpc3BsYXlNb2RlID09PSBEaXNwbGF5TW9kZS5zaG93VGFiO1xyXG4gICAgdGhpcy5zaG93SW50ZXJ2YWxPbmx5ID0gdGhpcy5kaXNwbGF5TW9kZSA9PT0gRGlzcGxheU1vZGUuc2hvd0ludGVydmFsT25seTtcclxuICAgIHRoaXMuc2hvd0N1c3RvbU9ubHkgPSB0aGlzLmRpc3BsYXlNb2RlID09PSBEaXNwbGF5TW9kZS5zaG93Q3VzdG9tT25seTtcclxuICAgIHRoaXMuZ2VuZXJhdGVJbnRlcnZhbE9wdGlvbkl0ZW1zKHRoaXMuaW50ZXJ2YWxPcHRpb25zIHx8IFtdKTtcclxuICB9XHJcblxyXG4gIHNldEluaXRpYWxEYXRlUmFuZ2UoKSB7XHJcbiAgICB0aGlzLmRlZmF1bHREYXRlUmFuZ2UgPSB0aGlzLmRlZmF1bHREYXRlUmFuZ2UgfHwge1xyXG4gICAgICBmcm9tRGF0ZTogbmV3IERhdGUoKSxcclxuICAgICAgdG9EYXRlOiBuZXcgRGF0ZSgpXHJcbiAgICB9O1xyXG4gICAgdGhpcy5kYXRlRm9ybWF0ID0gdGhpcy5kYXRlRm9ybWF0IHx8ICdkZC9NTS95eXl5JztcclxuICAgIHRoaXMuZnJvbURhdGUgPSB0aGlzLmRlZmF1bHREYXRlUmFuZ2UuZnJvbURhdGU7XHJcbiAgICB0aGlzLnRvRGF0ZSA9IHRoaXMuZGVmYXVsdERhdGVSYW5nZS50b0RhdGU7XHJcbiAgICB0aGlzLl9kaXNwbGF5UmFuZ2UgPSB0aGlzLmNyZWF0ZURhdGVSYW5nZSgpO1xyXG4gIH1cclxuXHJcbiAgcmVzZXREYXRlUmFuZ2UoKSB7XHJcbiAgICB0aGlzLmZyb21EYXRlID0gbmV3IERhdGUoKTtcclxuICAgIHRoaXMudG9EYXRlID0gbmV3IERhdGUoKTtcclxuICAgIHRoaXMuX2Rpc3BsYXlSYW5nZSA9IHRoaXMuY3JlYXRlRGF0ZVJhbmdlKCk7XHJcbiAgfVxyXG5cclxuICBnZW5lcmF0ZUludGVydmFsT3B0aW9uSXRlbXMoaXRlbUxpc3Q6IHN0cmluZ1tdKSB7XHJcbiAgICB0aGlzLmludGVydmFsTGlzdCA9IGZ1bGxJbnRlcnZhbExpc3QuZmlsdGVyKGl0ZW0gPT5cclxuICAgICAgaXRlbUxpc3QuaW5jbHVkZXMoaXRlbS5kaXNwbGF5TmFtZSlcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBoaWRlKGNsb3NlRHJvcGRvd246IGJvb2xlYW4pIHtcclxuICAgIGlmIChjbG9zZURyb3Bkb3duKSB7XHJcbiAgICAgIHRoaXMuZHJvcGRvd24uaGlkZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdG9nZ2xlKCkge1xyXG4gICAgdGhpcy5kcm9wZG93bi50b2dnbGUoKTtcclxuICB9XHJcblxyXG4gIG9uQ3VzdG9tRGF0ZVNlbGVjdGlvbihuZXdDdXN0b21EYXRlOiBEYXRlW10pIHtcclxuICAgIC8vIGRvIG5vdCB1cGRhdGUgcmFuZ2UgaWYgdW5kZWZpbmVkLCBudWxsW10sIGZyb20gPiB0b1xyXG4gICAgaWYgKFxyXG4gICAgICAhbmV3Q3VzdG9tRGF0ZSB8fFxyXG4gICAgICBuZXdDdXN0b21EYXRlWzBdID09IG51bGwgfHxcclxuICAgICAgbmV3Q3VzdG9tRGF0ZVsxXSA9PSBudWxsIHx8XHJcbiAgICAgIG5ld0N1c3RvbURhdGVbMF0gPiBuZXdDdXN0b21EYXRlWzFdXHJcbiAgICApIHtcclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5mcm9tRGF0ZSA9IG5ld0N1c3RvbURhdGVbMF07XHJcbiAgICB0aGlzLnRvRGF0ZSA9IG5ld0N1c3RvbURhdGVbMV07XHJcbiAgICB0aGlzLl9kaXNwbGF5UmFuZ2UgPSB0aGlzLmNyZWF0ZURhdGVSYW5nZSgpO1xyXG4gICAgdGhpcy5vbkRhdGVSYW5nZVNlbGVjdGVkLmVtaXQoPERhdGVSYW5nZT57XHJcbiAgICAgIGZyb21EYXRlOiB0aGlzLmZyb21EYXRlLFxyXG4gICAgICB0b0RhdGU6IHRoaXMudG9EYXRlXHJcbiAgICB9KTtcclxuICAgIHRoaXMuY3VycmVudFRhYiA9IERhdGVTZWxlY3Rpb25UeXBlLmN1c3RvbTtcclxuICAgIHRoaXMuc2VsZWN0ZWRJbnRlcnZhbCA9IG51bGw7XHJcbiAgfVxyXG5cclxuICBvbkludGVydmFsU2VsZWN0aW9uKHNlbGVjdGVkSXRlbTogSW50ZXJ2YWxJdGVtKSB7XHJcbiAgICBpZiAoc2VsZWN0ZWRJdGVtKSB7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRJbnRlcnZhbCA9IHNlbGVjdGVkSXRlbTtcclxuICAgICAgY29uc3QgdG9kYXk6IERhdGUgPSBuZXcgRGF0ZSgpO1xyXG4gICAgICBsZXQgY2FsY3VsYXRlZERhdGU6IERhdGU7XHJcbiAgICAgIGlmIChzZWxlY3RlZEl0ZW0udW5pdCA9PT0gJ2RheScpIHtcclxuICAgICAgICBjYWxjdWxhdGVkRGF0ZSA9IG5ldyBEYXRlKFxyXG4gICAgICAgICAgdG9kYXkuZ2V0RnVsbFllYXIoKSxcclxuICAgICAgICAgIHRvZGF5LmdldE1vbnRoKCksXHJcbiAgICAgICAgICB0b2RheS5nZXREYXRlKCkgKyBzZWxlY3RlZEl0ZW0uY291bnRcclxuICAgICAgICApO1xyXG4gICAgICB9IGVsc2UgaWYgKHNlbGVjdGVkSXRlbS51bml0ID09PSAnbW9udGgnKSB7XHJcbiAgICAgICAgY2FsY3VsYXRlZERhdGUgPSBuZXcgRGF0ZShcclxuICAgICAgICAgIHRvZGF5LmdldEZ1bGxZZWFyKCksXHJcbiAgICAgICAgICB0b2RheS5nZXRNb250aCgpICsgc2VsZWN0ZWRJdGVtLmNvdW50LFxyXG4gICAgICAgICAgdG9kYXkuZ2V0RGF0ZSgpXHJcbiAgICAgICAgKTtcclxuICAgICAgfSBlbHNlIGlmIChzZWxlY3RlZEl0ZW0udW5pdCA9PT0gJ3llYXInKSB7XHJcbiAgICAgICAgY2FsY3VsYXRlZERhdGUgPSBuZXcgRGF0ZShcclxuICAgICAgICAgIHRvZGF5LmdldEZ1bGxZZWFyKCkgKyBzZWxlY3RlZEl0ZW0uY291bnQsXHJcbiAgICAgICAgICB0b2RheS5nZXRNb250aCgpLFxyXG4gICAgICAgICAgdG9kYXkuZ2V0RGF0ZSgpXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKGNhbGN1bGF0ZWREYXRlID49IHRvZGF5KSB7XHJcbiAgICAgICAgdGhpcy5mcm9tRGF0ZSA9IHRvZGF5O1xyXG4gICAgICAgIHRoaXMudG9EYXRlID0gY2FsY3VsYXRlZERhdGU7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5mcm9tRGF0ZSA9IGNhbGN1bGF0ZWREYXRlO1xyXG4gICAgICAgIHRoaXMudG9EYXRlID0gdG9kYXk7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5fZGlzcGxheVJhbmdlID0gdGhpcy5jcmVhdGVEYXRlUmFuZ2UoKTtcclxuXHJcbiAgICAgIHRoaXMub25EYXRlUmFuZ2VTZWxlY3RlZC5lbWl0KDxEYXRlUmFuZ2U+e1xyXG4gICAgICAgIGZyb21EYXRlOiB0aGlzLmZyb21EYXRlLFxyXG4gICAgICAgIHRvRGF0ZTogdGhpcy50b0RhdGVcclxuICAgICAgfSk7XHJcbiAgICAgIHRoaXMuY3VycmVudFRhYiA9IERhdGVTZWxlY3Rpb25UeXBlLmludGVydmFsO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY3JlYXRlRGF0ZVJhbmdlKCk6IHN0cmluZyB7XHJcbiAgICBjb25zdCBmcm9tRGF0ZVN0ciA9IHRoaXMuZGF0ZVBpcGUudHJhbnNmb3JtKHRoaXMuZnJvbURhdGUsIHRoaXMuZGF0ZUZvcm1hdCk7XHJcbiAgICBjb25zdCB0b0RhdGVTdHIgPSB0aGlzLmRhdGVQaXBlLnRyYW5zZm9ybSh0aGlzLnRvRGF0ZSwgdGhpcy5kYXRlRm9ybWF0KTtcclxuICAgIGlmIChmcm9tRGF0ZVN0ciA9PT0gdG9EYXRlU3RyKSB7XHJcbiAgICAgIHJldHVybiBmcm9tRGF0ZVN0cjtcclxuICAgIH1cclxuICAgIHJldHVybiBgJHtmcm9tRGF0ZVN0cn0gLSAke3RvRGF0ZVN0cn1gO1xyXG4gIH1cclxufVxyXG4iLCI8ZGl2XHJcbiAgY2xhc3M9XCJoeC1kcm9wZG93blwiXHJcbiAgaHhEcm9wZG93blxyXG4gICNkcm9wZG93bj1cImh4LWRyb3Bkb3duXCJcclxuICBbYXV0b0Nsb3NlXT1cImF1dG9DbG9zZVwiXHJcbiAgW2lzRGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxyXG4gIFtwbGFjZW1lbnRdPVwicGxhY2VtZW50XCJcclxuPlxyXG4gIDxidXR0b24gY2xhc3M9XCJoeC1idXR0b25cIiBoeERyb3Bkb3duVG9nZ2xlIHR5cGU9XCJidXR0b25cIj5cclxuICAgIDxzcGFuPlxyXG4gICAgICA8c3BhbiBjbGFzcz1cImlzLXRleHQtd2VpZ2h0LWxpZ2h0XCIgKm5nSWY9XCIhIXBsYWNlaG9sZGVyXCI+XHJcbiAgICAgICAge3sgcGxhY2Vob2xkZXIgfX06IFxyXG4gICAgICA8L3NwYW4+XHJcbiAgICAgIDxzcGFuIGNsYXNzPVwiaXMtdGV4dC13ZWlnaHQtYm9sZGVyXCI+e3sgX2Rpc3BsYXlSYW5nZSB9fTwvc3Bhbj5cclxuICAgIDwvc3Bhbj5cclxuICAgIDxzcGFuIGNsYXNzPVwiaHgtaWNvbi1jb250cm9sXCIgKm5nSWY9XCJzaG93Q2FyZXREb3duXCI+XHJcbiAgICAgIDxpIGNsYXNzPVwiaWNvbiBpY29uLWNhcmV0LWRvd25cIj48L2k+XHJcbiAgICA8L3NwYW4+XHJcbiAgPC9idXR0b24+XHJcbiAgPGRpdiBcclxuICAgIGNsYXNzPVwiaHgtZHJvcGRvd24tbWVudSBkcm9wZG93bi1tZW51LXdpZGVyIHB5LTAgcHgtMFwiIFxyXG4gICAgKmh4RHJvcGRvd25NZW51XHJcbiAgPlxyXG4gICAgPGRpdiBjbGFzcz1cImh4YS10YWJzXCIgKm5nSWY9XCJzaG93VGFiXCI+XHJcbiAgICAgIDxoeC10YWJzZXQgW2p1c3RpZmllZF09XCJ0cnVlXCIgY29udGVudEN1c3RvbUNsYXNzPVwicGEtMFwiPlxyXG4gICAgICAgIDxoeC10YWJcclxuICAgICAgICAgIGhlYWRpbmc9XCJJTlRFUlZBTFwiXHJcbiAgICAgICAgICBbYWN0aXZlXT1cImN1cnJlbnRUYWIgPT09IERhdGVTZWxlY3Rpb25UeXBlLmludGVydmFsXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICA8aHhhLWRhdGUtcmFuZ2UtcGlja2VyLWludGVydmFsXHJcbiAgICAgICAgICAgIFtpbnRlcnZhbE9wdGlvbkxpc3RdPVwiaW50ZXJ2YWxMaXN0XCJcclxuICAgICAgICAgICAgW2N1cnJlbnRTZWxlY3RlZEludGVydmFsXT1cInNlbGVjdGVkSW50ZXJ2YWxcIlxyXG4gICAgICAgICAgICAobmV3U2VsZWN0ZWRJbnRlcnZhbCk9XCJvbkludGVydmFsU2VsZWN0aW9uKCRldmVudClcIlxyXG4gICAgICAgICAgICAoY2xvc2VEcm9wZG93bik9XCJoaWRlKCRldmVudClcIlxyXG4gICAgICAgICAgPjwvaHhhLWRhdGUtcmFuZ2UtcGlja2VyLWludGVydmFsPlxyXG4gICAgICAgIDwvaHgtdGFiPlxyXG4gICAgICAgIDxoeC10YWJcclxuICAgICAgICAgIGhlYWRpbmc9XCJDVVNUT01cIlxyXG4gICAgICAgICAgW2FjdGl2ZV09XCJjdXJyZW50VGFiID09PSBEYXRlU2VsZWN0aW9uVHlwZS5jdXN0b21cIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIDxoeGEtZGF0ZS1yYW5nZS1waWNrZXItY3VzdG9tXHJcbiAgICAgICAgICAgIFtjdXJyZW50RnJvbURhdGVdPVwiZnJvbURhdGVcIlxyXG4gICAgICAgICAgICBbY3VycmVudFRvRGF0ZV09XCJ0b0RhdGVcIlxyXG4gICAgICAgICAgICBbZGF0ZUZvcm1hdF09XCJkYXRlRm9ybWF0XCJcclxuICAgICAgICAgICAgKG5ld1NlbGVjdGVkQ3VzdG9tRGF0ZSk9XCJvbkN1c3RvbURhdGVTZWxlY3Rpb24oJGV2ZW50KVwiXHJcbiAgICAgICAgICAgIChjbG9zZURyb3Bkb3duKT1cImhpZGUoJGV2ZW50KVwiXHJcbiAgICAgICAgICA+PC9oeGEtZGF0ZS1yYW5nZS1waWNrZXItY3VzdG9tPlxyXG4gICAgICAgIDwvaHgtdGFiPlxyXG4gICAgICA8L2h4LXRhYnNldD5cclxuICAgIDwvZGl2PlxyXG4gICAgPGRpdiBcclxuICAgICAgKm5nSWY9XCIhc2hvd1RhYiAmJiBzaG93SW50ZXJ2YWxPbmx5XCIgXHJcbiAgICAgIGNsYXNzPVwiaW50ZXJuYWwtY3VzdG9tLXRhYiBwYS0wXCJcclxuICAgID5cclxuICAgICAgPGh4YS1kYXRlLXJhbmdlLXBpY2tlci1pbnRlcnZhbFxyXG4gICAgICAgIFtpbnRlcnZhbE9wdGlvbkxpc3RdPVwiaW50ZXJ2YWxMaXN0XCJcclxuICAgICAgICBbY3VycmVudFNlbGVjdGVkSW50ZXJ2YWxdPVwic2VsZWN0ZWRJbnRlcnZhbFwiXHJcbiAgICAgICAgKG5ld1NlbGVjdGVkSW50ZXJ2YWwpPVwib25JbnRlcnZhbFNlbGVjdGlvbigkZXZlbnQpXCJcclxuICAgICAgICAoY2xvc2VEcm9wZG93bik9XCJoaWRlKCRldmVudClcIlxyXG4gICAgICA+PC9oeGEtZGF0ZS1yYW5nZS1waWNrZXItaW50ZXJ2YWw+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxkaXZcclxuICAgICAgKm5nSWY9XCIhc2hvd1RhYiAmJiBzaG93Q3VzdG9tT25seVwiXHJcbiAgICAgIGNsYXNzPVwiaW50ZXJuYWwtY3VzdG9tLXRhYiBweC0wIHBiLTBcIlxyXG4gICAgPlxyXG4gICAgICA8aHhhLWRhdGUtcmFuZ2UtcGlja2VyLWN1c3RvbVxyXG4gICAgICAgIFtjdXJyZW50RnJvbURhdGVdPVwiZnJvbURhdGVcIlxyXG4gICAgICAgIFtjdXJyZW50VG9EYXRlXT1cInRvRGF0ZVwiXHJcbiAgICAgICAgW2RhdGVGb3JtYXRdPVwiZGF0ZUZvcm1hdFwiXHJcbiAgICAgICAgKG5ld1NlbGVjdGVkQ3VzdG9tRGF0ZSk9XCJvbkN1c3RvbURhdGVTZWxlY3Rpb24oJGV2ZW50KVwiXHJcbiAgICAgICAgKGNsb3NlRHJvcGRvd24pPVwiaGlkZSgkZXZlbnQpXCJcclxuICAgICAgPjwvaHhhLWRhdGUtcmFuZ2UtcGlja2VyLWN1c3RvbT5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG48L2Rpdj5cclxuIl19