UNPKG

@uiowa/date-range-picker

Version:
108 lines 27 kB
import { Component, Input, Output, EventEmitter, ElementRef, ViewChild, ChangeDetectionStrategy, } from '@angular/core'; import { NgbDate, } from '@ng-bootstrap/ng-bootstrap'; import { DateRange } from '../models/date-range'; import * as i0 from "@angular/core"; import * as i1 from "@ng-bootstrap/ng-bootstrap"; export class DateRangePickerComponent { constructor(dateAdapter) { this.dateAdapter = dateAdapter; this.id = ''; this.dateRange = new DateRange(); this.disabled = false; this.dateRangeChange = new EventEmitter(); this.hoveredDate = null; this.fromDate = null; this.toDate = null; this.min = null; this.max = null; this.isInside = (date) => date.after(this.fromDate) && date.before(this.toDate); this.isFrom = (date) => date.equals(this.fromDate); this.isTo = (date) => date.equals(this.toDate); this.isDisabled = (date) => date.after(this.max) || date.before(this.min); this.isInFuture = (date) => date.after(this.toDate); } ngOnInit() { this.id = this.id || `date-range-picker-` + Math.random().toString(36).substring(4); this.fromDate = NgbDate.from(this.dateAdapter.fromModel(this.dateRange.start)); this.toDate = NgbDate.from(this.dateAdapter.fromModel(this.dateRange.end)); this.min = NgbDate.from(this.minDate ? this.dateAdapter.fromModel(this.minDate) : null); this.max = NgbDate.from(this.maxDate ? this.dateAdapter.fromModel(this.maxDate) : null); this.inputElRef.nativeElement.value = this.formatInputText(); if (this.fromDate) { this.dp.startDate = { year: this.fromDate.year, month: this.fromDate.month, }; } } ngOnChanges(changes) { if (changes['dateRange'] || changes['disabled']) { this.ngOnInit(); } } onDateChange(date, dp) { if (!this.fromDate && !this.toDate) { this.fromDate = date; this.dateRange.start = this.dateAdapter.toModel(this.fromDate); } else if (this.fromDate && !this.toDate && date.after(this.fromDate)) { this.toDate = date; this.dateRange.end = this.dateAdapter.toModel(this.toDate); dp.close(); } else { this.toDate = null; this.fromDate = date; this.dateRange.start = this.dateAdapter.toModel(this.fromDate); this.dateRange.end = null; } this.inputElRef.nativeElement.value = this.formatInputText(); this.dateRangeChange.emit(this.dateRange); } formatInputText() { if (this.dateRange.start && this.dateRange.end && DateRange.isValidDate(this.dateRange.start) && DateRange.isValidDate(this.dateRange.end)) { return `${this.dateRange.start.toLocaleDateString()} - ${this.dateRange.end.toLocaleDateString()}`; } return ''; } isHovered(date) { return (this.fromDate && !this.toDate && this.hoveredDate && date.after(this.fromDate) && date.before(this.hoveredDate)); } isWeekend(date) { const d = new Date(date.year, date.month - 1, date.day); return d.getDay() === 0 || d.getDay() === 6; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.5", ngImport: i0, type: DateRangePickerComponent, deps: [{ token: i1.NgbDateNativeAdapter }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.5", type: DateRangePickerComponent, selector: "date-range-picker", inputs: { id: "id", dateRange: "dateRange", minDate: "minDate", maxDate: "maxDate", disabled: "disabled" }, outputs: { dateRangeChange: "dateRangeChange" }, viewQueries: [{ propertyName: "inputElRef", first: true, predicate: ["dp"], descendants: true, read: ElementRef, static: true }, { propertyName: "dp", first: true, predicate: ["dp"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"input-group\">\r\n <input\r\n ngbDatepicker\r\n #dp=\"ngbDatepicker\"\r\n type=\"text\"\r\n class=\"form-control\"\r\n style=\"max-width: 208px; cursor: pointer\"\r\n readonly\r\n [attr.id]=\"id\"\r\n [disabled]=\"disabled\"\r\n [autoClose]=\"false\"\r\n [displayMonths]=\"2\"\r\n [dayTemplate]=\"t\"\r\n [showWeekNumbers]=\"false\"\r\n [markDisabled]=\"isDisabled\"\r\n [firstDayOfWeek]=\"7\"\r\n (click)=\"dp.toggle()\"\r\n (keydown.enter)=\"dp.toggle()\"\r\n (dateSelect)=\"onDateChange($event, dp)\"\r\n title=\"click to select a date range\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-outline-secondary d-flex align-items-center\"\r\n (click)=\"dp.toggle()\"\r\n [disabled]=\"disabled\"\r\n >\r\n <svg\r\n aria-hidden=\"true\"\r\n role=\"icon\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 448 512\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M148 288h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12zm108-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm96 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 96v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm96-260v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z\"\r\n ></path>\r\n </svg>\r\n </button>\r\n</div>\r\n\r\n<ng-template\r\n #t\r\n let-date=\"date\"\r\n let-focused=\"focused\"\r\n let-disabled=\"disabled\"\r\n let-currentMonth=\"currentMonth\"\r\n>\r\n <span\r\n class=\"custom-day\"\r\n [class.focused]=\"focused\"\r\n [class.range]=\"\r\n isFrom(date) || isTo(date) || isInside(date) || isHovered(date)\r\n \"\r\n [class.faded]=\"isHovered(date) || isInside(date)\"\r\n [class.weekend]=\"isWeekend(date)\"\r\n [class.disabled]=\"disabled\"\r\n [class.outside]=\"date.month !== currentMonth\"\r\n (mouseenter)=\"hoveredDate = date\"\r\n (mouseleave)=\"hoveredDate = null\"\r\n >\r\n {{ date.day }}\r\n </span>\r\n</ng-template>\r\n", styles: [".custom-day{text-align:center;padding:.185rem .25rem;display:inline-block;height:2rem;width:2rem}.custom-day.focused{background-color:#e6e6e6}.custom-day.range,.custom-day:hover{background-color:#0275d8;color:#fff}.custom-day.faded{background-color:#0275d880}.custom-day.weekend{color:#d81e1e}.custom-day.disabled{color:#c8cdd2}.custom-day.outside{opacity:.5}svg{width:1rem;height:1rem}.form-control[readonly]{background-color:#fdfdfd!important}\n"], dependencies: [{ kind: "directive", type: i1.NgbInputDatepicker, selector: "input[ngbDatepicker]", inputs: ["autoClose", "contentTemplate", "datepickerClass", "dayTemplate", "dayTemplateData", "displayMonths", "firstDayOfWeek", "footerTemplate", "markDisabled", "minDate", "maxDate", "navigation", "outsideDays", "placement", "popperOptions", "restoreFocus", "showWeekNumbers", "startDate", "container", "positionTarget", "weekdays", "disabled"], outputs: ["dateSelect", "navigate", "closed"], exportAs: ["ngbDatepicker"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.5", ngImport: i0, type: DateRangePickerComponent, decorators: [{ type: Component, args: [{ selector: 'date-range-picker', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"input-group\">\r\n <input\r\n ngbDatepicker\r\n #dp=\"ngbDatepicker\"\r\n type=\"text\"\r\n class=\"form-control\"\r\n style=\"max-width: 208px; cursor: pointer\"\r\n readonly\r\n [attr.id]=\"id\"\r\n [disabled]=\"disabled\"\r\n [autoClose]=\"false\"\r\n [displayMonths]=\"2\"\r\n [dayTemplate]=\"t\"\r\n [showWeekNumbers]=\"false\"\r\n [markDisabled]=\"isDisabled\"\r\n [firstDayOfWeek]=\"7\"\r\n (click)=\"dp.toggle()\"\r\n (keydown.enter)=\"dp.toggle()\"\r\n (dateSelect)=\"onDateChange($event, dp)\"\r\n title=\"click to select a date range\"\r\n />\r\n <button\r\n type=\"button\"\r\n class=\"btn btn-outline-secondary d-flex align-items-center\"\r\n (click)=\"dp.toggle()\"\r\n [disabled]=\"disabled\"\r\n >\r\n <svg\r\n aria-hidden=\"true\"\r\n role=\"icon\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n viewBox=\"0 0 448 512\"\r\n >\r\n <path\r\n fill=\"currentColor\"\r\n d=\"M148 288h-40c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v40c0 6.6-5.4 12-12 12zm108-12v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm96 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 96v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm-96 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm192 0v-40c0-6.6-5.4-12-12-12h-40c-6.6 0-12 5.4-12 12v40c0 6.6 5.4 12 12 12h40c6.6 0 12-5.4 12-12zm96-260v352c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h48V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h128V12c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h48c26.5 0 48 21.5 48 48zm-48 346V160H48v298c0 3.3 2.7 6 6 6h340c3.3 0 6-2.7 6-6z\"\r\n ></path>\r\n </svg>\r\n </button>\r\n</div>\r\n\r\n<ng-template\r\n #t\r\n let-date=\"date\"\r\n let-focused=\"focused\"\r\n let-disabled=\"disabled\"\r\n let-currentMonth=\"currentMonth\"\r\n>\r\n <span\r\n class=\"custom-day\"\r\n [class.focused]=\"focused\"\r\n [class.range]=\"\r\n isFrom(date) || isTo(date) || isInside(date) || isHovered(date)\r\n \"\r\n [class.faded]=\"isHovered(date) || isInside(date)\"\r\n [class.weekend]=\"isWeekend(date)\"\r\n [class.disabled]=\"disabled\"\r\n [class.outside]=\"date.month !== currentMonth\"\r\n (mouseenter)=\"hoveredDate = date\"\r\n (mouseleave)=\"hoveredDate = null\"\r\n >\r\n {{ date.day }}\r\n </span>\r\n</ng-template>\r\n", styles: [".custom-day{text-align:center;padding:.185rem .25rem;display:inline-block;height:2rem;width:2rem}.custom-day.focused{background-color:#e6e6e6}.custom-day.range,.custom-day:hover{background-color:#0275d8;color:#fff}.custom-day.faded{background-color:#0275d880}.custom-day.weekend{color:#d81e1e}.custom-day.disabled{color:#c8cdd2}.custom-day.outside{opacity:.5}svg{width:1rem;height:1rem}.form-control[readonly]{background-color:#fdfdfd!important}\n"] }] }], ctorParameters: () => [{ type: i1.NgbDateNativeAdapter }], propDecorators: { id: [{ type: Input }], dateRange: [{ type: Input }], minDate: [{ type: Input }], maxDate: [{ type: Input }], disabled: [{ type: Input }], dateRangeChange: [{ type: Output }], inputElRef: [{ type: ViewChild, args: ['dp', { read: ElementRef, static: true }] }], dp: [{ type: ViewChild, args: ['dp', { static: true }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1yYW5nZS1waWNrZXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdWlvd2EvZGF0ZS1yYW5nZS1waWNrZXIvc3JjL2xpYi9kYXRlLXJhbmdlLXBpY2tlci9kYXRlLXJhbmdlLXBpY2tlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy91aW93YS9kYXRlLXJhbmdlLXBpY2tlci9zcmMvbGliL2RhdGUtcmFuZ2UtcGlja2VyL2RhdGUtcmFuZ2UtcGlja2VyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxTQUFTLEVBRVQsS0FBSyxFQUNMLE1BQU0sRUFDTixZQUFZLEVBQ1osVUFBVSxFQUNWLFNBQVMsRUFHVCx1QkFBdUIsR0FDeEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUVMLE9BQU8sR0FFUixNQUFNLDRCQUE0QixDQUFDO0FBQ3BDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQzs7O0FBUWpELE1BQU0sT0FBTyx3QkFBd0I7SUF1Qm5DLFlBQTZCLFdBQWlDO1FBQWpDLGdCQUFXLEdBQVgsV0FBVyxDQUFzQjtRQXRCckQsT0FBRSxHQUFHLEVBQUUsQ0FBQztRQUVqQixjQUFTLEdBQWMsSUFBSSxTQUFTLEVBQUUsQ0FBQztRQU12QyxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBRWpCLG9CQUFlLEdBQUcsSUFBSSxZQUFZLEVBQWEsQ0FBQztRQUNoRCxnQkFBVyxHQUFtQixJQUFJLENBQUM7UUFFM0IsYUFBUSxHQUFtQixJQUFJLENBQUM7UUFDaEMsV0FBTSxHQUFtQixJQUFJLENBQUM7UUFDOUIsUUFBRyxHQUFtQixJQUFJLENBQUM7UUFDM0IsUUFBRyxHQUFtQixJQUFJLENBQUM7UUEyRW5DLGFBQVEsR0FBRyxDQUFDLElBQWEsRUFBRSxFQUFFLENBQzNCLElBQUksQ0FB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dCB7XHJcbiAgQ29tcG9uZW50LFxyXG4gIE9uSW5pdCxcclxuICBJbnB1dCxcclxuICBPdXRwdXQsXHJcbiAgRXZlbnRFbWl0dGVyLFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgVmlld0NoaWxkLFxyXG4gIE9uQ2hhbmdlcyxcclxuICBTaW1wbGVDaGFuZ2VzLFxyXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQge1xyXG4gIE5nYklucHV0RGF0ZXBpY2tlcixcclxuICBOZ2JEYXRlLFxyXG4gIE5nYkRhdGVOYXRpdmVBZGFwdGVyLFxyXG59IGZyb20gJ0BuZy1ib290c3RyYXAvbmctYm9vdHN0cmFwJztcclxuaW1wb3J0IHsgRGF0ZVJhbmdlIH0gZnJvbSAnLi4vbW9kZWxzL2RhdGUtcmFuZ2UnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdkYXRlLXJhbmdlLXBpY2tlcicsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL2RhdGUtcmFuZ2UtcGlja2VyLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9kYXRlLXJhbmdlLXBpY2tlci5jb21wb25lbnQuY3NzJ10sXHJcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBEYXRlUmFuZ2VQaWNrZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XHJcbiAgQElucHV0KCkgaWQgPSAnJztcclxuICBASW5wdXQoKVxyXG4gIGRhdGVSYW5nZTogRGF0ZVJhbmdlID0gbmV3IERhdGVSYW5nZSgpO1xyXG4gIEBJbnB1dCgpXHJcbiAgbWluRGF0ZT86IERhdGU7XHJcbiAgQElucHV0KClcclxuICBtYXhEYXRlPzogRGF0ZTtcclxuICBASW5wdXQoKVxyXG4gIGRpc2FibGVkID0gZmFsc2U7XHJcbiAgQE91dHB1dCgpXHJcbiAgZGF0ZVJhbmdlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxEYXRlUmFuZ2U+KCk7XHJcbiAgaG92ZXJlZERhdGU6IE5nYkRhdGUgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgcHJpdmF0ZSBmcm9tRGF0ZTogTmdiRGF0ZSB8IG51bGwgPSBudWxsO1xyXG4gIHByaXZhdGUgdG9EYXRlOiBOZ2JEYXRlIHwgbnVsbCA9IG51bGw7XHJcbiAgcHJpdmF0ZSBtaW46IE5nYkRhdGUgfCBudWxsID0gbnVsbDtcclxuICBwcml2YXRlIG1heDogTmdiRGF0ZSB8IG51bGwgPSBudWxsO1xyXG4gIEBWaWV3Q2hpbGQoJ2RwJywgeyByZWFkOiBFbGVtZW50UmVmLCBzdGF0aWM6IHRydWUgfSlcclxuICBwcml2YXRlIGlucHV0RWxSZWYhOiBFbGVtZW50UmVmO1xyXG4gIEBWaWV3Q2hpbGQoJ2RwJywgeyBzdGF0aWM6IHRydWUgfSlcclxuICBwcml2YXRlIGRwITogTmdiSW5wdXREYXRlcGlja2VyO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGRhdGVBZGFwdGVyOiBOZ2JEYXRlTmF0aXZlQWRhcHRlcikge31cclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICB0aGlzLmlkID1cclxuICAgICAgdGhpcy5pZCB8fCBgZGF0ZS1yYW5nZS1waWNrZXItYCArIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cmluZyg0KTtcclxuICAgIHRoaXMuZnJvbURhdGUgPSBOZ2JEYXRlLmZyb20oXHJcbiAgICAgIHRoaXMuZGF0ZUFkYXB0ZXIuZnJvbU1vZGVsKHRoaXMuZGF0ZVJhbmdlLnN0YXJ0KVxyXG4gICAgKTtcclxuICAgIHRoaXMudG9EYXRlID0gTmdiRGF0ZS5mcm9tKHRoaXMuZGF0ZUFkYXB0ZXIuZnJvbU1vZGVsKHRoaXMuZGF0ZVJhbmdlLmVuZCkpO1xyXG4gICAgdGhpcy5taW4gPSBOZ2JEYXRlLmZyb20oXHJcbiAgICAgIHRoaXMubWluRGF0ZSA/IHRoaXMuZGF0ZUFkYXB0ZXIuZnJvbU1vZGVsKHRoaXMubWluRGF0ZSkgOiBudWxsXHJcbiAgICApO1xyXG4gICAgdGhpcy5tYXggPSBOZ2JEYXRlLmZyb20oXHJcbiAgICAgIHRoaXMubWF4RGF0ZSA/IHRoaXMuZGF0ZUFkYXB0ZXIuZnJvbU1vZGVsKHRoaXMubWF4RGF0ZSkgOiBudWxsXHJcbiAgICApO1xyXG4gICAgdGhpcy5pbnB1dEVsUmVmLm5hdGl2ZUVsZW1lbnQudmFsdWUgPSB0aGlzLmZvcm1hdElucHV0VGV4dCgpO1xyXG4gICAgaWYgKHRoaXMuZnJvbURhdGUpIHtcclxuICAgICAgdGhpcy5kcC5zdGFydERhdGUgPSB7XHJcbiAgICAgICAgeWVhcjogdGhpcy5mcm9tRGF0ZS55ZWFyLFxyXG4gICAgICAgIG1vbnRoOiB0aGlzLmZyb21EYXRlLm1vbnRoLFxyXG4gICAgICB9O1xyXG4gICAgfVxyXG4gIH1cclxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XHJcbiAgICBpZiAoY2hhbmdlc1snZGF0ZVJhbmdlJ10gfHwgY2hhbmdlc1snZGlzYWJsZWQnXSkge1xyXG4gICAgICB0aGlzLm5nT25Jbml0KCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBvbkRhdGVDaGFuZ2UoZGF0ZTogTmdiRGF0ZSwgZHA6IE5nYklucHV0RGF0ZXBpY2tlcikge1xyXG4gICAgaWYgKCF0aGlzLmZyb21EYXRlICYmICF0aGlzLnRvRGF0ZSkge1xyXG4gICAgICB0aGlzLmZyb21EYXRlID0gZGF0ZTtcclxuICAgICAgdGhpcy5kYXRlUmFuZ2Uuc3RhcnQgPSB0aGlzLmRhdGVBZGFwdGVyLnRvTW9kZWwodGhpcy5mcm9tRGF0ZSk7XHJcbiAgICB9IGVsc2UgaWYgKHRoaXMuZnJvbURhdGUgJiYgIXRoaXMudG9EYXRlICYmIGRhdGUuYWZ0ZXIodGhpcy5mcm9tRGF0ZSkpIHtcclxuICAgICAgdGhpcy50b0RhdGUgPSBkYXRlO1xyXG4gICAgICB0aGlzLmRhdGVSYW5nZS5lbmQgPSB0aGlzLmRhdGVBZGFwdGVyLnRvTW9kZWwodGhpcy50b0RhdGUpO1xyXG4gICAgICBkcC5jbG9zZSgpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy50b0RhdGUgPSBudWxsO1xyXG4gICAgICB0aGlzLmZyb21EYXRlID0gZGF0ZTtcclxuICAgICAgdGhpcy5kYXRlUmFuZ2Uuc3RhcnQgPSB0aGlzLmRhdGVBZGFwdGVyLnRvTW9kZWwodGhpcy5mcm9tRGF0ZSk7XHJcbiAgICAgIHRoaXMuZGF0ZVJhbmdlLmVuZCA9IG51bGw7XHJcbiAgICB9XHJcbiAgICB0aGlzLmlucHV0RWxSZWYubmF0aXZlRWxlbWVudC52YWx1ZSA9IHRoaXMuZm9ybWF0SW5wdXRUZXh0KCk7XHJcbiAgICB0aGlzLmRhdGVSYW5nZUNoYW5nZS5lbWl0KHRoaXMuZGF0ZVJhbmdlKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZm9ybWF0SW5wdXRUZXh0KCk6IHN0cmluZyB7XHJcbiAgICBpZiAoXHJcbiAgICAgIHRoaXMuZGF0ZVJhbmdlLnN0YXJ0ICYmXHJcbiAgICAgIHRoaXMuZGF0ZVJhbmdlLmVuZCAmJlxyXG4gICAgICBEYXRlUmFuZ2UuaXNWYWxpZERhdGUodGhpcy5kYXRlUmFuZ2Uuc3RhcnQpICYmXHJcbiAgICAgIERhdGVSYW5nZS5pc1ZhbGlkRGF0ZSh0aGlzLmRhdGVSYW5nZS5lbmQpXHJcbiAgICApIHtcclxuICAgICAgcmV0dXJuIGAke3RoaXMuZGF0ZVJhbmdlLnN0YXJ0LnRvTG9jYWxlRGF0ZVN0cmluZygpfSAtICR7dGhpcy5kYXRlUmFuZ2UuZW5kLnRvTG9jYWxlRGF0ZVN0cmluZygpfWA7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gJyc7XHJcbiAgfVxyXG5cclxuICBpc0hvdmVyZWQoZGF0ZTogTmdiRGF0ZSkge1xyXG4gICAgcmV0dXJuIChcclxuICAgICAgdGhpcy5mcm9tRGF0ZSAmJlxyXG4gICAgICAhdGhpcy50b0RhdGUgJiZcclxuICAgICAgdGhpcy5ob3ZlcmVkRGF0ZSAmJlxyXG4gICAgICBkYXRlLmFmdGVyKHRoaXMuZnJvbURhdGUpICYmXHJcbiAgICAgIGRhdGUuYmVmb3JlKHRoaXMuaG92ZXJlZERhdGUpXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgaXNJbnNpZGUgPSAoZGF0ZTogTmdiRGF0ZSkgPT5cclxuICAgIGRhdGUuYWZ0ZXIodGhpcy5mcm9tRGF0ZSkgJiYgZGF0ZS5iZWZvcmUodGhpcy50b0RhdGUpO1xyXG4gIGlzRnJvbSA9IChkYXRlOiBOZ2JEYXRlKSA9PiBkYXRlLmVxdWFscyh0aGlzLmZyb21EYXRlKTtcclxuICBpc1RvID0gKGRhdGU6IE5nYkRhdGUpID0+IGRhdGUuZXF1YWxzKHRoaXMudG9EYXRlKTtcclxuICBpc1dlZWtlbmQoZGF0ZTogTmdiRGF0ZSkge1xyXG4gICAgY29uc3QgZCA9IG5ldyBEYXRlKGRhdGUueWVhciwgZGF0ZS5tb250aCAtIDEsIGRhdGUuZGF5KTtcclxuICAgIHJldHVybiBkLmdldERheSgpID09PSAwIHx8IGQuZ2V0RGF5KCkgPT09IDY7XHJcbiAgfVxyXG4gIGlzRGlzYWJsZWQgPSAoZGF0ZTogTmdiRGF0ZSkgPT4gZGF0ZS5hZnRlcih0aGlzLm1heCkgfHwgZGF0ZS5iZWZvcmUodGhpcy5taW4pO1xyXG4gIGlzSW5GdXR1cmUgPSAoZGF0ZTogTmdiRGF0ZSkgPT4gZGF0ZS5hZnRlcih0aGlzLnRvRGF0ZSk7XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cImlucHV0LWdyb3VwXCI+XHJcbiAgPGlucHV0XHJcbiAgICBuZ2JEYXRlcGlja2VyXHJcbiAgICAjZHA9XCJuZ2JEYXRlcGlja2VyXCJcclxuICAgIHR5cGU9XCJ0ZXh0XCJcclxuICAgIGNsYXNzPVwiZm9ybS1jb250cm9sXCJcclxuICAgIHN0eWxlPVwibWF4LXdpZHRoOiAyMDhweDsgY3Vyc29yOiBwb2ludGVyXCJcclxuICAgIHJlYWRvbmx5XHJcbiAgICBbYXR0ci5pZF09XCJpZFwiXHJcbiAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxyXG4gICAgW2F1dG9DbG9zZV09XCJmYWxzZVwiXHJcbiAgICBbZGlzcGxheU1vbnRoc109XCIyXCJcclxuICAgIFtkYXlUZW1wbGF0ZV09XCJ0XCJcclxuICAgIFtzaG93V2Vla051bWJlcnNdPVwiZmFsc2VcIlxyXG4gICAgW21hcmtEaXNhYmxlZF09XCJpc0Rpc2FibGVkXCJcclxuICAgIFtmaXJzdERheU9mV2Vla109XCI3XCJcclxuICAgIChjbGljayk9XCJkcC50b2dnbGUoKVwiXHJcbiAgICAoa2V5ZG93bi5lbnRlcik9XCJkcC50b2dnbGUoKVwiXHJcbiAgICAoZGF0ZVNlbGVjdCk9XCJvbkRhdGVDaGFuZ2UoJGV2ZW50LCBkcClcIlxyXG4gICAgdGl0bGU9XCJjbGljayB0byBzZWxlY3QgYSBkYXRlIHJhbmdlXCJcclxuICAvPlxyXG4gIDxidXR0b25cclxuICAgIHR5cGU9XCJidXR0b25cIlxyXG4gICAgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtc2Vjb25kYXJ5IGQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXJcIlxyXG4gICAgKGNsaWNrKT1cImRwLnRvZ2dsZSgpXCJcclxuICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlZFwiXHJcbiAgPlxyXG4gICAgPHN2Z1xyXG4gICAgICBhcmlhLWhpZGRlbj1cInRydWVcIlxyXG4gICAgICByb2xlPVwiaWNvblwiXHJcbiAgICAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIlxyXG4gICAgICB2aWV3Qm94PVwiMCAwIDQ0OCA1MTJcIlxyXG4gICAgPlxyXG4gICAgICA8cGF0aFxyXG4gICAgICAgIGZpbGw9XCJjdXJyZW50Q29sb3JcIlxyXG4gICAgICAgIGQ9XCJNMTQ4IDI4OGgtNDBjLTYuNiAwLTEyLTUuNC0xMi0xMnYtNDBjMC02LjYgNS40LTEyIDEyLTEyaDQwYzYuNiAwIDEyIDUuNCAxMiAxMnY0MGMwIDYuNi01LjQgMTItMTIgMTJ6bTEwOC0xMnYtNDBjMC02LjYtNS40LTEyLTEyLTEyaC00MGMtNi42IDAtMTIgNS40LTEyIDEydjQwYzAgNi42IDUuNCAxMiAxMiAxMmg0MGM2LjYgMCAxMi01LjQgMTItMTJ6bTk2IDB2LTQwYzAtNi42LTUuNC0xMi0xMi0xMmgtNDBjLTYuNiAwLTEyIDUuNC0xMiAxMnY0MGMwIDYuNiA1LjQgMTIgMTIgMTJoNDBjNi42IDAgMTItNS40IDEyLTEyem0tOTYgOTZ2LTQwYzAtNi42LTUuNC0xMi0xMi0xMmgtNDBjLTYuNiAwLTEyIDUuNC0xMiAxMnY0MGMwIDYuNiA1LjQgMTIgMTIgMTJoNDBjNi42IDAgMTItNS40IDEyLTEyem0tOTYgMHYtNDBjMC02LjYtNS40LTEyLTEyLTEyaC00MGMtNi42IDAtMTIgNS40LTEyIDEydjQwYzAgNi42IDUuNCAxMiAxMiAxMmg0MGM2LjYgMCAxMi01LjQgMTItMTJ6bTE5MiAwdi00MGMwLTYuNi01LjQtMTItMTItMTJoLTQwYy02LjYgMC0xMiA1LjQtMTIgMTJ2NDBjMCA2LjYgNS40IDEyIDEyIDEyaDQwYzYuNiAwIDEyLTUuNCAxMi0xMnptOTYtMjYwdjM1MmMwIDI2LjUtMjEuNSA0OC00OCA0OEg0OGMtMjYuNSAwLTQ4LTIxLjUtNDgtNDhWMTEyYzAtMjYuNSAyMS41LTQ4IDQ4LTQ4aDQ4VjEyYzAtNi42IDUuNC0xMiAxMi0xMmg0MGM2LjYgMCAxMiA1LjQgMTIgMTJ2NTJoMTI4VjEyYzAtNi42IDUuNC0xMiAxMi0xMmg0MGM2LjYgMCAxMiA1LjQgMTIgMTJ2NTJoNDhjMjYuNSAwIDQ4IDIxLjUgNDggNDh6bS00OCAzNDZWMTYwSDQ4djI5OGMwIDMuMyAyLjcgNiA2IDZoMzQwYzMuMyAwIDYtMi43IDYtNnpcIlxyXG4gICAgICA+PC9wYXRoPlxyXG4gICAgPC9zdmc+XHJcbiAgPC9idXR0b24+XHJcbjwvZGl2PlxyXG5cclxuPG5nLXRlbXBsYXRlXHJcbiAgI3RcclxuICBsZXQtZGF0ZT1cImRhdGVcIlxyXG4gIGxldC1mb2N1c2VkPVwiZm9jdXNlZFwiXHJcbiAgbGV0LWRpc2FibGVkPVwiZGlzYWJsZWRcIlxyXG4gIGxldC1jdXJyZW50TW9udGg9XCJjdXJyZW50TW9udGhcIlxyXG4+XHJcbiAgPHNwYW5cclxuICAgIGNsYXNzPVwiY3VzdG9tLWRheVwiXHJcbiAgICBbY2xhc3MuZm9jdXNlZF09XCJmb2N1c2VkXCJcclxuICAgIFtjbGFzcy5yYW5nZV09XCJcclxuICAgICAgaXNGcm9tKGRhdGUpIHx8IGlzVG8oZGF0ZSkgfHwgaXNJbnNpZGUoZGF0ZSkgfHwgaXNIb3ZlcmVkKGRhdGUpXHJcbiAgICBcIlxyXG4gICAgW2NsYXNzLmZhZGVkXT1cImlzSG92ZXJlZChkYXRlKSB8fCBpc0luc2lkZShkYXRlKVwiXHJcbiAgICBbY2xhc3Mud2Vla2VuZF09XCJpc1dlZWtlbmQoZGF0ZSlcIlxyXG4gICAgW2NsYXNzLmRpc2FibGVkXT1cImRpc2FibGVkXCJcclxuICAgIFtjbGFzcy5vdXRzaWRlXT1cImRhdGUubW9udGggIT09IGN1cnJlbnRNb250aFwiXHJcbiAgICAobW91c2VlbnRlcik9XCJob3ZlcmVkRGF0ZSA9IGRhdGVcIlxyXG4gICAgKG1vdXNlbGVhdmUpPVwiaG92ZXJlZERhdGUgPSBudWxsXCJcclxuICA+XHJcbiAgICB7eyBkYXRlLmRheSB9fVxyXG4gIDwvc3Bhbj5cclxuPC9uZy10ZW1wbGF0ZT5cclxuIl19