ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
543 lines (537 loc) • 65.6 kB
JavaScript
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';
import { fromEvent, merge, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { CandyDate, cloneDate, wrongSortOrder } from 'ng-zorro-antd/core/time';
import { getTimeConfig, isAllowedDate, PREFIX_CLASS } from './util';
import * as i0 from "@angular/core";
import * as i1 from "./date-picker.service";
import * as i2 from "@angular/common";
import * as i3 from "./calendar-footer.component";
import * as i4 from "./inner-popup.component";
export class DateRangePopupComponent {
get hasTimePicker() {
return !!this.showTime;
}
get hasFooter() {
return this.showToday || this.hasTimePicker || !!this.extraFooter || !!this.ranges;
}
get arrowPosition() {
return this.dir === 'rtl'
? { right: `${this.datePickerService?.arrowLeft}px` }
: { left: `${this.datePickerService?.arrowLeft}px` };
}
constructor(datePickerService, cdr, ngZone, host) {
this.datePickerService = datePickerService;
this.cdr = cdr;
this.ngZone = ngZone;
this.host = host;
this.inline = false;
this.dir = 'ltr';
this.panelModeChange = new EventEmitter();
this.calendarChange = new EventEmitter();
this.resultOk = new EventEmitter(); // Emitted when done with date selecting
this.prefixCls = PREFIX_CLASS;
this.endPanelMode = 'date';
this.timeOptions = null;
this.hoverValue = []; // Range ONLY
this.checkedPartArr = [false, false];
this.destroy$ = new Subject();
this.disabledStartTime = (value) => this.disabledTime && this.disabledTime(value, 'start');
this.disabledEndTime = (value) => this.disabledTime && this.disabledTime(value, 'end');
}
ngOnInit() {
merge(this.datePickerService.valueChange$, this.datePickerService.inputPartChange$)
.pipe(takeUntil(this.destroy$))
.subscribe(() => {
this.updateActiveDate();
this.cdr.markForCheck();
});
this.ngZone.runOutsideAngular(() => {
fromEvent(this.host.nativeElement, 'mousedown')
.pipe(takeUntil(this.destroy$))
.subscribe(event => event.preventDefault());
});
}
ngOnChanges(changes) {
// Parse showTime options
if (changes.showTime || changes.disabledTime) {
if (this.showTime) {
this.buildTimeOptions();
}
}
if (changes.panelMode) {
this.endPanelMode = this.panelMode;
}
if (changes.defaultPickerValue) {
this.updateActiveDate();
}
}
ngOnDestroy() {
this.destroy$.next(true);
this.destroy$.complete();
}
updateActiveDate() {
const activeDate = this.datePickerService.hasValue()
? this.datePickerService.value
: this.datePickerService.makeValue(this.defaultPickerValue);
this.datePickerService.setActiveDate(activeDate, this.hasTimePicker, this.getPanelMode(this.endPanelMode));
}
onClickOk() {
const inputIndex = { left: 0, right: 1 }[this.datePickerService.activeInput];
const value = this.isRange
? this.datePickerService.value[inputIndex]
: this.datePickerService.value;
this.changeValueFromSelect(value);
this.resultOk.emit();
}
onClickToday(value) {
this.changeValueFromSelect(value, !this.showTime);
}
onCellHover(value) {
if (!this.isRange) {
return;
}
const otherInputIndex = { left: 1, right: 0 }[this.datePickerService.activeInput];
const base = this.datePickerService.value[otherInputIndex];
if (base) {
if (base.isBeforeDay(value)) {
this.hoverValue = [base, value];
}
else {
this.hoverValue = [value, base];
}
}
}
onPanelModeChange(mode, partType) {
if (this.isRange) {
const index = this.datePickerService.getActiveIndex(partType);
if (index === 0) {
this.panelMode = [mode, this.panelMode[1]];
}
else {
this.panelMode = [this.panelMode[0], mode];
}
}
else {
this.panelMode = mode;
}
this.panelModeChange.emit(this.panelMode);
}
onActiveDateChange(value, partType) {
if (this.isRange) {
const activeDate = [];
activeDate[this.datePickerService.getActiveIndex(partType)] = value;
this.datePickerService.setActiveDate(activeDate, this.hasTimePicker, this.getPanelMode(this.endPanelMode, partType));
}
else {
this.datePickerService.setActiveDate(value);
}
}
onSelectTime(value, partType) {
if (this.isRange) {
const newValue = cloneDate(this.datePickerService.value);
const index = this.datePickerService.getActiveIndex(partType);
newValue[index] = this.overrideHms(value, newValue[index]);
this.datePickerService.setValue(newValue);
}
else {
const newValue = this.overrideHms(value, this.datePickerService.value);
this.datePickerService.setValue(newValue); // If not select a date currently, use today
}
this.datePickerService.inputPartChange$.next(null);
this.buildTimeOptions();
}
changeValueFromSelect(value, emitValue = true) {
if (this.isRange) {
const selectedValue = cloneDate(this.datePickerService.value);
const checkedPart = this.datePickerService.activeInput;
let nextPart = checkedPart;
selectedValue[this.datePickerService.getActiveIndex(checkedPart)] = value;
this.checkedPartArr[this.datePickerService.getActiveIndex(checkedPart)] = true;
this.hoverValue = selectedValue;
if (emitValue) {
if (this.inline) {
// For UE, Should always be reversed, and clear vaue when next part is right
nextPart = this.reversedPart(checkedPart);
if (nextPart === 'right') {
selectedValue[this.datePickerService.getActiveIndex(nextPart)] = null;
this.checkedPartArr[this.datePickerService.getActiveIndex(nextPart)] = false;
}
this.datePickerService.setValue(selectedValue);
this.calendarChange.emit(selectedValue);
if (this.isBothAllowed(selectedValue) && this.checkedPartArr[0] && this.checkedPartArr[1]) {
this.clearHoverValue();
this.datePickerService.emitValue$.next();
}
}
else {
/**
* if sort order is wrong, clear the other part's value
*/
if (wrongSortOrder(selectedValue)) {
nextPart = this.reversedPart(checkedPart);
selectedValue[this.datePickerService.getActiveIndex(nextPart)] = null;
this.checkedPartArr[this.datePickerService.getActiveIndex(nextPart)] = false;
}
this.datePickerService.setValue(selectedValue);
/**
* range date usually selected paired,
* so we emit the date value only both date is allowed and both part are checked
*/
if (this.isBothAllowed(selectedValue) && this.checkedPartArr[0] && this.checkedPartArr[1]) {
this.calendarChange.emit(selectedValue);
this.clearHoverValue();
this.datePickerService.emitValue$.next();
}
else if (this.isAllowed(selectedValue)) {
nextPart = this.reversedPart(checkedPart);
this.calendarChange.emit([value.clone()]);
}
}
}
else {
this.datePickerService.setValue(selectedValue);
}
this.datePickerService.inputPartChange$.next(nextPart);
}
else {
this.datePickerService.setValue(value);
this.datePickerService.inputPartChange$.next(null);
if (emitValue && this.isAllowed(value)) {
this.datePickerService.emitValue$.next();
}
}
this.buildTimeOptions();
}
reversedPart(part) {
return part === 'left' ? 'right' : 'left';
}
getPanelMode(panelMode, partType) {
if (this.isRange) {
return panelMode[this.datePickerService.getActiveIndex(partType)];
}
else {
return panelMode;
}
}
// Get single value or part value of a range
getValue(partType) {
if (this.isRange) {
return (this.datePickerService.value || [])[this.datePickerService.getActiveIndex(partType)];
}
else {
return this.datePickerService.value;
}
}
getActiveDate(partType) {
if (this.isRange) {
return this.datePickerService.activeDate[this.datePickerService.getActiveIndex(partType)];
}
else {
return this.datePickerService.activeDate;
}
}
isOneAllowed(selectedValue) {
const index = this.datePickerService.getActiveIndex();
const disabledTimeArr = [this.disabledStartTime, this.disabledEndTime];
return isAllowedDate(selectedValue[index], this.disabledDate, disabledTimeArr[index]);
}
isBothAllowed(selectedValue) {
return (isAllowedDate(selectedValue[0], this.disabledDate, this.disabledStartTime) &&
isAllowedDate(selectedValue[1], this.disabledDate, this.disabledEndTime));
}
isAllowed(value, isBoth = false) {
if (this.isRange) {
return isBoth ? this.isBothAllowed(value) : this.isOneAllowed(value);
}
else {
return isAllowedDate(value, this.disabledDate, this.disabledTime);
}
}
getTimeOptions(partType) {
if (this.showTime && this.timeOptions) {
return this.timeOptions instanceof Array
? this.timeOptions[this.datePickerService.getActiveIndex(partType)]
: this.timeOptions;
}
return null;
}
onClickPresetRange(val) {
const value = typeof val === 'function' ? val() : val;
if (value) {
this.datePickerService.setValue([new CandyDate(value[0]), new CandyDate(value[1])]);
this.datePickerService.emitValue$.next();
}
}
onPresetRangeMouseLeave() {
this.clearHoverValue();
}
onHoverPresetRange(val) {
if (typeof val !== 'function') {
this.hoverValue = [new CandyDate(val[0]), new CandyDate(val[1])];
}
}
getObjectKeys(obj) {
return obj ? Object.keys(obj) : [];
}
show(partType) {
const hide = this.showTime && this.isRange && this.datePickerService.activeInput !== partType;
return !hide;
}
clearHoverValue() {
this.hoverValue = [];
}
buildTimeOptions() {
if (this.showTime) {
const showTime = typeof this.showTime === 'object' ? this.showTime : {};
if (this.isRange) {
const value = this.datePickerService.value;
this.timeOptions = [
this.overrideTimeOptions(showTime, value[0], 'start'),
this.overrideTimeOptions(showTime, value[1], 'end')
];
}
else {
this.timeOptions = this.overrideTimeOptions(showTime, this.datePickerService.value);
}
}
else {
this.timeOptions = null;
}
}
overrideTimeOptions(origin, value, partial) {
let disabledTimeFn;
if (partial) {
disabledTimeFn = partial === 'start' ? this.disabledStartTime : this.disabledEndTime;
}
else {
disabledTimeFn = this.disabledTime;
}
return { ...origin, ...getTimeConfig(value, disabledTimeFn) };
}
overrideHms(newValue, oldValue) {
newValue = newValue || new CandyDate();
oldValue = oldValue || new CandyDate();
return oldValue.setHms(newValue.getHours(), newValue.getMinutes(), newValue.getSeconds());
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: DateRangePopupComponent, deps: [{ token: i1.DatePickerService }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.3", type: DateRangePopupComponent, selector: "date-range-popup", inputs: { isRange: "isRange", inline: "inline", showWeek: "showWeek", locale: "locale", disabledDate: "disabledDate", disabledTime: "disabledTime", showToday: "showToday", showNow: "showNow", showTime: "showTime", extraFooter: "extraFooter", ranges: "ranges", dateRender: "dateRender", panelMode: "panelMode", defaultPickerValue: "defaultPickerValue", dir: "dir" }, outputs: { panelModeChange: "panelModeChange", calendarChange: "calendarChange", resultOk: "resultOk" }, exportAs: ["dateRangePopup"], usesOnChanges: true, ngImport: i0, template: `
<ng-container *ngIf="isRange; else singlePanel">
<div class="{{ prefixCls }}-range-wrapper {{ prefixCls }}-date-range-wrapper">
<div class="{{ prefixCls }}-range-arrow" [style]="arrowPosition"></div>
<div class="{{ prefixCls }}-panel-container {{ showWeek ? prefixCls + '-week-number' : '' }}">
<div class="{{ prefixCls }}-panels">
<ng-container *ngIf="hasTimePicker; else noTimePicker">
<ng-container
*ngTemplateOutlet="tplInnerPopup; context: { partType: datePickerService.activeInput }"
></ng-container>
</ng-container>
<ng-template #noTimePicker>
<ng-container *ngTemplateOutlet="tplInnerPopup; context: { partType: 'left' }"></ng-container>
<ng-container *ngTemplateOutlet="tplInnerPopup; context: { partType: 'right' }"></ng-container>
</ng-template>
</div>
<ng-container *ngTemplateOutlet="tplFooter"></ng-container>
</div>
</div>
</ng-container>
<ng-template #singlePanel>
<div
class="{{ prefixCls }}-panel-container {{ showWeek ? prefixCls + '-week-number' : '' }} {{
hasTimePicker ? prefixCls + '-time' : ''
}} {{ isRange ? prefixCls + '-range' : '' }}"
>
<div class="{{ prefixCls }}-panel" [class.ant-picker-panel-rtl]="dir === 'rtl'" tabindex="-1">
<!-- Single ONLY -->
<ng-container *ngTemplateOutlet="tplInnerPopup"></ng-container>
<ng-container *ngTemplateOutlet="tplFooter"></ng-container>
</div>
</div>
</ng-template>
<ng-template #tplInnerPopup let-partType="partType">
<div class="{{ prefixCls }}-panel" [class.ant-picker-panel-rtl]="dir === 'rtl'">
<!-- TODO(@wenqi73) [selectedValue] [hoverValue] types-->
<inner-popup
[showWeek]="showWeek"
[endPanelMode]="getPanelMode(endPanelMode, partType)"
[partType]="partType"
[locale]="locale!"
[showTimePicker]="hasTimePicker"
[timeOptions]="getTimeOptions(partType)"
[panelMode]="getPanelMode(panelMode, partType)"
(panelModeChange)="onPanelModeChange($event, partType)"
[activeDate]="getActiveDate(partType)"
[value]="getValue(partType)"
[disabledDate]="disabledDate"
[dateRender]="dateRender"
[selectedValue]="$any(datePickerService?.value)"
[hoverValue]="$any(hoverValue)"
(cellHover)="onCellHover($event)"
(selectDate)="changeValueFromSelect($event, !showTime)"
(selectTime)="onSelectTime($event, partType)"
(headerChange)="onActiveDateChange($event, partType)"
></inner-popup>
</div>
</ng-template>
<ng-template #tplFooter>
<calendar-footer
*ngIf="hasFooter"
[locale]="locale!"
[isRange]="isRange"
[showToday]="showToday"
[showNow]="showNow"
[hasTimePicker]="hasTimePicker"
[okDisabled]="!isAllowed($any(datePickerService?.value))"
[extraFooter]="extraFooter"
[rangeQuickSelector]="ranges ? tplRangeQuickSelector : null"
(clickOk)="onClickOk()"
(clickToday)="onClickToday($event)"
></calendar-footer>
</ng-template>
<!-- Range ONLY: Range Quick Selector -->
<ng-template #tplRangeQuickSelector>
<li
*ngFor="let name of getObjectKeys(ranges)"
class="{{ prefixCls }}-preset"
(click)="onClickPresetRange(ranges![name])"
(mouseenter)="onHoverPresetRange(ranges![name])"
(mouseleave)="onPresetRangeMouseLeave()"
>
<span class="ant-tag ant-tag-blue">{{ name }}</span>
</li>
</ng-template>
`, isInline: true, dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i3.CalendarFooterComponent, selector: "calendar-footer", inputs: ["locale", "showToday", "showNow", "hasTimePicker", "isRange", "okDisabled", "disabledDate", "extraFooter", "rangeQuickSelector"], outputs: ["clickOk", "clickToday"], exportAs: ["calendarFooter"] }, { kind: "component", type: i4.InnerPopupComponent, selector: "inner-popup", inputs: ["activeDate", "endPanelMode", "panelMode", "showWeek", "locale", "showTimePicker", "timeOptions", "disabledDate", "dateRender", "selectedValue", "hoverValue", "value", "partType"], outputs: ["panelModeChange", "headerChange", "selectDate", "selectTime", "cellHover"], exportAs: ["innerPopup"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: DateRangePopupComponent, decorators: [{
type: Component,
args: [{
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'date-range-popup',
exportAs: 'dateRangePopup',
template: `
<ng-container *ngIf="isRange; else singlePanel">
<div class="{{ prefixCls }}-range-wrapper {{ prefixCls }}-date-range-wrapper">
<div class="{{ prefixCls }}-range-arrow" [style]="arrowPosition"></div>
<div class="{{ prefixCls }}-panel-container {{ showWeek ? prefixCls + '-week-number' : '' }}">
<div class="{{ prefixCls }}-panels">
<ng-container *ngIf="hasTimePicker; else noTimePicker">
<ng-container
*ngTemplateOutlet="tplInnerPopup; context: { partType: datePickerService.activeInput }"
></ng-container>
</ng-container>
<ng-template #noTimePicker>
<ng-container *ngTemplateOutlet="tplInnerPopup; context: { partType: 'left' }"></ng-container>
<ng-container *ngTemplateOutlet="tplInnerPopup; context: { partType: 'right' }"></ng-container>
</ng-template>
</div>
<ng-container *ngTemplateOutlet="tplFooter"></ng-container>
</div>
</div>
</ng-container>
<ng-template #singlePanel>
<div
class="{{ prefixCls }}-panel-container {{ showWeek ? prefixCls + '-week-number' : '' }} {{
hasTimePicker ? prefixCls + '-time' : ''
}} {{ isRange ? prefixCls + '-range' : '' }}"
>
<div class="{{ prefixCls }}-panel" [class.ant-picker-panel-rtl]="dir === 'rtl'" tabindex="-1">
<!-- Single ONLY -->
<ng-container *ngTemplateOutlet="tplInnerPopup"></ng-container>
<ng-container *ngTemplateOutlet="tplFooter"></ng-container>
</div>
</div>
</ng-template>
<ng-template #tplInnerPopup let-partType="partType">
<div class="{{ prefixCls }}-panel" [class.ant-picker-panel-rtl]="dir === 'rtl'">
<!-- TODO(@wenqi73) [selectedValue] [hoverValue] types-->
<inner-popup
[showWeek]="showWeek"
[endPanelMode]="getPanelMode(endPanelMode, partType)"
[partType]="partType"
[locale]="locale!"
[showTimePicker]="hasTimePicker"
[timeOptions]="getTimeOptions(partType)"
[panelMode]="getPanelMode(panelMode, partType)"
(panelModeChange)="onPanelModeChange($event, partType)"
[activeDate]="getActiveDate(partType)"
[value]="getValue(partType)"
[disabledDate]="disabledDate"
[dateRender]="dateRender"
[selectedValue]="$any(datePickerService?.value)"
[hoverValue]="$any(hoverValue)"
(cellHover)="onCellHover($event)"
(selectDate)="changeValueFromSelect($event, !showTime)"
(selectTime)="onSelectTime($event, partType)"
(headerChange)="onActiveDateChange($event, partType)"
></inner-popup>
</div>
</ng-template>
<ng-template #tplFooter>
<calendar-footer
*ngIf="hasFooter"
[locale]="locale!"
[isRange]="isRange"
[showToday]="showToday"
[showNow]="showNow"
[hasTimePicker]="hasTimePicker"
[okDisabled]="!isAllowed($any(datePickerService?.value))"
[extraFooter]="extraFooter"
[rangeQuickSelector]="ranges ? tplRangeQuickSelector : null"
(clickOk)="onClickOk()"
(clickToday)="onClickToday($event)"
></calendar-footer>
</ng-template>
<!-- Range ONLY: Range Quick Selector -->
<ng-template #tplRangeQuickSelector>
<li
*ngFor="let name of getObjectKeys(ranges)"
class="{{ prefixCls }}-preset"
(click)="onClickPresetRange(ranges![name])"
(mouseenter)="onHoverPresetRange(ranges![name])"
(mouseleave)="onPresetRangeMouseLeave()"
>
<span class="ant-tag ant-tag-blue">{{ name }}</span>
</li>
</ng-template>
`
}]
}], ctorParameters: () => [{ type: i1.DatePickerService }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: i0.ElementRef }], propDecorators: { isRange: [{
type: Input
}], inline: [{
type: Input
}], showWeek: [{
type: Input
}], locale: [{
type: Input
}], disabledDate: [{
type: Input
}], disabledTime: [{
type: Input
}], showToday: [{
type: Input
}], showNow: [{
type: Input
}], showTime: [{
type: Input
}], extraFooter: [{
type: Input
}], ranges: [{
type: Input
}], dateRender: [{
type: Input
}], panelMode: [{
type: Input
}], defaultPickerValue: [{
type: Input
}], dir: [{
type: Input
}], panelModeChange: [{
type: Output
}], calendarChange: [{
type: Output
}], resultOk: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1yYW5nZS1wb3B1cC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9jb21wb25lbnRzL2RhdGUtcGlja2VyL2RhdGUtcmFuZ2UtcG9wdXAuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU1BLE9BQU8sRUFDTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUVULFlBQVksRUFDWixLQUFLLEVBS0wsTUFBTSxFQUdOLGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDakQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTNDLE9BQU8sRUFDTCxTQUFTLEVBQ1QsU0FBUyxFQUlULGNBQWMsRUFDZixNQUFNLHlCQUF5QixDQUFDO0FBZWpDLE9BQU8sRUFBRSxhQUFhLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxNQUFNLFFBQVEsQ0FBQzs7Ozs7O0FBa0dwRSxNQUFNLE9BQU8sdUJBQXVCO0lBNEJsQyxJQUFJLGFBQWE7UUFDZixPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxJQUFJLFNBQVM7UUFDWCxPQUFPLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztJQUNyRixDQUFDO0lBRUQsSUFBSSxhQUFhO1FBQ2YsT0FBTyxJQUFJLENBQUMsR0FBRyxLQUFLLEtBQUs7WUFDdkIsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLFNBQVMsSUFBSSxFQUFFO1lBQ3JELENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxpQkFBaUIs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QVM7bUJBQUM7b0JBQ1QsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7b0JBQ3JDLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNO29CQUMvQyw4REFBOEQ7b0JBQzlELFFBQVEsRUFBRSxrQkFBa0I7b0JBQzVCLFFBQVEsRUFBRSxnQkFBZ0I7b0JBQzFCLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXdGVDtpQkFDRjtvS0FFVSxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csTUFBTTtzQkFBZCxLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csU0FBUztzQkFBakIsS0FBSztnQkFDRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBQ0csR0FBRztzQkFBWCxLQUFLO2dCQUVhLGVBQWU7c0JBQWpDLE1BQU07Z0JBQ1ksY0FBYztzQkFBaEMsTUFBTTtnQkFDWSxRQUFRO3NCQUExQixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHsgRGlyZWN0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2JpZGknO1xuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBmcm9tRXZlbnQsIG1lcmdlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7XG4gIENhbmR5RGF0ZSxcbiAgY2xvbmVEYXRlLFxuICBDb21wYXRpYmxlVmFsdWUsXG4gIE5vcm1hbGl6ZWRNb2RlLFxuICBTaW5nbGVWYWx1ZSxcbiAgd3JvbmdTb3J0T3JkZXJcbn0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3RpbWUnO1xuaW1wb3J0IHsgRnVuY3Rpb25Qcm9wIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3R5cGVzJztcbmltcG9ydCB7IE56Q2FsZW5kYXJJMThuSW50ZXJmYWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9pMThuJztcblxuaW1wb3J0IHsgRGF0ZVBpY2tlclNlcnZpY2UgfSBmcm9tICcuL2RhdGUtcGlja2VyLnNlcnZpY2UnO1xuaW1wb3J0IHtcbiAgQ29tcGF0aWJsZURhdGUsXG4gIERpc2FibGVkRGF0ZUZuLFxuICBEaXNhYmxlZFRpbWVGbixcbiAgRGlzYWJsZWRUaW1lUGFydGlhbCxcbiAgTnpEYXRlTW9kZSxcbiAgUHJlc2V0UmFuZ2VzLFxuICBSYW5nZVBhcnRUeXBlLFxuICBTdXBwb3J0VGltZU9wdGlvbnNcbn0gZnJvbSAnLi9zdGFuZGFyZC10eXBlcyc7XG5pbXBvcnQgeyBnZXRUaW1lQ29uZmlnLCBpc0FsbG93ZWREYXRlLCBQUkVGSVhfQ0xBU1MgfSBmcm9tICcuL3V0aWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAYW5ndWxhci1lc2xpbnQvY29tcG9uZW50LXNlbGVjdG9yXG4gIHNlbGVjdG9yOiAnZGF0ZS1yYW5nZS1wb3B1cCcsXG4gIGV4cG9ydEFzOiAnZGF0ZVJhbmdlUG9wdXAnLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc1JhbmdlOyBlbHNlIHNpbmdsZVBhbmVsXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LXJhbmdlLXdyYXBwZXIge3sgcHJlZml4Q2xzIH19LWRhdGUtcmFuZ2Utd3JhcHBlclwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LXJhbmdlLWFycm93XCIgW3N0eWxlXT1cImFycm93UG9zaXRpb25cIj48L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInt7IHByZWZpeENscyB9fS1wYW5lbC1jb250YWluZXIge3sgc2hvd1dlZWsgPyBwcmVmaXhDbHMgKyAnLXdlZWstbnVtYmVyJyA6ICcnIH19XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInt7IHByZWZpeENscyB9fS1wYW5lbHNcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJoYXNUaW1lUGlja2VyOyBlbHNlIG5vVGltZVBpY2tlclwiPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0cGxJbm5lclBvcHVwOyBjb250ZXh0OiB7IHBhcnRUeXBlOiBkYXRlUGlja2VyU2VydmljZS5hY3RpdmVJbnB1dCB9XCJcbiAgICAgICAgICAgICAgPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI25vVGltZVBpY2tlcj5cbiAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRwbElubmVyUG9wdXA7IGNvbnRleHQ6IHsgcGFydFR5cGU6ICdsZWZ0JyB9XCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0cGxJbm5lclBvcHVwOyBjb250ZXh0OiB7IHBhcnRUeXBlOiAncmlnaHQnIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRwbEZvb3RlclwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxuZy10ZW1wbGF0ZSAjc2luZ2xlUGFuZWw+XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LXBhbmVsLWNvbnRhaW5lciB7eyBzaG93V2VlayA/IHByZWZpeENscyArICctd2Vlay1udW1iZXInIDogJycgfX0ge3tcbiAgICAgICAgICBoYXNUaW1lUGlja2VyID8gcHJlZml4Q2xzICsgJy10aW1lJyA6ICcnXG4gICAgICAgIH19IHt7IGlzUmFuZ2UgPyBwcmVmaXhDbHMgKyAnLXJhbmdlJyA6ICcnIH19XCJcbiAgICAgID5cbiAgICAgICAgPGRpdiBjbGFzcz1cInt7IHByZWZpeENscyB9fS1wYW5lbFwiIFtjbGFzcy5hbnQtcGlja2VyLXBhbmVsLXJ0bF09XCJkaXIgPT09ICdydGwnXCIgdGFiaW5kZXg9XCItMVwiPlxuICAgICAgICAgIDwhLS0gU2luZ2xlIE9OTFkgLS0+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRwbElubmVyUG9wdXBcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidHBsRm9vdGVyXCI+PC9uZy1jb250YWluZXI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgIDxuZy10ZW1wbGF0ZSAjdHBsSW5uZXJQb3B1cCBsZXQtcGFydFR5cGU9XCJwYXJ0VHlwZVwiPlxuICAgICAgPGRpdiBjbGFzcz1cInt7IHByZWZpeENscyB9fS1wYW5lbFwiIFtjbGFzcy5hbnQtcGlja2VyLXBhbmVsLXJ0bF09XCJkaXIgPT09ICdydGwnXCI+XG4gICAgICAgIDwhLS0gVE9ETyhAd2VucWk3MykgW3NlbGVjdGVkVmFsdWVdIFtob3ZlclZhbHVlXSB0eXBlcy0tPlxuICAgICAgICA8aW5uZXItcG9wdXBcbiAgICAgICAgICBbc2hvd1dlZWtdPVwic2hvd1dlZWtcIlxuICAgICAgICAgIFtlbmRQYW5lbE1vZGVdPVwiZ2V0UGFuZWxNb2RlKGVuZFBhbmVsTW9kZSwgcGFydFR5cGUpXCJcbiAgICAgICAgICBbcGFydFR5cGVdPVwicGFydFR5cGVcIlxuICAgICAgICAgIFtsb2NhbGVdPVwibG9jYWxlIVwiXG4gICAgICAgICAgW3Nob3dUaW1lUGlja2VyXT1cImhhc1RpbWVQaWNrZXJcIlxuICAgICAgICAgIFt0aW1lT3B0aW9uc109XCJnZXRUaW1lT3B0aW9ucyhwYXJ0VHlwZSlcIlxuICAgICAgICAgIFtwYW5lbE1vZGVdPVwiZ2V0UGFuZWxNb2RlKHBhbmVsTW9kZSwgcGFydFR5cGUpXCJcbiAgICAgICAgICAocGFuZWxNb2RlQ2hhbmdlKT1cIm9uUGFuZWxNb2RlQ2hhbmdlKCRldmVudCwgcGFydFR5cGUpXCJcbiAgICAgICAgICBbYWN0aXZlRGF0ZV09XCJnZXRBY3RpdmVEYXRlKHBhcnRUeXBlKVwiXG4gICAgICAgICAgW3ZhbHVlXT1cImdldFZhbHVlKHBhcnRUeXBlKVwiXG4gICAgICAgICAgW2Rpc2FibGVkRGF0ZV09XCJkaXNhYmxlZERhdGVcIlxuICAgICAgICAgIFtkYXRlUmVuZGVyXT1cImRhdGVSZW5kZXJcIlxuICAgICAgICAgIFtzZWxlY3RlZFZhbHVlXT1cIiRhbnkoZGF0ZVBpY2tlclNlcnZpY2U/LnZhbHVlKVwiXG4gICAgICAgICAgW2hvdmVyVmFsdWVdPVwiJGFueShob3ZlclZhbHVlKVwiXG4gICAgICAgICAgKGNlbGxIb3Zlcik9XCJvbkNlbGxIb3ZlcigkZXZlbnQpXCJcbiAgICAgICAgICAoc2VsZWN0RGF0ZSk9XCJjaGFuZ2VWYWx1ZUZyb21TZWxlY3QoJGV2ZW50LCAhc2hvd1RpbWUpXCJcbiAgICAgICAgICAoc2VsZWN0VGltZSk9XCJvblNlbGVjdFRpbWUoJGV2ZW50LCBwYXJ0VHlwZSlcIlxuICAgICAgICAgIChoZWFkZXJDaGFuZ2UpPVwib25BY3RpdmVEYXRlQ2hhbmdlKCRldmVudCwgcGFydFR5cGUpXCJcbiAgICAgICAgPjwvaW5uZXItcG9wdXA+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPG5nLXRlbXBsYXRlICN0cGxGb290ZXI+XG4gICAgICA8Y2FsZW5kYXItZm9vdGVyXG4gICAgICAgICpuZ0lmPVwiaGFzRm9vdGVyXCJcbiAgICAgICAgW2xvY2FsZV09XCJsb2NhbGUhXCJcbiAgICAgICAgW2lzUmFuZ2VdPVwiaXNSYW5nZVwiXG4gICAgICAgIFtzaG93VG9kYXldPVwic2hvd1RvZGF5XCJcbiAgICAgICAgW3Nob3dOb3ddPVwic2hvd05vd1wiXG4gICAgICAgIFtoYXNUaW1lUGlja2VyXT1cImhhc1RpbWVQaWNrZXJcIlxuICAgICAgICBbb2tEaXNhYmxlZF09XCIhaXNBbGxvd2VkKCRhbnkoZGF0ZVBpY2tlclNlcnZpY2U/LnZhbHVlKSlcIlxuICAgICAgICBbZXh0cmFGb290ZXJdPVwiZXh0cmFGb290ZXJcIlxuICAgICAgICBbcmFuZ2VRdWlja1NlbGVjdG9yXT1cInJhbmdlcyA/IHRwbFJhbmdlUXVpY2tTZWxlY3RvciA6IG51bGxcIlxuICAgICAgICAoY2xpY2tPayk9XCJvbkNsaWNrT2soKVwiXG4gICAgICAgIChjbGlja1RvZGF5KT1cIm9uQ2xpY2tUb2RheSgkZXZlbnQpXCJcbiAgICAgID48L2NhbGVuZGFyLWZvb3Rlcj5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPCEtLSBSYW5nZSBPTkxZOiBSYW5nZSBRdWljayBTZWxlY3RvciAtLT5cbiAgICA8bmctdGVtcGxhdGUgI3RwbFJhbmdlUXVpY2tTZWxlY3Rvcj5cbiAgICAgIDxsaVxuICAgICAgICAqbmdGb3I9XCJsZXQgbmFtZSBvZiBnZXRPYmplY3RLZXlzKHJhbmdlcylcIlxuICAgICAgICBjbGFzcz1cInt7IHByZWZpeENscyB9fS1wcmVzZXRcIlxuICAgICAgICAoY2xpY2spPVwib25DbGlja1ByZXNldFJhbmdlKHJhbmdlcyFbbmFtZV0pXCJcbiAgICAgICAgKG1vdXNlZW50ZXIpPVwib25Ib3ZlclByZXNldFJhbmdlKHJhbmdlcyFbbmFtZV0pXCJcbiAgICAgICAgKG1vdXNlbGVhdmUpPVwib25QcmVzZXRSYW5nZU1vdXNlTGVhdmUoKVwiXG4gICAgICA+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwiYW50LXRhZyBhbnQtdGFnLWJsdWVcIj57eyBuYW1lIH19PC9zcGFuPlxuICAgICAgPC9saT5cbiAgICA8L25nLXRlbXBsYXRlPlxuICBgXG59KVxuZXhwb3J0IGNsYXNzIERhdGVSYW5nZVBvcHVwQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIGlzUmFuZ2UhOiBib29sZWFuO1xuICBASW5wdXQoKSBpbmxpbmU6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgc2hvd1dlZWshOiBib29sZWFuO1xuICBASW5wdXQoKSBsb2NhbGUhOiBOekNhbGVuZGFySTE4bkludGVyZmFjZSB8IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgZGlzYWJsZWREYXRlPzogRGlzYWJsZWREYXRlRm47XG4gIEBJbnB1dCgpIGRpc2FibGVkVGltZT86IERpc2FibGVkVGltZUZuOyAvLyBUaGlzIHdpbGwgbGVhZCB0byByZWJ1aWxkIHRpbWUgb3B0aW9uc1xuICBASW5wdXQoKSBzaG93VG9kYXkhOiBib29sZWFuO1xuICBASW5wdXQoKSBzaG93Tm93ITogYm9vbGVhbjtcbiAgQElucHV0KCkgc2hvd1RpbWUhOiBTdXBwb3J0VGltZU9wdGlvbnMgfCBib29sZWFuO1xuICBASW5wdXQoKSBleHRyYUZvb3Rlcj86IFRlbXBsYXRlUmVmPHZvaWQ+IHwgc3RyaW5nO1xuICBASW5wdXQoKSByYW5nZXM/OiBQcmVzZXRSYW5nZXM7XG4gIEBJbnB1dCgpIGRhdGVSZW5kZXI/OiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjxEYXRlPiB8IEZ1bmN0aW9uUHJvcDxUZW1wbGF0ZVJlZjxEYXRlPiB8IHN0cmluZz47XG4gIEBJbnB1dCgpIHBhbmVsTW9kZSE6IE56RGF0ZU1vZGUgfCBOekRhdGVNb2RlW107XG4gIEBJbnB1dCgpIGRlZmF1bHRQaWNrZXJWYWx1ZSE6IENvbXBhdGlibGVEYXRlIHwgdW5kZWZpbmVkIHwgbnVsbDtcbiAgQElucHV0KCkgZGlyOiBEaXJlY3Rpb24gPSAnbHRyJztcblxuICBAT3V0cHV0KCkgcmVhZG9ubHkgcGFuZWxNb2RlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxOekRhdGVNb2RlIHwgTnpEYXRlTW9kZVtdPigpO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgY2FsZW5kYXJDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPENvbXBhdGlibGVWYWx1ZT4oKTtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IHJlc3VsdE9rID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpOyAvLyBFbWl0dGVkIHdoZW4gZG9uZSB3aXRoIGRhdGUgc2VsZWN0aW5nXG5cbiAgcHJlZml4Q2xzOiBzdHJpbmcgPSBQUkVGSVhfQ0xBU1M7XG4gIGVuZFBhbmVsTW9kZTogTnpEYXRlTW9kZSB8IE56RGF0ZU1vZGVbXSA9ICdkYXRlJztcbiAgdGltZU9wdGlvbnM6IFN1cHBvcnRUaW1lT3B0aW9ucyB8IFN1cHBvcnRUaW1lT3B0aW9uc1tdIHwgbnVsbCA9IG51bGw7XG4gIGhvdmVyVmFsdWU6IFNpbmdsZVZhbHVlW10gPSBbXTsgLy8gUmFuZ2UgT05MWVxuICBjaGVja2VkUGFydEFycjogYm9vbGVhbltdID0gW2ZhbHNlLCBmYWxzZV07XG4gIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8Ym9vbGVhbj4oKTtcblxuICBnZXQgaGFzVGltZVBpY2tlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLnNob3dUaW1lO1xuICB9XG5cbiAgZ2V0IGhhc0Zvb3RlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gd