UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

73 lines 23.6 kB
import { Component, EventEmitter, Input, Output, inject } from '@angular/core'; import { FormControl, FormGroup, FormsModule, ReactiveFormsModule } from '@angular/forms'; import { gettext } from '../i18n'; import { BsDropdownModule } from 'ngx-bootstrap/dropdown'; import { CdkTrapFocus } from '@angular/cdk/a11y'; import { IconDirective } from '../common/icon.directive'; import { NgIf, DatePipe } from '@angular/common'; import { FormGroupComponent } from '../forms/form-group.component'; import { C8yTranslateDirective } from '../i18n/c8y-translate.directive'; import { RequiredInputPlaceholderDirective } from '../forms/required-input-placeholder.directive'; import { BsDatepickerModule } from 'ngx-bootstrap/datepicker'; import { C8yTranslatePipe } from '../i18n/c8y-translate.pipe'; import { DateFormatService } from '../common/date-format.service'; import * as i0 from "@angular/core"; import * as i1 from "ngx-bootstrap/dropdown"; import * as i2 from "@angular/forms"; import * as i3 from "ngx-bootstrap/datepicker"; export class DatePickerComponent { constructor() { this.onDateSelected = new EventEmitter(); this.placeholder = gettext('Filter by date'); this.dateFormatService = inject(DateFormatService); } ngOnInit() { if (!this.dateInputFormat) { this.dateInputFormat = this.dateFormatService.getDateFormat(); } this.fgDatePicker = new FormGroup({ dateFrom: new FormControl(), dateTo: new FormControl() }); } filter() { this.onDateSelected.emit(this.fgDatePicker.value); this.dateFrom = this.fgDatePicker.get('dateFrom').value; this.dateTo = this.fgDatePicker.get('dateTo').value; } clearFilter() { this.fgDatePicker.setValue({ dateFrom: null, dateTo: null }); this.onDateSelected.emit(null); this.dateFrom = null; this.dateTo = null; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DatePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DatePickerComponent, isStandalone: true, selector: "c8y-date-picker", inputs: { placeholder: "placeholder", dateInputFormat: "dateInputFormat" }, outputs: { onDateSelected: "onDateSelected" }, ngImport: i0, template: "<div\n dropdown\n class=\"c8y-child-assets-selector dropdown\"\n #datefilter=\"bs-dropdown\"\n [insideClick]=\"true\"\n placement=\"bottom left\"\n [cdkTrapFocus]=\"datefilter.isOpen\"\n >\n <button\n id=\"date-range\"\n dropdownToggle\n title=\"{{ 'Date filter' | translate }}\"\n type=\"button\"\n class=\"btn dropdown-toggle d-flex a-i-center c8y-dropdown\"\n >\n <i c8yIcon=\"calendar-o\" class=\"m-r-4 text-primary\"></i>\n <span class=\"text-truncate\">\n <span *ngIf=\"dateFrom\">\n <span class=\"text-label-small\">{{ 'From`date`' | translate }}</span>\n {{ dateFrom | date }}\n </span>\n <span *ngIf=\"dateTo\">\n <span class=\"text-label-small\">{{ 'To`date`' | translate }}</span>\n {{ dateTo | date }}\n </span>\n <em *ngIf=\"!dateFrom && !dateTo\" class=\"text-muted\">\n {{ placeholder }}\n </em>\n </span>\n </button>\n\n <form [formGroup]=\"fgDatePicker\"\n id=\"dropdown-date-range\"\n *dropdownMenu\n class=\"dropdown-menu\">\n <div class=\"dropdown-form p-b-0\">\n <c8y-form-group class=\"form-group-sm\">\n <label for=\"dateFrom\" class=\"text-medium m-b-4\" translate>Date from</label>\n <div class=\"form-group datepicker d-block m-b-0\">\n <input\n id=\"dateFrom\"\n formControlName=\"dateFrom\"\n class=\"form-control fit-w text-left\"\n placeholder=\"{{ 'Date from' | translate }}\"\n bsDatepicker\n [maxDate]=\"dateTo\"\n (bsValueChange)=\"dateFrom = $event\"\n [bsConfig]=\"{ customTodayClass: 'today', returnFocusToInput: true, dateInputFormat: dateInputFormat }\"\n />\n </div>\n </c8y-form-group>\n <c8y-form-group class=\"form-group form-group-sm \">\n <label for=\"dateTo\" translate>Date to</label>\n <div class=\"form-group datepicker m-l-0 d-block m-b-0 \">\n <input\n name=\"dateTo\"\n id=\"dateTo\"\n formControlName=\"dateTo\"\n class=\"form-control fit-w text-left\"\n placeholder=\"{{ 'Date to' | translate }}\"\n bsDatepicker\n [minDate]=\"dateFrom\"\n (bsValueChange)=\"dateTo = $event\"\n [bsConfig]=\"{ customTodayClass: 'today', returnFocusToInput: true, dateInputFormat: dateInputFormat }\"\n />\n </div>\n </c8y-form-group>\n </div>\n <div class=\"p-16 d-flex separator-top gap-8\">\n <button\n title=\"{{ 'Clear selection' | translate }}\"\n type=\"button\"\n class=\"btn btn-default btn-sm flex-grow\"\n (click)=\"clearFilter(); datefilter.isOpen = !datefilter.isOpen\"\n >\n {{ 'Clear`selection`' | translate }}\n </button>\n <button\n [disabled]=\"!fgDatePicker.get('dateFrom').value && !fgDatePicker.get('dateTo').value\"\n title=\"{{ 'Apply selection' | translate }}\"\n type=\"submit\"\n class=\"btn btn-primary btn-sm flex-grow\"\n (click)=\"filter(); datefilter.isOpen = !datefilter.isOpen\"\n >\n {{ 'Apply`selection`' | translate }}\n </button>\n </div>\n </form>\n</div>\n", dependencies: [{ kind: "ngmodule", type: BsDropdownModule }, { kind: "directive", type: i1.BsDropdownMenuDirective, selector: "[bsDropdownMenu],[dropdownMenu]", exportAs: ["bs-dropdown-menu"] }, { kind: "directive", type: i1.BsDropdownToggleDirective, selector: "[bsDropdownToggle],[dropdownToggle]", exportAs: ["bs-dropdown-toggle"] }, { kind: "directive", type: i1.BsDropdownDirective, selector: "[bsDropdown], [dropdown]", inputs: ["placement", "triggers", "container", "dropup", "autoClose", "isAnimated", "insideClick", "isDisabled", "isOpen"], outputs: ["isOpenChange", "onShown", "onHidden"], exportAs: ["bs-dropdown"] }, { kind: "directive", type: CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "directive", type: IconDirective, selector: "[c8yIcon]", inputs: ["c8yIcon"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: FormGroupComponent, selector: "c8y-form-group", inputs: ["hasError", "hasWarning", "hasSuccess", "novalidation", "status"] }, { kind: "directive", type: C8yTranslateDirective, selector: "[translate],[ngx-translate]" }, { kind: "directive", type: RequiredInputPlaceholderDirective, selector: "input[required], input[formControlName]" }, { kind: "ngmodule", type: BsDatepickerModule }, { kind: "directive", type: i3.BsDatepickerDirective, selector: "[bsDatepicker]", inputs: ["placement", "triggers", "outsideClick", "container", "outsideEsc", "isDisabled", "minDate", "maxDate", "minMode", "daysDisabled", "datesDisabled", "datesEnabled", "dateCustomClasses", "dateTooltipTexts", "isOpen", "bsValue", "bsConfig"], outputs: ["onShown", "onHidden", "bsValueChange"], exportAs: ["bsDatepicker"] }, { kind: "directive", type: i3.BsDatepickerInputDirective, selector: "input[bsDatepicker]" }, { kind: "pipe", type: DatePipe, name: "date" }, { kind: "pipe", type: C8yTranslatePipe, name: "translate" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DatePickerComponent, decorators: [{ type: Component, args: [{ selector: 'c8y-date-picker', standalone: true, imports: [ BsDropdownModule, CdkTrapFocus, IconDirective, NgIf, FormsModule, ReactiveFormsModule, FormGroupComponent, C8yTranslateDirective, RequiredInputPlaceholderDirective, BsDatepickerModule, DatePipe, C8yTranslatePipe ], template: "<div\n dropdown\n class=\"c8y-child-assets-selector dropdown\"\n #datefilter=\"bs-dropdown\"\n [insideClick]=\"true\"\n placement=\"bottom left\"\n [cdkTrapFocus]=\"datefilter.isOpen\"\n >\n <button\n id=\"date-range\"\n dropdownToggle\n title=\"{{ 'Date filter' | translate }}\"\n type=\"button\"\n class=\"btn dropdown-toggle d-flex a-i-center c8y-dropdown\"\n >\n <i c8yIcon=\"calendar-o\" class=\"m-r-4 text-primary\"></i>\n <span class=\"text-truncate\">\n <span *ngIf=\"dateFrom\">\n <span class=\"text-label-small\">{{ 'From`date`' | translate }}</span>\n {{ dateFrom | date }}\n </span>\n <span *ngIf=\"dateTo\">\n <span class=\"text-label-small\">{{ 'To`date`' | translate }}</span>\n {{ dateTo | date }}\n </span>\n <em *ngIf=\"!dateFrom && !dateTo\" class=\"text-muted\">\n {{ placeholder }}\n </em>\n </span>\n </button>\n\n <form [formGroup]=\"fgDatePicker\"\n id=\"dropdown-date-range\"\n *dropdownMenu\n class=\"dropdown-menu\">\n <div class=\"dropdown-form p-b-0\">\n <c8y-form-group class=\"form-group-sm\">\n <label for=\"dateFrom\" class=\"text-medium m-b-4\" translate>Date from</label>\n <div class=\"form-group datepicker d-block m-b-0\">\n <input\n id=\"dateFrom\"\n formControlName=\"dateFrom\"\n class=\"form-control fit-w text-left\"\n placeholder=\"{{ 'Date from' | translate }}\"\n bsDatepicker\n [maxDate]=\"dateTo\"\n (bsValueChange)=\"dateFrom = $event\"\n [bsConfig]=\"{ customTodayClass: 'today', returnFocusToInput: true, dateInputFormat: dateInputFormat }\"\n />\n </div>\n </c8y-form-group>\n <c8y-form-group class=\"form-group form-group-sm \">\n <label for=\"dateTo\" translate>Date to</label>\n <div class=\"form-group datepicker m-l-0 d-block m-b-0 \">\n <input\n name=\"dateTo\"\n id=\"dateTo\"\n formControlName=\"dateTo\"\n class=\"form-control fit-w text-left\"\n placeholder=\"{{ 'Date to' | translate }}\"\n bsDatepicker\n [minDate]=\"dateFrom\"\n (bsValueChange)=\"dateTo = $event\"\n [bsConfig]=\"{ customTodayClass: 'today', returnFocusToInput: true, dateInputFormat: dateInputFormat }\"\n />\n </div>\n </c8y-form-group>\n </div>\n <div class=\"p-16 d-flex separator-top gap-8\">\n <button\n title=\"{{ 'Clear selection' | translate }}\"\n type=\"button\"\n class=\"btn btn-default btn-sm flex-grow\"\n (click)=\"clearFilter(); datefilter.isOpen = !datefilter.isOpen\"\n >\n {{ 'Clear`selection`' | translate }}\n </button>\n <button\n [disabled]=\"!fgDatePicker.get('dateFrom').value && !fgDatePicker.get('dateTo').value\"\n title=\"{{ 'Apply selection' | translate }}\"\n type=\"submit\"\n class=\"btn btn-primary btn-sm flex-grow\"\n (click)=\"filter(); datefilter.isOpen = !datefilter.isOpen\"\n >\n {{ 'Apply`selection`' | translate }}\n </button>\n </div>\n </form>\n</div>\n" }] }], propDecorators: { onDateSelected: [{ type: Output }], placeholder: [{ type: Input }], dateInputFormat: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1waWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vY29yZS9kYXRlLXBpY2tlci9kYXRlLXBpY2tlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9jb3JlL2RhdGUtcGlja2VyL2RhdGUtcGlja2VyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFVLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3ZGLE9BQU8sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTFGLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDbEMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDMUQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQ25FLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxpQ0FBaUMsRUFBRSxNQUFNLCtDQUErQyxDQUFDO0FBQ2xHLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzlELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzlELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLCtCQUErQixDQUFDOzs7OztBQXFCbEUsTUFBTSxPQUFPLG1CQUFtQjtJQW5CaEM7UUFvQlksbUJBQWMsR0FBOEIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUV6RSxnQkFBVyxHQUFHLE9BQU8sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBUWpDLHNCQUFpQixHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0tBMkJ2RDtJQXpCQyxRQUFRO1FBQ04sSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUMxQixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNoRSxDQUFDO1FBQ0QsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLFNBQVMsQ0FBQztZQUNoQyxRQUFRLEVBQUUsSUFBSSxXQUFXLEVBQUU7WUFDM0IsTUFBTSxFQUFFLElBQUksV0FBVyxFQUFFO1NBQzFCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxNQUFNO1FBQ0osSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNsRCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUN4RCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUN0RCxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDO1lBQ3pCLFFBQVEsRUFBRSxJQUFJO1lBQ2QsTUFBTSxFQUFFLElBQUk7U0FDYixDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMvQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztRQUNyQixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztJQUNyQixDQUFDOytHQXJDVSxtQkFBbUI7bUdBQW5CLG1CQUFtQixzTUNsQ2hDLCtxR0F5RkEsMkNEckVJLGdCQUFnQix1bEJBQ2hCLFlBQVksNElBQ1osYUFBYSwyRUFDYixJQUFJLDRGQUNKLFdBQVcsMnBCQUNYLG1CQUFtQixnVkFDbkIsa0JBQWtCLHVJQUNsQixxQkFBcUIsd0VBQ3JCLGlDQUFpQyxtRkFDakMsa0JBQWtCLGloQkFDbEIsUUFBUSx3Q0FDUixnQkFBZ0I7OzRGQUdQLG1CQUFtQjtrQkFuQi9CLFNBQVM7K0JBQ0UsaUJBQWlCLGNBRWYsSUFBSSxXQUNQO3dCQUNQLGdCQUFnQjt3QkFDaEIsWUFBWTt3QkFDWixhQUFhO3dCQUNiLElBQUk7d0JBQ0osV0FBVzt3QkFDWCxtQkFBbUI7d0JBQ25CLGtCQUFrQjt3QkFDbEIscUJBQXFCO3dCQUNyQixpQ0FBaUM7d0JBQ2pDLGtCQUFrQjt3QkFDbEIsUUFBUTt3QkFDUixnQkFBZ0I7cUJBQ2pCOzhCQUdTLGNBQWM7c0JBQXZCLE1BQU07Z0JBRVAsV0FBVztzQkFEVixLQUFLO2dCQUdOLGVBQWU7c0JBRGQsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBPbkluaXQsIElucHV0LCBPdXRwdXQsIGluamVjdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUNvbnRyb2wsIEZvcm1Hcm91cCwgRm9ybXNNb2R1bGUsIFJlYWN0aXZlRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBQaWNrZWREYXRlcyB9IGZyb20gJy4vZGF0ZS1waWNrZXIubW9kZWwnO1xuaW1wb3J0IHsgZ2V0dGV4dCB9IGZyb20gJy4uL2kxOG4nO1xuaW1wb3J0IHsgQnNEcm9wZG93bk1vZHVsZSB9IGZyb20gJ25neC1ib290c3RyYXAvZHJvcGRvd24nO1xuaW1wb3J0IHsgQ2RrVHJhcEZvY3VzIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2ExMXknO1xuaW1wb3J0IHsgSWNvbkRpcmVjdGl2ZSB9IGZyb20gJy4uL2NvbW1vbi9pY29uLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBOZ0lmLCBEYXRlUGlwZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBGb3JtR3JvdXBDb21wb25lbnQgfSBmcm9tICcuLi9mb3Jtcy9mb3JtLWdyb3VwLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBDOHlUcmFuc2xhdGVEaXJlY3RpdmUgfSBmcm9tICcuLi9pMThuL2M4eS10cmFuc2xhdGUuZGlyZWN0aXZlJztcbmltcG9ydCB7IFJlcXVpcmVkSW5wdXRQbGFjZWhvbGRlckRpcmVjdGl2ZSB9IGZyb20gJy4uL2Zvcm1zL3JlcXVpcmVkLWlucHV0LXBsYWNlaG9sZGVyLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBCc0RhdGVwaWNrZXJNb2R1bGUgfSBmcm9tICduZ3gtYm9vdHN0cmFwL2RhdGVwaWNrZXInO1xuaW1wb3J0IHsgQzh5VHJhbnNsYXRlUGlwZSB9IGZyb20gJy4uL2kxOG4vYzh5LXRyYW5zbGF0ZS5waXBlJztcbmltcG9ydCB7IERhdGVGb3JtYXRTZXJ2aWNlIH0gZnJvbSAnLi4vY29tbW9uL2RhdGUtZm9ybWF0LnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktZGF0ZS1waWNrZXInLFxuICB0ZW1wbGF0ZVVybDogJy4vZGF0ZS1waWNrZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQnNEcm9wZG93bk1vZHVsZSxcbiAgICBDZGtUcmFwRm9jdXMsXG4gICAgSWNvbkRpcmVjdGl2ZSxcbiAgICBOZ0lmLFxuICAgIEZvcm1zTW9kdWxlLFxuICAgIFJlYWN0aXZlRm9ybXNNb2R1bGUsXG4gICAgRm9ybUdyb3VwQ29tcG9uZW50LFxuICAgIEM4eVRyYW5zbGF0ZURpcmVjdGl2ZSxcbiAgICBSZXF1aXJlZElucHV0UGxhY2Vob2xkZXJEaXJlY3RpdmUsXG4gICAgQnNEYXRlcGlja2VyTW9kdWxlLFxuICAgIERhdGVQaXBlLFxuICAgIEM4eVRyYW5zbGF0ZVBpcGVcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBEYXRlUGlja2VyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQE91dHB1dCgpIG9uRGF0ZVNlbGVjdGVkOiBFdmVudEVtaXR0ZXI8UGlja2VkRGF0ZXM+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBASW5wdXQoKVxuICBwbGFjZWhvbGRlciA9IGdldHRleHQoJ0ZpbHRlciBieSBkYXRl4oCmJyk7XG4gIEBJbnB1dCgpXG4gIGRhdGVJbnB1dEZvcm1hdDogc3RyaW5nO1xuXG4gIGRhdGVGcm9tOiBzdHJpbmc7XG4gIGRhdGVUbzogc3RyaW5nO1xuICBmZ0RhdGVQaWNrZXI6IEZvcm1Hcm91cDtcblxuICBwcml2YXRlIGRhdGVGb3JtYXRTZXJ2aWNlID0gaW5qZWN0KERhdGVGb3JtYXRTZXJ2aWNlKTtcblxuICBuZ09uSW5pdCgpIHtcbiAgICBpZiAoIXRoaXMuZGF0ZUlucHV0Rm9ybWF0KSB7XG4gICAgICB0aGlzLmRhdGVJbnB1dEZvcm1hdCA9IHRoaXMuZGF0ZUZvcm1hdFNlcnZpY2UuZ2V0RGF0ZUZvcm1hdCgpO1xuICAgIH1cbiAgICB0aGlzLmZnRGF0ZVBpY2tlciA9IG5ldyBGb3JtR3JvdXAoe1xuICAgICAgZGF0ZUZyb206IG5ldyBGb3JtQ29udHJvbCgpLFxuICAgICAgZGF0ZVRvOiBuZXcgRm9ybUNvbnRyb2woKVxuICAgIH0pO1xuICB9XG5cbiAgZmlsdGVyKCkge1xuICAgIHRoaXMub25EYXRlU2VsZWN0ZWQuZW1pdCh0aGlzLmZnRGF0ZVBpY2tlci52YWx1ZSk7XG4gICAgdGhpcy5kYXRlRnJvbSA9IHRoaXMuZmdEYXRlUGlja2VyLmdldCgnZGF0ZUZyb20nKS52YWx1ZTtcbiAgICB0aGlzLmRhdGVUbyA9IHRoaXMuZmdEYXRlUGlja2VyLmdldCgnZGF0ZVRvJykudmFsdWU7XG4gIH1cblxuICBjbGVhckZpbHRlcigpIHtcbiAgICB0aGlzLmZnRGF0ZVBpY2tlci5zZXRWYWx1ZSh7XG4gICAgICBkYXRlRnJvbTogbnVsbCxcbiAgICAgIGRhdGVUbzogbnVsbFxuICAgIH0pO1xuICAgIHRoaXMub25EYXRlU2VsZWN0ZWQuZW1pdChudWxsKTtcbiAgICB0aGlzLmRhdGVGcm9tID0gbnVsbDtcbiAgICB0aGlzLmRhdGVUbyA9IG51bGw7XG4gIH1cbn1cbiIsIjxkaXZcbiAgZHJvcGRvd25cbiAgY2xhc3M9XCJjOHktY2hpbGQtYXNzZXRzLXNlbGVjdG9yIGRyb3Bkb3duXCJcbiAgI2RhdGVmaWx0ZXI9XCJicy1kcm9wZG93blwiXG4gIFtpbnNpZGVDbGlja109XCJ0cnVlXCJcbiAgcGxhY2VtZW50PVwiYm90dG9tIGxlZnRcIlxuICBbY2RrVHJhcEZvY3VzXT1cImRhdGVmaWx0ZXIuaXNPcGVuXCJcbiAgPlxuICA8YnV0dG9uXG4gICAgaWQ9XCJkYXRlLXJhbmdlXCJcbiAgICBkcm9wZG93blRvZ2dsZVxuICAgIHRpdGxlPVwie3sgJ0RhdGUgZmlsdGVyJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgdHlwZT1cImJ1dHRvblwiXG4gICAgY2xhc3M9XCJidG4gZHJvcGRvd24tdG9nZ2xlIGQtZmxleCBhLWktY2VudGVyIGM4eS1kcm9wZG93blwiXG4gID5cbiAgICA8aSBjOHlJY29uPVwiY2FsZW5kYXItb1wiIGNsYXNzPVwibS1yLTQgdGV4dC1wcmltYXJ5XCI+PC9pPlxuICAgIDxzcGFuIGNsYXNzPVwidGV4dC10cnVuY2F0ZVwiPlxuICAgICAgPHNwYW4gKm5nSWY9XCJkYXRlRnJvbVwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbGFiZWwtc21hbGxcIj57eyAnRnJvbWBkYXRlYCcgfCB0cmFuc2xhdGUgfX08L3NwYW4+XG4gICAgICAgIHt7IGRhdGVGcm9tIHwgZGF0ZSB9fVxuICAgICAgPC9zcGFuPlxuICAgICAgPHNwYW4gKm5nSWY9XCJkYXRlVG9cIj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LWxhYmVsLXNtYWxsXCI+e3sgJ1RvYGRhdGVgJyB8IHRyYW5zbGF0ZSB9fTwvc3Bhbj5cbiAgICAgICAge3sgZGF0ZVRvIHwgZGF0ZSB9fVxuICAgICAgPC9zcGFuPlxuICAgICAgPGVtICpuZ0lmPVwiIWRhdGVGcm9tICYmICFkYXRlVG9cIiBjbGFzcz1cInRleHQtbXV0ZWRcIj5cbiAgICAgICAge3sgcGxhY2Vob2xkZXIgfX1cbiAgICAgIDwvZW0+XG4gICAgPC9zcGFuPlxuICA8L2J1dHRvbj5cblxuICA8Zm9ybSBbZm9ybUdyb3VwXT1cImZnRGF0ZVBpY2tlclwiXG4gICAgaWQ9XCJkcm9wZG93bi1kYXRlLXJhbmdlXCJcbiAgICAqZHJvcGRvd25NZW51XG4gICAgY2xhc3M9XCJkcm9wZG93bi1tZW51XCI+XG4gICAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLWZvcm0gcC1iLTBcIj5cbiAgICAgIDxjOHktZm9ybS1ncm91cCBjbGFzcz1cImZvcm0tZ3JvdXAtc21cIj5cbiAgICAgICAgPGxhYmVsIGZvcj1cImRhdGVGcm9tXCIgY2xhc3M9XCJ0ZXh0LW1lZGl1bSBtLWItNFwiIHRyYW5zbGF0ZT5EYXRlIGZyb208L2xhYmVsPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCBkYXRlcGlja2VyIGQtYmxvY2sgbS1iLTBcIj5cbiAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgIGlkPVwiZGF0ZUZyb21cIlxuICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwiZGF0ZUZyb21cIlxuICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZml0LXcgdGV4dC1sZWZ0XCJcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwie3sgJ0RhdGUgZnJvbScgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgICAgICAgYnNEYXRlcGlja2VyXG4gICAgICAgICAgICBbbWF4RGF0ZV09XCJkYXRlVG9cIlxuICAgICAgICAgICAgKGJzVmFsdWVDaGFuZ2UpPVwiZGF0ZUZyb20gPSAkZXZlbnRcIlxuICAgICAgICAgICAgW2JzQ29uZmlnXT1cInsgY3VzdG9tVG9kYXlDbGFzczogJ3RvZGF5JywgcmV0dXJuRm9jdXNUb0lucHV0OiB0cnVlLCBkYXRlSW5wdXRGb3JtYXQ6IGRhdGVJbnB1dEZvcm1hdCB9XCJcbiAgICAgICAgICAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvYzh5LWZvcm0tZ3JvdXA+XG4gICAgICA8Yzh5LWZvcm0tZ3JvdXAgY2xhc3M9XCJmb3JtLWdyb3VwIGZvcm0tZ3JvdXAtc20gXCI+XG4gICAgICAgIDxsYWJlbCBmb3I9XCJkYXRlVG9cIiB0cmFuc2xhdGU+RGF0ZSB0bzwvbGFiZWw+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWdyb3VwIGRhdGVwaWNrZXIgbS1sLTAgZC1ibG9jayBtLWItMCBcIj5cbiAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgIG5hbWU9XCJkYXRlVG9cIlxuICAgICAgICAgICAgaWQ9XCJkYXRlVG9cIlxuICAgICAgICAgICAgZm9ybUNvbnRyb2xOYW1lPVwiZGF0ZVRvXCJcbiAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sIGZpdC13IHRleHQtbGVmdFwiXG4gICAgICAgICAgICBwbGFjZWhvbGRlcj1cInt7ICdEYXRlIHRvJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgICBic0RhdGVwaWNrZXJcbiAgICAgICAgICAgIFttaW5EYXRlXT1cImRhdGVGcm9tXCJcbiAgICAgICAgICAgIChic1ZhbHVlQ2hhbmdlKT1cImRhdGVUbyA9ICRldmVudFwiXG4gICAgICAgICAgICBbYnNDb25maWddPVwieyBjdXN0b21Ub2RheUNsYXNzOiAndG9kYXknLCByZXR1cm5Gb2N1c1RvSW5wdXQ6IHRydWUsIGRhdGVJbnB1dEZvcm1hdDogZGF0ZUlucHV0Rm9ybWF0IH1cIlxuICAgICAgICAgIC8+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9jOHktZm9ybS1ncm91cD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwicC0xNiBkLWZsZXggc2VwYXJhdG9yLXRvcCBnYXAtOFwiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICB0aXRsZT1cInt7ICdDbGVhciBzZWxlY3Rpb24nIHwgdHJhbnNsYXRlIH19XCJcbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0IGJ0bi1zbSBmbGV4LWdyb3dcIlxuICAgICAgICAoY2xpY2spPVwiY2xlYXJGaWx0ZXIoKTsgZGF0ZWZpbHRlci5pc09wZW4gPSAhZGF0ZWZpbHRlci5pc09wZW5cIlxuICAgICAgPlxuICAgICAgICB7eyAnQ2xlYXJgc2VsZWN0aW9uYCcgfCB0cmFuc2xhdGUgfX1cbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBbZGlzYWJsZWRdPVwiIWZnRGF0ZVBpY2tlci5nZXQoJ2RhdGVGcm9tJykudmFsdWUgJiYgIWZnRGF0ZVBpY2tlci5nZXQoJ2RhdGVUbycpLnZhbHVlXCJcbiAgICAgICAgdGl0bGU9XCJ7eyAnQXBwbHkgc2VsZWN0aW9uJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICAgIHR5cGU9XCJzdWJtaXRcIlxuICAgICAgICBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBidG4tc20gZmxleC1ncm93XCJcbiAgICAgICAgKGNsaWNrKT1cImZpbHRlcigpOyBkYXRlZmlsdGVyLmlzT3BlbiA9ICFkYXRlZmlsdGVyLmlzT3BlblwiXG4gICAgICA+XG4gICAgICAgIHt7ICdBcHBseWBzZWxlY3Rpb25gJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZm9ybT5cbjwvZGl2PlxuIl19