ng-devui
Version:
DevUI components based on Angular
417 lines • 53.3 kB
JavaScript
import { CdkOverlayOrigin } from '@angular/cdk/overlay';
import { DOCUMENT } from '@angular/common';
import { ChangeDetectorRef, Component, ElementRef, EventEmitter, HostListener, Inject, Input, Output, Renderer2, TemplateRef, ViewContainerRef, forwardRef, } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { I18nService } from 'ng-devui/i18n';
import { AppendToBodyDirectionsConfig, DefaultDateConverter, addClassToOrigin, fadeInOut, formWithDropDown, removeClassFromOrigin, } from 'ng-devui/utils';
import { fromEvent } from 'rxjs';
import { debounceTime, filter, map } from 'rxjs/operators';
import { SelectDateChangeReason } from './date-change-event-args.model';
import { DatePickerConfigService as DatePickerConfig } from './date-picker.config.service';
import * as i0 from "@angular/core";
import * as i1 from "./date-picker.config.service";
import * as i2 from "ng-devui/i18n";
import * as i3 from "@angular/cdk/overlay";
import * as i4 from "./datepicker.component";
export class DatePickerAppendToBodyComponent {
set showTime(showTime) {
this._showTime = showTime;
}
get showTime() {
return typeof this._showTime === 'boolean' ? this._showTime : this.dateConfig.timePicker;
}
set dateConfig(dateConfig) {
if (this.checkDateConfig(dateConfig)) {
this._dateConfig = dateConfig;
}
else {
this._dateConfig = this.datePickerConfig.dateConfig;
}
this._dateFormat = this.showTime ? this._dateConfig.format.time : this._dateConfig.format.date;
}
get dateConfig() {
return this._dateConfig;
}
set dateFormat(dateFormat) {
if (dateFormat && this._dateFormat !== dateFormat) {
this._dateFormat = dateFormat;
this.writeModelValue({ selectedDate: this.selectedDate, reason: SelectDateChangeReason.format });
}
}
get dateFormat() {
return this._dateFormat || this.datePickerConfig.defaultFormat;
}
set maxDate(date) {
const parseDate = this.dateConverter.parse(date, this.dateFormat, this.locale || this.i18nLocale);
if (parseDate) {
this._maxDate = parseDate;
}
}
get maxDate() {
return this._maxDate;
}
set minDate(date) {
const parseDate = this.dateConverter.parse(date, this.dateFormat, this.locale || this.i18nLocale);
if (parseDate) {
this._minDate = parseDate;
}
}
get minDate() {
return this._minDate;
}
set isOpen(open) {
if (this._isOpen !== open) {
this._isOpen = open;
if (!open) {
this.startAnimation = false;
removeClassFromOrigin(this.elementRef);
this.document.removeEventListener('click', this.onDocumentClick);
}
else {
setTimeout(() => {
this.startAnimation = true;
this.cdr.detectChanges();
addClassToOrigin(this.elementRef);
this.document.addEventListener('click', this.onDocumentClick);
});
}
}
}
get isOpen() {
return this._isOpen;
}
constructor(elementRef, viewContainerRef, renderer2, datePickerConfig, i18n, cdr, doc) {
this.elementRef = elementRef;
this.viewContainerRef = viewContainerRef;
this.renderer2 = renderer2;
this.datePickerConfig = datePickerConfig;
this.i18n = i18n;
this.cdr = cdr;
this.doc = doc;
this.appendToBodyDirections = ['rightDown', 'leftDown', 'rightUp', 'leftUp'];
this.autoOpen = false;
this.showAnimation = false;
this.selectedDateChange = new EventEmitter();
this._isOpen = false;
this.datepickerPosition = 'bottom';
this.startAnimation = false;
this.onChange = (_) => null;
this.onTouched = () => null;
this.onDocumentClick = ($event) => {
if (this.elementRef.nativeElement !== $event.target) {
this.isOpen = false;
this.cdr.markForCheck();
}
};
this.clearAll = (reason) => {
if (this.disabled) {
return;
}
this.writeValue(null);
this.selectedDate = null;
this.onChange(null);
this.onTouched();
const currentReason = typeof reason === 'number' ? reason : SelectDateChangeReason.custom;
this.selectedDateChange.emit({
reason: currentReason,
selectedDate: null,
});
};
this._dateConfig = datePickerConfig.dateConfig;
this.dateConverter = datePickerConfig.dateConfig.dateConverter || new DefaultDateConverter();
this.setI18nText();
this.document = this.doc;
}
onBlur($event) {
this.onTouched();
const value = this.elementRef.nativeElement.value;
if (!this.validateDate(value)) {
this.resetValue();
}
}
checkDateConfig(dateConfig) {
if (!dateConfig) {
return false;
}
if (typeof dateConfig.timePicker !== 'boolean' || !dateConfig.max || !dateConfig.min || !dateConfig.format) {
return false;
}
return true;
}
ngOnInit() {
this._minDate = this.minDate ? new Date(this.minDate) : new Date(this.dateConfig.min, 0, 1, 0, 0, 0);
this._maxDate = this.maxDate ? new Date(this.maxDate) : new Date(this.dateConfig.max, 11, 31, 23, 59, 59);
this.setPositions();
this.updateCdkConnectedOverlayOrigin();
if (this.autoOpen) {
this.isOpen = true;
}
this.valueChanges = this.registerInputEvent();
this.userInputSubscription = this.valueChanges.subscribe((source) => this.transUserInputToDatepicker(source));
}
ngOnChanges(changes) {
if (changes.appendToBodyDirections) {
this.setPositions();
}
}
registerOnChange(fn) {
this.onChange = fn;
}
registerOnTouched(fn) {
this.onTouched = fn;
}
registerInputEvent() {
return fromEvent(this.elementRef.nativeElement, 'keyup').pipe(map((e) => e.target.value), filter(() => !this.disabled), debounceTime(300));
}
writeValue(obj) {
this.selectedDate = obj ? this.dateConverter.parse(obj, this.dateFormat, this.locale || this.i18nLocale) : null;
const value = this.selectedDate ? this.dateConverter.format(this.selectedDate, this.dateFormat, this.locale || this.i18nLocale) : '';
this.renderer2.setProperty(this.elementRef.nativeElement, 'value', value);
}
setI18nText() {
this.i18nLocale = this.i18n.getI18nText().locale;
this.i18nSubscription = this.i18n.langChange().subscribe((data) => {
this.i18nLocale = data.locale;
});
}
timeChange(dateObj) {
this.writeValue(dateObj ? dateObj.selectedDate : null);
this.writeModelValue(dateObj);
if (dateObj &&
((dateObj.reason === SelectDateChangeReason.date && !this.showTime) || dateObj.reason === SelectDateChangeReason.button)) {
this.isOpen = false;
}
}
updateCdkConnectedOverlayOrigin() {
if (this.elementRef.nativeElement) {
this.cdkConnectedOverlayOrigin = new CdkOverlayOrigin(formWithDropDown(this.elementRef) || this.elementRef.nativeElement);
}
}
toggle(clickShow) {
if (clickShow === undefined) {
if (this.isOpen) {
this.hide();
}
else {
this.show();
}
}
else {
if (clickShow) {
this.show();
}
else {
this.hide();
}
}
}
hide() {
this.isOpen = false;
}
show() {
this.isOpen = true;
}
writeModelValue(selectDateObj) {
let selectDate;
let dateReason = SelectDateChangeReason.time;
if (selectDateObj && typeof selectDateObj === 'object' && Object.prototype.hasOwnProperty.call(selectDateObj, 'selectedDate')) {
selectDate = selectDateObj.selectedDate;
dateReason = selectDateObj.reason;
}
if (selectDate) {
selectDate = new Date(selectDate);
}
else {
selectDate = null;
}
this.onChange(selectDate); // 这行代码能触发ngModel绑定的变量值发生变化
this.onTouched();
this.selectedDateChange.emit({
reason: dateReason,
selectedDate: this.selectedDate,
});
}
onPositionChange(position) {
switch (position.connectionPair.overlayY) {
case 'top':
case 'center':
this.datepickerPosition = 'bottom';
break;
case 'bottom':
this.datepickerPosition = 'top';
break;
default:
}
}
setPositions() {
if (this.appendToBodyDirections && this.appendToBodyDirections.length > 0) {
this.positions = this.appendToBodyDirections
.map((position) => {
if (typeof position === 'string') {
return AppendToBodyDirectionsConfig[position];
}
else {
return position;
}
})
.filter((position) => position !== undefined);
}
else {
this.positions = undefined;
}
}
transUserInputToDatepicker(value) {
if (!value && !this.selectedDate) {
return;
}
if (!value) {
this.clearAll();
return;
}
const valueDate = new Date(value);
const valueFormat = valueDate && !isNaN(valueDate.getTime()) && this.dateConverter.format(valueDate, this.dateFormat, this.locale || this.i18nLocale);
if (new Date(valueFormat).getTime() === new Date(this.selectedDate).getTime() || !this.validateDate(value)) {
return;
}
if (this.showTime || this.disabled) {
this.resetValue();
}
else {
this.selectedDate = valueDate;
this.writeModelValue({
reason: SelectDateChangeReason.custom,
selectedDate: valueDate,
});
}
}
validateDate(value) {
const valueDate = new Date(value);
const valueFormat = valueDate && !isNaN(valueDate.getTime()) && this.dateConverter.format(valueDate, this.dateFormat, this.locale || this.i18nLocale);
if (!valueDate ||
value !== valueFormat ||
(value === valueFormat && (valueDate.getTime() < this.minDate.getTime() || valueDate.getTime() > this.maxDate.getTime()))) {
return false;
}
else {
return true;
}
}
resetValue() {
const resDate = this.selectedDate ? this.dateConverter.format(this.selectedDate, this.dateFormat, this.locale || this.i18nLocale) : '';
this.elementRef.nativeElement.value = resDate;
}
ngOnDestroy() {
if (this.i18nSubscription) {
this.i18nSubscription.unsubscribe();
}
if (this.userInputSubscription) {
this.userInputSubscription.unsubscribe();
}
this.document.removeEventListener('click', this.onDocumentClick);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DatePickerAppendToBodyComponent, deps: [{ token: i0.ElementRef }, { token: i0.ViewContainerRef }, { token: i0.Renderer2 }, { token: i1.DatePickerConfigService }, { token: i2.I18nService }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DatePickerAppendToBodyComponent, selector: "[dDatepicker][appendToBody]", inputs: { appendToBodyDirections: "appendToBodyDirections", locale: "locale", cssClass: "cssClass", disabled: "disabled", dateConverter: "dateConverter", customViewTemplate: "customViewTemplate", autoOpen: "autoOpen", showAnimation: "showAnimation", showTime: "showTime", dateConfig: "dateConfig", dateFormat: "dateFormat", maxDate: "maxDate", minDate: "minDate" }, outputs: { selectedDateChange: "selectedDateChange" }, host: { listeners: { "blur": "onBlur($event)" } }, providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DatePickerAppendToBodyComponent),
multi: true,
},
], exportAs: ["datepicker"], usesOnChanges: true, ngImport: i0, template: `
<ng-template
cdk-connected-overlay
[cdkConnectedOverlayOrigin]="cdkConnectedOverlayOrigin"
[cdkConnectedOverlayPositions]="positions"
[cdkConnectedOverlayOpen]="isOpen"
(backdropClick)="isOpen = false"
(positionChange)="onPositionChange($event)"
>
<d-datepicker
[@fadeInOut]="startAnimation ? datepickerPosition : 'void'"
[locale]="locale || i18nLocale"
[@.disabled]="!showAnimation"
[showTime]="showTime"
[cssClass]="cssClass"
[selectedDate]="selectedDate"
[disabled]="disabled"
[dateConverter]="dateConverter"
(selectedDateChange)="timeChange($event)"
[dateConfig]="dateConfig"
[customViewTemplate]="customViewTemplate"
[maxDate]="maxDate"
[minDate]="minDate"
class="devui-datepicker"
></d-datepicker>
</ng-template>
`, isInline: true, styles: [".devui-datepicker{border-radius:var(--devui-border-radius, 2px);margin:4px 0}\n"], dependencies: [{ kind: "directive", type: i3.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "component", type: i4.DatepickerComponent, selector: "d-datepicker", inputs: ["cssClass", "dateConverter", "locale", "disabled", "customViewTemplate", "selectedDate", "mode", "dateFormat", "showTime", "dateConfig", "minDate", "maxDate"], outputs: ["selectedDateChange"] }], animations: [fadeInOut] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DatePickerAppendToBodyComponent, decorators: [{
type: Component,
args: [{ selector: '[dDatepicker][appendToBody]', providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DatePickerAppendToBodyComponent),
multi: true,
},
], exportAs: 'datepicker', template: `
<ng-template
cdk-connected-overlay
[cdkConnectedOverlayOrigin]="cdkConnectedOverlayOrigin"
[cdkConnectedOverlayPositions]="positions"
[cdkConnectedOverlayOpen]="isOpen"
(backdropClick)="isOpen = false"
(positionChange)="onPositionChange($event)"
>
<d-datepicker
[@fadeInOut]="startAnimation ? datepickerPosition : 'void'"
[locale]="locale || i18nLocale"
[@.disabled]="!showAnimation"
[showTime]="showTime"
[cssClass]="cssClass"
[selectedDate]="selectedDate"
[disabled]="disabled"
[dateConverter]="dateConverter"
(selectedDateChange)="timeChange($event)"
[dateConfig]="dateConfig"
[customViewTemplate]="customViewTemplate"
[maxDate]="maxDate"
[minDate]="minDate"
class="devui-datepicker"
></d-datepicker>
</ng-template>
`, animations: [fadeInOut], preserveWhitespaces: false, styles: [".devui-datepicker{border-radius:var(--devui-border-radius, 2px);margin:4px 0}\n"] }]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ViewContainerRef }, { type: i0.Renderer2 }, { type: i1.DatePickerConfigService }, { type: i2.I18nService }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
type: Inject,
args: [DOCUMENT]
}] }], propDecorators: { appendToBodyDirections: [{
type: Input
}], locale: [{
type: Input
}], cssClass: [{
type: Input
}], disabled: [{
type: Input
}], dateConverter: [{
type: Input
}], customViewTemplate: [{
type: Input
}], autoOpen: [{
type: Input
}], showAnimation: [{
type: Input
}], selectedDateChange: [{
type: Output
}], showTime: [{
type: Input
}], dateConfig: [{
type: Input
}], dateFormat: [{
type: Input
}], maxDate: [{
type: Input
}], minDate: [{
type: Input
}], onBlur: [{
type: HostListener,
args: ['blur', ['$event']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXBpY2tlci1jZGstb3ZlcmxheS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9kZXZ1aS9kYXRlcGlja2VyL2RhdGVwaWNrZXItY2RrLW92ZXJsYXkuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxnQkFBZ0IsRUFBNEUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsSSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFJTCxNQUFNLEVBQ04sU0FBUyxFQUVULFdBQVcsRUFDWCxnQkFBZ0IsRUFDaEIsVUFBVSxHQUNYLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBd0IsaUJBQWlCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RSxPQUFPLEVBQWlCLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRCxPQUFPLEVBRUwsNEJBQTRCLEVBRTVCLG9CQUFvQixFQUNwQixnQkFBZ0IsRUFDaEIsU0FBUyxFQUNULGdCQUFnQixFQUNoQixxQkFBcUIsR0FDdEIsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQTRCLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMzRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzRCxPQUFPLEVBQTZCLHNCQUFzQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDbkcsT0FBTyxFQUFFLHVCQUF1QixJQUFJLGdCQUFnQixFQUFFLE1BQU0sOEJBQThCLENBQUM7Ozs7OztBQTRDM0YsTUFBTSxPQUFPLCtCQUErQjtJQStCMUMsSUFBYSxRQUFRLENBQUMsUUFBaUI7UUFDckMsSUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUM7SUFDNUIsQ0FBQztJQUVELElBQUksUUFBUTtRQUNWLE9BQU8sT0FBTyxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUM7SUFDM0YsQ0FBQztJQUVELElBQWEsVUFBVSxDQUFDLFVBQWU7UUFDckMsSUFBSSxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDckMsSUFBSSxDQUFDLFdBQVcsR0FBRyxVQUFVLENBQUM7UUFDaEMsQ0FBQzthQUFNLENBQUM7WUFDTixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUM7UUFDdEQsQ0FBQztRQUNELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7SUFDakcsQ0FBQztJQUVELElBQUksVUFBVTtRQUNaLE9BQU8sSUFBSSxDQUFDLFdBQVcsQ0FBQztJQUMxQixDQUFDO0lBRUQsSUFBYSxVQUFVLENBQUMsVUFBa0I7UUFDeEMsSUFBSSxVQUFVLElBQUksSUFBSSxDQUFDLFdBQVcsS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUNsRCxJQUFJLENBQUMsV0FBVyxHQUFHLFVBQVUsQ0FBQztZQUM5QixJQUFJLENBQUMsZUFBZSxDQUFDLEVBQUUsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsTUFBTSxFQUFFLHNCQUFzQixDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDbkcsQ0FBQztJQUNILENBQUM7SUFFRCxJQUFJLFVBQVU7UUFDWixPQUFPLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLGFBQWEsQ0FBQztJQUNqRSxDQUFDO0lBRUQsSUFBYSxPQUFPLENBQUMsSUFBZ0I7UUFDbkMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDbEcsSUFBSSxTQUFTLEVBQUUsQ0FBQztZQUNkLElBQUksQ0FBQyxRQUFRLEdBQUcsU0FBUyxDQUFDO1FBQzVCLENBQUM7SUFDSCxDQUFDO0lBQ0QsSUFBSSxPQUFPO1FBQ1QsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxJQUFhLE9BQU8sQ0FBQyxJQUFnQjtRQUNuQyxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNsRyxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQ2QsSUFBSSxDQUFDLFFBQVEsR0FBRyxTQUFTLENBQUM7UUFDNUIsQ0FBQztJQUNILENBQUM7SUFDRCxJQUFJLE9BQU87UUFDVCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDdkIsQ0FBQztJQUVELElBQUksTUFBTSxDQUFDLElBQWE7UUFDdEIsSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLElBQUksRUFBRSxDQUFDO1lBQzFCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDO1lBQ3BCLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDVixJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQztnQkFDNUIscUJBQXFCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUN2QyxJQUFJLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDbkUsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLFVBQVUsQ0FBQyxHQUFHLEVBQUU7b0JBQ2QsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7b0JBQzNCLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7b0JBQ3pCLGdCQUFnQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztvQkFDbEMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO2dCQUNoRSxDQUFDLENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUksTUFBTTtRQUNSLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN0QixDQUFDO0lBRUQsWUFDVSxVQUFzQixFQUN0QixnQkFBa0MsRUFDbEMsU0FBb0IsRUFDcEIsZ0JBQWtDLEVBQ2xDLElBQWlCLEVBQ2pCLEdBQXNCLEVBQ0osR0FBUTtRQU4xQixlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3RCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBa0I7UUFDbEMsY0FBUyxHQUFULFNBQVMsQ0FBVztRQUNwQixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ2xDLFNBQUksR0FBSixJQUFJLENBQWE7UUFDakIsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFDSixRQUFHLEdBQUgsR0FBRyxDQUFLO1FBL0czQiwyQkFBc0IsR0FBcUQsQ0FBQyxXQUFXLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxRQUFRLENBQUMsQ0FBQztRQU0xSCxhQUFRLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLHVCQUFrQixHQUFHLElBQUksWUFBWSxFQUE2QixDQUFDO1FBRTdFLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFHaEIsdUJBQWtCLEdBQTBCLFFBQVEsQ0FBQztRQUNyRCxtQkFBYyxHQUFHLEtBQUssQ0FBQztRQWFmLGFBQVEsR0FBRyxDQUFDLENBQU0sRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDO1FBQzVCLGNBQVMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUM7UUEwTi9CLG9CQUFlLEdBQUcsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUMzQixJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxLQUFLLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDcEQsSUFBSSxDQUFDLE1BQU0sR0FBRyxLQUFLLENBQUM7Z0JBQ3BCLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDMUIsQ0FBQztRQUNILENBQUMsQ0FBQztRQTRFRixhQUFRLEdBQUcsQ0FBQyxNQUErQixFQUFFLEVBQUU7WUFDN0MsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7Z0JBQ2xCLE9BQU87WUFDVCxDQUFDO1lBQ0QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN0QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztZQUN6QixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3BCLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNqQixNQUFNLGFBQWEsR0FBRyxPQUFPLE1BQU0sS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsc0JBQXNCLENBQUMsTUFBTSxDQUFDO1lBQzFGLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUM7Z0JBQzNCLE1BQU0sRUFBRSxhQUFhO2dCQUNyQixZQUFZLEVBQUUsSUFBSTthQUNuQixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUM7UUFuT0EsSUFBSSxDQUFDLFdBQVcsR0FBRyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUM7UUFDL0MsSUFBSSxDQUFDLGFBQWEsR0FBRyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsYUFBYSxJQUFJLElBQUksb0JBQW9CLEVBQUUsQ0FBQztRQUM3RixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO0lBQzNCLENBQUM7SUFHRCxNQUFNLENBQUMsTUFBTTtRQUNYLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNqQixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUM7UUFDbEQsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUM5QixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDcEIsQ0FBQztJQUNILENBQUM7SUFFRCxlQUFlLENBQUMsVUFBZTtRQUM3QixJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDaEIsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBQ0QsSUFBSSxPQUFPLFVBQVUsQ0FBQyxVQUFVLEtBQUssU0FBUyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDM0csT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsUUFBUTtRQUNOLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDckcsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUMxRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLCtCQUErQixFQUFFLENBQUM7UUFDdkMsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDbEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7UUFDckIsQ0FBQztRQUNELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDOUMsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsMEJBQTBCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNoSCxDQUFDO0lBRUQsV0FBVyxDQUFDLE9BQXNCO1FBQ2hDLElBQUksT0FBTyxDQUFDLHNCQUFzQixFQUFFLENBQUM7WUFDbkMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3RCLENBQUM7SUFDSCxDQUFDO0lBRUQsZ0JBQWdCLENBQUMsRUFBTztRQUN0QixJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQsaUJBQWlCLENBQUMsRUFBTztRQUN2QixJQUFJLENBQUMsU0FBUyxHQUFHLEVBQUUsQ0FBQztJQUN0QixDQUFDO0lBRUQsa0JBQWtCO1FBQ2hCLE9BQU8sU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FDM0QsR0FBRyxDQUFDLENBQUMsQ0FBTSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUMvQixNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQzVCLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FDbEIsQ0FBQztJQUNKLENBQUM7SUFFRCxVQUFVLENBQUMsR0FBUTtRQUNqQixJQUFJLENBQUMsWUFBWSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNoSCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNySSxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsRUFBRSxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDNUUsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDO1FBQ2pELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ2hFLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUNoQyxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxVQUFVLENBQUMsT0FBTztRQUNoQixJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUM5QixJQUNFLE9BQU87WUFDUCxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sS0FBSyxzQkFBc0IsQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxzQkFBc0IsQ0FBQyxNQUFNLENBQUMsRUFDeEgsQ0FBQztZQUNELElBQUksQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLENBQUM7SUFDSCxDQUFDO0lBRUQsK0JBQStCO1FBQzdCLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNsQyxJQUFJLENBQUMseUJBQXlCLEdBQUcsSUFBSSxnQkFBZ0IsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUM1SCxDQUFDO0lBQ0gsQ0FBQztJQUVELE1BQU0sQ0FBQyxTQUFtQjtRQUN4QixJQUFJLFNBQVMsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUM1QixJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDaEIsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2QsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNkLENBQUM7UUFDSCxDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksU0FBUyxFQUFFLENBQUM7Z0JBQ2QsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2QsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNkLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVELElBQUk7UUFDRixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztJQUN0QixDQUFDO0lBRUQsSUFBSTtRQUNGLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO0lBQ3JCLENBQUM7SUFFTyxlQUFlLENBQUMsYUFBa0I7UUFDeEMsSUFBSSxVQUFVLENBQUM7UUFDZixJQUFJLFVBQVUsR0FBRyxzQkFBc0IsQ0FBQyxJQUFJLENBQUM7UUFDN0MsSUFBSSxhQUFhLElBQUksT0FBTyxhQUFhLEtBQUssUUFBUSxJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsY0FBYyxDQUFDLEVBQUUsQ0FBQztZQUM5SCxVQUFVLEdBQUcsYUFBYSxDQUFDLFlBQVksQ0FBQztZQUN4QyxVQUFVLEdBQUcsYUFBYSxDQUFDLE1BQU0sQ0FBQztRQUNwQyxDQUFDO1FBQ0QsSUFBSSxVQUFVLEVBQUUsQ0FBQztZQUNmLFVBQVUsR0FBRyxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNwQyxDQUFDO2FBQU0sQ0FBQztZQUNOLFVBQVUsR0FBRyxJQUFJLENBQUM7UUFDcEIsQ0FBQztRQUNELElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQywyQkFBMkI7UUFDdEQsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUM7WUFDM0IsTUFBTSxFQUFFLFVBQVU7WUFDbEIsWUFBWSxFQUFFLElBQUksQ0FBQyxZQUFZO1NBQ2hDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFTRCxnQkFBZ0IsQ0FBQyxRQUF3QztRQUN2RCxRQUFRLFFBQVEsQ0FBQyxjQUFjLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDM0MsS0FBSyxLQUFLLENBQUM7WUFDWCxLQUFLLFFBQVE7Z0JBQ1gsSUFBSSxDQUFDLGtCQUFrQixHQUFHLFFBQVEsQ0FBQztnQkFDbkMsTUFBTTtZQUNSLEtBQUssUUFBUTtnQkFDWCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsS0FBSyxDQUFDO2dCQUNoQyxNQUFNO1lBQ1IsUUFBUTtRQUNSLENBQUM7SUFDSCxDQUFDO0lBRUQsWUFBWTtRQUNWLElBQUksSUFBSSxDQUFDLHNCQUFzQixJQUFJLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDMUUsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsc0JBQXNCO2lCQUN6QyxHQUFHLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtnQkFDaEIsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLEVBQUUsQ0FBQztvQkFDakMsT0FBTyw0QkFBNEIsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDaEQsQ0FBQztxQkFBTSxDQUFDO29CQUNOLE9BQU8sUUFBUSxDQUFDO2dCQUNsQixDQUFDO1lBQ0gsQ0FBQyxDQUFDO2lCQUNELE1BQU0sQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsUUFBUSxLQUFLLFNBQVMsQ0FBQyxDQUFDO1FBQ2xELENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFDN0IsQ0FBQztJQUNILENBQUM7SUFFTywwQkFBMEIsQ0FBQyxLQUFLO1FBQ3RDLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDakMsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDaEIsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLFNBQVMsR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNsQyxNQUFNLFdBQVcsR0FDZixTQUFTLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxDQUFDLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDcEksSUFBSSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxPQUFPLEVBQUUsS0FBSyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDM0csT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ25DLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNwQixDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxZQUFZLEdBQUcsU0FBUyxDQUFDO1lBQzlCLElBQUksQ0FBQyxlQUFlLENBQUM7Z0JBQ25CLE1BQU0sRUFBRSxzQkFBc0IsQ0FBQyxNQUFNO2dCQUNyQyxZQUFZLEVBQUUsU0FBUzthQUN4QixDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQztJQUVELFlBQVksQ0FBQyxLQUFhO1FBQ3hCLE1BQU0sU0FBUyxHQUFHLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2xDLE1BQU0sV0FBVyxHQUNmLFNBQVMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNwSSxJQUNFLENBQUMsU0FBUztZQUNWLEtBQUssS0FBSyxXQUFXO1lBQ3JCLENBQUMsS0FBSyxLQUFLLFdBQVcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxJQUFJLFNBQVMsQ0FBQyxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsRUFDekgsQ0FBQztZQUNELE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBRUQsVUFBVTtRQUNSLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ3ZJLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLEtBQUssR0FBRyxPQUFPLENBQUM7SUFDaEQsQ0FBQztJQWlCRCxXQUFXO1FBQ1QsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUMxQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDdEMsQ0FBQztRQUNELElBQUksSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLHFCQUFxQixDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzNDLENBQUM7UUFDRCxJQUFJLENBQUMsUUFBUSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUM7SUFDbkUsQ0FBQzsrR0EvVlUsK0JBQStCLHdNQWdIaEMsUUFBUTttR0FoSFAsK0JBQStCLDhnQkF2Qy9CO1lBQ1Q7Z0JBQ0UsT0FBTyxFQUFFLGlCQUFpQjtnQkFDMUIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQywrQkFBK0IsQ0FBQztnQkFDOUQsS0FBSyxFQUFFLElBQUk7YUFDWjtTQUNGLHlFQUVTOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTBCVCxzNkNBQ1csQ0FBQyxTQUFTLENBQUM7OzRGQUlaLCtCQUErQjtrQkExQzNDLFNBQVM7K0JBRUUsNkJBQTZCLGFBQzVCO3dCQUNUOzRCQUNFLE9BQU8sRUFBRSxpQkFBaUI7NEJBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLGdDQUFnQyxDQUFDOzRCQUM5RCxLQUFLLEVBQUUsSUFBSTt5QkFDWjtxQkFDRixZQUNTLFlBQVksWUFDWjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EwQlQsY0FDVyxDQUFDLFNBQVMsQ0FBQyx1QkFFRixLQUFLOzswQkFrSHZCLE1BQU07MkJBQUMsUUFBUTt5Q0EvR1Qsc0JBQXNCO3NCQUE5QixLQUFLO2dCQUNHLE1BQU07c0JBQWQsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csYUFBYTtzQkFBckIsS0FBSztnQkFDRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDRyxhQUFhO3NCQUFyQixLQUFLO2dCQUNJLGtCQUFrQjtzQkFBM0IsTUFBTTtnQkFzQk0sUUFBUTtzQkFBcEIsS0FBSztnQkFRTyxVQUFVO3NCQUF0QixLQUFLO2dCQWFPLFVBQVU7c0JBQXRCLEtBQUs7Z0JBV08sT0FBTztzQkFBbkIsS0FBSztnQkFVTyxPQUFPO3NCQUFuQixLQUFLO2dCQWdETixNQUFNO3NCQURMLFlBQVk7dUJBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2RrT3ZlcmxheU9yaWdpbiwgQ29ubmVjdGVkT3ZlcmxheVBvc2l0aW9uQ2hhbmdlLCBDb25uZWN0ZWRQb3NpdGlvbiwgVmVydGljYWxDb25uZWN0aW9uUG9zIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xyXG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcbmltcG9ydCB7XHJcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgQ29tcG9uZW50LFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgRXZlbnRFbWl0dGVyLFxyXG4gIEhvc3RMaXN0ZW5lcixcclxuICBJbmplY3QsXHJcbiAgSW5wdXQsXHJcbiAgT25DaGFuZ2VzLFxyXG4gIE9uRGVzdHJveSxcclxuICBPbkluaXQsXHJcbiAgT3V0cHV0LFxyXG4gIFJlbmRlcmVyMixcclxuICBTaW1wbGVDaGFuZ2VzLFxyXG4gIFRlbXBsYXRlUmVmLFxyXG4gIFZpZXdDb250YWluZXJSZWYsXHJcbiAgZm9yd2FyZFJlZixcclxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQ29udHJvbFZhbHVlQWNjZXNzb3IsIE5HX1ZBTFVFX0FDQ0VTU09SIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgeyBJMThuSW50ZXJmYWNlLCBJMThuU2VydmljZSB9IGZyb20gJ25nLWRldnVpL2kxOG4nO1xyXG5pbXBvcnQge1xyXG4gIEFwcGVuZFRvQm9keURpcmVjdGlvbixcclxuICBBcHBlbmRUb0JvZHlEaXJlY3Rpb25zQ29uZmlnLFxyXG4gIERhdGVDb252ZXJ0ZXIsXHJcbiAgRGVmYXVsdERhdGVDb252ZXJ0ZXIsXHJcbiAgYWRkQ2xhc3NUb09yaWdpbixcclxuICBmYWRlSW5PdXQsXHJcbiAgZm9ybVdpdGhEcm9wRG93bixcclxuICByZW1vdmVDbGFzc0Zyb21PcmlnaW4sXHJcbn0gZnJvbSAnbmctZGV2dWkvdXRpbHMnO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb24sIGZyb21FdmVudCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUsIGZpbHRlciwgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQgeyBTZWxlY3REYXRlQ2hhbmdlRXZlbnRBcmdzLCBTZWxlY3REYXRlQ2hhbmdlUmVhc29uIH0gZnJvbSAnLi9kYXRlLWNoYW5nZS1ldmVudC1hcmdzLm1vZGVsJztcclxuaW1wb3J0IHsgRGF0ZVBpY2tlckNvbmZpZ1NlcnZpY2UgYXMgRGF0ZVBpY2tlckNvbmZpZyB9IGZyb20gJy4vZGF0ZS1waWNrZXIuY29uZmlnLnNlcnZpY2UnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgLyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEBhbmd1bGFyLWVzbGludC9jb21wb25lbnQtc2VsZWN0b3IqL1xyXG4gIHNlbGVjdG9yOiAnW2REYXRlcGlja2VyXVthcHBlbmRUb0JvZHldJyxcclxuICBwcm92aWRlcnM6IFtcclxuICAgIHtcclxuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXHJcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IERhdGVQaWNrZXJBcHBlbmRUb0JvZHlDb21wb25lbnQpLFxyXG4gICAgICBtdWx0aTogdHJ1ZSxcclxuICAgIH0sXHJcbiAgXSxcclxuICBleHBvcnRBczogJ2RhdGVwaWNrZXInLFxyXG4gIHRlbXBsYXRlOiBgXHJcbiAgICA8bmctdGVtcGxhdGVcclxuICAgICAgY2RrLWNvbm5lY3RlZC1vdmVybGF5XHJcbiAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5T3JpZ2luXT1cImNka0Nvbm5lY3RlZE92ZXJsYXlPcmlnaW5cIlxyXG4gICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheVBvc2l0aW9uc109XCJwb3NpdGlvbnNcIlxyXG4gICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheU9wZW5dPVwiaXNPcGVuXCJcclxuICAgICAgKGJhY2tkcm9wQ2xpY2spPVwiaXNPcGVuID0gZmFsc2VcIlxyXG4gICAgICAocG9zaXRpb25DaGFuZ2UpPVwib25Qb3NpdGlvbkNoYW5nZSgkZXZlbnQpXCJcclxuICAgID5cclxuICAgICAgPGQtZGF0ZXBpY2tlclxyXG4gICAgICAgIFtAZmFkZUluT3V0XT1cInN0YXJ0QW5pbWF0aW9uID8gZGF0ZXBpY2tlclBvc2l0aW9uIDogJ3ZvaWQnXCJcclxuICAgICAgICBbbG9jYWxlXT1cImxvY2FsZSB8fCBpMThuTG9jYWxlXCJcclxuICAgICAgICBbQC5kaXNhYmxlZF09XCIhc2hvd0FuaW1hdGlvblwiXHJcbiAgICAgICAgW3Nob3dUaW1lXT1cInNob3dUaW1lXCJcclxuICAgICAgICBbY3NzQ2xhc3NdPVwiY3NzQ2xhc3NcIlxyXG4gICAgICAgIFtzZWxlY3RlZERhdGVdPVwic2VsZWN0ZWREYXRlXCJcclxuICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxyXG4gICAgICAgIFtkYXRlQ29udmVydGVyXT1cImRhdGVDb252ZXJ0ZXJcIlxyXG4gICAgICAgIChzZWxlY3RlZERhdGVDaGFuZ2UpPVwidGltZUNoYW5nZSgkZXZlbnQpXCJcclxuICAgICAgICBbZGF0ZUNvbmZpZ109XCJkYXRlQ29uZmlnXCJcclxuICAgICAgICBbY3VzdG9tVmlld1RlbXBsYXRlXT1cImN1c3RvbVZpZXdUZW1wbGF0ZVwiXHJcbiAgICAgICAgW21heERhdGVdPVwibWF4RGF0ZVwiXHJcbiAgICAgICAgW21pbkRhdGVdPVwibWluRGF0ZVwiXHJcbiAgICAgICAgY2xhc3M9XCJkZXZ1aS1kYXRlcGlja2VyXCJcclxuICAgICAgPjwvZC1kYXRlcGlja2VyPlxyXG4gICAgPC9uZy10ZW1wbGF0ZT5cclxuICBgLFxyXG4gIGFuaW1hdGlvbnM6IFtmYWRlSW5PdXRdLFxyXG4gIHN0eWxlVXJsczogWycuL2RhdGVwaWNrZXItY2RrLW92ZXJsYXkuY29tcG9uZW50LnNjc3MnXSxcclxuICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBmYWxzZSxcclxufSlcclxuZXhwb3J0IGNsYXNzIERhdGVQaWNrZXJBcHBlbmRUb0JvZHlDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgT25EZXN0cm95LCBDb250cm9sVmFsdWVBY2Nlc3NvciB7XHJcbiAgQElucHV0KCkgYXBwZW5kVG9Cb2R5RGlyZWN0aW9uczogQXJyYXk8QXBwZW5kVG9Cb2R5RGlyZWN0aW9uIHwgQ29ubmVjdGVkUG9zaXRpb24+ID0gWydyaWdodERvd24nLCAnbGVmdERvd24nLCAncmlnaHRVcCcsICdsZWZ0VXAnXTtcclxuICBASW5wdXQoKSBsb2NhbGU6IHN0cmluZztcclxuICBASW5wdXQoKSBjc3NDbGFzczogc3RyaW5nO1xyXG4gIEBJbnB1dCgpIGRpc2FibGVkOiBib29sZWFuO1xyXG4gIEBJbnB1dCgpIGRhdGVDb252ZXJ0ZXI6IERhdGVDb252ZXJ0ZXI7XHJcbiAgQElucHV0KCkgY3VzdG9tVmlld1RlbXBsYXRlOiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG4gIEBJbnB1dCgpIGF1dG9PcGVuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgc2hvd0FuaW1hdGlvbiA9IGZhbHNlO1xyXG4gIEBPdXRwdXQoKSBzZWxlY3RlZERhdGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPFNlbGVjdERhdGVDaGFuZ2VFdmVudEFyZ3M+KCk7XHJcbiAgc2VsZWN0ZWREYXRlOiBEYXRlO1xyXG4gIF9pc09wZW4gPSBmYWxzZTtcclxuICBfZGF0ZUNvbmZpZzogYW55O1xyXG4gIHBvc2l0aW9uczogQ29ubmVjdGVkUG9zaXRpb25bXTtcclxuICBkYXRlcGlja2VyUG9zaXRpb246IFZlcnRpY2FsQ29ubmVjdGlvblBvcyA9ICdib3R0b20nO1xyXG4gIHN0YXJ0QW5pbWF0aW9uID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSBfZGF0ZUZvcm1hdDogc3RyaW5nO1xyXG4gIHByaXZhdGUgX21heERhdGU6IERhdGU7XHJcbiAgcHJpdmF0ZSBfbWluRGF0ZTogRGF0ZTtcclxuICBwcml2YXRlIF9zaG93VGltZTogYm9vbGVhbjtcclxuICBwcml2YXRlIHZhbHVlQ2hhbmdlczogT2JzZXJ2YWJsZTxhbnk+O1xyXG4gIHByaXZhdGUgdXNlcklucHV0U3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XHJcbiAgcHJpdmF0ZSBpMThuU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XHJcbiAgcHVibGljIGkxOG5Mb2NhbGU6IEkxOG5JbnRlcmZhY2VbJ2xvY2FsZSddO1xyXG5cclxuICBwdWJsaWMgY2RrQ29ubmVjdGVkT3ZlcmxheU9yaWdpbjogYW55O1xyXG4gIGRvY3VtZW50OiBEb2N1bWVudDtcclxuXHJcbiAgcHJpdmF0ZSBvbkNoYW5nZSA9IChfOiBhbnkpID0+IG51bGw7XHJcbiAgcHJpdmF0ZSBvblRvdWNoZWQgPSAoKSA9PiBudWxsO1xyXG5cclxuICBASW5wdXQoKSBzZXQgc2hvd1RpbWUoc2hvd1RpbWU6IGJvb2xlYW4pIHtcclxuICAgIHRoaXMuX3Nob3dUaW1lID0gc2hvd1RpbWU7XHJcbiAgfVxyXG5cclxuICBnZXQgc2hvd1RpbWUoKSB7XHJcbiAgICByZXR1cm4gdHlwZW9mIHRoaXMuX3Nob3dUaW1lID09PSAnYm9vbGVhbicgPyB0aGlzLl9zaG93VGltZSA6IHRoaXMuZGF0ZUNvbmZpZy50aW1lUGlja2VyO1xyXG4gIH1cclxuXHJcbiAgQElucHV0KCkgc2V0IGRhdGVDb25maWcoZGF0ZUNvbmZpZzogYW55KSB7XHJcbiAgICBpZiAodGhpcy5jaGVja0RhdGVDb25maWcoZGF0ZUNvbmZpZykpIHtcclxuICAgICAgdGhpcy5fZGF0ZUNvbmZpZyA9IGRhdGVDb25maWc7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLl9kYXRlQ29uZmlnID0gdGhpcy5kYXRlUGlja2VyQ29uZmlnLmRhdGVDb25maWc7XHJcbiAgICB9XHJcbiAgICB0aGlzLl9kYXRlRm9ybWF0ID0gdGhpcy5zaG93VGltZSA/IHRoaXMuX2RhdGVDb25maWcuZm9ybWF0LnRpbWUgOiB0aGlzLl9kYXRlQ29uZmlnLmZvcm1hdC5kYXRlO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGRhdGVDb25maWcoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fZGF0ZUNvbmZpZztcclxuICB9XHJcblxyXG4gIEBJbnB1dCgpIHNldCBkYXRlRm9ybWF0KGRhdGVGb3JtYXQ6IHN0cmluZykge1xyXG4gICAgaWYgKGRhdGVGb3JtYXQgJiYgdGhpcy5fZGF0ZUZvcm1hdCAhPT0gZGF0ZUZvcm1hdCkge1xyXG4gICAgICB0aGlzLl9kYXRlRm9ybWF0ID0gZGF0ZUZvcm1hdDtcclxuICAgICAgdGhpcy53cml0ZU1vZGVsVmFsdWUoeyBzZWxlY3RlZERhdGU6IHRoaXMuc2VsZWN0ZWREYXRlLCByZWFzb246IFNlbGVjdERhdGVDaGFuZ2VSZWFzb24uZm9ybWF0IH0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0IGRhdGVGb3JtYXQoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5fZGF0ZUZvcm1hdCB8fCB0aGlzLmRhdGVQaWNrZXJDb25maWcuZGVmYXVsdEZvcm1hdDtcclxuICB9XHJcblxyXG4gIEBJbnB1dCgpIHNldCBtYXhEYXRlKGRhdGU6IERhdGUgfCBhbnkpIHtcclxuICAgIGNvbnN0IHBhcnNlRGF0ZSA9IHRoaXMuZGF0ZUNvbnZlcnRlci5wYXJzZShkYXRlLCB0aGlzLmRhdGVGb3JtYXQsIHRoaXMubG9jYWxlIHx8IHRoaXMuaTE4bkxvY2FsZSk7XHJcbiAgICBpZiAocGFyc2VEYXRlKSB7XHJcbiAgICAgIHRoaXMuX21heERhdGUgPSBwYXJzZURhdGU7XHJcbiAgICB9XHJcbiAgfVxyXG4gIGdldCBtYXhEYXRlKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX21heERhdGU7XHJcbiAgfVxyXG5cclxuICBASW5wdXQoKSBzZXQgbWluRGF0ZShkYXRlOiBEYXRlIHwgYW55KSB7XHJcbiAgICBjb25zdCBwYXJzZURhdGUgPSB0aGlzLmRhdGVDb252ZXJ0ZXIucGFyc2UoZGF0ZSwgdGhpcy5kYXRlRm9ybWF0LCB0aGlzLmxvY2FsZSB8fCB0aGlzLmkxOG5Mb2NhbGUpO1xyXG4gICAgaWYgKHBhcnNlRGF0ZSkge1xyXG4gICAgICB0aGlzLl9taW5EYXRlID0gcGFyc2VEYXRlO1xyXG4gICAgfVxyXG4gIH1cclxuICBnZXQgbWluRGF0ZSgpIHtcclxuICAgIHJldHVybiB0aGlzLl9taW5EYXRlO1xyXG4gIH1cclxuXHJcbiAgc2V0IGlzT3BlbihvcGVuOiBib29sZWFuKSB7XHJcbiAgICBpZiAodGhpcy5faXNPcGVuICE9PSBvcGVuKSB7XHJcbiAgICAgIHRoaXMuX2lzT3BlbiA9IG9wZW47XHJcbiAgICAgIGlmICghb3Blbikge1xyXG4gICAgICAgIHRoaXMuc3RhcnRBbmltYXRpb24gPSBmYWxzZTtcclxuICAgICAgICByZW1vdmVDbGFzc0Zyb21PcmlnaW4odGhpcy5lbGVtZW50UmVmKTtcclxuICAgICAgICB0aGlzLmRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5vbkRvY3VtZW50Q2xpY2spO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgdGhpcy5zdGFydEFuaW1hdGlvbiA9IHRydWU7XHJcbiAgICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgICAgICAgICBhZGRDbGFzc1RvT3JpZ2luKHRoaXMuZWxlbWVudFJlZik7XHJcbiAgICAgICAgICB0aGlzLmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5vbkRvY3VtZW50Q2xpY2spO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXQgaXNPcGVuKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuX2lzT3BlbjtcclxuICB9XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxyXG4gICAgcHJpdmF0ZSB2aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmLFxyXG4gICAgcHJpdmF0ZSByZW5kZXJlcjI6IFJlbmRlcmVyMixcclxuICAgIHByaXZhdGUgZGF0ZVBpY2tlckNvbmZpZzogRGF0ZVBpY2tlckNvbmZpZyxcclxuICAgIHByaXZhdGUgaTE4bjogSTE4blNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBwcml2YXRlIGRvYzogYW55XHJcbiAgKSB7XHJcbiAgICB0aGlzLl9kYXRlQ29uZmlnID0gZGF0ZVBpY2tlckNvbmZpZy5kYXRlQ29uZmlnO1xyXG4gICAgdGhpcy5kYXRlQ29udmVydGVyID0gZGF0ZVBpY2tlckNvbmZpZy5kYXRlQ29uZmlnLmRhdGVDb252ZXJ0ZXIgfHwgbmV3IERlZmF1bHREYXRlQ29udmVydGVyKCk7XHJcbiAgICB0aGlzLnNldEkxOG5UZXh0KCk7XHJcbiAgICB0aGlzLmRvY3VtZW50ID0gdGhpcy5kb2M7XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKCdibHVyJywgWyckZXZlbnQnXSlcclxuICBvbkJsdXIoJGV2ZW50KSB7XHJcbiAgICB0aGlzLm9uVG91Y2hlZCgpO1xyXG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC52YWx1ZTtcclxuICAgIGlmICghdGhpcy52YWxpZGF0ZURhdGUodmFsdWUpKSB7XHJcbiAgICAgIHRoaXMucmVzZXRWYWx1ZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY2hlY2tEYXRlQ29uZmlnKGRhdGVDb25maWc6IGFueSkge1xyXG4gICAgaWYgKCFkYXRlQ29uZmlnKSB7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuICAgIGlmICh0eXBlb2YgZGF0ZUNvbmZpZy50aW1lUGlja2VyICE9PSAnYm9vbGVhbicgfHwgIWRhdGVDb25maWcubWF4IHx8ICFkYXRlQ29uZmlnLm1pbiB8fCAhZGF0ZUNvbmZpZy5mb3JtYXQpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIHRoaXMuX21pbkRhdGUgPSB0aGlzLm1pbkRhdGUgPyBuZXcgRGF0ZSh0aGlzLm1pbkRhdGUpIDogbmV3IERhdGUodGhpcy5kYXRlQ29uZmlnLm1pbiwgMCwgMSwgMCwgMCwgMCk7XHJcbiAgICB0aGlzLl9tYXhEYXRlID0gdGhpcy5tYXhEYXRlID8gbmV3IERhdGUodGhpcy5tYXhEYXRlKSA6IG5ldyBEYXRlKHRoaXMuZGF0ZUNvbmZpZy5tYXgsIDExLCAzMSwgMjMsIDU5LCA1OSk7XHJcbiAgICB0aGlzLnNldFBvc2l0aW9ucygpO1xyXG4gICAgdGhpcy51cGRhdGVDZGtDb25uZWN0ZWRPdmVybGF5T3JpZ2luKCk7XHJcbiAgICBpZiAodGhpcy5hdXRvT3Blbikge1xyXG4gICAgICB0aGlzLmlzT3BlbiA9IHRydWU7XHJcbiAgICB9XHJcbiAgICB0aGlzLnZhbHVlQ2hhbmdlcyA9IHRoaXMucmVnaXN0ZXJJbnB1dEV2ZW50KCk7XHJcbiAgICB0aGlzLnVzZXJJbnB1dFN1YnNjcmlwdGlvbiA9IHRoaXMudmFsdWVDaGFuZ2VzLnN1YnNjcmliZSgoc291cmNlKSA9PiB0aGlzLnRyYW5zVXNlcklucHV0VG9EYXRlcGlja2VyKHNvdXJjZSkpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xyXG4gICAgaWYgKGNoYW5nZXMuYXBwZW5kVG9Cb2R5RGlyZWN0aW9ucykge1xyXG4gICAgICB0aGlzLnNldFBvc2l0aW9ucygpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLm9uQ2hhbmdlID0gZm47XHJcbiAgfVxyXG5cclxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLm9uVG91Y2hlZCA9IGZuO1xyXG4gIH1cclxuXHJcbiAgcmVnaXN0ZXJJbnB1dEV2ZW50KCkge1xyXG4gICAgcmV0dXJuIGZyb21FdmVudCh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJ2tleXVwJykucGlwZShcclxuICAgICAgbWFwKChlOiBhbnkpID0+IGUudGFyZ2V0LnZhbHVlKSxcclxuICAgICAgZmlsdGVyKCgpID0+ICF0aGlzLmRpc2FibGVkKSxcclxuICAgICAgZGVib3VuY2VUaW1lKDMwMClcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICB3cml0ZVZhbHVlKG9iajogYW55KTogdm9pZCB7XHJcbiAgICB0aGlzLnNlbGVjdGVkRGF0ZSA9IG9iaiA/IHRoaXMuZGF0ZUNvbnZlcnRlci5wYXJzZShvYmosIHRoaXMuZGF0ZUZvcm1hdCwgdGhpcy5sb2NhbGUgfHwgdGhpcy5pMThuTG9jYWxlKSA6IG51bGw7XHJcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuc2VsZWN0ZWREYXRlID8gdGhpcy5kYXRlQ29udmVydGVyLmZvcm1hdCh0aGlzLnNlbGVjdGVkRGF0ZSwgdGhpcy5kYXRlRm9ybWF0LCB0aGlzLmxvY2FsZSB8fCB0aGlzLmkxOG5Mb2NhbGUpIDogJyc7XHJcbiAgICB0aGlzLnJlbmRlcmVyMi5zZXRQcm9wZXJ0eSh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJ3ZhbHVlJywgdmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgc2V0STE4blRleHQoKSB7XHJcbiAgICB0aGlzLmkxOG5Mb2NhbGUgPSB0aGlzLmkxOG4uZ2V0STE4blRleHQoKS5sb2NhbGU7XHJcbiAgICB0aGlzLmkxOG5TdWJzY3JpcHRpb24gPSB0aGlzLmkxOG4ubGFuZ0NoYW5nZSgpLnN1YnNjcmliZSgoZGF0YSkgPT4ge1xyXG4gICAgICB0aGlzLmkxOG5Mb2NhbGUgPSBkYXRhLmxvY2FsZTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgdGltZUNoYW5nZShkYXRlT2JqKSB7XHJcbiAgICB0aGlzLndyaXRlVmFsdWUoZGF0ZU9iaiA/IGRhdGVPYmouc2VsZWN0ZWREYXRlIDogbnVsbCk7XHJcbiAgICB0aGlzLndyaXRlTW9kZWxWYWx1ZShkYXRlT2JqKTtcclxuICAgIGlmIChcclxuICAgICAgZGF0ZU9iaiAmJlxyXG4gICAgICAoKGRhdGVPYmoucmVhc29uID09PSBTZWxlY3REYXRlQ2hhbmdlUmVhc29uLmRhdGUgJiYgIXRoaXMuc2hvd1RpbWUpIHx8IGRhdGVPYmoucmVhc29uID09PSBTZWxlY3REYXRlQ2hhbmdlUmVhc29uLmJ1dHRvbilcclxuICAgICkge1xyXG4gICAgICB0aGlzLmlzT3BlbiA9IGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdXBkYXRlQ2RrQ29ubmVjdGVkT3ZlcmxheU9yaWdpbigpIHtcclxuICAgIGlmICh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCkge1xyXG4gICAgICB0aGlzLmNka0Nvbm5lY3RlZE92ZXJsYXlPcmlnaW4gPSBuZXcgQ2RrT3ZlcmxheU9yaWdpbihmb3JtV2l0aERyb3BEb3duKHRoaXMuZWxlbWVudFJlZikgfHwgdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgdG9nZ2xlKGNsaWNrU2hvdz86IGJvb2xlYW4pIHtcclxuICAgIGlmIChjbGlja1Nob3cgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICBpZiAodGhpcy5pc09wZW4pIHtcclxuICAgICAgICB0aGlzLmhpZGUoKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLnNob3coKTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKGNsaWNrU2hvdykge1xyXG4gICAgICAgIHRoaXMuc2hvdygpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuaGlkZSgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBoaWRlKCkge1xyXG4gICAgdGhpcy5pc09wZW4gPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIHNob3coKSB7XHJcbiAgICB0aGlzLmlzT3BlbiA9IHRydWU7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHdyaXRlTW9kZWxWYWx1ZShzZWxlY3REYXRlT2JqOiBhbnkpIHtcclxuICAgIGxldCBzZWxlY3REYXRlO1xyXG4gICAgbGV0IGRhdGVSZWFzb24gPSBTZWxlY3REYXRlQ2hhbmdlUmVhc29uLnRpbWU7XHJcbiAgICBpZiAoc2VsZWN0RGF0ZU9iaiAmJiB0eXBlb2Ygc2VsZWN0RGF0ZU9iaiA9PT0gJ29iamVjdCcgJiYgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNlbGVjdERhdGVPYmosICdzZWxlY3RlZERhdGUnKSkge1xyXG4gICAgICBzZWxlY3REYXRlID0gc2VsZWN0RGF0ZU9iai5zZWxlY3RlZERhdGU7XHJcbiAgICAgIGRhdGVSZWFzb24gPSBzZWxlY3REYXRlT2JqLnJlYXNvbjtcclxuICAgIH1cclxuICAgIGlmIChzZWxlY3REYXRlKSB7XHJcbiAgICAgIHNlbGVjdERhdGUgPSBuZXcgRGF0ZShzZWxlY3REYXRlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHNlbGVjdERhdGUgPSBudWxsO1xyXG4gICAgfVxyXG4gICAgdGhpcy5vbkNoYW5nZShzZWxlY3REYXRlKTsgLy8g6L+Z6KGM5Luj56CB6IO96Kem5Y+RbmdNb2RlbOe7keWumueahOWPmOmHj+WAvOWPkeeUn+WPmOWMllxyXG4gICAgdGhpcy5vblRvdWNoZWQoKTtcclxuICAgIHRoaXMuc2VsZWN0ZWREYXRlQ2hhbmdlLmVtaXQoe1xyXG4gICAgICByZWFzb246IGRhdGVSZWFzb24sXHJcbiAgICAgIHNlbGVjdGVkRGF0ZTogdGhpcy5zZWxlY3RlZERhdGUsXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIG9uRG9jdW1lbnRDbGljayA9ICgkZXZlbnQpID0+IHtcclxuICAgIGlmICh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCAhPT0gJGV2ZW50LnRhcmdldCkge1xyXG4gICAgICB0aGlzLmlzT3BlbiA9IGZhbHNlO1xyXG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICBvblBvc2l0aW9uQ2hhbmdlKHBvc2l0aW9uOiBDb25uZWN0ZWRPdmVybGF5UG9zaXRpb25DaGFuZ2UpIHtcclxuICAgIHN3aXRjaCAocG9zaXRpb24uY29ubmVjdGlvblBhaXIub3ZlcmxheVkpIHtcclxuICAgIGNhc2UgJ3RvcCc6XHJcbiAgICBjYXNlICdjZW50ZXInOlxyXG4gICAgICB0aGlzLmRhdGVwaWNrZXJQb3NpdGlvbiA9ICdib3R0b20nO1xyXG4gICAgICBicmVhaztcclxuICAgIGNhc2UgJ2JvdHRvbSc6XHJcbiAgICAgIHRoaXMuZGF0ZXBpY2tlclBvc2l0aW9uID0gJ3RvcCc7XHJcbiAgICAgIGJyZWFrO1xyXG4gICAgZGVmYXVsdDpcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHNldFBvc2l0aW9ucygpIHtcclxuICAgIGlmICh0aGlzLmFwcGVuZFRvQm9keURpcmVjdGlvbnMgJiYgdGhpcy5hcHBlbmRUb0JvZHlEaXJlY3Rpb25zLmxlbmd0aCA+IDApIHtcclxuICAgICAgdGhpcy5wb3NpdGlvbnMgPSB0aGlzLmFwcGVuZFRvQm9keURpcmVjdGlvbnNcclxuICAgICAgICAubWFwKChwb3NpdGlvbikgPT4ge1xyXG4gICAgICAgICAgaWYgKHR5cGVvZiBwb3NpdGlvbiA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICAgICAgcmV0dXJuIEFwcGVuZFRvQm9keURpcmVjdGlvbnNDb25maWdbcG9zaXRpb25dO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHBvc2l0aW9uO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pXHJcbiAgICAgICAgLmZpbHRlcigocG9zaXRpb24pID0+IHBvc2l0aW9uICE9PSB1bmRlZmluZWQpO1xyXG