ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
626 lines (622 loc) • 57.2 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: date-range-popup.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* @license
* Copyright Alibaba.com All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core';
import { CandyDate, cloneDate, sortRangeValue } from 'ng-zorro-antd/core/time';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { DatePickerService } from './date-picker.service';
import { getTimeConfig, isAllowedDate, PREFIX_CLASS } from './util';
export class DateRangePopupComponent {
/**
* @param {?} datePickerService
* @param {?} cdr
*/
constructor(datePickerService, cdr) {
this.datePickerService = datePickerService;
this.cdr = cdr;
this.panelModeChange = new EventEmitter();
this.calendarChange = new EventEmitter();
this.resultOk = new EventEmitter(); // Emitted when done with date selecting
// Emitted when done with date selecting
this.prefixCls = PREFIX_CLASS;
this.endPanelMode = 'date';
this.timeOptions = null;
this.hoverValue = []; // Range ONLY
// Range ONLY
this.destroy$ = new Subject();
this.disabledStartTime = (/**
* @param {?} value
* @return {?}
*/
(value) => {
return this.disabledTime && this.disabledTime(value, 'start');
});
this.disabledEndTime = (/**
* @param {?} value
* @return {?}
*/
(value) => {
return this.disabledTime && this.disabledTime(value, 'end');
});
}
/**
* @return {?}
*/
get hasTimePicker() {
return !!this.showTime;
}
/**
* @return {?}
*/
get hasFooter() {
return this.showToday || this.hasTimePicker || !!this.extraFooter || !!this.ranges;
}
/**
* @return {?}
*/
ngOnInit() {
this.datePickerService.valueChange$.pipe(takeUntil(this.destroy$)).subscribe((/**
* @return {?}
*/
() => {
this.initActiveDate();
this.cdr.markForCheck();
}));
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
// Parse showTime options
if (changes.showTime || changes.disabledTime) {
if (this.showTime) {
this.buildTimeOptions();
}
}
if (changes.panelMode) {
this.endPanelMode = this.panelMode;
}
}
/**
* @return {?}
*/
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
/**
* @return {?}
*/
initActiveDate() {
/** @type {?} */
const activeDate = this.datePickerService.hasValue()
? this.datePickerService.value
: this.datePickerService.makeValue((/** @type {?} */ (this.defaultPickerValue)));
this.datePickerService.setActiveDate(activeDate, !this.showTime);
}
/**
* @return {?}
*/
onClickOk() {
/** @type {?} */
const otherPart = this.datePickerService.activeInput === 'left' ? 'right' : 'left';
/** @type {?} */
const selectedValue = this.datePickerService.value;
if (this.isAllowed(selectedValue, true)) {
this.resultOk.emit();
}
else {
if (this.isRange && this.isOneAllowed((/** @type {?} */ (selectedValue)))) {
this.datePickerService.inputPartChange$.next(otherPart);
}
else {
this.datePickerService.inputPartChange$.next();
}
}
}
/**
* @param {?} value
* @return {?}
*/
onClickToday(value) {
this.changeValueFromSelect(value, !this.showTime);
}
/**
* @param {?} value
* @return {?}
*/
onDayHover(value) {
if (!this.isRange) {
return;
}
/** @type {?} */
const otherInputIndex = { left: 1, right: 0 }[this.datePickerService.activeInput];
/** @type {?} */
const base = (/** @type {?} */ (((/** @type {?} */ (this.datePickerService.value)))[otherInputIndex]));
if (base) {
if (base.isBeforeDay(value)) {
this.hoverValue = [base, value];
}
else {
this.hoverValue = [value, base];
}
}
}
/**
* @param {?} mode
* @param {?=} partType
* @return {?}
*/
onPanelModeChange(mode, partType) {
if (this.isRange) {
/** @type {?} */
const index = this.datePickerService.getActiveIndex(partType);
if (index === 0) {
this.panelMode = (/** @type {?} */ ([mode, this.panelMode[1]]));
}
else {
this.panelMode = (/** @type {?} */ ([this.panelMode[0], mode]));
}
}
else {
this.panelMode = mode;
}
// this.cdr.markForCheck();
this.panelModeChange.emit(this.panelMode);
}
/**
* @param {?} value
* @param {?} partType
* @return {?}
*/
onActiveDateChange(value, partType) {
if (this.isRange) {
if (partType === 'left') {
this.datePickerService.activeDate = [value, value.addMonths(1)];
}
else {
this.datePickerService.activeDate = [value.addMonths(-1), value];
}
}
else {
this.datePickerService.activeDate = value;
}
}
/**
* @param {?} value
* @param {?=} partType
* @return {?}
*/
onSelectTime(value, partType) {
if (this.isRange) {
/** @type {?} */
const newValue = (/** @type {?} */ (cloneDate(this.datePickerService.value)));
/** @type {?} */
const index = this.datePickerService.getActiveIndex(partType);
newValue[index] = this.overrideHms(value, newValue[index]);
this.datePickerService.setValue(newValue);
}
else {
/** @type {?} */
const newValue = this.overrideHms(value, (/** @type {?} */ (this.datePickerService.value)));
this.datePickerService.setValue(newValue); // If not select a date currently, use today
}
this.datePickerService.inputPartChange$.next();
this.buildTimeOptions();
}
/**
* @param {?} value
* @param {?=} emitValue
* @return {?}
*/
changeValueFromSelect(value, emitValue = true) {
if (this.isRange) {
/** @type {?} */
let selectedValue = (/** @type {?} */ (cloneDate(this.datePickerService.value)));
/** @type {?} */
let otherPart;
if (this.datePickerService.activeInput === 'left') {
otherPart = 'right';
selectedValue[0] = value;
}
else {
otherPart = 'left';
selectedValue[1] = value;
}
selectedValue = sortRangeValue(selectedValue);
this.hoverValue = selectedValue;
this.datePickerService.setValue(selectedValue);
this.datePickerService.setActiveDate(selectedValue, !this.showTime);
this.datePickerService.inputPartChange$.next();
if (!this.isAllowed(selectedValue)) {
return;
}
if (emitValue) {
// If the other input has value
if (this.isBothAllowed(selectedValue)) {
this.calendarChange.emit(selectedValue);
this.clearHoverValue();
this.datePickerService.emitValue$.next();
}
else {
this.calendarChange.emit([value.clone()]);
this.datePickerService.inputPartChange$.next((/** @type {?} */ (otherPart)));
}
}
}
else {
this.datePickerService.setValue(value);
this.datePickerService.setActiveDate(value, !this.showTime);
this.datePickerService.inputPartChange$.next();
if (!this.isAllowed(value)) {
return;
}
if (emitValue) {
this.datePickerService.emitValue$.next();
}
}
}
/**
* @param {?} panelMode
* @param {?=} partType
* @return {?}
*/
getPanelMode(panelMode, partType) {
if (this.isRange) {
return (/** @type {?} */ (panelMode[this.datePickerService.getActiveIndex(partType)]));
}
else {
return (/** @type {?} */ (panelMode));
}
}
// Get single value or part value of a range
/**
* @param {?=} partType
* @return {?}
*/
getValue(partType) {
if (this.isRange) {
return (((/** @type {?} */ (this.datePickerService.value))) || [])[this.datePickerService.getActiveIndex(partType)];
}
else {
return (/** @type {?} */ (this.datePickerService.value));
}
}
/**
* @param {?=} partType
* @return {?}
*/
getActiveDate(partType) {
if (this.isRange) {
return ((/** @type {?} */ (this.datePickerService.activeDate)))[this.datePickerService.getActiveIndex(partType)];
}
else {
return (/** @type {?} */ (this.datePickerService.activeDate));
}
}
/**
* @param {?} selectedValue
* @return {?}
*/
isOneAllowed(selectedValue) {
/** @type {?} */
const index = this.datePickerService.getActiveIndex();
/** @type {?} */
const disabledTimeArr = [this.disabledStartTime, this.disabledEndTime];
return isAllowedDate((/** @type {?} */ (selectedValue[index])), this.disabledDate, disabledTimeArr[index]);
}
/**
* @param {?} selectedValue
* @return {?}
*/
isBothAllowed(selectedValue) {
return (isAllowedDate((/** @type {?} */ (selectedValue[0])), this.disabledDate, this.disabledStartTime) &&
isAllowedDate((/** @type {?} */ (selectedValue[1])), this.disabledDate, this.disabledEndTime));
}
/**
* @param {?} value
* @param {?=} isBoth
* @return {?}
*/
isAllowed(value, isBoth = false) {
if (this.isRange) {
return isBoth ? this.isBothAllowed((/** @type {?} */ (value))) : this.isOneAllowed((/** @type {?} */ (value)));
}
else {
return isAllowedDate((/** @type {?} */ (value)), this.disabledDate, this.disabledTime);
}
}
/**
* @param {?=} partType
* @return {?}
*/
getTimeOptions(partType) {
if (this.showTime && this.timeOptions) {
return this.timeOptions instanceof Array ? this.timeOptions[this.datePickerService.getActiveIndex(partType)] : this.timeOptions;
}
return null;
}
/**
* @param {?} val
* @return {?}
*/
onClickPresetRange(val) {
/** @type {?} */
const value = typeof val === 'function' ? val() : val;
if (value) {
this.datePickerService.setValue([new CandyDate(value[0]), new CandyDate(value[1])]);
this.resultOk.emit();
}
}
/**
* @return {?}
*/
onPresetRangeMouseLeave() {
this.clearHoverValue();
}
/**
* @param {?} val
* @return {?}
*/
onHoverPresetRange(val) {
if (typeof val !== 'function') {
this.hoverValue = [new CandyDate(val[0]), new CandyDate(val[1])];
}
}
/**
* @param {?=} obj
* @return {?}
*/
getObjectKeys(obj) {
return obj ? Object.keys(obj) : [];
}
/**
* @param {?} partType
* @return {?}
*/
show(partType) {
/** @type {?} */
const hide = this.showTime && this.isRange && this.datePickerService.activeInput !== partType;
return !hide;
}
/**
* @private
* @return {?}
*/
clearHoverValue() {
this.hoverValue = [];
}
/**
* @private
* @return {?}
*/
buildTimeOptions() {
if (this.showTime) {
/** @type {?} */
const showTime = typeof this.showTime === 'object' ? this.showTime : {};
if (this.isRange) {
/** @type {?} */
const value = (/** @type {?} */ (this.datePickerService.value));
this.timeOptions = [this.overrideTimeOptions(showTime, value[0], 'start'), this.overrideTimeOptions(showTime, value[1], 'end')];
}
else {
this.timeOptions = this.overrideTimeOptions(showTime, (/** @type {?} */ (this.datePickerService.value)));
}
}
else {
this.timeOptions = null;
}
}
/**
* @private
* @param {?} origin
* @param {?} value
* @param {?=} partial
* @return {?}
*/
overrideTimeOptions(origin, value, partial) {
/** @type {?} */
let disabledTimeFn;
if (partial) {
disabledTimeFn = partial === 'start' ? this.disabledStartTime : this.disabledEndTime;
}
else {
disabledTimeFn = this.disabledTime;
}
return Object.assign(Object.assign({}, origin), getTimeConfig(value, disabledTimeFn));
}
/**
* @private
* @param {?} newValue
* @param {?} oldValue
* @return {?}
*/
overrideHms(newValue, oldValue) {
// tslint:disable-next-line:no-parameter-reassignment
newValue = newValue || new CandyDate();
// tslint:disable-next-line:no-parameter-reassignment
oldValue = oldValue || new CandyDate();
return oldValue.setHms(newValue.getHours(), newValue.getMinutes(), newValue.getSeconds());
}
}
DateRangePopupComponent.decorators = [
{ type: Component, args: [{
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
// tslint:disable-next-line: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" [ngStyle]="datePickerService?.arrowPositionStyle!"></div>
<div class="{{ prefixCls }}-panel-container">
<div class="{{ prefixCls }}-panels">
<ng-container *ngTemplateOutlet="tplRangePart; context: { partType: 'left' }"></ng-container>
<ng-container *ngTemplateOutlet="tplRangePart; context: { partType: 'right' }"></ng-container>
</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" 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">
<!-- TODO(@wenqi73) [selectedValue] [hoverValue] types-->
<inner-popup
*ngIf="show(partType)"
[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)"
(dayHover)="onDayHover($event)"
(selectDate)="changeValueFromSelect($event, !showTime)"
(selectTime)="onSelectTime($event, partType)"
(headerChange)="onActiveDateChange($event, partType)"
></inner-popup>
</ng-template>
<ng-template #tplFooter>
<calendar-footer
*ngIf="hasFooter"
[locale]="locale!"
[isRange]="isRange"
[showToday]="showToday"
[hasTimePicker]="hasTimePicker"
[okDisabled]="!isAllowed($any(datePickerService?.value))"
[extraFooter]="extraFooter"
[rangeQuickSelector]="ranges ? tplRangeQuickSelector : null"
(clickOk)="onClickOk()"
(clickToday)="onClickToday($event)"
></calendar-footer>
</ng-template>
<ng-template #tplRangePart let-partType="partType">
<div class="{{ prefixCls }}-panel">
<ng-container *ngTemplateOutlet="tplInnerPopup; context: { partType: partType }"></ng-container>
</div>
</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>
`
}] }
];
/** @nocollapse */
DateRangePopupComponent.ctorParameters = () => [
{ type: DatePickerService },
{ type: ChangeDetectorRef }
];
DateRangePopupComponent.propDecorators = {
isRange: [{ type: Input }],
showWeek: [{ type: Input }],
locale: [{ type: Input }],
format: [{ type: Input }],
placeholder: [{ type: Input }],
disabledDate: [{ type: Input }],
disabledTime: [{ type: Input }],
showToday: [{ type: Input }],
showTime: [{ type: Input }],
extraFooter: [{ type: Input }],
ranges: [{ type: Input }],
dateRender: [{ type: Input }],
panelMode: [{ type: Input }],
defaultPickerValue: [{ type: Input }],
panelModeChange: [{ type: Output }],
calendarChange: [{ type: Output }],
resultOk: [{ type: Output }]
};
if (false) {
/** @type {?} */
DateRangePopupComponent.prototype.isRange;
/** @type {?} */
DateRangePopupComponent.prototype.showWeek;
/** @type {?} */
DateRangePopupComponent.prototype.locale;
/** @type {?} */
DateRangePopupComponent.prototype.format;
/** @type {?} */
DateRangePopupComponent.prototype.placeholder;
/** @type {?} */
DateRangePopupComponent.prototype.disabledDate;
/** @type {?} */
DateRangePopupComponent.prototype.disabledTime;
/** @type {?} */
DateRangePopupComponent.prototype.showToday;
/** @type {?} */
DateRangePopupComponent.prototype.showTime;
/** @type {?} */
DateRangePopupComponent.prototype.extraFooter;
/** @type {?} */
DateRangePopupComponent.prototype.ranges;
/** @type {?} */
DateRangePopupComponent.prototype.dateRender;
/** @type {?} */
DateRangePopupComponent.prototype.panelMode;
/** @type {?} */
DateRangePopupComponent.prototype.defaultPickerValue;
/** @type {?} */
DateRangePopupComponent.prototype.panelModeChange;
/** @type {?} */
DateRangePopupComponent.prototype.calendarChange;
/** @type {?} */
DateRangePopupComponent.prototype.resultOk;
/** @type {?} */
DateRangePopupComponent.prototype.prefixCls;
/** @type {?} */
DateRangePopupComponent.prototype.endPanelMode;
/** @type {?} */
DateRangePopupComponent.prototype.timeOptions;
/** @type {?} */
DateRangePopupComponent.prototype.hoverValue;
/** @type {?} */
DateRangePopupComponent.prototype.destroy$;
/** @type {?} */
DateRangePopupComponent.prototype.disabledStartTime;
/** @type {?} */
DateRangePopupComponent.prototype.disabledEndTime;
/** @type {?} */
DateRangePopupComponent.prototype.datePickerService;
/** @type {?} */
DateRangePopupComponent.prototype.cdr;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1yYW5nZS1wb3B1cC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZy16b3Jyby1hbnRkL2RhdGUtcGlja2VyLyIsInNvdXJjZXMiOlsiZGF0ZS1yYW5nZS1wb3B1cC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBUUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBSUwsTUFBTSxFQUdOLGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUV2QixPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBZ0MsY0FBYyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHN0csT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvQixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFXMUQsT0FBTyxFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQUUsWUFBWSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBK0ZwRSxNQUFNLE9BQU8sdUJBQXVCOzs7OztJQWlDbEMsWUFBbUIsaUJBQW9DLEVBQVMsR0FBc0I7UUFBbkUsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFtQjtRQUFTLFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBbEJuRSxvQkFBZSxHQUFHLElBQUksWUFBWSxFQUE2QixDQUFDO1FBQ2hFLG1CQUFjLEdBQUcsSUFBSSxZQUFZLEVBQW1CLENBQUM7UUFDckQsYUFBUSxHQUFHLElBQUksWUFBWSxFQUFRLENBQUMsQ0FBQyx3Q0FBd0M7O1FBRWhHLGNBQVMsR0FBVyxZQUFZLENBQUM7UUFDakMsaUJBQVksR0FBOEIsTUFBTSxDQUFDO1FBQ2pELGdCQUFXLEdBQXFELElBQUksQ0FBQztRQUNyRSxlQUFVLEdBQWtCLEVBQUUsQ0FBQyxDQUFDLGFB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dkMsNENBQTZCOztJQUM3QiwyQ0FBaUQ7O0lBQ2pELDhDQUFrRDs7SUFDbEQseUNBQStCOztJQUMvQiw2Q0FBNEY7O0lBQzVGLDRDQUErQzs7SUFDL0MscURBQWdFOztJQUNoRSxrREFBbUY7O0lBQ25GLGlEQUF3RTs7SUFDeEUsMkNBQXVEOztJQUV2RCw0Q0FBaUM7O0lBQ2pDLCtDQUFpRDs7SUFDakQsOENBQXFFOztJQUNyRSw2Q0FBK0I7O0lBQy9CLDJDQUF5Qjs7SUE2THpCLG9EQUVFOztJQUVGLGtEQUVFOztJQXpMVSxvREFBMkM7O0lBQUUsc0NBQTZCIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEFsaWJhYmEuY29tIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3RW5jYXBzdWxhdGlvblxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgQ2FuZHlEYXRlLCBjbG9uZURhdGUsIENvbXBhdGlibGVWYWx1ZSwgU2luZ2xlVmFsdWUsIHNvcnRSYW5nZVZhbHVlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3RpbWUnO1xuaW1wb3J0IHsgRnVuY3Rpb25Qcm9wIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3R5cGVzJztcbmltcG9ydCB7IE56Q2FsZW5kYXJJMThuSW50ZXJmYWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9pMThuJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IERhdGVQaWNrZXJTZXJ2aWNlIH0gZnJvbSAnLi9kYXRlLXBpY2tlci5zZXJ2aWNlJztcbmltcG9ydCB7XG4gIENvbXBhdGlibGVEYXRlLFxuICBEaXNhYmxlZERhdGVGbixcbiAgRGlzYWJsZWRUaW1lRm4sXG4gIERpc2FibGVkVGltZVBhcnRpYWwsXG4gIE56RGF0ZU1vZGUsXG4gIFByZXNldFJhbmdlcyxcbiAgUmFuZ2VQYXJ0VHlwZSxcbiAgU3VwcG9ydFRpbWVPcHRpb25zXG59IGZyb20gJy4vc3RhbmRhcmQtdHlwZXMnO1xuaW1wb3J0IHsgZ2V0VGltZUNvbmZpZywgaXNBbGxvd2VkRGF0ZSwgUFJFRklYX0NMQVNTIH0gZnJvbSAnLi91dGlsJztcblxuQENvbXBvbmVudCh7XG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6Y29tcG9uZW50LXNlbGVjdG9yXG4gIHNlbGVjdG9yOiAnZGF0ZS1yYW5nZS1wb3B1cCcsXG4gIGV4cG9ydEFzOiAnZGF0ZVJhbmdlUG9wdXAnLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc1JhbmdlOyBlbHNlIHNpbmdsZVBhbmVsXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LXJhbmdlLXdyYXBwZXIge3sgcHJlZml4Q2xzIH19LWRhdGUtcmFuZ2Utd3JhcHBlclwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LXJhbmdlLWFycm93XCIgW25nU3R5bGVdPVwiZGF0ZVBpY2tlclNlcnZpY2U/LmFycm93UG9zaXRpb25TdHlsZSFcIj48L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInt7IHByZWZpeENscyB9fS1wYW5lbC1jb250YWluZXJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LXBhbmVsc1wiPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRwbFJhbmdlUGFydDsgY29udGV4dDogeyBwYXJ0VHlwZTogJ2xlZnQnIH1cIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0cGxSYW5nZVBhcnQ7IGNvbnRleHQ6IHsgcGFydFR5cGU6ICdyaWdodCcgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0cGxGb290ZXJcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8bmctdGVtcGxhdGUgI3NpbmdsZVBhbmVsPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cInt7IHByZWZpeENscyB9fS1wYW5lbC1jb250YWluZXIge3sgc2hvd1dlZWsgPyBwcmVmaXhDbHMgKyAnLXdlZWstbnVtYmVyJyA6ICcnIH19IHt7XG4gICAgICAgICAgaGFzVGltZVBpY2tlciA/IHByZWZpeENscyArICctdGltZScgOiAnJ1xuICAgICAgICB9fSB7eyBpc1JhbmdlID8gcHJlZml4Q2xzICsgJy1yYW5nZScgOiAnJyB9fVwiXG4gICAgICA+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ7eyBwcmVmaXhDbHMgfX0tcGFuZWxcIiB0YWJpbmRleD1cIi0xXCI+XG4gICAgICAgICAgPCEtLSBTaW5nbGUgT05MWSAtLT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidHBsSW5uZXJQb3B1cFwiPjwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0cGxGb290ZXJcIj48L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPG5nLXRlbXBsYXRlICN0cGxJbm5lclBvcHVwIGxldC1wYXJ0VHlwZT1cInBhcnRUeXBlXCI+XG4gICAgICA8IS0tIFRPRE8oQHdlbnFpNzMpIFtzZWxlY3RlZFZhbHVlXSBbaG92ZXJWYWx1ZV0gdHlwZXMtLT5cbiAgICAgIDxpbm5lci1wb3B1cFxuICAgICAgICAqbmdJZj1cInNob3cocGFydFR5cGUpXCJcbiAgICAgICAgW3Nob3dXZWVrXT1cInNob3dXZWVrXCJcbiAgICAgICAgW2VuZFBhbmVsTW9kZV09XCJnZXRQYW5lbE1vZGUoZW5kUGFuZWxNb2RlLCBwYXJ0VHlwZSlcIlxuICAgICAgICBbcGFydFR5cGVdPVwicGFydFR5cGVcIlxuICAgICAgICBbbG9jYWxlXT1cImxvY2FsZSFcIlxuICAgICAgICBbc2hvd1RpbWVQaWNrZXJdPVwiaGFzVGltZVBpY2tlclwiXG4gICAgICAgIFt0aW1lT3B0aW9uc109XCJnZXRUaW1lT3B0aW9ucyhwYXJ0VHlwZSlcIlxuICAgICAgICBbcGFuZWxNb2RlXT1cImdldFBhbmVsTW9kZShwYW5lbE1vZGUsIHBhcnRUeXBlKVwiXG4gICAgICAgIChwYW5lbE1vZGVDaGFuZ2UpPVwib25QYW5lbE1vZGVDaGFuZ2UoJGV2ZW50LCBwYXJ0VHlwZSlcIlxuICAgICAgICBbYWN0aXZlRGF0ZV09XCJnZXRBY3RpdmVEYXRlKHBhcnRUeXBlKVwiXG4gICAgICAgIFt2YWx1ZV09XCJnZXRWYWx1ZShwYXJ0VHlwZSlcIlxuICAgICAgICBbZGlzYWJsZWREYXRlXT1cImRpc2FibGVkRGF0ZVwiXG4gICAgICAgIFtkYXRlUmVuZGVyXT1cImRhdGVSZW5kZXJcIlxuICAgICAgICBbc2VsZWN0ZWRWYWx1ZV09XCIkYW55KGRhdGVQaWNrZXJTZXJ2aWNlPy52YWx1ZSlcIlxuICAgICAgICBbaG92ZXJWYWx1ZV09XCIkYW55KGhvdmVyVmFsdWUpXCJcbiAgICAgICAgKGRheUhvdmVyKT1cIm9uRGF5SG92ZXIoJGV2ZW50KVwiXG4gICAgICAgIChzZWxlY3REYXRlKT1cImNoYW5nZVZhbHVlRnJvbVNlbGVjdCgkZXZlbnQsICFzaG93VGltZSlcIlxuICAgICAgICAoc2VsZWN0VGltZSk9XCJvblNlbGVjdFRpbWUoJGV2ZW50LCBwYXJ0VHlwZSlcIlxuICAgICAgICAoaGVhZGVyQ2hhbmdlKT1cIm9uQWN0aXZlRGF0ZUNoYW5nZSgkZXZlbnQsIHBhcnRUeXBlKVwiXG4gICAgICA+PC9pbm5lci1wb3B1cD5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPG5nLXRlbXBsYXRlICN0cGxGb290ZXI+XG4gICAgICA8Y2FsZW5kYXItZm9vdGVyXG4gICAgICAgICpuZ0lmPVwiaGFzRm9vdGVyXCJcbiAgICAgICAgW2xvY2FsZV09XCJsb2NhbGUhXCJcbiAgICAgICAgW2lzUmFuZ2VdPVwiaXNSYW5nZVwiXG4gICAgICAgIFtzaG93VG9kYXldPVwic2hvd1RvZGF5XCJcbiAgICAgICAgW2hhc1RpbWVQaWNrZXJdPVwiaGFzVGltZVBpY2tlclwiXG4gICAgICAgIFtva0Rpc2FibGVkXT1cIiFpc0FsbG93ZWQoJGFueShkYXRlUGlja2VyU2VydmljZT8udmFsdWUpKVwiXG4gICAgICAgIFtleHRyYUZvb3Rlcl09XCJleHRyYUZvb3RlclwiXG4gICAgICAgIFtyYW5nZVF1aWNrU2VsZWN0b3JdPVwicmFuZ2VzID8gdHBsUmFuZ2VRdWlja1NlbGVjdG9yIDogbnVsbFwiXG4gICAgICAgIChjbGlja09rKT1cIm9uQ2xpY2tPaygpXCJcbiAgICAgICAgKGNsaWNrVG9kYXkpPVwib25DbGlja1RvZGF5KCRldmVudClcIlxuICAgICAgPjwvY2FsZW5kYXItZm9vdGVyPlxuICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICA8bmctdGVtcGxhdGUgI3RwbFJhbmdlUGFydCBsZXQtcGFydFR5cGU9XCJwYXJ0VHlwZVwiPlxuICAgICAgPGRpdiBjbGFzcz1cInt7IHByZWZpeENscyB9fS1wYW5lbFwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidHBsSW5uZXJQb3B1cDsgY29udGV4dDogeyBwYXJ0VHlwZTogcGFydFR5cGUgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgIDwhLS0gUmFuZ2UgT05MWTogUmFuZ2UgUXVpY2sgU2VsZWN0b3IgLS0+XG4gICAgPG5nLXRlbXBsYXRlICN0cGxSYW5nZVF1aWNrU2VsZWN0b3I+XG4gICAgICA8bGlcbiAgICAgICAgKm5nRm9yPVwibGV0IG5hbWUgb2YgZ2V0T2JqZWN0S2V5cyhyYW5nZXMpXCJcbiAgICAgICAgY2xhc3M9XCJ7eyBwcmVmaXhDbHMgfX0tcHJlc2V0XCJcbiAgICAgICAgKGNsaWNrKT1cIm9uQ2xpY2tQcmVzZXRSYW5nZShyYW5nZXMhW25hbWVdKVwiXG4gICAgICAgIChtb3VzZWVudGVyKT1cIm9uSG92ZXJQcmVzZXRSYW5nZShyYW5nZXMhW25hbWVdKVwiXG4gICAgICAgIChtb3VzZWxlYXZlKT1cIm9uUHJlc2V0UmFuZ2VNb3VzZUxlYXZlKClcIlxuICAgICAgPlxuICAgICAgICA8c3BhbiBjbGFzcz1cImFudC10YWcgYW50LXRhZy1ibHVlXCI+e3sgbmFtZSB9fTwvc3Bhbj5cbiAgICAgIDwvbGk+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgYFxufSlcbmV4cG9ydCBjbGFzcyBEYXRlUmFuZ2VQb3B1cENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBPbkRlc3Ryb3kge1xuICBASW5wdXQoKSBpc1JhbmdlITogYm9vbGVhbjtcbiAgQElucHV0KCkgc2hvd1dlZWshOiBib29sZWFuO1xuICBASW5wdXQoKSBsb2NhbGUhOiBOekNhbGVuZGFySTE4bkludGVyZmFjZSB8IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgZm9ybWF0ITogc3RyaW5nO1xuICBASW5wdXQoKSBwbGFjZWhvbGRlciE6IHN0cmluZyB8IHN0cmluZ1tdO1xuICBASW5wdXQoKSBkaXNhYmxlZERhdGU/OiBEaXNhYmxlZERhdGVGbjtcbiAgQElucHV0KCkgZGlzYWJsZWRUaW1lPzogRGlzYWJsZWRUaW1lRm47IC8vIFRoaXMgd2lsbCBsZWFkIHRvIHJlYnVpbGQgdGltZSBvcHRpb25zXG4gIEBJbnB1dCgpIHNob3dUb2RheSE6IGJvb2xlYW47XG4gIEBJbnB1dCgpIHNob3dUaW1lITogU3VwcG9ydFRpbWVPcHRpb25zIHwgYm9vbGVhbjtcbiAgQElucHV0KCkgZXh0cmFGb290ZXI/OiBUZW1wbGF0ZVJlZjx2b2lkPiB8IHN0cmluZztcbiAgQElucHV0KCkgcmFuZ2VzPzogUHJlc2V0UmFuZ2VzO1xuICBASW5wdXQoKSBkYXRlUmVuZGVyPzogc3RyaW5nIHwgVGVtcGxhdGVSZWY8RGF0ZT4gfCBGdW5jdGlvblByb3A8VGVtcGxhdGVSZWY8RGF0ZT4gfCBzdHJpbmc+O1xuICBASW5wdXQoKSBwYW5lbE1vZGUhOiBOekRhdGVNb2RlIHwgTnpEYXRlTW9kZVtdO1xuICBASW5wdXQoKSBkZWZhdWx0UGlja2VyVmFsdWUhOiBDb21wYXRpYmxlRGF0ZSB8IHVuZGVmaW5lZCB8IG51bGw7XG4gIEBPdXRwdXQoKSByZWFkb25seSBwYW5lbE1vZGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPE56RGF0ZU1vZGUgfCBOekRhdGVNb2RlW10+KCk7XG4gIEBPdXRwdXQoKSByZWFkb25seSBjYWxlbmRhckNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Q29tcGF0aWJsZVZhbHVlPigpO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgcmVzdWx0T2sgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7IC8vIEVtaXR0ZWQgd2hlbiBkb25lIHdpdGggZGF0ZSBzZWxlY3RpbmdcblxuICBwcmVmaXhDbHM6IHN0cmluZyA9IFBSRUZJWF9DTEFTUztcbiAgZW5kUGFuZWxNb2RlOiBOekRhdGVNb2RlIHwgTnpEYXRlTW9kZVtdID0gJ2RhdGUnO1xuICB0aW1lT3B0aW9uczogU3VwcG9ydFRpbWVPcHRpb25zIHwgU3VwcG9ydFRpbWVPcHRpb25zW10gfCBudWxsID0gbnVsbDtcbiAgaG92ZXJWYWx1ZTogU2luZ2xlVmFsdWVbXSA9IFtdOyAvLyBSYW5nZSBPTkxZXG4gIGRlc3Ryb3kkID0gbmV3IFN1YmplY3QoKTtcblxuICBnZXQgaGFzVGltZVBpY2tlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLnNob3dUaW1lO1xuICB9XG5cbiAgZ2V0IGhhc0Zvb3RlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zaG93VG9kYXkgfHwgdGhpcy5oYXNUaW1lUGlja2VyIHx8ICEhdGhpcy5leHRyYUZvb3RlciB8fCAhIXRoaXMucmFuZ2VzO1xuICB9XG5cbiAgY29uc3RydWN0b3IocHVibGljIGRhdGVQaWNrZXJTZXJ2aWNlOiBEYXRlUGlja2VyU2VydmljZSwgcHVibGljIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHt9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5kYXRlUGlja2VyU2VydmljZS52YWx1ZUNoYW5nZSQucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLmluaXRBY3RpdmVEYXRlKCk7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICAvLyBQYXJzZSBzaG93VGltZSBvcHRpb25zXG4gICAgaWYgKGNoYW5nZXMuc2hvd1RpbWUgfHwgY2hhbmdlcy5kaXNhYmxlZFRpbWUpIHtcbiAgICAgIGlmICh0aGlzLnNob3dUaW1lKSB7XG4gICAgICAgIHRoaXMuYnVpbGRUaW1lT3B0aW9ucygpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoY2hhbmdlcy5wYW5lbE1vZGUpIHtcbiAgICAgIHRoaXMuZW5kUGFuZWxNb2RlID0gdGhpcy5wYW5lbE1vZGU7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgaW5pdEFjdGl2ZURhdGUoKTogdm9pZCB7XG4gICAgY29uc3QgYWN0aXZlRGF0ZSA9IHRoaXMuZGF0ZVBpY2tlclNlcnZpY2UuaGFzVmFsdWUoKVxuICAgICAgPyB0aGlzLmRhdGVQaWNrZXJTZXJ2aWNlLnZhbHVlXG4gICAgICA6IHRoaXMuZGF0ZVBpY2tlclNlcnZpY2UubWFrZVZhbHVlKHRoaXMuZGVmYXVsdFBpY2tlclZhbHVlISk7XG4gICAgdGhpcy5kYXRlUGlja2VyU2VydmljZS5zZXRBY3RpdmVEYXRlKGFjdGl2ZURhdGUsICF0aGlzLnNob3dUaW1lKTtcbiAgfVxuXG4gIG9uQ2xpY2tPaygpOiB2b2lkIHtcbiAgICBjb25zdCBvdGhlclBhcnQgPSB0aGlzLmRhdGVQaWNrZXJTZXJ2aWNlLmFjdGl2ZUlucHV0ID09PSAnbGVmdCcgPyAncmlnaHQnIDogJ2xlZnQnO1xuICAgIGNvbnN0IHNlbGVjdGVkVmFsdWUgPSB0aGlzLmRhdGVQaWNrZXJTZXJ2aWNlLnZhbHVlO1xuICAgIGlmICh0aGlzLmlzQWxsb3dlZChzZWxlY3RlZFZhbHVlLCB0cnVlKSkge1xuICAgICAgdGhpcy5yZXN1bHRPay5lbWl0KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICh0aGlzLmlzUmFuZ2UgJiYgdGhpcy5pc09uZUFsbG93ZWQoc2VsZWN0ZWRWYWx1ZSBhcyBDYW5keURhdGVbXSkpIHtcbiAgICAgICAgdGhpcy5kYXRlUGlja2VyU2VydmljZS5pbnB1dFBhcnRDaGFuZ2UkLm5leHQob3RoZXJQYXJ0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZGF0ZVBpY2tlclNlcnZpY2UuaW5wdXRQYXJ0Q2hhbmdlJC5uZXh0KCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgb25DbGlja1RvZGF5KHZhbHVlOiBDYW5keURhdGUpOiB2b2lkIHtcbiAgICB0aGlzLmNoYW5nZVZhbHVlRnJvbVNlbGVjdCh2YWx1ZSwgIXRoaXMuc2hvd1RpbWUpO1xuICB9XG5cbiAgb25EYXlIb3Zlcih2YWx1ZTogQ2FuZHlEYXRlKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLmlzUmFuZ2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgb3RoZXJJbnB1dEluZGV4ID0geyBsZWZ0OiAxLCByaWdodDogMCB9W3RoaXMuZGF0ZVBpY2tlclNlcnZpY2UuYWN0aXZlSW5wdXRdO1xuICAgIGNvbnN0IGJhc2UgPSAodGhpcy5kYXRlUGlja2VyU2VydmljZS52YWx1ZSBhcyBDYW5keURhdGVbXSlbb3RoZXJJbnB1dEluZGV4XSE7XG4gICAgaWYgKGJhc2UpIHtcbiAgICAgIGlmIChiYXNlLmlzQmVmb3JlRGF5KHZhbHVlKSkge1xuICAgICAgICB0aGlzLmhvdmVyVmFsdWUgPSBbYmFzZSwgdmFsdWVdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5ob3ZlclZhbHVlID0gW3ZhbHVlLCBiYXNlXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBvblBhbmVsTW9kZUNoYW5nZShtb2RlOiBOekRhdGVNb2RlLCBwYXJ0VHlwZT86IFJhbmdlUGFydFR5cGUpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc1JhbmdlKSB7XG4gICAgICBjb25zdCBpbmRleCA9IHRoaXMuZGF0ZVBpY2tlclNlcnZpY2UuZ2V0QWN0aXZlSW5kZXgocGFydFR5cGUpO1xuICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgIHRoaXMucGFuZWxNb2RlID0gW21vZGUsIHRoaXMucGFuZWxNb2RlWzFdXSBhcyBOekRhdGVNb2RlW107XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLnBhbmVsTW9kZSA9IFt0aGlzLnBhbmVsTW9kZVswXSwgbW9kZV0gYXMgTnpEYXRlTW9kZVtdO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnBhbmVsTW9kZSA9IG1vZGU7XG4gICAgfVxuICAgIC8vIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIHRoaXMucGFuZWxNb2RlQ2hhbmdlLmVtaXQodGhpcy5wYW5lbE1vZGUpO1xuICB9XG5cbiAgb25BY3RpdmVEYXRlQ2hhbmdlKHZhbHVlOiBDYW5keURhdGUsIHBhcnRUeXBlOiBSYW5nZVBhcnRUeXBlKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNSYW5nZSkge1xuICAgICAgaWYgKHBhcnRUeXBlID09PSAnbGVmdCcpIHtcbiAgICAgICAgdGhpcy5kYXRlUGlja2VyU2VydmljZS5hY3RpdmVEYXRlID0gW3ZhbHVlLCB2YWx1ZS5hZGRNb250aHMoMSldO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5kYXRlUGlja2VyU2VydmljZS5hY3RpdmVEYXRlID0gW3ZhbHVlLmFkZE1vbnRocygtMSksIHZhbHVlXTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kYXRlUGlja2VyU2VydmljZS5hY3RpdmVEYXRlID0gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgb25TZWxlY3RUaW1lKHZhbHVlOiBDYW5keURhdGUsIHBhcnRUeXBlPzogUmFuZ2VQYXJ0VHlwZSk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzUmFuZ2UpIHtcbiAgICAgIGNvbnN0IG5ld1ZhbHVlID0gY2xvbmVEYXRlKHRoaXMuZGF0ZVBpY2tlclNlcnZpY2UudmFsdWUpIGFzIFNpbmdsZVZhbHVlW107XG4gICAgICBjb25zdCBpbmRleCA9IHRoaXMuZGF0ZVBpY2tlclNlcnZpY2UuZ2V0QWN0aXZlSW5kZXgocGFydFR5cGUpO1xuICAgICAgbmV3VmFsdWVbaW5kZXhdID0gdGhpcy5vdmVycmlkZUhtcyh2YWx1ZSwgbmV3VmFsdWVbaW5kZXhdKTtcbiAgICAgIHRoaXMuZGF0ZVBpY2tlclNlcnZpY2Uuc2V0VmFsdWUobmV3VmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBuZXdWYWx1ZSA9IHRoaXMub3ZlcnJpZGVIbXModmFsdWUsIHRoaXMuZGF0ZVBpY2tlclNlcnZpY2UudmFsdWUgYXMgQ2FuZHlEYXRlKTtcbiAgICAgIHRoaXMuZGF0ZVBpY2tlclNlcnZpY2Uuc2V0VmFsdWUobmV3VmFsdWUpOyAvLyBJZiBub3Qgc2VsZWN0IGEgZGF0ZSBjdXJyZW50bHksIHVzZSB0b2RheVxuICAgIH1cbiAgICB0aGlzLmRhdGVQaWNrZXJTZXJ2aWNlLmlucHV0UGFydENoYW5nZSQubmV4dCgpO1xuICAgIHRoaXMuYnVpbGRUaW1lT3B0aW9ucygpO1xuICB9XG5cbiAgY2hhbmdlVmFsdWVGcm9tU2VsZWN0KHZhbHVlOiBDYW5keURhdGUsIGVtaXRWYWx1ZTogYm9vbGVhbiA9IHRydWUpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc1JhbmdlKSB7XG4gICAgICBsZXQgc2VsZWN0ZWRWYWx1ZTogU2luZ2xlVmFsdWVbXSA9IGNsb25lRGF0ZSh0aGlzLmRhdGVQaWNrZXJTZXJ2aWNlLnZhbHVlKSBhcyBDYW5keURhdGVbXTtcbiAgICAgIGxldCBvdGhlclBhcnQ6IFJhbmdlUGFydFR5cGU7XG4gICAgICBpZiAodGhpcy5kYXRlUGlja2VyU2VydmljZS5hY3RpdmVJbnB1dCA9PT0gJ2xlZnQnKSB7XG4gICAgICAgIG90aGVyUGFydCA9ICdyaWdodCc7XG4gICAgICAgIHNlbGVjdGVkVmFsdWVbMF0gPSB2YWx1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG90aGVyUGFydCA9ICdsZWZ0JztcbiAgICAgICAgc2VsZWN0ZWRWYWx1ZVsxXSA9IHZhbHVlO1xuICAgICAgfVxuXG4gICAgICBzZWxlY3RlZFZhbHVlID0gc29ydFJhbmdlVmFsdWUoc2VsZWN0ZWRWYWx1ZSk7XG4gICAgICB0aGlzLmhvdmVyVmFsdWUgPSBzZWxlY3RlZFZhbHVlO1xuICAgICAgdGhpcy5kYXRlUGlja2VyU2VydmljZS5zZXRWYWx1ZShzZWxlY3RlZFZhbHVlKTtcbiAgICAgIHRoaXMuZGF0ZVBpY2tlclNlcnZpY2Uuc2V0QWN0aXZlRGF0ZShzZWxlY3RlZFZhbHVlLCAhdGhpcy5zaG93VGltZSk7XG4gICAgICB0aGlzLmRhdGVQaWNrZXJTZXJ2aWNlLmlucHV0UGFydENoYW5nZSQubmV4dCgpO1xuXG4gICAgICBpZiAoIXRoaXMuaXNBbGxvd