ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
627 lines (624 loc) • 54.8 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: picker.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
/**
* 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 { CdkConnectedOverlay, CdkOverlayOrigin } from '@angular/cdk/overlay';
import { DOCUMENT } from '@angular/common';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ContentChild, ElementRef, EventEmitter, Inject, Input, Output, QueryList, ViewChild, ViewChildren, ViewEncapsulation } from '@angular/core';
import { slideMotion } from 'ng-zorro-antd/core/animation';
import { CandyDate } from 'ng-zorro-antd/core/time';
import { DateHelperService } from 'ng-zorro-antd/i18n';
import { fromEvent, Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { DatePickerService } from './date-picker.service';
import { DateRangePopupComponent } from './date-range-popup.component';
import { PREFIX_CLASS } from './util';
export class NzPickerComponent {
/**
* @param {?} elementRef
* @param {?} dateHelper
* @param {?} changeDetector
* @param {?} datePickerService
* @param {?} doc
*/
constructor(elementRef, dateHelper, changeDetector, datePickerService, doc) {
this.elementRef = elementRef;
this.dateHelper = dateHelper;
this.changeDetector = changeDetector;
this.datePickerService = datePickerService;
this.noAnimation = false;
this.isRange = false;
this.open = undefined;
this.disabled = false;
this.popupStyle = null;
this.focusChange = new EventEmitter();
this.valueChange = new EventEmitter();
this.openChange = new EventEmitter(); // Emitted when overlay's open state change
this.destroy$ = new Subject();
this.prefixCls = PREFIX_CLASS;
this.activeBarStyle = { position: 'absolute' };
this.animationOpenState = false;
this.overlayOpen = false; // Available when "open"=undefined
// Available when "open"=undefined
this.overlayPositions = (/** @type {?} */ ([
{
offsetX: -12,
offsetY: 8,
originX: 'start',
originY: 'bottom',
overlayX: 'start',
overlayY: 'top'
},
{
offsetX: -12,
offsetY: -8,
originX: 'start',
originY: 'top',
overlayX: 'start',
overlayY: 'bottom'
},
{
offsetX: 12,
offsetY: 8,
originX: 'end',
originY: 'bottom',
overlayX: 'end',
overlayY: 'top'
},
{
offsetX: 12,
offsetY: -8,
originX: 'end',
originY: 'top',
overlayX: 'end',
overlayY: 'bottom'
}
]));
this.currentPositionX = 'start';
this.currentPositionY = 'bottom';
this.document = doc;
this.origin = new CdkOverlayOrigin(this.elementRef);
this.updateInputValue();
}
/**
* @return {?}
*/
get realOpenState() {
// The value that really decide the open state of overlay
return this.isOpenHandledByUser() ? !!this.open : this.overlayOpen;
}
/**
* @return {?}
*/
ngOnInit() {
this.inputSize = Math.max(10, this.format.length) + 2;
this.datePickerService.valueChange$.pipe(takeUntil(this.destroy$)).subscribe((/**
* @return {?}
*/
() => {
this.updateInputValue();
this.changeDetector.markForCheck();
}));
}
/**
* @return {?}
*/
ngAfterViewInit() {
if (this.autoFocus) {
this.focus();
}
if (this.isRange) {
fromEvent(window, 'resize')
.pipe(takeUntil(this.destroy$))
.subscribe((/**
* @return {?}
*/
() => {
this.resetInputWidthAndArrowLeft();
}));
}
this.datePickerService.inputPartChange$.pipe(takeUntil(this.destroy$)).subscribe((/**
* @param {?} partType
* @return {?}
*/
partType => {
var _a;
if (partType) {
this.datePickerService.activeInput = partType;
}
this.datePickerService.arrowPositionStyle = {
left: this.datePickerService.activeInput === 'left' ? '0px' : `${this.arrowLeft}px`
};
this.activeBarStyle = Object.assign(Object.assign(Object.assign({}, this.activeBarStyle), this.datePickerService.arrowPositionStyle), { width: `${this.inputWidth}px` });
if (this.document.activeElement !== this.getInput(this.datePickerService.activeInput)) {
this.focus();
}
(_a = this.panel) === null || _a === void 0 ? void 0 : _a.cdr.markForCheck();
this.changeDetector.markForCheck();
}));
}
/**
* @return {?}
*/
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
if (changes.open) {
this.animationStart();
}
}
/**
* @return {?}
*/
resetInputWidthAndArrowLeft() {
var _a, _b, _c;
this.inputWidth = ((_b = (_a = this.rangePickerInputs) === null || _a === void 0 ? void 0 : _a.first) === null || _b === void 0 ? void 0 : _b.nativeElement.offsetWidth) || 0;
this.arrowLeft = this.inputWidth + ((_c = this.separatorElement) === null || _c === void 0 ? void 0 : _c.nativeElement.offsetWidth) || 0;
}
/**
* @param {?=} partType
* @return {?}
*/
getInput(partType) {
return this.isRange
? partType === 'left'
? this.rangePickerInputs.first.nativeElement
: this.rangePickerInputs.last.nativeElement
: (/** @type {?} */ (this.pickerInput)).nativeElement;
}
/**
* @return {?}
*/
focus() {
this.getInput(this.datePickerService.activeInput).focus(); // Focus on the first input
}
/**
* @param {?=} partType
* @return {?}
*/
onFocus(partType) {
if (partType) {
this.datePickerService.inputPartChange$.next(partType);
}
this.focusChange.emit(true);
}
/**
* @return {?}
*/
onBlur() {
this.focusChange.emit(false);
}
// Show overlay content
/**
* @return {?}
*/
showOverlay() {
if (!this.realOpenState) {
this.resetInputWidthAndArrowLeft();
this.overlayOpen = true;
this.animationStart();
this.focus();
this.openChange.emit(true);
}
}
/**
* @return {?}
*/
hideOverlay() {
if (this.realOpenState) {
this.overlayOpen = false;
this.openChange.emit(false);
this.focus();
}
}
/**
* @return {?}
*/
showClear() {
return !this.disabled && !this.isEmptyValue(this.datePickerService.value) && !!this.allowClear;
}
/**
* @param {?} event
* @param {?=} partType
* @return {?}
*/
onClickInputBox(event, partType) {
event.stopPropagation();
if (!this.disabled && !this.isOpenHandledByUser()) {
this.showOverlay();
}
this.onFocus(partType);
}
/**
* @return {?}
*/
onClickBackdrop() {
if (this.panel.isAllowed((/** @type {?} */ (this.datePickerService.value)), true)) {
this.updateInputValue();
this.datePickerService.emitValue$.next();
}
else {
this.datePickerService.setValue((/** @type {?} */ (this.datePickerService.initialValue)));
this.hideOverlay();
}
}
/**
* @return {?}
*/
onOverlayDetach() {
this.hideOverlay();
}
/**
* @param {?} event
* @return {?}
*/
onOverlayKeydown(event) {
if (event.key === 'Escape') {
this.datePickerService.setValue((/** @type {?} */ (this.datePickerService.initialValue)));
}
}
// NOTE: A issue here, the first time position change, the animation will not be triggered.
// Because the overlay's "positionChange" event is emitted after the content's full shown up.
// All other components like "nz-dropdown" which depends on overlay also has the same issue.
// See: https://github.com/NG-ZORRO/ng-zorro-antd/issues/1429
/**
* @param {?} position
* @return {?}
*/
onPositionChange(position) {
this.currentPositionX = position.connectionPair.originX;
this.currentPositionY = position.connectionPair.originY;
this.changeDetector.detectChanges(); // Take side-effects to position styles
}
/**
* @param {?} event
* @return {?}
*/
onClickClear(event) {
event.preventDefault();
event.stopPropagation();
this.datePickerService.setValue(this.isRange ? [] : null);
this.datePickerService.emitValue$.next();
}
/**
* @return {?}
*/
updateInputValue() {
/** @type {?} */
const newValue = this.datePickerService.value;
if (this.isRange) {
this.inputValue = newValue ? ((/** @type {?} */ (newValue))).map((/**
* @param {?} v
* @return {?}
*/
v => this.formatValue(v))) : ['', ''];
}
else {
this.inputValue = this.formatValue((/** @type {?} */ (newValue)));
}
}
/**
* @param {?} value
* @return {?}
*/
formatValue(value) {
return this.dateHelper.format(value && ((/** @type {?} */ (value))).nativeDate, this.format);
}
/**
* @param {?} event
* @param {?=} isEnter
* @return {?}
*/
onInputKeyup(event, isEnter = false) {
if (isEnter && !this.realOpenState) {
this.showOverlay();
return;
}
/** @type {?} */
const date = this.checkValidInputDate((/** @type {?} */ (((/** @type {?} */ (event))).target)));
if (this.panel && date) {
this.panel.changeValueFromSelect(date, isEnter);
}
}
/**
* @private
* @param {?} inputTarget
* @return {?}
*/
checkValidInputDate(inputTarget) {
/** @type {?} */
const input = ((/** @type {?} */ (inputTarget))).value;
/** @type {?} */
const date = new CandyDate(this.dateHelper.parseDate(input, this.format));
if (!date.isValid() || input !== this.dateHelper.format(date.nativeDate, this.format)) {
return null;
}
return date;
}
/**
* @param {?=} partType
* @return {?}
*/
getPlaceholder(partType) {
return this.isRange ? this.placeholder[this.datePickerService.getActiveIndex((/** @type {?} */ (partType)))] : ((/** @type {?} */ (this.placeholder)));
}
/**
* @param {?} value
* @return {?}
*/
isEmptyValue(value) {
if (value === null) {
return true;
}
else if (this.isRange) {
return !value || !Array.isArray(value) || value.every((/**
* @param {?} val
* @return {?}
*/
val => !val));
}
else {
return !value;
}
}
// Whether open state is permanently controlled by user himself
/**
* @return {?}
*/
isOpenHandledByUser() {
return this.open !== undefined;
}
/**
* @return {?}
*/
animationStart() {
if (this.realOpenState) {
this.animationOpenState = true;
}
}
/**
* @return {?}
*/
animationDone() {
if (!this.realOpenState) {
this.animationOpenState = false;
this.changeDetector.markForCheck();
}
}
}
NzPickerComponent.decorators = [
{ type: Component, args: [{
encapsulation: ViewEncapsulation.None,
selector: '[nz-picker]',
exportAs: 'nzPicker',
template: `
<!-- Content of single picker -->
<div *ngIf="!isRange" class="{{ prefixCls }}-input">
<input
#pickerInput
[class.ant-input-disabled]="disabled"
[disabled]="disabled"
[(ngModel)]="inputValue"
placeholder="{{ getPlaceholder() }}"
[size]="inputSize"
(focus)="onFocus()"
(blur)="onBlur()"
(input)="onInputKeyup($event)"
(keyup.enter)="onInputKeyup($event, true)"
/>
<ng-container *ngTemplateOutlet="tplRightRest"></ng-container>
</div>
<!-- Content of range picker -->
<ng-container *ngIf="isRange">
<div class="{{ prefixCls }}-input">
<ng-container *ngTemplateOutlet="tplRangeInput; context: { partType: 'left' }"></ng-container>
</div>
<div #separatorElement class="{{ prefixCls }}-range-separator">
<span class="{{ prefixCls }}-separator">
<ng-container *ngIf="separator; else defaultSeparator">{{ separator }}</ng-container>
</span>
<ng-template #defaultSeparator>
<i nz-icon nzType="swap-right" nzTheme="outline"></i>
</ng-template>
</div>
<div class="{{ prefixCls }}-input">
<ng-container *ngTemplateOutlet="tplRangeInput; context: { partType: 'right' }"></ng-container>
</div>
<ng-container *ngTemplateOutlet="tplRightRest"></ng-container>
</ng-container>
<!-- Input for Range ONLY -->
<ng-template #tplRangeInput let-partType="partType">
<input
#rangePickerInput
[disabled]="disabled"
[size]="inputSize"
(click)="onClickInputBox($event, partType)"
(blur)="onBlur()"
(input)="onInputKeyup($event, false)"
(focus)="onFocus(partType)"
(keyup.enter)="onInputKeyup($event, true)"
[(ngModel)]="inputValue[datePickerService.getActiveIndex(partType)]"
placeholder="{{ getPlaceholder(partType) }}"
/>
</ng-template>
<!-- Right operator icons -->
<ng-template #tplRightRest>
<div class="{{ prefixCls }}-active-bar" [ngStyle]="activeBarStyle"></div>
<span *ngIf="showClear()" class="{{ prefixCls }}-clear" (click)="onClickClear($event)">
<i nz-icon nzType="close-circle" nzTheme="fill"></i>
</span>
<span class="{{ prefixCls }}-suffix">
<ng-container *nzStringTemplateOutlet="suffixIcon; let suffixIcon">
<i nz-icon [nzType]="suffixIcon"></i>
</ng-container>
</span>
</ng-template>
<!-- Overlay -->
<ng-template
cdkConnectedOverlay
nzConnectedOverlay
[cdkConnectedOverlayOrigin]="origin"
[cdkConnectedOverlayOpen]="realOpenState"
[cdkConnectedOverlayHasBackdrop]="!isOpenHandledByUser()"
[cdkConnectedOverlayPositions]="overlayPositions"
[cdkConnectedOverlayTransformOriginOn]="'.ant-picker-wrapper'"
(positionChange)="onPositionChange($event)"
(backdropClick)="onClickBackdrop()"
(detach)="onOverlayDetach()"
(overlayKeydown)="onOverlayKeydown($event)"
>
<div
class="ant-picker-wrapper"
[nzNoAnimation]="noAnimation"
[@slideMotion]="'enter'"
(@slideMotion.done)="animationDone()"
style="position: relative;"
>
<div
class="{{ prefixCls }}-dropdown {{ dropdownClassName }}"
[class.ant-picker-dropdown-placement-bottomLeft]="currentPositionY === 'bottom' && currentPositionX === 'start'"
[class.ant-picker-dropdown-placement-topLeft]="currentPositionY === 'top' && currentPositionX === 'start'"
[class.ant-picker-dropdown-placement-bottomRight]="currentPositionY === 'bottom' && currentPositionX === 'end'"
[class.ant-picker-dropdown-placement-topRight]="currentPositionY === 'top' && currentPositionX === 'end'"
[class.ant-picker-dropdown-range]="isRange"
[ngStyle]="popupStyle"
>
<!-- Compatible for overlay that not support offset dynamically and immediately -->
<ng-content></ng-content>
</div>
</div>
</ng-template>
`,
animations: [slideMotion],
changeDetection: ChangeDetectionStrategy.OnPush
}] }
];
/** @nocollapse */
NzPickerComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: DateHelperService },
{ type: ChangeDetectorRef },
{ type: DatePickerService },
{ type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }
];
NzPickerComponent.propDecorators = {
noAnimation: [{ type: Input }],
isRange: [{ type: Input }],
open: [{ type: Input }],
disabled: [{ type: Input }],
placeholder: [{ type: Input }],
allowClear: [{ type: Input }],
autoFocus: [{ type: Input }],
format: [{ type: Input }],
separator: [{ type: Input }],
popupStyle: [{ type: Input }],
dropdownClassName: [{ type: Input }],
suffixIcon: [{ type: Input }],
focusChange: [{ type: Output }],
valueChange: [{ type: Output }],
openChange: [{ type: Output }],
cdkConnectedOverlay: [{ type: ViewChild, args: [CdkConnectedOverlay, { static: false },] }],
separatorElement: [{ type: ViewChild, args: ['separatorElement', { static: false },] }],
pickerInput: [{ type: ViewChild, args: ['pickerInput', { static: false },] }],
rangePickerInputs: [{ type: ViewChildren, args: ['rangePickerInput',] }],
panel: [{ type: ContentChild, args: [DateRangePopupComponent,] }]
};
if (false) {
/** @type {?} */
NzPickerComponent.prototype.noAnimation;
/** @type {?} */
NzPickerComponent.prototype.isRange;
/** @type {?} */
NzPickerComponent.prototype.open;
/** @type {?} */
NzPickerComponent.prototype.disabled;
/** @type {?} */
NzPickerComponent.prototype.placeholder;
/** @type {?} */
NzPickerComponent.prototype.allowClear;
/** @type {?} */
NzPickerComponent.prototype.autoFocus;
/** @type {?} */
NzPickerComponent.prototype.format;
/** @type {?} */
NzPickerComponent.prototype.separator;
/** @type {?} */
NzPickerComponent.prototype.popupStyle;
/** @type {?} */
NzPickerComponent.prototype.dropdownClassName;
/** @type {?} */
NzPickerComponent.prototype.suffixIcon;
/** @type {?} */
NzPickerComponent.prototype.focusChange;
/** @type {?} */
NzPickerComponent.prototype.valueChange;
/** @type {?} */
NzPickerComponent.prototype.openChange;
/** @type {?} */
NzPickerComponent.prototype.cdkConnectedOverlay;
/** @type {?} */
NzPickerComponent.prototype.separatorElement;
/** @type {?} */
NzPickerComponent.prototype.pickerInput;
/** @type {?} */
NzPickerComponent.prototype.rangePickerInputs;
/** @type {?} */
NzPickerComponent.prototype.panel;
/** @type {?} */
NzPickerComponent.prototype.origin;
/** @type {?} */
NzPickerComponent.prototype.document;
/** @type {?} */
NzPickerComponent.prototype.inputSize;
/** @type {?} */
NzPickerComponent.prototype.inputWidth;
/** @type {?} */
NzPickerComponent.prototype.arrowLeft;
/** @type {?} */
NzPickerComponent.prototype.destroy$;
/** @type {?} */
NzPickerComponent.prototype.prefixCls;
/** @type {?} */
NzPickerComponent.prototype.inputValue;
/** @type {?} */
NzPickerComponent.prototype.activeBarStyle;
/** @type {?} */
NzPickerComponent.prototype.animationOpenState;
/** @type {?} */
NzPickerComponent.prototype.overlayOpen;
/** @type {?} */
NzPickerComponent.prototype.overlayPositions;
/** @type {?} */
NzPickerComponent.prototype.currentPositionX;
/** @type {?} */
NzPickerComponent.prototype.currentPositionY;
/**
* @type {?}
* @private
*/
NzPickerComponent.prototype.elementRef;
/**
* @type {?}
* @private
*/
NzPickerComponent.prototype.dateHelper;
/**
* @type {?}
* @private
*/
NzPickerComponent.prototype.changeDetector;
/** @type {?} */
NzPickerComponent.prototype.datePickerService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGlja2VyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLXpvcnJvLWFudGQvZGF0ZS1waWNrZXIvIiwic291cmNlcyI6WyJwaWNrZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUtBLE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsZ0JBQWdCLEVBS2pCLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxZQUFZLEVBQ1osVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUlMLE1BQU0sRUFDTixTQUFTLEVBR1QsU0FBUyxFQUNULFlBQVksRUFDWixpQkFBaUIsRUFDbEIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRTNELE9BQU8sRUFBRSxTQUFTLEVBQW1CLE1BQU0seUJBQXlCLENBQUM7QUFFckUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDdkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDMUMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzFELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRXZFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxRQUFRLENBQUM7QUE4R3RDLE1BQU0sT0FBTyxpQkFBaUI7Ozs7Ozs7O0lBOEU1QixZQUNVLFVBQXNCLEVBQ3RCLFVBQTZCLEVBQzdCLGNBQWlDLEVBQ2xDLGlCQUFvQyxFQUN6QixHQUFjO1FBSnhCLGVBQVUsR0FBVixVQUFV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bUQ7Ozs7O0lBUWpELHVDQUE4Qjs7Ozs7SUFDOUIsdUNBQXFDOzs7OztJQUNyQywyQ0FBeUM7O0lBQ3pDLDhDQUEyQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9naXRodWIuY29tL05HLVpPUlJPL25nLXpvcnJvLWFudGQvYmxvYi9tYXN0ZXIvTElDRU5TRVxuICovXG5cbmltcG9ydCB7XG4gIENka0Nvbm5lY3RlZE92ZXJsYXksXG4gIENka092ZXJsYXlPcmlnaW4sXG4gIENvbm5lY3RlZE92ZXJsYXlQb3NpdGlvbkNoYW5nZSxcbiAgQ29ubmVjdGlvblBvc2l0aW9uUGFpcixcbiAgSG9yaXpvbnRhbENvbm5lY3Rpb25Qb3MsXG4gIFZlcnRpY2FsQ29ubmVjdGlvblBvc1xufSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgUXVlcnlMaXN0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0NoaWxkLFxuICBWaWV3Q2hpbGRyZW4sXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgc2xpZGVNb3Rpb24gfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvYW5pbWF0aW9uJztcblxuaW1wb3J0IHsgQ2FuZHlEYXRlLCBDb21wYXRpYmxlVmFsdWUgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdGltZSc7XG5pbXBvcnQgeyBOZ1N0eWxlSW50ZXJmYWNlLCBOelNhZmVBbnkgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdHlwZXMnO1xuaW1wb3J0IHsgRGF0ZUhlbHBlclNlcnZpY2UgfSBmcm9tICduZy16b3Jyby1hbnRkL2kxOG4nO1xuaW1wb3J0IHsgZnJvbUV2ZW50LCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBEYXRlUGlja2VyU2VydmljZSB9IGZyb20gJy4vZGF0ZS1waWNrZXIuc2VydmljZSc7XG5pbXBvcnQgeyBEYXRlUmFuZ2VQb3B1cENvbXBvbmVudCB9IGZyb20gJy4vZGF0ZS1yYW5nZS1wb3B1cC5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmFuZ2VQYXJ0VHlwZSB9IGZyb20gJy4vc3RhbmRhcmQtdHlwZXMnO1xuaW1wb3J0IHsgUFJFRklYX0NMQVNTIH0gZnJvbSAnLi91dGlsJztcblxuQENvbXBvbmVudCh7XG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIHNlbGVjdG9yOiAnW256LXBpY2tlcl0nLFxuICBleHBvcnRBczogJ256UGlja2VyJyxcbiAgdGVtcGxhdGU6IGBcbiAgICA8IS0tIENvbnRlbnQgb2Ygc2luZ2xlIHBpY2tlciAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwiIWlzUmFuZ2VcIiBjbGFzcz1cInt7IHByZWZpeENscyB9fS1pbnB1dFwiPlxuICAgICAgPGlucHV0XG4gICAgICAgICNwaWNrZXJJbnB1dFxuICAgICAgICBbY2xhc3MuYW50LWlucHV0LWRpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVkXCJcbiAgICAgICAgWyhuZ01vZGVsKV09XCJpbnB1dFZhbHVlXCJcbiAgICAgICAgcGxhY2Vob2xkZXI9XCJ7eyBnZXRQbGFjZWhvbGRlcigpIH19XCJcbiAgICAgICAgW3NpemVdPVwiaW5wdXRTaXplXCJcbiAgICAgICAgKGZvY3VzKT1cIm9uRm9jdXMoKVwiXG4gICAgICAgIChibHVyKT1cIm9uQmx1cigpXCJcbiAgICAgICAgKGlucHV0KT1cIm9uSW5wdXRLZXl1cCgkZXZlbnQpXCJcbiAgICAgICAgKGtleXVwLmVudGVyKT1cIm9uSW5wdXRLZXl1cCgkZXZlbnQsIHRydWUpXCJcbiAgICAgIC8+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidHBsUmlnaHRSZXN0XCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIENvbnRlbnQgb2YgcmFuZ2UgcGlja2VyIC0tPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc1JhbmdlXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LWlucHV0XCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nVGVtcGxhdGVPdXRsZXQ9XCJ0cGxSYW5nZUlucHV0OyBjb250ZXh0OiB7IHBhcnRUeXBlOiAnbGVmdCcgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2ICNzZXBhcmF0b3JFbGVtZW50IGNsYXNzPVwie3sgcHJlZml4Q2xzIH19LXJhbmdlLXNlcGFyYXRvclwiPlxuICAgICAgICA8c3BhbiBjbGFzcz1cInt7IHByZWZpeENscyB9fS1zZXBhcmF0b3JcIj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2VwYXJhdG9yOyBlbHNlIGRlZmF1bHRTZXBhcmF0b3JcIj57eyBzZXBhcmF0b3IgfX08L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgICA8bmctdGVtcGxhdGUgI2RlZmF1bHRTZXBhcmF0b3I+XG4gICAgICAgICAgPGkgbnotaWNvbiBuelR5cGU9XCJzd2FwLXJpZ2h0XCIgbnpUaGVtZT1cIm91dGxpbmVcIj48L2k+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgY2xhc3M9XCJ7eyBwcmVmaXhDbHMgfX0taW5wdXRcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdUZW1wbGF0ZU91dGxldD1cInRwbFJhbmdlSW5wdXQ7IGNvbnRleHQ6IHsgcGFydFR5cGU6ICdyaWdodCcgfVwiPjwvbmctY29udGFpbmVyPlxuICAgICAgPC9kaXY+XG4gICAgICA8bmctY29udGFpbmVyICpuZ1RlbXBsYXRlT3V0bGV0PVwidHBsUmlnaHRSZXN0XCI+PC9uZy1jb250YWluZXI+XG4gICAgPC9uZy1jb250YWluZXI+XG4gICAgPCEtLSBJbnB1dCBmb3IgUmFuZ2UgT05MWSAtLT5cbiAgICA8bmctdGVtcGxhdGUgI3RwbFJhbmdlSW5wdXQgbGV0LXBhcnRUeXBlPVwicGFydFR5cGVcIj5cbiAgICAgIDxpbnB1dFxuICAgICAgICAjcmFuZ2VQaWNrZXJJbnB1dFxuICAgICAgICBbZGlzYWJsZWRdPVwiZGlzYWJsZWRcIlxuICAgICAgICBbc2l6ZV09XCJpbnB1dFNpemVcIlxuICAgICAgICAoY2xpY2spPVwib25DbGlja0lucHV0Qm94KCRldmVudCwgcGFydFR5cGUpXCJcbiAgICAgICAgKGJsdXIpPVwib25CbHVyKClcIlxuICAgICAgICAoaW5wdXQpPVwib25JbnB1dEtleXVwKCRldmVudCwgZmFsc2UpXCJcbiAgICAgICAgKGZvY3VzKT1cIm9uRm9jdXMocGFydFR5cGUpXCJcbiAgICAgICAgKGtleXVwLmVudGVyKT1cIm9uSW5wdXRLZXl1cCgkZXZlbnQsIHRydWUpXCJcbiAgICAgICAgWyhuZ01vZGVsKV09XCJpbnB1dFZhbHVlW2RhdGVQaWNrZXJTZXJ2aWNlLmdldEFjdGl2ZUluZGV4KHBhcnRUeXBlKV1cIlxuICAgICAgICBwbGFjZWhvbGRlcj1cInt7IGdldFBsYWNlaG9sZGVyKHBhcnRUeXBlKSB9fVwiXG4gICAgICAvPlxuICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICA8IS0tIFJpZ2h0IG9wZXJhdG9yIGljb25zIC0tPlxuICAgIDxuZy10ZW1wbGF0ZSAjdHBsUmlnaHRSZXN0PlxuICAgICAgPGRpdiBjbGFzcz1cInt7IHByZWZpeENscyB9fS1hY3RpdmUtYmFyXCIgW25nU3R5bGVdPVwiYWN0aXZlQmFyU3R5bGVcIj48L2Rpdj5cbiAgICAgIDxzcGFuICpuZ0lmPVwic2hvd0NsZWFyKClcIiBjbGFzcz1cInt7IHByZWZpeENscyB9fS1jbGVhclwiIChjbGljayk9XCJvbkNsaWNrQ2xlYXIoJGV2ZW50KVwiPlxuICAgICAgICA8aSBuei1pY29uIG56VHlwZT1cImNsb3NlLWNpcmNsZVwiIG56VGhlbWU9XCJmaWxsXCI+PC9pPlxuICAgICAgPC9zcGFuPlxuICAgICAgPHNwYW4gY2xhc3M9XCJ7eyBwcmVmaXhDbHMgfX0tc3VmZml4XCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm56U3RyaW5nVGVtcGxhdGVPdXRsZXQ9XCJzdWZmaXhJY29uOyBsZXQgc3VmZml4SWNvblwiPlxuICAgICAgICAgIDxpIG56LWljb24gW256VHlwZV09XCJzdWZmaXhJY29uXCI+PC9pPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvc3Bhbj5cbiAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgPCEtLSBPdmVybGF5IC0tPlxuICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgY2RrQ29ubmVjdGVkT3ZlcmxheVxuICAgICAgbnpDb25uZWN0ZWRPdmVybGF5XG4gICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheU9yaWdpbl09XCJvcmlnaW5cIlxuICAgICAgW2Nka0Nvbm5lY3RlZE92ZXJsYXlPcGVuXT1cInJlYWxPcGVuU3RhdGVcIlxuICAgICAgW2Nka0Nvbm5lY3RlZE92ZXJsYXlIYXNCYWNrZHJvcF09XCIhaXNPcGVuSGFuZGxlZEJ5VXNlcigpXCJcbiAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5UG9zaXRpb25zXT1cIm92ZXJsYXlQb3NpdGlvbnNcIlxuICAgICAgW2Nka0Nvbm5lY3RlZE92ZXJsYXlUcmFuc2Zvcm1PcmlnaW5Pbl09XCInLmFudC1waWNrZXItd3JhcHBlcidcIlxuICAgICAgKHBvc2l0aW9uQ2hhbmdlKT1cIm9uUG9zaXRpb25DaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAoYmFja2Ryb3BDbGljayk9XCJvbkNsaWNrQmFja2Ryb3AoKVwiXG4gICAgICAoZGV0YWNoKT1cIm9uT3ZlcmxheURldGFjaCgpXCJcbiAgICAgIChvdmVybGF5S2V5ZG93bik9XCJvbk92ZXJsYXlLZXlkb3duKCRldmVudClcIlxuICAgID5cbiAgICAgIDxkaXZcbiAgICAgICAgY2xhc3M9XCJhbnQtcGlja2VyLXdyYXBwZXJcIlxuICAgICAgICBbbnpOb0FuaW1hdGlvbl09XCJub0FuaW1hdGlvblwiXG4gICAgICAgIFtAc2xpZGVNb3Rpb25dPVwiJ2VudGVyJ1wiXG4gICAgICAgIChAc2xpZGVNb3Rpb24uZG9uZSk9XCJhbmltYXRpb25Eb25lKClcIlxuICAgICAgICBzdHlsZT1cInBvc2l0aW9uOiByZWxhdGl2ZTtcIlxuICAgICAgPlxuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3M9XCJ7eyBwcmVmaXhDbHMgfX0tZHJvcGRvd24ge3sgZHJvcGRvd25DbGFzc05hbWUgfX1cIlxuICAgICAgICAgIFtjbGFzcy5hbnQtcGlja2VyLWRyb3Bkb3duLXBsYWNlbWVudC1ib3R0b21MZWZ0XT1cImN1cnJlbnRQb3NpdGlvblkgPT09ICdib3R0b20nICYmIGN1cnJlbnRQb3NpdGlvblggPT09ICdzdGFydCdcIlxuICAgICAgICAgIFtjbGFzcy5hbnQtcGlja2VyLWRyb3Bkb3duLXBsYWNlbWVudC10b3BMZWZ0XT1cImN1cnJlbnRQb3NpdGlvblkgPT09ICd0b3AnICYmIGN1cnJlbnRQb3NpdGlvblggPT09ICdzdGFydCdcIlxuICAgICAgICAgIFtjbGFzcy5hbnQtcGlja2VyLWRyb3Bkb3duLXBsYWNlbWVudC1ib3R0b21SaWdodF09XCJjdXJyZW50UG9zaXRpb25ZID09PSAnYm90dG9tJyAmJiBjdXJyZW50UG9zaXRpb25YID09PSAnZW5kJ1wiXG4gICAgICAgICAgW2NsYXNzLmFudC1waWNrZXItZHJvcGRvd24tcGxhY2VtZW50LXRvcFJpZ2h0XT1cImN1cnJlbnRQb3NpdGlvblkgPT09ICd0b3AnICYmIGN1cnJlbnRQb3NpdGlvblggPT09ICdlbmQnXCJcbiAgICAgICAgICBbY2xhc3MuYW50LXBpY2tlci1kcm9wZG93bi1yYW5nZV09XCJpc1JhbmdlXCJcbiAgICAgICAgICBbbmdTdHlsZV09XCJwb3B1cFN0eWxlXCJcbiAgICAgICAgPlxuICAgICAgICAgIDwhLS0gQ29tcGF0aWJsZSBmb3Igb3ZlcmxheSB0aGF0IG5vdCBzdXBwb3J0IG9mZnNldCBkeW5hbWljYWxseSBhbmQgaW1tZWRpYXRlbHkgLS0+XG4gICAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvbmctdGVtcGxhdGU+XG4gIGAsXG4gIGFuaW1hdGlvbnM6IFtzbGlkZU1vdGlvbl0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoXG59KVxuZXhwb3J0IGNsYXNzIE56UGlja2VyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBBZnRlclZpZXdJbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIG5vQW5pbWF0aW9uOiBib29sZWFuID0gZmFsc2U7XG4gIEBJbnB1dCgpIGlzUmFuZ2U6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgb3BlbjogYm9vbGVhbiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgZGlzYWJsZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgQElucHV0KCkgcGxhY2Vob2xkZXIhOiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgQElucHV0KCkgYWxsb3dDbGVhcj86IGJvb2xlYW47XG4gIEBJbnB1dCgpIGF1dG9Gb2N1cz86IGJvb2xlYW47XG4gIEBJbnB1dCgpIGZvcm1hdCE6IHN0cmluZztcbiAgQElucHV0KCkgc2VwYXJhdG9yPzogc3RyaW5nO1xuICBASW5wdXQoKSBwb3B1cFN0eWxlOiBOZ1N0eWxlSW50ZXJmYWNlIHwgbnVsbCA9IG51bGw7XG4gIEBJbnB1dCgpIGRyb3Bkb3duQ2xhc3NOYW1lPzogc3RyaW5nO1xuICBASW5wdXQoKSBzdWZmaXhJY29uPzogc3RyaW5nIHwgVGVtcGxhdGVSZWY8TnpTYWZlQW55PjtcblxuICBAT3V0cHV0KCkgcmVhZG9ubHkgZm9jdXNDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG4gIEBPdXRwdXQoKSByZWFkb25seSB2YWx1ZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Q2FuZHlEYXRlIHwgQ2FuZHlEYXRlW10gfCBudWxsPigpO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgb3BlbkNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTsgLy8gRW1pdHRlZCB3aGVuIG92ZXJsYXkncyBvcGVuIHN0YXRlIGNoYW5nZVxuXG4gIEBWaWV3Q2hpbGQoQ2RrQ29ubmVjdGVkT3ZlcmxheSwgeyBzdGF0aWM6IGZhbHNlIH0pIGNka0Nvbm5lY3RlZE92ZXJsYXk/OiBDZGtDb25uZWN0ZWRPdmVybGF5O1xuICBAVmlld0NoaWxkKCdzZXBhcmF0b3JFbGVtZW50JywgeyBzdGF0aWM6IGZhbHNlIH0pIHNlcGFyYXRvckVsZW1lbnQ/OiBFbGVtZW50UmVmO1xuICBAVmlld0NoaWxkKCdwaWNrZXJJbnB1dCcsIHsgc3RhdGljOiBmYWxzZSB9KSBwaWNrZXJJbnB1dD86IEVsZW1lbnRSZWY8SFRNTElucHV0RWxlbWVudD47XG4gIEBWaWV3Q2hpbGRyZW4oJ3JhbmdlUGlja2VySW5wdXQnKSByYW5nZVBpY2tlcklucHV0cyE6IFF1ZXJ5TGlzdDxFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+PjtcbiAgQENvbnRlbnRDaGlsZChEYXRlUmFuZ2VQb3B1cENvbXBvbmVudCkgcGFuZWwhOiBEYXRlUmFuZ2VQb3B1cENvbXBvbmVudDtcblxuICBvcmlnaW46IENka092ZXJsYXlPcmlnaW47XG4gIGRvY3VtZW50OiBEb2N1bWVudDtcbiAgaW5wdXRTaXplPzogbnVtYmVyO1xuICBpbnB1dFdpZHRoPzogbnVtYmVyO1xuICBhcnJvd0xlZnQ/OiBudW1iZXI7XG4gIGRlc3Ryb3kkID0gbmV3IFN1YmplY3QoKTtcbiAgcHJlZml4Q2xzID0gUFJFRklYX0NMQVNTO1xuICAvLyBJbmRleCBzaWduYXR1cmUgaW4gdHlwZSAnc3RyaW5nIHwgc3RyaW5nW10nIG9ubHkgcGVybWl0cyByZWFkaW5nXG4gIGlucHV0VmFsdWU6IE56U2FmZUFueTtcbiAgYWN0aXZlQmFyU3R5bGU6IG9iamVjdCA9IHsgcG9zaXRpb246ICdhYnNvbHV0ZScgfTtcbiAgYW5pbWF0aW9uT3BlblN0YXRlID0gZmFsc2U7XG4gIG92ZXJsYXlPcGVuOiBib29sZWFuID0gZmFsc2U7IC8vIEF2YWlsYWJsZSB3aGVuIFwib3BlblwiPXVuZGVmaW5lZFxuICBvdmVybGF5UG9zaXRpb25zOiBDb25uZWN0aW9uUG9zaXRpb25QYWlyW10gPSBbXG4gICAge1xuICAgICAgb2Zmc2V0WDogLTEyLFxuICAgICAgb2Zmc2V0WTogOCxcbiAgICAgIG9yaWdpblg6ICdzdGFydCcsXG4gICAgICBvcmlnaW5ZOiAnYm90dG9tJyxcbiAgICAgIG92ZXJsYXlYOiAnc3RhcnQnLFxuICAgICAgb3ZlcmxheVk6ICd0b3AnXG4gICAgfSxcbiAgICB7XG4gICAgICBvZmZzZXRYOiAtMTIsXG4gICAgICBvZmZzZXRZOiAtOCxcbiAgICAgIG9yaWdpblg6ICdzdGFydCcsXG4gICAgICBvcmlnaW5ZOiAndG9wJyxcbiAgICAgIG92ZXJsYXlYOiAnc3RhcnQnLFxuICAgICAgb3ZlcmxheVk6ICdib3R0b20nXG4gICAgfSxcbiAgICB7XG4gICAgICBvZmZzZXRYOiAxMixcbiAgICAgIG9mZnNldFk6IDgsXG4gICAgICBvcmlnaW5YOiAnZW5kJyxcbiAgICAgIG9yaWdpblk6ICdib3R0b20nLFxuICAgICAgb3ZlcmxheVg6ICdlbmQnLFxuICAgICAgb3ZlcmxheVk6ICd0b3AnXG4gICAgfSxcbiAgICB7XG4gICAgICBvZmZzZXRYOiAxMixcbiAgICAgIG9mZnNldFk6IC04LFxuICAgICAgb3JpZ2luWDogJ2VuZCcsXG4gICAgICBvcmlnaW5ZOiAndG9wJyxcbiAgICAgIG92ZXJsYXlYOiAnZW5kJyxcbiAgICAgIG92ZXJsYXlZOiAnYm90dG9tJ1xuICAgIH1cbiAgXSBhcyBDb25uZWN0aW9uUG9zaXRpb25QYWlyW107XG4gIGN1cnJlbnRQb3NpdGlvblg6IEhvcml6b250YWxDb25uZWN0aW9uUG9zID0gJ3N0YXJ0JztcbiAgY3VycmVudFBvc2l0aW9uWTogVmVydGljYWxDb25uZWN0aW9uUG9zID0gJ2JvdHRvbSc7XG5cbiAgZ2V0IHJlYWxPcGVuU3RhdGUoKTogYm9vbGVhbiB7XG4gICAgLy8gVGhlIHZhbHVlIHRoYXQgcmVhbGx5IGRlY2lkZSB0aGUgb3BlbiBzdGF0ZSBvZiBvdmVybGF5XG4gICAgcmV0dXJuIHRoaXMuaXNPcGVuSGFuZGxlZEJ5VXNlcigpID8gISF0aGlzLm9wZW4gOiB0aGlzLm92ZXJsYXlPcGVuO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHByaXZhdGUgZGF0ZUhlbHBlcjogRGF0ZUhlbHBlclNlcnZpY2UsXG4gICAgcHJpdmF0ZSBjaGFuZ2VEZXRlY3RvcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHVibGljIGRhdGVQaWNrZXJTZXJ2aWNlOiBEYXRlUGlja2VyU2VydmljZSxcbiAgICBASW5qZWN0KERPQ1VNRU5UKSBkb2M6IE56U2FmZUFueVxuICApIHtcbiAgICB0aGlzLmRvY3VtZW50ID0gZG9jO1xuICAgIHRoaXMub3JpZ2luID0gbmV3IENka092ZXJsYXlPcmlnaW4odGhpcy5lbGVtZW50UmVmKTtcbiAgICB0aGlzLnVwZGF0ZUlucHV0VmFsdWUoKTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuaW5wdXRTaXplID0gTWF0aC5tYXgoMTAsIHRoaXMuZm9ybWF0Lmxlbmd0aCkgKyAyO1xuXG4gICAgdGhpcy5kYXRlUGlja2VyU2VydmljZS52YWx1ZUNoYW5nZSQucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICB0aGlzLnVwZGF0ZUlucHV0VmFsdWUoKTtcbiAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IubWFya0ZvckNoZWNrKCk7XG4gICAgfSk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYXV0b0ZvY3VzKSB7XG4gICAgICB0aGlzLmZvY3VzKCk7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuaXNSYW5nZSkge1xuICAgICAgZnJvbUV2ZW50KHdpbmRvdywgJ3Jlc2l6ZScpXG4gICAgICAgIC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5yZXNldElucHV0V2lkdGhBbmRBcnJvd0xlZnQoKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMuZGF0ZVBpY2tlclNlcnZpY2UuaW5wdXRQYXJ0Q2hhbmdlJC5waXBlKHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSkuc3Vic2NyaWJlKHBhcnRUeXBlID0+IHtcbiAgICAgIGlmIChwYXJ0VHlwZSkge1xuICAgICAgICB0aGlzLmRhdGVQaWNrZXJTZXJ2aWNlLmFjdGl2ZUlucHV0ID0gcGFydFR5cGU7XG4gICAgICB9XG4gICAgICB0aGlzLmRhdGVQaWNrZXJTZXJ2aWNlLmFycm93UG9zaXRpb25TdHlsZSA9IHtcbiAgICAgICAgbGVmdDogdGhpcy5kYXRlUGlja2VyU2VydmljZS5hY3RpdmVJbnB1dCA9PT0gJ2xlZnQnID8gJzBweCcgOiBgJHt0aGlzLmFycm93TGVmdH1weGBcbiAgICAgIH07XG4gICAgICB0aGlzLmFjdGl2ZUJhclN0eWxlID0ge1xuICAgICAgICAuLi50aGlzLmFjdGl2ZUJhclN0eWxlLFxuICAgICAgICAuLi50aGlzLmRhdGVQaWNrZXJTZXJ2aWNlLmFycm93UG9zaXRpb25TdHlsZSxcbiAgICAgICAgd2lkdGg6IGAke3RoaXMuaW5wdXRXaWR0aH1weGBcbiAgICAgIH07XG4gICAgICBpZiAodGhpcy5kb2N1bWVudC5hY3RpdmVFbGVtZW50ICE9PSB0aGlzLmdldElucHV0KHRoaXMuZGF0ZVBpY2tlclNlcnZpY2UuYWN0aXZlSW5wdXQpKSB7XG4gICAgICAgIHRoaXMuZm9jdXMoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucGFuZWw/LmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIHRoaXMuY2hhbmdlRGV0ZWN0b3IubWFya0ZvckNoZWNrKCk7XG4gICAgfSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgaWYgKGNoYW5nZXMub3Blbikge1xuICAgICAgdGhpcy5hbmltYXRpb25TdGFydCgpO1xuICAgIH1cbiAgfVxuXG4gIHJlc2V0SW5wdXRXaWR0aEFuZEFycm93TGVmdCgpOiB2b2lkIHtcbiAgICB0aGlzLmlucHV0V2lkdGggPSB0aGlzLnJhbmdlUGlja2VySW5wdXRzPy5maXJzdD8ubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aCB8fCAwO1xuICAgIHRoaXMuYXJyb3dMZWZ0ID0gdGhpcy5pbnB1dFdpZHRoICsgdGhpcy5zZXBhcmF0b3JFbGVtZW50Py5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoIHx8IDA7XG4gIH1cblxuICBnZXRJbnB1dChwYXJ0VHlwZT86IFJhbmdlUGFydFR5cGUpOiBIVE1MSW5wdXRFbGVtZW50IHtcbiAgICByZXR1cm4gdGhpcy5pc1JhbmdlXG4gICAgICA/IHBhcnRUeXBlID09PSAnbGVmdCdcbiAgICAgICAgPyB0aGlzLnJhbmdlUGlja2VySW5wdXRzLmZpcnN0Lm5hdGl2ZUVsZW1lbnRcbiAgICAgICAgOiB0aGlzLnJhbmdlUGlja2VySW5wdXRzLmxhc3QubmF0aXZlRWxlbWVudFxuICAgICAgOiB0aGlzLnBpY2tlcklucHV0IS5uYXRpdmVFbGVtZW50O1xuICB9XG5cbiAgZm9jdXMoKTogdm9pZCB7XG4gICAgdGhpcy5nZXRJbnB1dCh0aGlzLmRhdGVQaWNrZXJTZXJ2aWNlLmFjdGl2ZUlucHV0KS5mb2N1cygpOyAvLyBGb2N1cyBvbiB0aGUgZmlyc3QgaW5wdXRcbiAgfVxuXG4gIG9uRm9jdXMocGFydFR5cGU/OiBSYW5nZVBhcnRUeXBlKTogdm9pZCB7XG4gICAgaWYgKHBhcnRUeXBlKSB7XG4gICAgICB0aGlzLmRhdGVQaWNrZXJTZXJ2aWNlLmlucHV0UGFydENoYW5nZSQubmV4dChwYXJ0VHlwZSk7XG4gICAgfVxuICAgIHRoaXMuZm9jdXNDaGFuZ2UuZW1pdCh0cnVlKTtcbiAgfVxuXG4gIG9uQmx1cigpOiB2b2lkIHtcbiAgICB0aGlzLmZvY3VzQ2hhbmdlLmVtaXQoZmFsc2UpO1xuICB9XG5cbiAgLy8gU2hvdyBvdmVybGF5IGNvbnRlbnRcbiAgc2hvd092ZXJsYXkoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnJlYWxPcGVuU3RhdGUpIHtcbiAgICAgIHRoaXMucmVzZXRJbnB1dFdpZHRoQW5kQXJyb3dMZWZ0KCk7XG4gICAgICB0aGlzLm92ZXJsYXlPcGVuID0gdHJ1ZTtcbiAgICAgIHRoaXMuYW5pbWF0aW9uU3RhcnQoKTtcbiAgICAgIHRoaXMuZm9jdXMoKTtcbiAgICAgIHRoaXMub3BlbkNoYW5nZS5lbWl0KHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIGhpZGVPdmVybGF5KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnJlYWxPcGVuU3RhdGUpIHtcbiAgICAgIHRoaXMub3ZlcmxheU9wZW4gPSBmYWxzZTtcbiAgICAgIHRoaXMub3BlbkNoYW5nZS5lbWl0KGZhbHNlKTtcbiAgICAgIHRoaXMuZm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICBzaG93Q2xlYXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICF0aGlzLmRpc2FibGVkICYmICF0aGlzLmlzRW1wdHlWYWx1ZSh0aGlzLmRhdGVQaWNrZXJTZXJ2aWNlLnZhbHVlKSAmJiAhIXRoaXMuYWxsb3dDbGVhcjtcbiAgfVxuXG4gIG9uQ2xpY2tJbnB1dEJveChldmVudDogTW91c2VFdmVudCwgcGFydFR5cGU/OiBSYW5nZVBhcnRUeXBlKTogdm9pZCB7XG4gICAgZXZlbnQuc