UNPKG

cm-angular-tooltip

Version:
486 lines 52.5 kB
import { Directive, HostListener, Input, Output, EventEmitter, Inject, Optional } from '@angular/core'; import { TooltipComponent } from './tooltip.component'; import { backwardCompatibilityOptions, defaultOptions } from './tooltip-options'; import { TooltipOptionsService } from './tooltip-options.service'; import * as i0 from "@angular/core"; export class TooltipDirective { set options(value) { if (value && defaultOptions) { this._options = value; } } get options() { return this._options; } // Content type set contentTypeBackwardCompatibility(value) { if (value) { this._contentType = value; } } set contentType(value) { if (value) { this._contentType = value; } } get contentType() { return this._contentType; } // z-index set zIndexBackwardCompatibility(value) { if (value) { this._zIndex = value; } } set zIndex(value) { if (value) { this._zIndex = value; } } get zIndex() { return this._zIndex; } // Animation duration set animationDurationBackwardCompatibility(value) { if (value) { this._animationDuration = value; } } set animationDuration(value) { if (value) { this._animationDuration = value; } } get animationDuration() { return this._animationDuration; } // Tooltip class set tooltipClassBackwardCompatibility(value) { if (value) { this._tooltipClass = value; } } set tooltipClass(value) { if (value) { this._tooltipClass = value; } } get tooltipClass() { return this._tooltipClass; } // Max width set maxWidthBackwardCompatibility(value) { if (value) { this._maxWidth = value; } } set maxWidth(value) { if (value) { this._maxWidth = value; } } get maxWidth() { return this._maxWidth; } // Show delay set showDelayBackwardCompatibility(value) { if (value) { this._showDelay = value; } } set showDelay(value) { if (value) { this._showDelay = value; } } get showDelay() { return this._showDelay; } // Hide delay set hideDelayBackwardCompatibility(value) { if (value) { this._hideDelay = value; } } set hideDelay(value) { if (value) { this._hideDelay = value; } } get hideDelay() { return this._hideDelay; } get isTooltipDestroyed() { return this.componentRef && this.componentRef.hostView.destroyed; } get destroyDelay() { if (this._destroyDelay) { return this._destroyDelay; } else { return Number(this.getHideDelay()) + Number(this.options['animationDuration']); } } set destroyDelay(value) { this._destroyDelay = value; } get tooltipPosition() { if (this.options['position']) { return this.options['position']; } else { return this.elementPosition; } } constructor(initOptions, elementRef, componentFactoryResolver, appRef, injector) { this.initOptions = initOptions; this.elementRef = elementRef; this.componentFactoryResolver = componentFactoryResolver; this.appRef = appRef; this.injector = injector; this._options = {}; this._contentType = "string"; this.events = new EventEmitter(); } onMouseEnter() { if (this.isDisplayOnHover == false) { return; } this.show(); } onMouseLeave() { if (this.options['trigger'] === 'hover') { this.destroyTooltip(); } } onClick() { if (this.isDisplayOnClick == false) { return; } this.show(); this.hideAfterClickTimeoutId = window.setTimeout(() => { this.destroyTooltip(); }, this.options['hideDelayAfterClick']); } ngOnInit() { } ngOnChanges(changes) { this.initOptions = this.renameProperties(this.initOptions); let changedOptions = this.getProperties(changes); changedOptions = this.renameProperties(changedOptions); this.applyOptionsDefault(defaultOptions, changedOptions); } ngOnDestroy() { this.destroyTooltip({ fast: true }); if (this.componentSubscribe) { this.componentSubscribe.unsubscribe(); } } getShowDelay() { return this.options['showDelay']; } getHideDelay() { const hideDelay = this.options['hideDelay']; const hideDelayTouchscreen = this.options['hideDelayTouchscreen']; return this.isTouchScreen ? hideDelayTouchscreen : hideDelay; } getProperties(changes) { let directiveProperties = {}; let customProperties = {}; let allProperties = {}; for (var prop in changes) { if (prop !== 'options' && prop !== 'tooltipValue') { directiveProperties[prop] = changes[prop].currentValue; } if (prop === 'options') { customProperties = changes[prop].currentValue; } } allProperties = Object.assign({}, customProperties, directiveProperties); return allProperties; } renameProperties(options) { for (var prop in options) { if (backwardCompatibilityOptions[prop]) { options[backwardCompatibilityOptions[prop]] = options[prop]; delete options[prop]; } } return options; } getElementPosition() { this.elementPosition = this.elementRef.nativeElement.getBoundingClientRect(); } createTooltip() { this.clearTimeouts(); this.getElementPosition(); this.createTimeoutId = window.setTimeout(() => { this.appendComponentToBody(TooltipComponent); }, this.getShowDelay()); this.showTimeoutId = window.setTimeout(() => { this.showTooltipElem(); }, this.getShowDelay()); } destroyTooltip(options = { fast: false }) { this.clearTimeouts(); if (this.isTooltipDestroyed == false) { this.hideTimeoutId = window.setTimeout(() => { this.hideTooltip(); }, options.fast ? 0 : this.getHideDelay()); this.destroyTimeoutId = window.setTimeout(() => { if (!this.componentRef || this.isTooltipDestroyed) { return; } this.appRef.detachView(this.componentRef.hostView); this.componentRef.destroy(); this.events.emit({ type: 'hidden', position: this.tooltipPosition }); }, options.fast ? 0 : this.destroyDelay); } } showTooltipElem() { this.clearTimeouts(); this.componentRef.instance.show = true; this.events.emit({ type: 'show', position: this.tooltipPosition }); } hideTooltip() { if (!this.componentRef || this.isTooltipDestroyed) { return; } this.componentRef.instance.show = false; this.events.emit({ type: 'hide', position: this.tooltipPosition }); } appendComponentToBody(component, data = {}) { this.componentRef = this.componentFactoryResolver .resolveComponentFactory(component) .create(this.injector); this.componentRef.instance.data = { value: this.tooltipValue, element: this.elementRef.nativeElement, elementPosition: this.tooltipPosition, options: this.options }; this.appRef.attachView(this.componentRef.hostView); const domElem = this.componentRef.hostView.rootNodes[0]; document.body.appendChild(domElem); this.componentSubscribe = this.componentRef.instance.events.subscribe((event) => { this.handleEvents(event); }); } clearTimeouts() { if (this.createTimeoutId) { clearTimeout(this.createTimeoutId); } if (this.showTimeoutId) { clearTimeout(this.showTimeoutId); } if (this.hideTimeoutId) { clearTimeout(this.hideTimeoutId); } if (this.destroyTimeoutId) { clearTimeout(this.destroyTimeoutId); } } get isDisplayOnHover() { if (this.options['display'] == false) { return false; } if (this.options['displayTouchscreen'] == false && this.isTouchScreen) { return false; } if (this.options['trigger'] !== 'hover') { return false; } return true; } get isDisplayOnClick() { if (this.options['display'] == false) { return false; } if (this.options['displayTouchscreen'] == false && this.isTouchScreen) { return false; } if (this.options['trigger'] != 'click') { return false; } return true; } get isTouchScreen() { var prefixes = ' -webkit- -moz- -o- -ms- '.split(' '); var mq = function (query) { return window.matchMedia(query).matches; }; if (('ontouchstart' in window)) { return true; } // include the 'heartz' as a way to have a non matching MQ to help terminate the join // https://git.io/vznFH var query = ['(', prefixes.join('touch-enabled),('), 'heartz', ')'].join(''); return mq(query); } applyOptionsDefault(defaultOptions, options) { this.options = Object.assign({}, defaultOptions, this.initOptions || {}, this.options, options); } handleEvents(event) { if (event.type === 'shown') { this.events.emit({ type: 'shown', position: this.tooltipPosition }); } } show() { if (!this.tooltipValue) { return; } if (!this.componentRef || this.isTooltipDestroyed) { this.createTooltip(); } else if (!this.isTooltipDestroyed) { this.showTooltipElem(); } } hide() { this.destroyTooltip(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TooltipDirective, deps: [{ token: TooltipOptionsService, optional: true }, { token: i0.ElementRef }, { token: i0.ComponentFactoryResolver }, { token: i0.ApplicationRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.12", type: TooltipDirective, selector: "[tooltip]", inputs: { options: "options", tooltipValue: ["tooltip", "tooltipValue"], placement: "placement", autoPlacement: "autoPlacement", contentTypeBackwardCompatibility: ["content-type", "contentTypeBackwardCompatibility"], contentType: "contentType", hideDelayMobile: ["hide-delay-mobile", "hideDelayMobile"], hideDelayTouchscreen: "hideDelayTouchscreen", zIndexBackwardCompatibility: ["z-index", "zIndexBackwardCompatibility"], zIndex: "zIndex", animationDurationBackwardCompatibility: ["animation-duration", "animationDurationBackwardCompatibility"], animationDuration: "animationDuration", trigger: "trigger", tooltipClassBackwardCompatibility: ["tooltip-class", "tooltipClassBackwardCompatibility"], tooltipClass: "tooltipClass", display: "display", displayMobile: ["display-mobile", "displayMobile"], displayTouchscreen: "displayTouchscreen", shadow: "shadow", theme: "theme", offset: "offset", width: "width", maxWidthBackwardCompatibility: ["max-width", "maxWidthBackwardCompatibility"], maxWidth: "maxWidth", id: "id", showDelayBackwardCompatibility: ["show-delay", "showDelayBackwardCompatibility"], showDelay: "showDelay", hideDelayBackwardCompatibility: ["hide-delay", "hideDelayBackwardCompatibility"], hideDelay: "hideDelay", hideDelayAfterClick: "hideDelayAfterClick", pointerEvents: "pointerEvents", position: "position" }, outputs: { events: "events" }, host: { listeners: { "focusin": "onMouseEnter()", "mouseenter": "onMouseEnter()", "focusout": "onMouseLeave()", "mouseleave": "onMouseLeave()", "click": "onClick()" } }, exportAs: ["tooltip"], usesOnChanges: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TooltipDirective, decorators: [{ type: Directive, args: [{ selector: '[tooltip]', exportAs: 'tooltip', }] }], ctorParameters: () => [{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [TooltipOptionsService] }] }, { type: i0.ElementRef }, { type: i0.ComponentFactoryResolver }, { type: i0.ApplicationRef }, { type: i0.Injector }], propDecorators: { options: [{ type: Input, args: ['options'] }], tooltipValue: [{ type: Input, args: ['tooltip'] }], placement: [{ type: Input, args: ['placement'] }], autoPlacement: [{ type: Input, args: ['autoPlacement'] }], contentTypeBackwardCompatibility: [{ type: Input, args: ['content-type'] }], contentType: [{ type: Input, args: ['contentType'] }], hideDelayMobile: [{ type: Input, args: ['hide-delay-mobile'] }], hideDelayTouchscreen: [{ type: Input, args: ['hideDelayTouchscreen'] }], zIndexBackwardCompatibility: [{ type: Input, args: ['z-index'] }], zIndex: [{ type: Input, args: ['zIndex'] }], animationDurationBackwardCompatibility: [{ type: Input, args: ['animation-duration'] }], animationDuration: [{ type: Input, args: ['animationDuration'] }], trigger: [{ type: Input, args: ['trigger'] }], tooltipClassBackwardCompatibility: [{ type: Input, args: ['tooltip-class'] }], tooltipClass: [{ type: Input, args: ['tooltipClass'] }], display: [{ type: Input, args: ['display'] }], displayMobile: [{ type: Input, args: ['display-mobile'] }], displayTouchscreen: [{ type: Input, args: ['displayTouchscreen'] }], shadow: [{ type: Input, args: ['shadow'] }], theme: [{ type: Input, args: ['theme'] }], offset: [{ type: Input, args: ['offset'] }], width: [{ type: Input, args: ['width'] }], maxWidthBackwardCompatibility: [{ type: Input, args: ['max-width'] }], maxWidth: [{ type: Input, args: ['maxWidth'] }], id: [{ type: Input, args: ['id'] }], showDelayBackwardCompatibility: [{ type: Input, args: ['show-delay'] }], showDelay: [{ type: Input, args: ['showDelay'] }], hideDelayBackwardCompatibility: [{ type: Input, args: ['hide-delay'] }], hideDelay: [{ type: Input, args: ['hideDelay'] }], hideDelayAfterClick: [{ type: Input, args: ['hideDelayAfterClick'] }], pointerEvents: [{ type: Input, args: ['pointerEvents'] }], position: [{ type: Input, args: ['position'] }], events: [{ type: Output }], onMouseEnter: [{ type: HostListener, args: ['focusin'] }, { type: HostListener, args: ['mouseenter'] }], onMouseLeave: [{ type: HostListener, args: ['focusout'] }, { type: HostListener, args: ['mouseleave'] }], onClick: [{ type: HostListener, args: ['click'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9vbHRpcC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9jbS1hbmd1bGFyLXRvb2x0aXAvc3JjL2xpYi90b29sdGlwLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQTZGLE1BQU0sRUFBRSxZQUFZLEVBQWEsTUFBTSxFQUFFLFFBQVEsRUFBaUIsTUFBTSxlQUFlLENBQUM7QUFDeE8sT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFdkQsT0FBTyxFQUFFLDRCQUE0QixFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2pGLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDOztBQWNsRSxNQUFNLE9BQU8sZ0JBQWdCO0lBc0J6QixJQUFzQixPQUFPLENBQUMsS0FBcUI7UUFDL0MsSUFBSSxLQUFLLElBQUksY0FBYyxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDMUIsQ0FBQztJQUNMLENBQUM7SUFDRCxJQUFJLE9BQU87UUFDUCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDekIsQ0FBQztJQU1ELGVBQWU7SUFDZixJQUEyQixnQ0FBZ0MsQ0FBQyxLQUFxQztRQUM3RixJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1IsSUFBSSxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7UUFDOUIsQ0FBQztJQUNMLENBQUM7SUFDRCxJQUEwQixXQUFXLENBQUMsS0FBcUM7UUFDdkUsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNSLElBQUksQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO1FBQzlCLENBQUM7SUFDTCxDQUFDO0lBQ0QsSUFBSSxXQUFXO1FBQ1gsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDO0lBQzdCLENBQUM7SUFLRCxVQUFVO0lBQ1YsSUFBc0IsMkJBQTJCLENBQUMsS0FBYTtRQUMzRCxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1IsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDekIsQ0FBQztJQUNMLENBQUM7SUFDRCxJQUFxQixNQUFNLENBQUMsS0FBYTtRQUNyQyxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1IsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDekIsQ0FBQztJQUNMLENBQUM7SUFDRCxJQUFJLE1BQU07UUFDTixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDeEIsQ0FBQztJQUVELHFCQUFxQjtJQUNyQixJQUFpQyxzQ0FBc0MsQ0FBQyxLQUFhO1FBQ2pGLElBQUksS0FBSyxFQUFFLENBQUM7WUFDUixJQUFJLENBQUMsa0JBQWtCLEdBQUcsS0FBSyxDQUFDO1FBQ3BDLENBQUM7SUFDTCxDQUFDO0lBQ0QsSUFBZ0MsaUJBQWlCLENBQUMsS0FBYTtRQUMzRCxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1IsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQztRQUNwQyxDQUFDO0lBQ0wsQ0FBQztJQUNELElBQUksaUJBQWlCO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDO0lBQ25DLENBQUM7SUFLRCxnQkFBZ0I7SUFDaEIsSUFBNEIsaUNBQWlDLENBQUMsS0FBYTtRQUN2RSxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1IsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7UUFDL0IsQ0FBQztJQUNMLENBQUM7SUFDRCxJQUEyQixZQUFZLENBQUMsS0FBYTtRQUNqRCxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1IsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7UUFDL0IsQ0FBQztJQUNMLENBQUM7SUFDRCxJQUFJLFlBQVk7UUFDWixPQUFPLElBQUksQ0FBQyxhQUFhLENBQUM7SUFDOUIsQ0FBQztJQVVELFlBQVk7SUFDWixJQUF3Qiw2QkFBNkIsQ0FBQyxLQUFhO1FBQy9ELElBQUksS0FBSyxFQUFFLENBQUM7WUFDUixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztRQUMzQixDQUFDO0lBQ0wsQ0FBQztJQUNELElBQXVCLFFBQVEsQ0FBQyxLQUFhO1FBQ3pDLElBQUksS0FBSyxFQUFFLENBQUM7WUFDUixJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztRQUMzQixDQUFDO0lBQ0wsQ0FBQztJQUNELElBQUksUUFBUTtRQUNSLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUMxQixDQUFDO0lBS0QsYUFBYTtJQUNiLElBQXlCLDhCQUE4QixDQUFDLEtBQWE7UUFDakUsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNSLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1FBQzVCLENBQUM7SUFDTCxDQUFDO0lBQ0QsSUFBd0IsU0FBUyxDQUFDLEtBQWE7UUFDM0MsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNSLElBQUksQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1FBQzVCLENBQUM7SUFDTCxDQUFDO0lBQ0QsSUFBSSxTQUFTO1FBQ1QsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQzNCLENBQUM7SUFFRCxhQUFhO0lBQ2IsSUFBeUIsOEJBQThCLENBQUMsS0FBYTtRQUNqRSxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1IsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7UUFDNUIsQ0FBQztJQUNMLENBQUM7SUFDRCxJQUF3QixTQUFTLENBQUMsS0FBYTtRQUMzQyxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1IsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7UUFDNUIsQ0FBQztJQUNMLENBQUM7SUFDRCxJQUFJLFNBQVM7UUFDVCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDM0IsQ0FBQztJQU1ELElBQUksa0JBQWtCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUM7SUFDckUsQ0FBQztJQUVELElBQUksWUFBWTtRQUNaLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3JCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztRQUM5QixDQUFDO2FBQU0sQ0FBQztZQUNKLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLG1CQUFtQixDQUFDLENBQUMsQ0FBQztRQUNuRixDQUFDO0lBQ0wsQ0FBQztJQUNELElBQUksWUFBWSxDQUFDLEtBQWE7UUFDMUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxLQUFLLENBQUM7SUFDL0IsQ0FBQztJQUVELElBQUksZUFBZTtRQUNmLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQzNCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNwQyxDQUFDO2FBQU0sQ0FBQztZQUNKLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQztRQUNoQyxDQUFDO0lBQ0wsQ0FBQztJQUlELFlBQ3VELFdBQWdCLEVBQzNELFVBQXNCLEVBQ3RCLHdCQUFrRCxFQUNsRCxNQUFzQixFQUN0QixRQUFrQjtRQUp5QixnQkFBVyxHQUFYLFdBQVcsQ0FBSztRQUMzRCxlQUFVLEdBQVYsVUFBVSxDQUFZO1FBQ3RCLDZCQUF3QixHQUF4Qix3QkFBd0IsQ0FBMEI7UUFDbEQsV0FBTSxHQUFOLE1BQU0sQ0FBZ0I7UUFDdEIsYUFBUSxHQUFSLFFBQVEsQ0FBVTtRQXJMOUIsYUFBUSxHQUFRLEVBQUUsQ0FBQztRQUluQixpQkFBWSxHQUFtQyxRQUFRLENBQUM7UUEwSzlDLFdBQU0sR0FBc0IsSUFBSSxZQUFZLEVBQU8sQ0FBQztJQU81QixDQUFDO0lBSW5DLFlBQVk7UUFDUixJQUFJLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNqQyxPQUFPO1FBQ1gsQ0FBQztRQUVELElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNoQixDQUFDO0lBSUQsWUFBWTtRQUNSLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsS0FBSyxPQUFPLEVBQUUsQ0FBQztZQUN0QyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDMUIsQ0FBQztJQUNMLENBQUM7SUFHRCxPQUFPO1FBQ0gsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLElBQUksS0FBSyxFQUFFLENBQUM7WUFDakMsT0FBTztRQUNYLENBQUM7UUFFRCxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDWixJQUFJLENBQUMsdUJBQXVCLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDbEQsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQzFCLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLHFCQUFxQixDQUFDLENBQUMsQ0FBQTtJQUMzQyxDQUFDO0lBRUQsUUFBUTtJQUNSLENBQUM7SUFFRCxXQUFXLENBQUMsT0FBc0I7UUFDOUIsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzNELElBQUksY0FBYyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDakQsY0FBYyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUV2RCxJQUFJLENBQUMsbUJBQW1CLENBQUMsY0FBYyxFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQzdELENBQUM7SUFFRCxXQUFXO1FBQ1AsSUFBSSxDQUFDLGNBQWMsQ0FBQztZQUNoQixJQUFJLEVBQUUsSUFBSTtTQUNiLENBQUMsQ0FBQztRQUVILElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzFDLENBQUM7SUFDTCxDQUFDO0lBRUQsWUFBWTtRQUNSLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRUQsWUFBWTtRQUNSLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDNUMsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLHNCQUFzQixDQUFDLENBQUM7UUFFbEUsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ2pFLENBQUM7SUFFRCxhQUFhLENBQUMsT0FBc0I7UUFDaEMsSUFBSSxtQkFBbUIsR0FBUSxFQUFFLENBQUM7UUFDbEMsSUFBSSxnQkFBZ0IsR0FBUSxFQUFFLENBQUM7UUFDL0IsSUFBSSxhQUFhLEdBQVEsRUFBRSxDQUFDO1FBRTVCLEtBQUssSUFBSSxJQUFJLElBQUksT0FBTyxFQUFFLENBQUM7WUFDdkIsSUFBSSxJQUFJLEtBQUssU0FBUyxJQUFJLElBQUksS0FBSyxjQUFjLEVBQUUsQ0FBQztnQkFDaEQsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLFlBQVksQ0FBQztZQUMzRCxDQUFDO1lBQ0QsSUFBSSxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3JCLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxZQUFZLENBQUM7WUFDbEQsQ0FBQztRQUNMLENBQUM7UUFFRCxhQUFhLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztRQUN6RSxPQUFPLGFBQWEsQ0FBQztJQUN6QixDQUFDO0lBRUQsZ0JBQWdCLENBQUMsT0FBWTtRQUN6QixLQUFLLElBQUksSUFBSSxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ3ZCLElBQUksNEJBQTRCLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDckMsT0FBTyxDQUFDLDRCQUE0QixDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUM1RCxPQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6QixDQUFDO1FBQ0wsQ0FBQztRQUVELE9BQU8sT0FBTyxDQUFDO0lBQ25CLENBQUM7SUFFRCxrQkFBa0I7UUFDZCxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLHFCQUFxQixFQUFFLENBQUM7SUFDakYsQ0FBQztJQUVELGFBQWE7UUFDVCxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFFMUIsSUFBSSxDQUFDLGVBQWUsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUMxQyxJQUFJLENBQUMscUJBQXFCLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUNqRCxDQUFDLEVBQUUsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7UUFFeEIsSUFBSSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUN4QyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDM0IsQ0FBQyxFQUFFLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFFRCxjQUFjLENBQUMsT0FBTyxHQUFHO1FBQ3JCLElBQUksRUFBRSxLQUFLO0tBQ2Q7UUFDRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFFckIsSUFBSSxJQUFJLENBQUMsa0JBQWtCLElBQUksS0FBSyxFQUFFLENBQUM7WUFDbkMsSUFBSSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDeEMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3ZCLENBQUMsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBRTNDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDM0MsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7b0JBQ2hELE9BQU87Z0JBQ1gsQ0FBQztnQkFFRCxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNuRCxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUM1QixJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQztvQkFDYixJQUFJLEVBQUUsUUFBUTtvQkFDZCxRQUFRLEVBQUUsSUFBSSxDQUFDLGVBQWU7aUJBQ2pDLENBQUMsQ0FBQztZQUNQLENBQUMsRUFBRSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztRQUM3QyxDQUFDO0lBQ0wsQ0FBQztJQUVELGVBQWU7UUFDWCxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDUCxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVMsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ3RELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO1lBQ2IsSUFBSSxFQUFFLE1BQU07WUFDWixRQUFRLEVBQUUsSUFBSSxDQUFDLGVBQWU7U0FDakMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELFdBQVc7UUFDUCxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUNoRCxPQUFPO1FBQ1gsQ0FBQztRQUNhLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUyxDQUFDLElBQUksR0FBRyxLQUFLLENBQUM7UUFDdkQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUM7WUFDYixJQUFJLEVBQUUsTUFBTTtZQUNaLFFBQVEsRUFBRSxJQUFJLENBQUMsZUFBZTtTQUNqQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQscUJBQXFCLENBQUMsU0FBYyxFQUFFLE9BQVksRUFBRTtRQUNoRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyx3QkFBd0I7YUFDNUMsdUJBQXVCLENBQUMsU0FBUyxDQUFDO2FBQ2xDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFYixJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVMsQ0FBQyxJQUFJLEdBQUc7WUFDN0MsS0FBSyxFQUFFLElBQUksQ0FBQyxZQUFZO1lBQ3hCLE9BQU8sRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWE7WUFDdEMsZUFBZSxFQUFFLElBQUksQ0FBQyxlQUFlO1lBQ3JDLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztTQUN4QixDQUFBO1FBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUNuRCxNQUFNLE9BQU8sR0FBSSxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQWlDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBZ0IsQ0FBQztRQUNqRyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUVuQyxJQUFJLENBQUMsa0JBQWtCLEdBQWlCLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxLQUFVLEVBQUUsRUFBRTtZQUNoRyxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELGFBQWE7UUFDVCxJQUFJLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUN2QixZQUFZLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ3ZDLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNyQixZQUFZLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3JDLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNyQixZQUFZLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3JDLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3hCLFlBQVksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUN4QyxDQUFDO0lBQ0wsQ0FBQztJQUVELElBQUksZ0JBQWdCO1FBQ2hCLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUNuQyxPQUFPLEtBQUssQ0FBQztRQUNqQixDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLG9CQUFvQixDQUFDLElBQUksS0FBSyxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNwRSxPQUFPLEtBQUssQ0FBQztRQUNqQixDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxLQUFLLE9BQU8sRUFBRSxDQUFDO1lBQ3RDLE9BQU8sS0FBSyxDQUFDO1FBQ2pCLENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQztJQUNoQixDQUFDO0lBRUQsSUFBSSxnQkFBZ0I7UUFDaEIsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ25DLE9BQU8sS0FBSyxDQUFDO1FBQ2pCLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsSUFBSSxLQUFLLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3BFLE9BQU8sS0FBSyxDQUFDO1FBQ2pCLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksT0FBTyxFQUFFLENBQUM7WUFDckMsT0FBTyxLQUFLLENBQUM7UUFDakIsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxJQUFJLGFBQWE7UUFDYixJQUFJLFFBQVEsR0FBRywyQkFBMkIsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdEQsSUFBSSxFQUFFLEdBQUcsVUFBVSxLQUFVO1lBQ3pCLE9BQU8sTUFBTSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUM7UUFDNUMsQ0FBQyxDQUFBO1FBRUQsSUFBSSxDQUFDLGNBQWMsSUFBSSxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQzdCLE9BQU8sSUFBSSxDQUFDO1FBQ2hCLENBQUM7UUFFRCxxRkFBcUY7UUFDckYsdUJBQXVCO1FBQ3ZCLElBQUksS0FBSyxHQUFHLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsRUFBRSxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzdFLE9BQU8sRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3JCLENBQUM7SUFFRCxtQkFBbUIsQ0FBQyxjQUFtQixFQUFFLE9BQVk7UUFDakQsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxjQUFjLEVBQUUsSUFBSSxDQUFDLFdBQVcsSUFBSSxFQUFFLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztJQUNwRyxDQUFDO0lBRUQsWUFBWSxDQUFDLEtBQVU7UUFDbkIsSUFBSSxLQUFLLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRSxDQUFDO1lBQ3pCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDO2dCQUNiLElBQUksRUFBRSxPQUFPO2dCQUNiLFFBQVEsRUFBRSxJQUFJLENBQUMsZUFBZTthQUNqQyxDQUFDLENBQUM7UUFDUCxDQUFDO0lBQ0wsQ0FBQztJQUVNLElBQUk7UUFDUCxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3JCLE9BQU87UUFDWCxDQUFDO1FBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDaEQsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3pCLENBQUM7YUFBTSxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDbEMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQzNCLENBQUM7SUFDTCxDQUFDO0lBRU0sSUFBSTtRQUNQLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUMxQixDQUFDOytHQTNjUSxnQkFBZ0Isa0JBMkxELHFCQUFxQjttR0EzTHBDLGdCQUFnQjs7NEZBQWhCLGdCQUFnQjtrQkFMNUIsU0FBUzttQkFBQztvQkFDUCxRQUFRLEVBQUUsV0FBVztvQkFDckIsUUFBUSxFQUFFLFNBQVM7aUJBQ3RCOzswQkE2TFEsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxxQkFBcUI7NkpBckt2QixPQUFPO3NCQUE1QixLQUFLO3VCQUFDLFNBQVM7Z0JBU0UsWUFBWTtzQkFBN0IsS0FBSzt1QkFBQyxTQUFTO2dCQUNJLFNBQVM7c0JBQTVCLEtBQUs7dUJBQUMsV0FBVztnQkFDTSxhQUFhO3NCQUFwQyxLQUFLO3VCQUFDLGVBQWU7Z0JBR0ssZ0NBQWdDO3NCQUExRCxLQUFLO3VCQUFDLGNBQWM7Z0JBS0ssV0FBVztzQkFBcEMsS0FBSzt1QkFBQyxhQUFhO2dCQVNRLGVBQWU7c0JBQTFDLEtBQUs7dUJBQUMsbUJBQW1CO2dCQUNLLG9CQUFvQjtzQkFBbEQsS0FBSzt1QkFBQyxzQkFBc0I7Z0JBR1AsMkJBQTJCO3NCQUFoRCxLQUFLO3VCQUFDLFNBQVM7Z0JBS0ssTUFBTTtzQkFBMUIsS0FBSzt1QkFBQyxRQUFRO2dCQVVrQixzQ0FBc0M7c0JBQXRFLEtBQUs7dUJBQUMsb0JBQW9CO2dCQUtLLGlCQUFpQjtzQkFBaEQsS0FBSzt1QkFBQyxtQkFBbUI7Z0JBVVIsT0FBTztzQkFBeEIsS0FBSzt1QkFBQyxTQUFTO2dCQUdZLGlDQUFpQztzQkFBNUQsS0FBSzt1QkFBQyxlQUFlO2dCQUtLLFlBQVk7c0JBQXRDLEtBQUs7dUJBQUMsY0FBYztnQkFTSCxPQUFPO3NCQUF4QixLQUFLO3VCQUFDLFNBQVM7Z0JBQ1MsYUFBYTtzQkFBckMsS0FBSzt1QkFBQyxnQkFBZ0I7Z0JBQ00sa0JBQWtCO3NCQUE5QyxLQUFLO3VCQUFDLG9CQUFvQjtnQkFDVixNQUFNO3NCQUF0QixLQUFLO3VCQUFDLFFBQVE7Z0JBQ0MsS0FBSztzQkFBcEIsS0FBSzt1QkFBQyxPQUFPO2dCQUNHLE1BQU07c0JBQXRCLEtBQUs7dUJBQUMsUUFBUTtnQkFDQyxLQUFLO3NCQUFwQixLQUFLO3VCQUFDLE9BQU87Z0JBR1UsNkJBQTZCO3NCQUFwRCxLQUFLO3VCQUFDLFdBQVc7Z0JBS0ssUUFBUTtzQkFBOUIsS0FBSzt1QkFBQyxVQUFVO2dCQVVKLEVBQUU7c0JBQWQsS0FBSzt1QkFBQyxJQUFJO2dCQUdjLDhCQUE4QjtzQkFBdEQsS0FBSzt1QkFBQyxZQUFZO2dCQUtLLFNBQVM7c0JBQWhDLEtBQUs7dUJBQUMsV0FBVztnQkFVTyw4QkFBOEI7c0JBQXRELEtBQUs7dUJBQUMsWUFBWTtnQkFLSyxTQUFTO3NCQUFoQyxLQUFLO3VCQUFDLFdBQVc7Z0JBU1ksbUJBQW1CO3NCQUFoRCxLQUFLO3VCQUFDLHFCQUFxQjtnQkFDSixhQUFhO3NCQUFwQyxLQUFLO3VCQUFDLGVBQWU7Z0JBQ0gsUUFBUTtzQkFBMUIsS0FBSzt1QkFBQyxVQUFVO2dCQXlCUCxNQUFNO3NCQUFmLE1BQU07Z0JBV1AsWUFBWTtzQkFGWCxZQUFZO3VCQUFDLFNBQVM7O3NCQUN0QixZQUFZO3VCQUFDLFlBQVk7Z0JBVzFCLFlBQVk7c0JBRlgsWUFBWTt1QkFBQyxVQUFVOztzQkFDdkIsWUFBWTt1QkFBQyxZQUFZO2dCQVExQixPQUFPO3NCQUROLFlBQVk7dUJBQUMsT0FBTyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgSG9zdExpc3RlbmVyLCBJbnB1dCwgQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLCBFbWJlZGRlZFZpZXdSZWYsIEFwcGxpY2F0aW9uUmVmLCBJbmplY3RvciwgQ29tcG9uZW50UmVmLCBPbkluaXQsIE91dHB1dCwgRXZlbnRFbWl0dGVyLCBPbkRlc3Ryb3ksIEluamVjdCwgT3B0aW9uYWwsIFNpbXBsZUNoYW5nZXMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgVG9vbHRpcENvbXBvbmVudCB9IGZyb20gJy4vdG9vbHRpcC5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBUb29sdGlwT3B0aW9ucyB9IGZyb20gJy4vdG9vbHRpcC1vcHRpb25zLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IGJhY2t3YXJkQ29tcGF0aWJpbGl0eU9wdGlvbnMsIGRlZmF1bHRPcHRpb25zIH0gZnJvbSAnLi90b29sdGlwLW9wdGlvbnMnO1xyXG5pbXBvcnQgeyBUb29sdGlwT3B0aW9uc1NlcnZpY2UgfSBmcm9tICcuL3Rvb2x0aXAtb3B0aW9ucy5zZXJ2aWNlJztcclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgQWRDb21wb25lbnQge1xyXG4gICAgZGF0YTogYW55O1xyXG4gICAgc2hvdzogYm9vbGVhbjtcclxuICAgIGNsb3NlOiBib29sZWFuO1xyXG4gICAgZXZlbnRzOiBhbnk7XHJcbn1cclxuXHJcbkBEaXJlY3RpdmUoe1xyXG4gICAgc2VsZWN0b3I6ICdbdG9vbHRpcF0nLFxyXG4gICAgZXhwb3J0QXM6ICd0b29sdGlwJyxcclxufSlcclxuXHJcbmV4cG9ydCBjbGFzcyBUb29sdGlwRGlyZWN0aXZlIHtcclxuXHJcbiAgICBoaWRlVGltZW91dElkITogbnVtYmVyO1xyXG4gICAgZGVzdHJveVRpbWVvdXRJZCE6IG51bWJlcjtcclxuICAgIGhpZGVBZnRlckNsaWNrVGltZW91dElkITogbnVtYmVyO1xyXG4gICAgY3JlYXRlVGltZW91dElkITogbnVtYmVyO1xyXG4gICAgc2hvd1RpbWVvdXRJZCE6IG51bWJlcjtcclxuICAgIGNvbXBvbmVudFJlZjogYW55O1xyXG4gICAgZWxlbWVudFBvc2l0aW9uOiBhbnk7XHJcbiAgICBfaWQ6IGFueTtcclxuICAgIF9vcHRpb25zOiBhbnkgPSB7fTtcclxuICAgIF9kZWZhdWx0T3B0aW9uczogYW55O1xyXG4gICAgX2Rlc3Ryb3lEZWxheSE6IG51bWJlcjtcclxuICAgIGNvbXBvbmVudFN1YnNjcmliZTogYW55O1xyXG4gICAgX2NvbnRlbnRUeXBlOiBcInN0cmluZ1wiIHwgXCJodG1sXCIgfCBcInRlbXBsYXRlXCIgPSBcInN0cmluZ1wiO1xyXG4gICAgX3Nob3dEZWxheSE6IG51bWJlcjtcclxuICAgIF9oaWRlRGVsYXkhOiBudW1iZXI7XHJcbiAgICBfekluZGV4ITogbnVtYmVyO1xyXG4gICAgX3Rvb2x0aXBDbGFzcyE6IHN0cmluZztcclxuICAgIF9hbmltYXRpb25EdXJhdGlvbiE6IG51bWJlcjtcclxuICAgIF9tYXhXaWR0aCE6IHN0cmluZztcclxuXHJcbiAgICBASW5wdXQoJ29wdGlvbnMnKSBzZXQgb3B0aW9ucyh2YWx1ZTogVG9vbHRpcE9wdGlvbnMpIHtcclxuICAgICAgICBpZiAodmFsdWUgJiYgZGVmYXVsdE9wdGlvbnMpIHtcclxuICAgICAgICAgICAgdGhpcy5fb3B0aW9ucyA9IHZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIGdldCBvcHRpb25zKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9vcHRpb25zO1xyXG4gICAgfVxyXG5cclxuICAgIEBJbnB1dCgndG9vbHRpcCcpIHRvb2x0aXBWYWx1ZSE6IHN0cmluZztcclxuICAgIEBJbnB1dCgncGxhY2VtZW50JykgcGxhY2VtZW50ITogc3RyaW5nO1xyXG4gICAgQElucHV0KCdhdXRvUGxhY2VtZW50JykgYXV0b1BsYWNlbWVudCE6IGJvb2xlYW47XHJcblxyXG4gICAgLy8gQ29udGVudCB0eXBlXHJcbiAgICBASW5wdXQoJ2NvbnRlbnQtdHlwZScpIHNldCBjb250ZW50VHlwZUJhY2t3YXJkQ29tcGF0aWJpbGl0eSh2YWx1ZTogXCJzdHJpbmdcIiB8IFwiaHRtbFwiIHwgXCJ0ZW1wbGF0ZVwiKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbnRlbnRUeXBlID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgQElucHV0KCdjb250ZW50VHlwZScpIHNldCBjb250ZW50VHlwZSh2YWx1ZTogXCJzdHJpbmdcIiB8IFwiaHRtbFwiIHwgXCJ0ZW1wbGF0ZVwiKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2NvbnRlbnRUeXBlID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZ2V0IGNvbnRlbnRUeXBlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9jb250ZW50VHlwZTtcclxuICAgIH1cclxuXHJcbiAgICBASW5wdXQoJ2hpZGUtZGVsYXktbW9iaWxlJykgaGlkZURlbGF5TW9iaWxlITogbnVtYmVyO1xyXG4gICAgQElucHV0KCdoaWRlRGVsYXlUb3VjaHNjcmVlbicpIGhpZGVEZWxheVRvdWNoc2NyZWVuITogbnVtYmVyO1xyXG5cclxuICAgIC8vIHotaW5kZXhcclxuICAgIEBJbnB1dCgnei1pbmRleCcpIHNldCB6SW5kZXhCYWNrd2FyZENvbXBhdGliaWxpdHkodmFsdWU6IG51bWJlcikge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl96SW5kZXggPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBASW5wdXQoJ3pJbmRleCcpIHNldCB6SW5kZXgodmFsdWU6IG51bWJlcikge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl96SW5kZXggPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBnZXQgekluZGV4KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl96SW5kZXg7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQW5pbWF0aW9uIGR1cmF0aW9uXHJcbiAgICBASW5wdXQoJ2FuaW1hdGlvbi1kdXJhdGlvbicpIHNldCBhbmltYXRpb25EdXJhdGlvbkJhY2t3YXJkQ29tcGF0aWJpbGl0eSh2YWx1ZTogbnVtYmVyKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2FuaW1hdGlvbkR1cmF0aW9uID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgQElucHV0KCdhbmltYXRpb25EdXJhdGlvbicpIHNldCBhbmltYXRpb25EdXJhdGlvbih2YWx1ZTogbnVtYmVyKSB7XHJcbiAgICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2FuaW1hdGlvbkR1cmF0aW9uID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZ2V0IGFuaW1hdGlvbkR1cmF0aW9uKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hbmltYXRpb25EdXJhdGlvbjtcclxuICAgIH1cclxuXHJcblxyXG4gICAgQElucHV0KCd0cmlnZ2VyJykgdHJpZ2dlciE6IHN0cmluZztcclxuXHJcbiAgICAvLyBUb29sdGlwIGNsYXNzXHJcbiAgICBASW5wdXQoJ3Rvb2x0aXAtY2xhc3MnKSBzZXQgdG9vbHRpcENsYXNzQmFja3dhcmRDb21wYXRpYmlsaXR5KHZhbHVlOiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fdG9vbHRpcENsYXNzID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgQElucHV0KCd0b29sdGlwQ2xhc3MnKSBzZXQgdG9vbHRpcENsYXNzKHZhbHVlOiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fdG9vbHRpcENsYXNzID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZ2V0IHRvb2x0aXBDbGFzcygpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fdG9vbHRpcENsYXNzO1xyXG4gICAgfVxyXG5cclxuICAgIEBJbnB1dCgnZGlzcGxheScpIGRpc3BsYXkhOiBib29sZWFuO1xyXG4gICAgQElucHV0KCdkaXNwbGF5LW1vYmlsZScpIGRpc3BsYXlNb2JpbGUhOiBib29sZWFuO1xyXG4gICAgQElucHV0KCdkaXNwbGF5VG91Y2hzY3JlZW4nKSBkaXNwbGF5VG91Y2hzY3JlZW4hOiBib29sZWFuO1xyXG4gICAgQElucHV0KCdzaGFkb3cnKSBzaGFkb3chOiBib29sZWFuO1xyXG4gICAgQElucHV0KCd0aGVtZScpIHRoZW1lITogXCJkYXJrXCIgfCBcImxpZ2h0XCI7XHJcbiAgICBASW5wdXQoJ29mZnNldCcpIG9mZnNldCE6IG51bWJlcjtcclxuICAgIEBJbnB1dCgnd2lkdGgnKSB3aWR0aCE6IHN0cmluZztcclxuXHJcbiAgICAvLyBNYXggd2lkdGhcclxuICAgIEBJbnB1dCgnbWF4LXdpZHRoJykgc2V0IG1heFdpZHRoQmFja3dhcmRDb21wYXRpYmlsaXR5KHZhbHVlOiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fbWF4V2lkdGggPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBASW5wdXQoJ21heFdpZHRoJykgc2V0IG1heFdpZHRoKHZhbHVlOiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fbWF4V2lkdGggPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBnZXQgbWF4V2lkdGgoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX21heFdpZHRoO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICBASW5wdXQoJ2lkJykgaWQ6IGFueTtcclxuXHJcbiAgICAvLyBTaG93IGRlbGF5XHJcbiAgICBASW5wdXQoJ3Nob3ctZGVsYXknKSBzZXQgc2hvd0RlbGF5QmFja3dhcmRDb21wYXRpYmlsaXR5KHZhbHVlOiBudW1iZXIpIHtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fc2hvd0RlbGF5ID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgQElucHV0KCdzaG93RGVsYXknKSBzZXQgc2hvd0RlbGF5KHZhbHVlOiBudW1iZXIpIHtcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fc2hvd0RlbGF5ID0gdmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgZ2V0IHNob3dEZWxheSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fc2hvd0RlbGF5O1xyXG4gICAgfVxyXG5cclxuICAgIC8vIEhpZGUgZGVsYXlcclxuICAgIEBJbnB1dCgnaGlkZS1kZWxheScpIHNldCBoaWRlRGVsYXlCYWNrd2FyZENvbXBhdGliaWxpdHkodmFsdWU6IG51bWJlcikge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl9oaWRlRGVsYXkgPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBASW5wdXQoJ2hpZGVEZWxheScpIHNldCBoaWRlRGVsYXkodmFsdWU6IG51bWJlcikge1xyXG4gICAgICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl9oaWRlRGVsYXkgPSB2YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBnZXQgaGlkZURlbGF5KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9oaWRlRGVsYXk7XHJcbiAgICB9XHJcblxyXG4gICAgQElucHV0KCdoaWRlRGVsYXlBZnRlckNsaWNrJykgaGlkZURlbGF5QWZ0ZXJDbGljayE6IG51bWJlcjtcclxuICAgIEBJbnB1dCgncG9pbnRlckV2ZW50cycpIHBvaW50ZXJFdmVudHMhOiAnYXV0bycgfCAnbm9uZSc7XHJcbiAgICBASW5wdXQoJ3Bvc2l0aW9uJykgcG9zaXRpb24hOiB7IHRvcDogbnVtYmVyLCBsZWZ0OiBudW1iZXIgfTtcclxuXHJcbiAgICBnZXQgaXNUb29sdGlwRGVzdHJveWVkKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbXBvbmVudFJlZiAmJiB0aGlzLmNvbXBvbmVudFJlZi5ob3N0Vmlldy5kZXN0cm95ZWQ7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGRlc3Ryb3lEZWxheSgpIHtcclxuICAgICAgICBpZiAodGhpcy5fZGVzdHJveURlbGF5KSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9kZXN0cm95RGVsYXk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIE51bWJlcih0aGlzLmdldEhpZGVEZWxheSgpKSArIE51bWJlcih0aGlzLm9wdGlvbnNbJ2FuaW1hdGlvbkR1cmF0aW9uJ10pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIHNldCBkZXN0cm95RGVsYXkodmFsdWU6IG51bWJlcikge1xyXG4gICAgICAgIHRoaXMuX2Rlc3Ryb3lEZWxheSA9IHZhbHVlO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCB0b29sdGlwUG9zaXRpb24oKSB7XHJcbiAgICAgICAgaWYgKHRoaXMub3B0aW9uc1sncG9zaXRpb24nXSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zWydwb3NpdGlvbiddO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRQb3NpdGlvbjtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgQE91dHB1dCgpIGV2ZW50czogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFRvb2x0aXBPcHRpb25zU2VydmljZSkgcHJpdmF0ZSBpbml0T3B0aW9uczogYW55LFxyXG4gICAgICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZixcclxuICAgICAgICBwcml2YXRlIGNvbXBvbmVudEZhY3RvcnlSZXNvbHZlcjogQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLFxyXG4gICAgICAgIHByaXZhdGUgYXBwUmVmOiBBcHBsaWNhdGlvblJlZixcclxuICAgICAgICBwcml2YXRlIGluamVjdG9yOiBJbmplY3RvcikgeyB9XHJcblxyXG4gICAgQEhvc3RMaXN0ZW5lcignZm9jdXNpbicpXHJcbiAgICBASG9zdExpc3RlbmVyKCdtb3VzZWVudGVyJylcclxuICAgIG9uTW91c2VFbnRlcigpIHtcclxuICAgICAgICBpZiAodGhpcy5pc0Rpc3BsYXlPbkhvdmVyID09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuc2hvdygpO1xyXG4gICAgfVxyXG5cclxuICAgIEBIb3N0TGlzdGVuZXIoJ2ZvY3Vzb3V0JylcclxuICAgIEBIb3N0TGlzdGVuZXIoJ21vdXNlbGVhdmUnKVxyXG4gICAgb25Nb3VzZUxlYXZlKCkge1xyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnNbJ3RyaWdnZXInXSA9PT0gJ2hvdmVyJykge1xyXG4gICAgICAgICAgICB0aGlzLmRlc3Ryb3lUb29sdGlwKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIEBIb3N0TGlzdGVuZXIoJ2NsaWNrJylcclxuICAgIG9uQ2xpY2soKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNEaXNwbGF5T25DbGljayA9PSBmYWxzZSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLnNob3coKTtcclxuICAgICAgICB0aGlzLmhpZGVBZnRlckNsaWNrVGltZW91dElkID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmRlc3Ryb3lUb29sdGlwKCk7XHJcbiAgICAgICAgfSwgdGhpcy5vcHRpb25zWydoaWRlRGVsYXlBZnRlckNsaWNrJ10pXHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xyXG4gICAgICAgIHRoaXMuaW5pdE9wdGlvbnMgPSB0aGlzLnJlbmFtZVByb3BlcnRpZXModGhpcy5pbml0T3B0aW9ucyk7XHJcbiAgICAgICAgbGV0IGNoYW5nZWRPcHRpb25zID0gdGhpcy5nZXRQcm9wZXJ0aWVzKGNoYW5nZXMpO1xyXG4gICAgICAgIGNoYW5nZWRPcHRpb25zID0gdGhpcy5yZW5hbWVQcm9wZXJ0aWVzKGNoYW5nZWRPcHRpb25zKTtcclxuXHJcbiAgICAgICAgdGhpcy5hcHBseU9wdGlvbnNEZWZhdWx0KGRlZmF1bHRPcHRpb25zLCBjaGFuZ2VkT3B0aW9ucyk7XHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5kZXN0cm95VG9vbHRpcCh7XHJcbiAgICAgICAgICAgIGZhc3Q6IHRydWVcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuY29tcG9uZW50U3Vic2NyaWJlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29tcG9uZW50U3Vic2NyaWJlLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGdldFNob3dEZWxheSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5vcHRpb25zWydzaG93RGVsYXknXTtcclxuICAgIH1cclxuXHJcbiAgICBnZXRIaWRlRGVsYXkoKSB7XHJcbiAgICAgICAgY29uc3QgaGlkZURlbGF5ID0gdGhpcy5vcHRpb25zWydoaWRlRGVsYXknXTtcclxuICAgICAgICBjb25zdCBoaWRlRGVsYXlUb3VjaHNjcmVlbiA9IHRoaXMub3B0aW9uc1snaGlkZURlbGF5VG91Y2hzY3JlZW4nXTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaXNUb3VjaFNjcmVlbiA/IGhpZGVEZWxheVRvdWNoc2NyZWVuIDogaGlkZURlbGF5O1xyXG4gICAgfVxyXG5cclxuICAgIGdldFByb3BlcnRpZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xyXG4gICAgICAgIGxldCBkaXJlY3RpdmVQcm9wZXJ0aWVzOiBhbnkgPSB7fTtcclxuICAgICAgICBsZXQgY3VzdG9tUHJvcGVydGllczogYW55ID0ge307XHJcbiAgICAgICAgbGV0IGFsbFByb3BlcnRpZXM6IGFueSA9IHt9O1xyXG5cclxuICAgICAgICBmb3IgKHZhciBwcm9wIGluIGNoYW5nZXMpIHtcclxuICAgICAgICAgICAgaWYgKHByb3AgIT09ICdvcHRpb25zJyAmJiBwcm9wICE9PSAndG9vbHRpcFZhbHVlJykge1xyXG4gICAgICAgICAgICAgICAgZGlyZWN0aXZlUHJvcGVydGllc1twcm9wXSA9IGNoYW5nZXNbcHJvcF0uY3VycmVudFZhbHVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChwcm9wID09PSAnb3B0aW9ucycpIHtcclxuICAgICAgICAgICAgICAgIGN1c3RvbVByb3BlcnRpZXMgPSBjaGFuZ2VzW3Byb3BdLmN1cnJlbnRWYWx1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYWxsUHJvcGVydGllcyA9IE9iamVjdC5hc3NpZ24oe30sIGN1c3RvbVByb3BlcnRpZXMsIGRpcmVjdGl2ZVByb3BlcnRpZXMpO1xyXG4gICAgICAgIHJldHVybiBhbGxQcm9wZXJ0aWVzO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbmFtZVByb3BlcnRpZXMob3B0aW9uczogYW55KSB7XHJcbiAgICAgICAgZm9yICh2YXIgcHJvcCBpbiBvcHRpb25zKSB7XHJcbiAgICAgICAgICAgIGlmIChiYWNrd2FyZENvbXBhdGliaWxpdHlPcHRpb25zW3Byb3BdKSB7XHJcbiAgICAgICAgICAgICAgICBvcHRpb25zW2JhY2t3YXJkQ29tcGF0aWJpbGl0eU9wdGlvbnNbcHJvcF1dID0gb3B0aW9uc1twcm9wXTtcclxuICAgICAgICAgICAgICAgIGRlbGV0ZSBvcHRpb25zW3Byb3BdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gb3B0aW9ucztcclxuICAgIH1cclxuXHJcbiAgICBnZXRFbGVtZW50UG9zaXRpb24oKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5lbGVtZW50UG9zaXRpb24gPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIH1cclxuXHJcbiAgICBjcmVhdGVUb29sdGlwKCk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuY2xlYXJUaW1lb3V0cygpO1xyXG4gICAgICAgIHRoaXMuZ2V0RWxlbWVudFBvc2l0aW9uKCk7XHJcblxyXG4gICAgICAgIHRoaXMuY3JlYXRlVGltZW91dElkID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLmFwcGVuZENvbXBvbmVudFRvQm9keShUb29sdGlwQ29tcG9uZW50KTtcclxuICAgICAgICB9LCB0aGlzLmdldFNob3dEZWxheSgpKTtcclxuXHJcbiAgICAgICAgdGhpcy5zaG93VGltZW91dElkID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLnNob3dUb29sdGlwRWxlbSgpO1xyXG4gICAgICAgIH0sIHRoaXMuZ2V0U2hvd0RlbGF5KCkpO1xyXG4gICAgfVxyXG5cclxuICAgIGRlc3Ryb3lUb29sdGlwKG9wdGlvbnMgPSB7XHJcbiAgICAgICAgZmFzdDogZmFsc2VcclxuICAgIH0pOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmNsZWFyVGltZW91dHMoKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuaXNUb29sdGlwRGVzdHJveWVkID09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaGlkZVRpbWVvdXRJZCA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaGlkZVRvb2x0aXAoKTtcclxuICAgICAgICAgICAgfSwgb3B0aW9ucy5mYXN0ID8gMCA6IHRoaXMuZ2V0SGlkZURlbGF5KCkpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5kZXN0cm95VGltZW91dElkID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmNvbXBvbmVudFJlZiB8fCB0aGlzLmlzVG9vbHRpcERlc3Ryb3llZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLmFwcFJlZi5kZXRhY2hWaWV3KHRoaXMuY29tcG9uZW50UmVmLmhvc3RWaWV3KTtcclxuICAgICAgICAgICAgICAgIHRoaXMuY29tcG9uZW50UmVmLmRlc3Ryb3koKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXZlbnRzLmVtaXQoe1xyXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICdoaWRkZW4nLFxyXG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiB0aGlzLnRvb2x0aXBQb3NpdGlvblxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0sIG9wdGlvbnMuZmFzdCA/IDAgOiB0aGlzLmRlc3Ryb3lEZWxheSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHNob3dUb29sdGlwRWxlbSgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmNsZWFyVGltZW91dHMoKTtcclxuICAgICAgICAoPEFkQ29tcG9uZW50PnRoaXMuY29tcG9uZW50UmVmLmluc3RhbmNlKS5zaG93ID0gdHJ1ZTtcclxuICAgICAgICB0aGlzLmV2ZW50cy5lbWl0KHtcclxuICAgICAgICAgICAgdHlwZTogJ3Nob3cnLFxyXG4gICAgICAgICAgICBwb3NpdGlvbjogdGhpcy50b29sdGlwUG9zaXRpb25cclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBoaWRlVG9vbHRpcCgpOiB2b2lkIHtcclxuICAgICAgICBpZiAoIXRoaXMuY29tcG9uZW50UmVmIHx8IHRoaXMuaXNUb29sdGlwRGVzdHJveWVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgKDxBZENvbXBvbmVudD50aGlzLmNvbXBvbmVudFJlZi5pbnN0YW5jZSkuc2hvdyA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuZXZlbnRzLmVtaXQoe1xyXG4gICAgICAgICAgICB0eXBlOiAnaGlkZScsXHJcbiAgICAgICAgICAgIHBvc2l0aW9uOiB0aGlzLnRvb2x0aXBQb3NpdGlvblxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGFwcGVuZENvbXBvbmVudFRvQm9keShjb21wb25lbnQ6IGFueSwgZGF0YTogYW55ID0ge30pOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmNvbXBvbmVudFJlZiA9IHRoaXMuY29tcG9uZW50RmFjdG9yeVJlc29sdmVyXHJcbiAgICAgICAgICAgIC5yZXNvbHZlQ29tcG9uZW50RmFjdG9yeShjb21wb25lbnQpXHJcbiAgICAgICAgICAgIC5jcmVhdGUodGhpcy5pbmplY3Rvcik7XHJcblxyXG4gICAgICAgICg8QWRDb21wb25lbnQ+dGhpcy5jb21wb25lbnRSZWYuaW5zdGFuY2UpLmRhdGEgPSB7XHJcbiAgICAgICAgICAgIHZhbHVlOiB0aGlzLnRvb2x0aXBWYWx1ZSxcclxuICAgICAgICAgICAgZWxlbWVudDogdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQsXHJcbiAgICAgICAgICAgIGVsZW1lbnRQb3NpdGlvbjogdGhpcy50b29sdGlwUG9zaXRpb24sXHJcbiAgICAgICAgICAgIG9wdGlvbnM6IHRoaXMub3B0aW9uc1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmFwcFJlZi5hdHRhY2hWaWV3KHRoaXMuY29tcG9uZW50UmVmLmhvc3RWaWV3KTtcclxuICAgICAgICBjb25zdCBkb21FbGVtID0gKHRoaXMuY29tcG9uZW50UmVmLmhvc3RWaWV3IGFzIEVtYmVkZGVkVmlld1JlZjxhbnk+KS5yb290Tm9kZXNbMF0gYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChkb21FbGVtKTtcclxuXHJcbiAgICAgICAgdGhpcy5jb21wb25lbnRTdWJzY3JpYmUgPSAoPEFkQ29tcG9uZW50PnRoaXMuY29tcG9uZW50UmVmLmluc3RhbmNlKS5ldmVudHMuc3Vic2NyaWJlKChldmVudDogYW55KSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlRXZlbnRzKGV2ZW50KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBjbGVhclRpbWVvdXRzKCk6IHZvaWQge1xyXG4gICAgICAgIGlmICh0aGlzLmNyZWF0ZVRpbWVvdXRJZCkge1xyXG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5jcmVhdGVUaW1lb3V0SWQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMuc2hvd1RpbWVvdXRJZCkge1xyXG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5zaG93VGltZW91dElkKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0aGlzLmhpZGVUaW1lb3V0SWQpIHtcclxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuaGlkZVRpbWVvdXRJZCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5kZXN0cm95VGltZW91dElkKSB7XHJcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmRlc3Ryb3lUaW1lb3V0SWQpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgaXNEaXNwbGF5T25Ib3ZlcigpOiBib29sZWFuIHtcclxuICAgICAgICBpZiAodGhpcy5vcHRpb25zWydkaXNwbGF5J10gPT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHRoaXMub3B0aW9uc1snZGlzcGxheVRvdWNoc2NyZWVuJ10gPT0gZmFsc2UgJiYgdGhpcy5pc1RvdWNoU2NyZWVuKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvb