ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
693 lines • 56.1 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: base.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 { CdkConnectedOverlay } from '@angular/cdk/overlay';
import { EventEmitter, Input, Output, TemplateRef, ViewChild } from '@angular/core';
import { warnDeprecation } from 'ng-zorro-antd/core/logger';
import { DEFAULT_TOOLTIP_POSITIONS, getPlacementName, POSITION_MAP } from 'ng-zorro-antd/core/overlay';
import { isNotNil, toBoolean } from 'ng-zorro-antd/core/util';
import { Subject } from 'rxjs';
import { distinctUntilChanged, takeUntil } from 'rxjs/operators';
/**
* @abstract
*/
export class NzTooltipBaseDirective {
/**
* @param {?} elementRef
* @param {?} hostView
* @param {?} resolver
* @param {?} renderer
* @param {?=} noAnimation
*/
constructor(elementRef, hostView, resolver, renderer, noAnimation) {
this.elementRef = elementRef;
this.hostView = hostView;
this.resolver = resolver;
this.renderer = renderer;
this.noAnimation = noAnimation;
/**
* @deprecated 10.0.0. This is deprecated and going to be removed in 10.0.0.
* Please use a more specific API. Like `nzTooltipTrigger`.
*/
this.nzTrigger = 'hover';
/**
* @deprecated 10.0.0. This is deprecated and going to be removed in 10.0.0.
* Please use a more specific API. Like `nzTooltipPlacement`.
*/
this.nzPlacement = 'top';
this.nzMouseEnterDelay = 0.15;
this.nzMouseLeaveDelay = 0.1;
this.needProxyProperties = [
'nzOverlayClassName',
'nzOverlayStyle',
'nzMouseEnterDelay',
'nzMouseLeaveDelay',
'nzVisible',
'noAnimation'
];
this.nzVisibleChange = new EventEmitter();
this.visible = false;
this.destroy$ = new Subject();
this.triggerDisposables = [];
}
/**
* This true title that would be used in other parts on this component.
* @protected
* @return {?}
*/
get title() {
return this.specificTitle || this.directiveNameTitle || this.nzTitle || null;
}
/**
* @protected
* @return {?}
*/
get content() {
return this.specificContent || this.directiveNameContent || this.nzContent || null;
}
/**
* @protected
* @return {?}
*/
get placement() {
return this.specificPlacement || this.nzPlacement;
}
/**
* @protected
* @return {?}
*/
get trigger() {
// NzTooltipTrigger can be null.
return typeof this.specificTrigger !== 'undefined' ? this.specificTrigger : this.nzTrigger;
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
const { nzTrigger, specificTrigger } = changes;
/** @type {?} */
const trigger = specificTrigger || nzTrigger;
if (trigger && !trigger.isFirstChange()) {
this.registerTriggers();
}
if (this.component) {
this.updateChangedProperties(changes);
}
// warn deprecated things when specific property is not given
if (changes.nzTitle && !this.specificTitle && !this.directiveNameTitle) {
warnDeprecation(`'nzTitle' of 'nz-tooltip' is deprecated and will be removed in 10.0.0.
Please use 'nzTooltipTitle' instead. The same with 'nz-popover' and 'nz-popconfirm'.`);
}
if (changes.nzContent && !this.specificContent) {
warnDeprecation(`'nzContent' of 'nz-popover' is deprecated and will be removed in 10.0.0.
Please use 'nzPopoverContent' instead.`);
}
if (changes.nzPlacement && !this.specificPlacement) {
warnDeprecation(`'nzPlacement' of 'nz-tooltip' is deprecated and will be removed in 10.0.0.
Please use 'nzTooltipContent' instead. The same with 'nz-popover' and 'nz-popconfirm'.`);
}
if (changes.nzTrigger && !this.specificTrigger) {
warnDeprecation(`'nzTrigger' of 'nz-tooltip' is deprecated and will be removed in 10.0.0.
Please use 'nzTooltipTrigger' instead. The same with 'nz-popover' and 'nz-popconfirm'.`);
}
}
/**
* @return {?}
*/
ngAfterViewInit() {
this.createComponent();
this.registerTriggers();
}
/**
* @return {?}
*/
ngOnDestroy() {
this.destroy$.next();
this.destroy$.complete();
// Clear toggling timer. Issue #3875 #4317 #4386
this.clearTogglingTimer();
this.removeTriggerListeners();
}
/**
* @return {?}
*/
show() {
var _a;
(_a = this.component) === null || _a === void 0 ? void 0 : _a.show();
}
/**
* @return {?}
*/
hide() {
var _a;
(_a = this.component) === null || _a === void 0 ? void 0 : _a.hide();
}
/**
* Force the component to update its position.
* @return {?}
*/
updatePosition() {
if (this.component) {
this.component.updatePosition();
}
}
/**
* Create a dynamic tooltip component. This method can be override.
* @protected
* @return {?}
*/
createComponent() {
/** @type {?} */
const componentRef = this.hostView.createComponent(this.componentFactory);
this.component = componentRef.instance;
// Remove the component's DOM because it should be in the overlay container.
this.renderer.removeChild(this.renderer.parentNode(this.elementRef.nativeElement), componentRef.location.nativeElement);
this.component.setOverlayOrigin({ elementRef: this.specificOrigin || this.elementRef });
this.updateChangedProperties(this.needProxyProperties);
this.component.nzVisibleChange.pipe(distinctUntilChanged(), takeUntil(this.destroy$)).subscribe((/**
* @param {?} visible
* @return {?}
*/
(visible) => {
this.visible = visible;
this.nzVisibleChange.emit(visible);
}));
}
/**
* @protected
* @return {?}
*/
registerTriggers() {
// When the method gets invoked, all properties has been synced to the dynamic component.
// After removing the old API, we can just check the directive's own `nzTrigger`.
/** @type {?} */
const el = this.elementRef.nativeElement;
/** @type {?} */
const trigger = this.trigger;
this.removeTriggerListeners();
if (trigger === 'hover') {
/** @type {?} */
let overlayElement;
this.triggerDisposables.push(this.renderer.listen(el, 'mouseenter', (/**
* @return {?}
*/
() => {
this.delayEnterLeave(true, true, this.nzMouseEnterDelay);
})));
this.triggerDisposables.push(this.renderer.listen(el, 'mouseleave', (/**
* @return {?}
*/
() => {
var _a;
this.delayEnterLeave(true, false, this.nzMouseLeaveDelay);
if (((_a = this.component) === null || _a === void 0 ? void 0 : _a.overlay.overlayRef) && !overlayElement) {
overlayElement = this.component.overlay.overlayRef.overlayElement;
this.triggerDisposables.push(this.renderer.listen(overlayElement, 'mouseenter', (/**
* @return {?}
*/
() => {
this.delayEnterLeave(false, true);
})));
this.triggerDisposables.push(this.renderer.listen(overlayElement, 'mouseleave', (/**
* @return {?}
*/
() => {
this.delayEnterLeave(false, false);
})));
}
})));
}
else if (trigger === 'focus') {
this.triggerDisposables.push(this.renderer.listen(el, 'focus', (/**
* @return {?}
*/
() => this.show())));
this.triggerDisposables.push(this.renderer.listen(el, 'blur', (/**
* @return {?}
*/
() => this.hide())));
}
else if (trigger === 'click') {
this.triggerDisposables.push(this.renderer.listen(el, 'click', (/**
* @param {?} e
* @return {?}
*/
e => {
e.preventDefault();
this.show();
})));
} // Else do nothing because user wants to control the visibility programmatically.
}
/**
* Sync changed properties to the component and trigger change detection in that component.
* @protected
* @param {?} propertiesOrChanges
* @return {?}
*/
updateChangedProperties(propertiesOrChanges) {
var _a;
/** @type {?} */
const isArray = Array.isArray(propertiesOrChanges);
/** @type {?} */
const keys = isArray ? ((/** @type {?} */ (propertiesOrChanges))) : Object.keys(propertiesOrChanges);
keys.forEach((/**
* @param {?} property
* @return {?}
*/
(property) => {
if (this.needProxyProperties.indexOf(property) !== -1) {
// @ts-ignore
this.updateComponentValue(property, this[property]);
}
}));
if (isArray) {
this.updateComponentValue('nzTitle', this.title);
this.updateComponentValue('nzContent', this.content);
this.updateComponentValue('nzPlacement', this.placement);
this.updateComponentValue('nzTrigger', this.trigger);
}
else {
/** @type {?} */
const c = (/** @type {?} */ (propertiesOrChanges));
if (c.specificTitle || c.directiveNameTitle || c.nzTitle) {
this.updateComponentValue('nzTitle', this.title);
}
if (c.specificContent || c.directiveNameContent || c.nzContent) {
this.updateComponentValue('nzContent', this.content);
}
if (c.specificTrigger || c.nzTrigger) {
this.updateComponentValue('nzTrigger', this.trigger);
}
if (c.specificPlacement || c.nzPlacement) {
this.updateComponentValue('nzPlacement', this.placement);
}
}
(_a = this.component) === null || _a === void 0 ? void 0 : _a.updateByDirective();
}
/**
* @private
* @param {?} key
* @param {?} value
* @return {?}
*/
updateComponentValue(key, value) {
if (typeof value !== 'undefined') {
// @ts-ignore
this.component[key] = value;
}
}
/**
* @private
* @param {?} isOrigin
* @param {?} isEnter
* @param {?=} delay
* @return {?}
*/
delayEnterLeave(isOrigin, isEnter, delay = -1) {
if (this.delayTimer) {
this.clearTogglingTimer();
}
else if (delay > 0) {
this.delayTimer = setTimeout((/**
* @return {?}
*/
() => {
this.delayTimer = undefined;
isEnter ? this.show() : this.hide();
}), delay * 1000);
}
else {
// `isOrigin` is used due to the tooltip will not hide immediately
// (may caused by the fade-out animation).
isEnter && isOrigin ? this.show() : this.hide();
}
}
/**
* @private
* @return {?}
*/
removeTriggerListeners() {
this.triggerDisposables.forEach((/**
* @param {?} dispose
* @return {?}
*/
dispose => dispose()));
this.triggerDisposables.length = 0;
}
/**
* @private
* @return {?}
*/
clearTogglingTimer() {
if (this.delayTimer) {
clearTimeout(this.delayTimer);
this.delayTimer = undefined;
}
}
}
NzTooltipBaseDirective.propDecorators = {
nzTitle: [{ type: Input }],
nzContent: [{ type: Input }],
nzTrigger: [{ type: Input }],
nzPlacement: [{ type: Input }],
nzMouseEnterDelay: [{ type: Input }],
nzMouseLeaveDelay: [{ type: Input }],
nzOverlayClassName: [{ type: Input }],
nzOverlayStyle: [{ type: Input }],
nzVisible: [{ type: Input }],
nzVisibleChange: [{ type: Output }]
};
if (false) {
/** @type {?} */
NzTooltipBaseDirective.prototype.directiveNameTitle;
/** @type {?} */
NzTooltipBaseDirective.prototype.specificTitle;
/** @type {?} */
NzTooltipBaseDirective.prototype.directiveNameContent;
/** @type {?} */
NzTooltipBaseDirective.prototype.specificContent;
/** @type {?} */
NzTooltipBaseDirective.prototype.specificTrigger;
/** @type {?} */
NzTooltipBaseDirective.prototype.specificPlacement;
/** @type {?} */
NzTooltipBaseDirective.prototype.specificOrigin;
/**
* @deprecated 10.0.0. This is deprecated and going to be removed in 10.0.0.
* Please use a more specific API. Like `nzTooltipTitle`.
* @type {?}
*/
NzTooltipBaseDirective.prototype.nzTitle;
/**
* @deprecated 10.0.0. This is deprecated and going to be removed in 10.0.0.
* Please use a more specific API. Like `nzPopoverContent`.
* @type {?}
*/
NzTooltipBaseDirective.prototype.nzContent;
/**
* @deprecated 10.0.0. This is deprecated and going to be removed in 10.0.0.
* Please use a more specific API. Like `nzTooltipTrigger`.
* @type {?}
*/
NzTooltipBaseDirective.prototype.nzTrigger;
/**
* @deprecated 10.0.0. This is deprecated and going to be removed in 10.0.0.
* Please use a more specific API. Like `nzTooltipPlacement`.
* @type {?}
*/
NzTooltipBaseDirective.prototype.nzPlacement;
/** @type {?} */
NzTooltipBaseDirective.prototype.nzMouseEnterDelay;
/** @type {?} */
NzTooltipBaseDirective.prototype.nzMouseLeaveDelay;
/** @type {?} */
NzTooltipBaseDirective.prototype.nzOverlayClassName;
/** @type {?} */
NzTooltipBaseDirective.prototype.nzOverlayStyle;
/** @type {?} */
NzTooltipBaseDirective.prototype.nzVisible;
/**
* For create tooltip dynamically. This should be override for each different component.
* @type {?}
* @protected
*/
NzTooltipBaseDirective.prototype.componentFactory;
/**
* @type {?}
* @protected
*/
NzTooltipBaseDirective.prototype.needProxyProperties;
/** @type {?} */
NzTooltipBaseDirective.prototype.nzVisibleChange;
/** @type {?} */
NzTooltipBaseDirective.prototype.visible;
/** @type {?} */
NzTooltipBaseDirective.prototype.component;
/**
* @type {?}
* @protected
*/
NzTooltipBaseDirective.prototype.destroy$;
/**
* @type {?}
* @protected
*/
NzTooltipBaseDirective.prototype.triggerDisposables;
/**
* @type {?}
* @private
*/
NzTooltipBaseDirective.prototype.delayTimer;
/** @type {?} */
NzTooltipBaseDirective.prototype.elementRef;
/**
* @type {?}
* @protected
*/
NzTooltipBaseDirective.prototype.hostView;
/**
* @type {?}
* @protected
*/
NzTooltipBaseDirective.prototype.resolver;
/**
* @type {?}
* @protected
*/
NzTooltipBaseDirective.prototype.renderer;
/**
* @type {?}
* @protected
*/
NzTooltipBaseDirective.prototype.noAnimation;
}
/**
* @abstract
*/
export class NzTooltipBaseComponent {
/**
* @param {?} cdr
* @param {?=} noAnimation
*/
constructor(cdr, noAnimation) {
this.cdr = cdr;
this.noAnimation = noAnimation;
this.nzVisibleChange = new Subject();
this.nzTitle = null;
this.nzContent = null;
this.nzOverlayStyle = {};
this._visible = false;
this._trigger = 'hover';
this.preferredPlacement = 'top';
this._classMap = {};
this._hasBackdrop = false;
this._prefix = 'ant-tooltip-placement';
this._positions = [...DEFAULT_TOOLTIP_POSITIONS];
}
/**
* @param {?} value
* @return {?}
*/
set nzVisible(value) {
/** @type {?} */
const visible = toBoolean(value);
if (this._visible !== visible) {
this._visible = visible;
this.nzVisibleChange.next(visible);
}
}
/**
* @return {?}
*/
get nzVisible() {
return this._visible;
}
/**
* @param {?} value
* @return {?}
*/
set nzTrigger(value) {
this._trigger = value;
this._hasBackdrop = this._trigger === 'click';
}
/**
* @return {?}
*/
get nzTrigger() {
return this._trigger;
}
/**
* @param {?} value
* @return {?}
*/
set nzPlacement(value) {
if (value !== this.preferredPlacement) {
this.preferredPlacement = value;
this._positions = [POSITION_MAP[this.nzPlacement], ...this._positions];
}
}
/**
* @return {?}
*/
get nzPlacement() {
return this.preferredPlacement;
}
/**
* @return {?}
*/
ngOnDestroy() {
this.nzVisibleChange.complete();
}
/**
* @return {?}
*/
show() {
if (this.nzVisible) {
return;
}
if (!this.isEmpty()) {
this.nzVisible = true;
this.nzVisibleChange.next(true);
this.cdr.detectChanges();
}
}
/**
* @return {?}
*/
hide() {
if (!this.nzVisible) {
return;
}
this.nzVisible = false;
this.nzVisibleChange.next(false);
this.cdr.detectChanges();
}
/**
* @return {?}
*/
updateByDirective() {
this.setClassMap();
this.cdr.detectChanges();
Promise.resolve().then((/**
* @return {?}
*/
() => {
this.updatePosition();
this.updateVisibilityByTitle();
}));
}
/**
* Force the component to update its position.
* @return {?}
*/
updatePosition() {
if (this.origin && this.overlay && this.overlay.overlayRef) {
this.overlay.overlayRef.updatePosition();
}
}
/**
* @param {?} position
* @return {?}
*/
onPositionChange(position) {
this.preferredPlacement = (/** @type {?} */ (getPlacementName(position)));
this.setClassMap();
this.cdr.detectChanges();
}
/**
* @return {?}
*/
setClassMap() {
this._classMap = {
[this.nzOverlayClassName]: true,
[`${this._prefix}-${this.preferredPlacement}`]: true
};
}
/**
* @param {?} origin
* @return {?}
*/
setOverlayOrigin(origin) {
this.origin = origin;
this.cdr.markForCheck();
}
/**
* Hide the component while the content is empty.
* @private
* @return {?}
*/
updateVisibilityByTitle() {
if (this.isEmpty()) {
this.hide();
}
}
}
NzTooltipBaseComponent.propDecorators = {
overlay: [{ type: ViewChild, args: ['overlay', { static: false },] }]
};
if (false) {
/** @type {?} */
NzTooltipBaseComponent.prototype.overlay;
/** @type {?} */
NzTooltipBaseComponent.prototype.nzVisibleChange;
/** @type {?} */
NzTooltipBaseComponent.prototype.nzTitle;
/** @type {?} */
NzTooltipBaseComponent.prototype.nzContent;
/** @type {?} */
NzTooltipBaseComponent.prototype.nzOverlayClassName;
/** @type {?} */
NzTooltipBaseComponent.prototype.nzOverlayStyle;
/** @type {?} */
NzTooltipBaseComponent.prototype.nzMouseEnterDelay;
/** @type {?} */
NzTooltipBaseComponent.prototype.nzMouseLeaveDelay;
/** @type {?} */
NzTooltipBaseComponent.prototype._visible;
/**
* @type {?}
* @protected
*/
NzTooltipBaseComponent.prototype._trigger;
/** @type {?} */
NzTooltipBaseComponent.prototype.origin;
/** @type {?} */
NzTooltipBaseComponent.prototype.preferredPlacement;
/** @type {?} */
NzTooltipBaseComponent.prototype._classMap;
/** @type {?} */
NzTooltipBaseComponent.prototype._hasBackdrop;
/** @type {?} */
NzTooltipBaseComponent.prototype._prefix;
/** @type {?} */
NzTooltipBaseComponent.prototype._positions;
/** @type {?} */
NzTooltipBaseComponent.prototype.cdr;
/** @type {?} */
NzTooltipBaseComponent.prototype.noAnimation;
/**
* Empty component cannot be opened.
* @abstract
* @protected
* @return {?}
*/
NzTooltipBaseComponent.prototype.isEmpty = function () { };
}
/**
* @param {?} value
* @return {?}
*/
export function isTooltipEmpty(value) {
return value instanceof TemplateRef ? false : value === '' || !isNotNil(value);
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25nLXpvcnJvLWFudGQvdG9vbHRpcC8iLCJzb3VyY2VzIjpbImJhc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBUUEsT0FBTyxFQUFFLG1CQUFtQixFQUE0RSxNQUFNLHNCQUFzQixDQUFDO0FBQ3JJLE9BQU8sRUFNTCxZQUFZLEVBQ1osS0FBSyxFQUdMLE1BQU0sRUFHTixXQUFXLEVBQ1gsU0FBUyxFQUVWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUU1RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsZ0JBQWdCLEVBQUUsWUFBWSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFdkcsT0FBTyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQzs7OztBQUlqRSxNQUFNLE9BQWdCLHNCQUFzQjs7Ozs7Ozs7SUFtRjFDLFlBQ1MsVUFBc0IsRUFDbkIsUUFBMEIsRUFDMUIsUUFBa0MsRUFDbEMsUUFBbUIsRUFDbkIsV0FBb0M7UUFKdkMsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUNuQixhQUFRLEdBQVIsUUFBUSxDQUFrQjtRQUMxQixhQUFRLEdBQVIsUUFBUSxDQUEwQjtRQUNsQyxhQUFRLEdBQVIsUUFBUSxDQUFXO1FBQ25CLGdCQUFXLEdBQVgsV0FBVyxDQUF5Qjs7Ozs7UUEvRHZDLGNBQVMsR0FBcUIsT0FBTyxDQUFDOzs7OztRQU10QyxnQkFBVyxHQUFXLEtBQUssQ0FBQztRQUU1QixzQkFBaUIsR0FBVyxJQUFJLENBQUM7UUFDakMsc0JBQWlCLEdBQVcsR0FBRyxDQUFDO1FBOEIvQix3QkFBbUIsR0FBRztZQUM5QixvQkFBb0I7WUFDcEIsZ0JBQWdCO1lBQ2hCLG1CQUFtQjtZQUNuQixtQkFBbUI7WUFDbkIsV0FBVztZQUNYLGFBQWE7U0FDZCxDQUFDO1FBRWlCLG9CQUFlLEdBQUcsSUFBSSxZQUFZLEVBQVcsQ0FBQztRQUVqRSxZQUFPLEdBQUcsS0FBSyxDQUFDO1FBR0csYUFBUSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFDL0IsdUJBQWtCLEdBQXNCLEVBQUUsQ0FBQztJQVUzRCxDQUFDOzs7Ozs7SUExQ0osSUFBYyxLQUFLO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLGFBQWEsSUFBSSxJQUFJLENBQUMsa0JBQWtCLElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUM7SUFDL0UsQ0FBQzs7Ozs7SUFFRCxJQUFjLE9BQU87UUFDbkIsT0FBTyxJQUFJLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQyxvQkFBb0IsSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQztJQUNyRixDQUFDOzs7OztJQUVELElBQWMsU0FBUztRQUNyQixPQUFPLElBQUksQ0FBQyxpQkFBaUIsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDO0lBQ3BELENBQUM7Ozs7O0lBRUQsSUFBYyxPQUFPO1FBQ25CLGdDQUFnQztRQUNoQyxPQUFPLE9BQU8sSUFBSSxDQUFDLGVBQWUsS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDN0YsQ0FBQzs7Ozs7SUE2QkQsV0FBVyxDQUFDLE9BQXNCO2NBQzFCLEVBQUUsU0FBUyxFQUFFLGVBQWUsRUFBRSxHQUFHLE9BQU87O2NBQ3hDLE9BQU8sR0FBRyxlQUFlLElBQUksU0FBUztRQUU1QyxJQUFJLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLEVBQUUsRUFBRTtZQUN2QyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztTQUN6QjtRQUVELElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNsQixJQUFJLENBQUMsdUJBQXVCLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDdkM7UUFFRCw2REFBNkQ7UUFDN0QsSUFBSSxPQUFPLENBQUMsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsSUFBSSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRTtZQUN0RSxlQUFlLENBQ2I7cUZBQzZFLENBQzlFLENBQUM7U0FDSDtRQUVELElBQUksT0FBTyxDQUFDLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUU7WUFDOUMsZUFBZSxDQUNiO3VDQUMrQixDQUNoQyxDQUFDO1NBQ0g7UUFFRCxJQUFJLE9BQU8sQ0FBQyxXQUFXLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUU7WUFDbEQsZUFBZSxDQUNiO3VGQUMrRSxDQUNoRixDQUFDO1NBQ0g7UUFFRCxJQUFJLE9BQU8sQ0FBQyxTQUFTLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFO1lBQzlDLGVBQWUsQ0FDYjt1RkFDK0UsQ0FDaEYsQ0FBQztTQUNIO0lBQ0gsQ0FBQzs7OztJQUVELGVBQWU7UUFDYixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7SUFDMUIsQ0FBQzs7OztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7UUFFekIsZ0RBQWdEO1FBQ2hELElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQzFCLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO0lBQ2hDLENBQUM7Ozs7SUFFRCxJQUFJOztRQUNGLE1BQUEsSUFBSSxDQUFDLFNBQVMsMENBQUUsSUFBSSxHQUFHO0lBQ3pCLENBQUM7Ozs7SUFFRCxJQUFJOztRQUNGLE1BQUEsSUFBSSxDQUFDLFNBQVMsMENBQUUsSUFBSSxHQUFHO0lBQ3pCLENBQUM7Ozs7O0lBS0QsY0FBYztRQUNaLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNsQixJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSxDQUFDO1NBQ2pDO0lBQ0gsQ0FBQzs7Ozs7O0lBS1MsZUFBZTs7Y0FDakIsWUFBWSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztRQUV6RSxJQUFJLENBQUMsU0FBUyxHQUFHLFlBQVksQ0FBQyxRQUFRLENBQUM7UUFFdkMsNEVBQTRFO1FBQzVFLElBQUksQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLEVBQUUsWUFBWSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUN4SCxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLEVBQUUsVUFBVSxFQUFFLElBQUksQ0FBQyxjQUFjLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7UUFFeEYsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBRXZELElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxFQUFFLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxTQUFTOzs7O1FBQUMsQ0FBQyxPQUFnQixFQUFFLEVBQUU7WUFDbkgsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7WUFDdkIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDckMsQ0FBQyxFQUFDLENBQUM7SUFDTCxDQUFDOzs7OztJQUVTLGdCQUFnQjs7OztjQUdsQixFQUFFLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhOztjQUNsQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU87UUFFNUIsSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7UUFFOUIsSUFBSSxPQUFPLEtBQUssT0FBTyxFQUFFOztnQkFDbkIsY0FBMkI7WUFDL0IsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FDMUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLFlBQVk7OztZQUFFLEdBQUcsRUFBRTtnQkFDMUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQzNELENBQUMsRUFBQyxDQUNILENBQUM7WUFDRixJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUMxQixJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsWUFBWTs7O1lBQUUsR0FBRyxFQUFFOztnQkFDMUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO2dCQUMxRCxJQUFJLE9BQUEsSUFBSSxDQUFDLFNBQVMsMENBQUUsT0FBTyxDQUFDLFVBQVUsS0FBSSxDQUFDLGNBQWMsRUFBRTtvQkFDekQsY0FBYyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUM7b0JBQ2xFLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQzFCLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxZQUFZOzs7b0JBQUUsR0FBRyxFQUFFO3dCQUN0RCxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztvQkFDcEMsQ0FBQyxFQUFDLENBQ0gsQ0FBQztvQkFDRixJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUMxQixJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxjQUFjLEVBQUUsWUFBWTs7O29CQUFFLEdBQUcsRUFBRTt3QkFDdEQsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7b0JBQ3JDLENBQUMsRUFBQyxDQUNILENBQUM7aUJBQ0g7WUFDSCxDQUFDLEVBQUMsQ0FDSCxDQUFDO1NBQ0g7YUFBTSxJQUFJLE9BQU8sS0FBSyxPQUFPLEVBQUU7WUFDOUIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsT0FBTzs7O1lBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxFQUFDLENBQUMsQ0FBQztZQUNuRixJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxNQUFNOzs7WUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUMsQ0FBQyxDQUFDO1NBQ25GO2FBQU0sSUFBSSxPQUFPLEtBQUssT0FBTyxFQUFFO1lBQzlCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQzFCLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxPQUFPOzs7O1lBQUUsQ0FBQyxDQUFDLEVBQUU7Z0JBQ3BDLENBQUMsQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDbkIsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ2QsQ0FBQyxFQUFDLENBQ0gsQ0FBQztTQUNILENBQUMsaUZBQWlGO0lBQ3JGLENBQUM7Ozs7Ozs7SUFLUyx1QkFBdUIsQ0FBQyxtQkFBNkM7OztjQUN2RSxPQUFPLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQzs7Y0FDNUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxtQkFBQSxtQkFBbUIsRUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUM7UUFFM0YsSUFBSSxDQUFDLE9BQU87Ozs7UUFBQyxDQUFDLFFBQW1CLEVBQUUsRUFBRTtZQUNuQyxJQUFJLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7Z0JBQ3JELGFBQWE7Z0JBQ2IsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQzthQUNyRDtRQUNILENBQUMsRUFBQyxDQUFDO1FBRUgsSUFBSSxPQUFPLEVBQUU7WUFDWCxJQUFJLENBQUMsb0JBQW9CLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNqRCxJQUFJLENBQUMsb0JBQW9CLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNyRCxJQUFJLENBQUMsb0JBQW9CLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN6RCxJQUFJLENBQUMsb0JBQW9CLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUN0RDthQUFNOztrQkFDQyxDQUFDLEdBQUcsbUJBQUEsbUJBQW1CLEVBQWlCO1lBQzlDLElBQUksQ0FBQyxDQUFDLGFBQWEsSUFBSSxDQUFDLENBQUMsa0JBQWtCLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRTtnQkFDeEQsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDbEQ7WUFDRCxJQUFJLENBQUMsQ0FBQyxlQUFlLElBQUksQ0FBQyxDQUFDLG9CQUFvQixJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUU7Z0JBQzlELElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQ3REO1lBQ0QsSUFBSSxDQUFDLENBQUMsZUFBZSxJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUU7Z0JBQ3BDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2FBQ3REO1lBQ0QsSUFBSSxDQUFDLENBQUMsaUJBQWlCLElBQUksQ0FBQyxDQUFDLFdBQVcsRUFBRTtnQkFDeEMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7YUFDMUQ7U0FDRjtRQUVELE1BQUEsSUFBSSxDQUFDLFNBQVMsMENBQUUsaUJBQWlCLEdBQUc7SUFDdEMsQ0FBQzs7Ozs7OztJQUVPLG9CQUFvQixDQUFDLEdBQVcsRUFBRSxLQUFnQjtRQUN4RCxJQUFJLE9BQU8sS0FBSyxLQUFLLFdBQVcsRUFBRTtZQUNoQyxhQUFhO1lBQ2IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUM7U0FDN0I7SUFDSCxDQUFDOzs7Ozs7OztJQUVPLGVBQWUsQ0FBQyxRQUFpQixFQUFFLE9BQWdCLEVBQUUsUUFBZ0IsQ0FBQyxDQUFDO1FBQzdFLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNuQixJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztTQUMzQjthQUFNLElBQUksS0FBSyxHQUFHLENBQUMsRUFBRTtZQUNwQixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVU7OztZQUFDLEdBQUcsRUFBRTtnQkFDaEMsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7Z0JBQzVCLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDdEMsQ0FBQyxHQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQztTQUNsQjthQUFNO1lBQ0wsa0VBQWtFO1lBQ2xFLDBDQUEwQztZQUMxQyxPQUFPLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUNqRDtJQUNILENBQUM7Ozs7O0lBRU8sc0JBQXNCO1FBQzVCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxPQUFPOzs7O1FBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7Ozs7O0lBRU8sa0JBQWtCO1FBQ3hCLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtZQUNuQixZQUFZLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzlCLElBQUksQ0FBQyxVQUFVLEdBQUcsU0FBUyxDQUFDO1NBQzdCO0lBQ0gsQ0FBQzs7O3NCQS9SQSxLQUFLO3dCQU1MLEtBQUs7d0JBTUwsS0FBSzswQkFNTCxLQUFLO2dDQUVMLEtBQUs7Z0NBQ0wsS0FBSztpQ0FDTCxLQUFLOzZCQUNMLEtBQUs7d0JBQ0wsS0FBSzs4QkFvQ0wsTUFBTTs7OztJQXhFUCxvREFBcUM7O0lBQ3JDLCtDQUFnQzs7SUFDaEMsc0RBQXVDOztJQUN2QyxpREFBa0M7O0lBQ2xDLGlEQUFtQzs7SUFDbkMsbURBQTJCOztJQUMzQixnREFBeUM7Ozs7OztJQU16Qyx5Q0FBbUM7Ozs7OztJQU1uQywyQ0FBcUM7Ozs7OztJQU1yQywyQ0FBK0M7Ozs7OztJQU0vQyw2Q0FBcUM7O0lBRXJDLG1EQUEwQzs7SUFDMUMsbURBQXlDOztJQUN6QyxvREFBcUM7O0lBQ3JDLGdEQUEyQzs7SUFDM0MsMkNBQTZCOzs7Ozs7SUFLN0Isa0RBQXNFOzs7OztJQXNCdEUscURBT0U7O0lBRUYsaURBQWlFOztJQUVqRSx5Q0FBZ0I7O0lBQ2hCLDJDQUFtQzs7Ozs7SUFFbkMsMENBQWtEOzs7OztJQUNsRCxvREFBOEQ7Ozs7O0lBRTlELDRDQUE0Qjs7SUFHMUIsNENBQTZCOzs7OztJQUM3QiwwQ0FBb0M7Ozs7O0lBQ3BDLDBDQUE0Qzs7Ozs7SUFDNUMsMENBQTZCOzs7OztJQUM3Qiw2Q0FBOEM7Ozs7O0FBdU5sRCxNQUFNLE9BQWdCLHNCQUFzQjs7Ozs7SUF1RDFDLFlBQW1CLEdBQXNCLEVBQVMsV0FBb0M7UUFBbkUsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFBUyxnQkFBVyxHQUFYLFdBQVcsQ0FBeUI7UUFwRHRGLG9CQUFlLEdBQUcsSUFBSSxPQUFPLEVBQVcsQ0FBQztRQUN6QyxZQUFPLEdBQW9CLElBQUksQ0FBQztRQUNoQyxjQUFTLEdBQW9CLElBQUksQ0FBQztRQUVsQyxtQkFBYyxHQUFxQixFQUFFLENBQUM7UUFnQnRDLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFXUCxhQUFRLEdBQXFCLE9BQU8sQ0FBQztRQWMvQyx1QkFBa0IsR0FBRyxLQUFLLENBQUM7UUFFM0IsY0FBUyxHQUFxQixFQUFFLENBQUM7UUFDakMsaUJBQVksR0FBRyxLQUFLLENBQUM7UUFDckIsWUFBTyxHQUFHLHVCQUF1QixDQUFDO1FBQ2xDLGVBQVUsR0FBNkIsQ0FBQyxHQUFHLHlCQUF5QixDQUFDLENBQUM7SUFFbUIsQ0FBQzs7Ozs7SUE1QzFGLElBQUksU0FBUyxDQUFDLEtBQWM7O2NBQ3BCLE9BQU8sR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDO1FBQ2hDLElBQUksSUFBSSxDQUFDLFFBQVEsS0FBSyxPQUFPLEVBQUU7WUFDN0IsSUFBSSxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUM7WUFDeEIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDcEM7SUFDSCxDQUFDOzs7O0lBRUQsSUFBSSxTQUFTO1FBQ1gsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3ZCLENBQUM7Ozs7O0lBSUQsSUFBSSxTQUFTLENBQUMsS0FBdUI7UUFDbkMsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7UUFDdEIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsUUFBUSxLQUFLLE9BQU8sQ0FBQztJQUNoRCxDQUFDOzs7O0lBRUQsSUFBSSxTQUFTO1FBQ1gsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDO0lBQ3ZCLENBQUM7Ozs7O0lBSUQsSUFBSSxXQUFXLENBQUMsS0FBYTtRQUMzQixJQUFJLEtBQUssS0FBSyxJQUFJLENBQUMsa0JBQWtCLEVBQUU7WUFDckMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLEtBQUssQ0FBQztZQUNoQyxJQUFJLENBQUMsVUFBVSxHQUFHLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztTQUN4RTtJQUNILENBQUM7Ozs7SUFFRCxJQUFJLFdBQVc7UUFDYixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztJQUNqQyxDQUFDOzs7O0lBWUQsV0FBVztRQUNULElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDbEMsQ0FBQzs7OztJQUVELElBQUk7UUFDRixJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDbEIsT0FBTztTQUNSO1FBRUQsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNuQixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztZQUN0QixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNoQyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO1NBQzFCO0lBQ0gsQ0FBQzs7OztJQUVELElBQUk7UUFDRixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNuQixPQUFPO1NBQ1I7UUFFRCxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQztRQUN2QixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqQyxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQzNCLENBQUM7Ozs7SUFFRCxpQkFBaUI7UUFDZixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUV6QixPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSTs7O1FBQUMsR0FBRyxFQUFFO1lBQzFCLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN0QixJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUNqQyxDQUFDLEVBQUMsQ0FBQztJQUNMLENBQUM7Ozs7O0lBS0QsY0FBYztRQUNaLElBQUksSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFO1lBQzFELElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLGNBQWMsRUFBRSxDQUFDO1NBQzFDO0lBQ0gsQ0FBQzs7Ozs7SUFFRCxnQkFBZ0IsQ0FBQyxRQUF3QztRQUN2RCxJQUFJLENBQUMsa0JBQWtCLEdBQUcsbUJBQUEsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLEVBQUMsQ0FBQztRQUN0RCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUMzQixDQUFDOzs7O0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxTQUFTLEdBQUc7WUFDZixDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLElBQUk7WUFDL0IsQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUMsRUFBRSxJQUFJO1NBQ3JELENBQUM7SUFDSixDQUFDOzs7OztJQUVELGdCQUFnQixDQUFDLE1BQXdCO1FBQ3ZDLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDMUIsQ0FBQzs7Ozs7O0lBS08sdUJBQXVCO1FBQzdCLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ2xCLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUNiO0lBQ0gsQ0FBQzs7O3NCQTlIQSxTQUFTLFNBQUMsU0FBUyxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRTs7OztJQUF2Qyx5Q0FBdUU7O0lBRXZFLGlEQUF5Qzs7SUFDekMseUNBQWdDOztJQUNoQywyQ0FBa0M7O0lBQ2xDLG9EQUE0Qjs7SUFDNUIsZ0RBQXNDOztJQUN0QyxtREFBMkI7O0lBQzNCLG1EQUEyQjs7SUFjM0IsMENBQWlCOzs7OztJQVdqQiwwQ0FBK0M7O0lBYS9DLHdDQUEwQjs7SUFDMUIsb0RBQTJCOztJQUUzQiwyQ0FBaUM7O0lBQ2pDLDhDQUFxQjs7SUFDckIseUNBQWtDOztJQUNsQyw0Q0FBc0U7O0lBRTFELHFDQUE2Qjs7SUFBRSw2Q0FBMkM7Ozs7Ozs7SUE2RXRGLDJEQUFzQzs7Ozs7O0FBR3hDLE1BQU0sVUFBVSxjQUFjLENBQUMsS0FBd0M7SUFDckUsT0FBTyxLQUFLLFlBQVksV0FBVyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDakYsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBBbGliYWJhLmNvbSBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQgeyBDZGtDb25uZWN0ZWRPdmVybGF5LCBDZGtPdmVybGF5T3JpZ2luLCBDb25uZWN0ZWRPdmVybGF5UG9zaXRpb25DaGFuZ2UsIENvbm5lY3Rpb25Qb3NpdGlvblBhaXIgfSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50RmFjdG9yeSxcbiAgQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT3V0cHV0LFxuICBSZW5kZXJlcjIsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFRlbXBsYXRlUmVmLFxuICBWaWV3Q2hpbGQsXG4gIFZpZXdDb250YWluZXJSZWZcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB3YXJuRGVwcmVjYXRpb24gfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvbG9nZ2VyJztcbmltcG9ydCB7IE56Tm9BbmltYXRpb25EaXJlY3RpdmUgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvbm8tYW5pbWF0aW9uJztcbmltcG9ydCB7IERFRkFVTFRfVE9PTFRJUF9QT1NJVElPTlMsIGdldFBsYWNlbWVudE5hbWUsIFBPU0lUSU9OX01BUCB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS9vdmVybGF5JztcbmltcG9ydCB7IE5nQ2xhc3NJbnRlcmZhY2UsIE5nU3R5bGVJbnRlcmZhY2UsIE56U2FmZUFueSwgTnpUU1R5cGUgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdHlwZXMnO1xuaW1wb3J0IHsgaXNOb3ROaWwsIHRvQm9vbGVhbiB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS91dGlsJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGRpc3RpbmN0VW50aWxDaGFuZ2VkLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmV4cG9ydCB0eXBlIE56VG9vbHRpcFRyaWdnZXIgPSAnY2xpY2snIHwgJ2ZvY3VzJyB8ICdob3ZlcicgfCBudWxsO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgTnpUb29sdGlwQmFzZURpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25EZXN0cm95LCBBZnRlclZpZXdJbml0IHtcbiAgZGlyZWN0aXZlTmFtZVRpdGxlPzogTnpUU1R5cGUgfCBudWxsO1xuICBzcGVjaWZpY1RpdGxlPzogTnpUU1R5cGUgfCBudWxsO1xuICBkaXJlY3RpdmVOYW1lQ29udGVudD86IE56VFNUeXBlIHwgbnVsbDtcbiAgc3BlY2lmaWNDb250ZW50PzogTnpUU1R5cGUgfCBudWxsO1xuICBzcGVjaWZpY1RyaWdnZXI/OiBOelRvb2x0aXBUcmlnZ2VyO1xuICBzcGVjaWZpY1BsYWNlbWVudD86IHN0cmluZztcbiAgc3BlY2lmaWNPcmlnaW4/OiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgMTAuMC4wLiBUaGlzIGlzIGRlcHJlY2F0ZWQgYW5kIGdvaW5nIHRvIGJlIHJlbW92ZWQgaW4gMTAuMC4wLlxuICAgKiBQbGVhc2UgdXNlIGEgbW9yZSBzcGVjaWZpYyBBUEkuIExpa2UgYG56VG9vbHRpcFRpdGxlYC5cbiAgICovXG4gIEBJbnB1dCgpIG56VGl0bGU/OiBOelRTVHlwZSB8IG51bGw7XG5cbiAgLyoqXG4gICAqIEBkZXByZWNhdGVkIDEwLjAuMC4gVGhpcyBpcyBkZXByZWNhdGVkIGFuZCBnb2luZyB0byBiZSByZW1vdmVkIGluIDEwLjAuMC5cbiAgICogUGxlYXNlIHVzZSBhIG1vcmUgc3BlY2lmaWMgQVBJLiBMaWtlIGBuelBvcG92ZXJDb250ZW50YC5cbiAgICovXG4gIEBJbnB1dCgpIG56Q29udGVudD86IE56VFNUeXBlIHwgbnVsbDtcblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgMTAuMC4wLiBUaGlzIGlzIGRlcHJlY2F0ZWQgYW5kIGdvaW5nIHRvIGJlIHJlbW92ZWQgaW4gMTAuMC4wLlxuICAgKiBQbGVhc2UgdXNlIGEgbW9yZSBzcGVjaWZpYyBBUEkuIExpa2UgYG56VG9vbHRpcFRyaWdnZXJgLlxuICAgKi9cbiAgQElucHV0KCkgbnpUcmlnZ2VyOiBOelRvb2x0aXBUcmlnZ2VyID0gJ2hvdmVyJztcblxuICAvKipcbiAgICogQGRlcHJlY2F0ZWQgMTAuMC4wLiBUaGlzIGlzIGRlcHJlY2F0ZWQgYW5kIGdvaW5nIHRvIGJlIHJlbW92ZWQgaW4gMTAuMC4wLlxuICAgKiBQbGVhc2UgdXNlIGEgbW9yZSBzcGVjaWZpYyBBUEkuIExpa2UgYG56VG9vbHRpcFBsYWNlbWVudGAuXG4gICAqL1xuICBASW5wdXQoKSBuelBsYWNlbWVudDogc3RyaW5nID0gJ3RvcCc7XG5cbiAgQElucHV0KCkgbnpNb3VzZUVudGVyRGVsYXk6IG51bWJlciA9IDAuMTU7XG4gIEBJbnB1dCgpIG56TW91c2VMZWF2ZURlbGF5OiBudW1iZXIgPSAwLjE7XG4gIEBJbnB1dCgpIG56T3ZlcmxheUNsYXNzTmFtZT86IHN0cmluZztcbiAgQElucHV0KCkgbnpPdmVybGF5U3R5bGU/OiBOZ1N0eWxlSW50ZXJmYWNlO1xuICBASW5wdXQoKSBuelZpc2libGU/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBGb3IgY3JlYXRlIHRvb2x0aXAgZHluYW1pY2FsbHkuIFRoaXMgc2hvdWxkIGJlIG92ZXJyaWRlIGZvciBlYWNoIGRpZmZlcmVudCBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgY29tcG9uZW50RmFjdG9yeSE6IENvbXBvbmVudEZhY3Rvcnk8TnpUb29sdGlwQmFzZUNvbXBvbmVudD47XG5cbiAgLyoqXG4gICAqIFRoaXMgdHJ1ZSB0aXRsZSB0aGF0IHdvdWxkIGJlIHVzZWQgaW4gb3RoZXIgcGFydHMgb24gdGhpcyBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IHRpdGxlKCk6IE56VFNUeXBlIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuc3BlY2lmaWNUaXRsZSB8fCB0aGlzLmRpcmVjdGl2ZU5hbWVUaXRsZSB8fCB0aGlzLm56VGl0bGUgfHwgbnVsbDtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXQgY29udGVudCgpOiBOelRTVHlwZSB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLnNwZWNpZmljQ29udGVudCB8fCB0aGlzLmRpcmVjdGl2ZU5hbWVDb250ZW50IHx8IHRoaXMubnpDb250ZW50IHx8IG51bGw7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IHBsYWNlbWVudCgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnNwZWNpZmljUGxhY2VtZW50IHx8IHRoaXMubnpQbGFjZW1lbnQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0IHRyaWdnZXIoKTogTnpUb29sdGlwVHJpZ2dlciB7XG4gICAgLy8gTnpUb29sdGlwVHJpZ2dlciBjYW4gYmUgbnVsbC5cbiAgICByZXR1cm4gdHlwZW9mIHRoaXMuc3BlY2lmaWNUcmlnZ2VyICE9PSAndW5kZWZpbmVkJyA/IHRoaXMuc3BlY2lmaWNUcmlnZ2VyIDogdGhpcy5uelRyaWdnZXI7XG4gIH1cblxuICBwcm90ZWN0ZWQgbmVlZFByb3h5UHJvcGVydGllcyA9IFtcbiAgICAnbnpPdmVybGF5Q2xhc3NOYW1lJyxcbiAgICAnbnpPdmVybGF5U3R5bGUnLFxuICAgICduek1vdXNlRW50ZXJEZWxheScsXG4gICAgJ256TW91c2VMZWF2ZURlbGF5JyxcbiAgICAnbnpWaXNpYmxlJyxcbiAgICAnbm9BbmltYXRpb24nXG4gIF07XG5cbiAgQE91dHB1dCgpIHJlYWRvbmx5IG56VmlzaWJsZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICB2aXNpYmxlID0gZmFsc2U7XG4gIGNvbXBvbmVudD86IE56VG9vbHRpcEJhc2VDb21wb25lbnQ7XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHRyaWdnZXJEaXNwb3NhYmxlczogQXJyYXk8KCkgPT4gdm9pZD4gPSBbXTtcblxuICBwcml2YXRlIGRlbGF5VGltZXI/OiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgcHJvdGVjdGVkIGhvc3RWaWV3OiBWaWV3Q29udGFpbmVyUmVmLFxuICAgIHByb3RlY3RlZCByZXNvbHZlcjogQ29tcG9uZW50RmFjdG9yeVJlc29sdmVyLFxuICAgIHByb3RlY3RlZCByZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgIHByb3RlY3RlZCBub0FuaW1hdGlvbj86IE56Tm9BbmltYXRpb25EaXJlY3RpdmVcbiAgKSB7fVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBjb25zdCB7IG56VHJpZ2dlciwgc3BlY2lmaWNUcmlnZ2VyIH0gPSBjaGFuZ2VzO1xuICAgIGNvbnN0IHRyaWdnZXIgPSBzcGVjaWZpY1RyaWdnZXIgfHwgbnpUcmlnZ2VyO1xuXG4gICAgaWYgKHRyaWdnZXIgJiYgIXRyaWdnZXIuaXNGaXJzdENoYW5nZSgpKSB7XG4gICAgICB0aGlzLnJlZ2lzdGVyVHJpZ2dlcnMoKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb21wb25lbnQpIHtcbiAgICAgIHRoaXMudXBkYXRlQ2hhbmdlZFByb3BlcnRpZXMoY2hhbmdlcyk7XG4gICAgfVxuXG4gICAgLy8gd2FybiBkZXByZWNhdGVkIHRoaW5ncyB3aGVuIHNwZWNpZmljIHByb3BlcnR5IGlzIG5vdCBnaXZlblxuICAgIGlmIChjaGFuZ2VzLm56VGl0bGUgJiYgIXRoaXMuc3BlY2lmaWNUaXRsZSAmJiAhdGhpcy5kaXJlY3RpdmVOYW1lVGl0bGUpIHtcbiAgICAgIHdhcm5EZXByZWNhdGlvbihcbiAgICAgICAgYCduelRpdGxlJyBvZiAnbnotdG9vbHRpcCcgaXMgZGVwcmVjYXRlZCBhbmQgd2lsbCBiZSByZW1vdmVkIGluIDEwLjAuMC5cblBsZWFzZSB1c2UgJ256VG9vbHRpcFRpdGxlJyBpbnN0ZWFkLiBUaGUgc2FtZSB3aXRoICduei1wb3BvdmVyJyBhbmQgJ256LXBvcGNvbmZpcm0nLmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZXMubnpDb250ZW50ICYmICF0aGlzLnNwZWNpZmljQ29udGVudCkge1xuICAgICAgd2FybkRlcHJlY2F0aW9uKFxuICAgICAgICBgJ256Q29udGVudCcgb2YgJ256LXBvcG92ZXInIGlzIGRlcHJlY2F0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiAxMC4wLjAuXG5QbGVhc2UgdXNlICduelBvcG92ZXJDb250ZW50JyBpbnN0ZWFkLmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZXMubnpQbGFjZW1lbnQgJiYgIXRoaXMuc3BlY2lmaWNQbGFjZW1lbnQpIHtcbiAgICAgIHdhcm5EZXByZWNhdGlvbihcbiAgICAgICAgYCduelBsYWNlbWVudCcgb2YgJ256LXRvb2x0aXAnIGlzIGRlcHJlY2F0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiAxMC4wLjAuXG5QbGVhc2UgdXNlICduelRvb2x0aXBDb250ZW50JyBpbnN0ZWFkLiBUaGUgc2FtZSB3aXRoICduei1wb3BvdmVyJyBhbmQgJ256LXBvcGNvbmZpcm0nLmBcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZXMubnpUcmlnZ2VyICYmICF0aGlzLnNwZWNpZmljVHJpZ2dlcikge1xuICAgICAgd2FybkRlcHJlY2F0aW9uKFxuICAgICAgICBgJ256VHJpZ2dlcicgb2YgJ256LXRvb2x0aXAnIGlzIGRlcHJlY2F0ZWQgYW5kIHdpbGwgYmUgcmVtb3ZlZCBpbiAxMC4wLjAuXG5QbGVhc2UgdXNlICduelRvb2x0aXBUcmlnZ2VyJyBpbnN0ZWFkLiBUaGUgc2FtZSB3aXRoICduei1wb3BvdmVyJyBhbmQgJ256LXBvcGNvbmZpcm0nLmBcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHRoaXMuY3JlYXRlQ29tcG9uZW50KCk7XG4gICAgdGhpcy5yZWdpc3RlclRyaWdnZXJzKCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG5cbiAgICAvLyBDbGVhciB0b2dnbGluZyB0aW1lci4gSXNzdWUgIzM4NzUgIzQzMTcgIzQzODZcbiAgICB0aGlzLmNsZWFyVG9nZ2xpbmdUaW1lcigpO1xuICAgIHRoaXMucmVtb3ZlVHJpZ2dlckxpc3RlbmVycygpO1xuICB9XG5cbiAgc2hvdygpOiB2b2lkIHtcbiAgICB0aGlzLmNvbXBvbmVudD8uc2hvdygpO1xuICB9XG5cbiAgaGlkZSgpOiB2b2lkIHtcbiAgICB0aGlzLmNvbXBvbmVudD8uaGlkZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcmNlIHRoZSBjb21wb25lbnQgdG8gdXBkYXRlIGl0cyBwb3NpdGlvbi5cbiAgICovXG4gIHVwZGF0ZVBvc2l0aW9uKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNvbXBvbmVudCkge1xuICAgICAgdGhpcy5jb21wb25lbnQudXBkYXRlUG9zaXRpb24oKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIGEgZHluYW1pYyB0b29sdGlwIGNvbXBvbmVudC4gVGhpcyBtZXRob2QgY2FuIGJlIG92ZXJyaWRlLlxuICAgKi9cbiAgcHJvdGVjdGVkIGNyZWF0ZUNvbXBvbmVudCgpOiB2b2lkIHtcbiAgICBjb25zdCBjb21wb25lbnRSZWYgPSB0aGlzLmhvc3RWaWV3LmNyZWF0ZUNvbXBvbmVudCh0aGlzLmNvbXBvbmVudEZhY3RvcnkpO1xuXG4gICAgdGhpcy5jb21wb25lbnQgPSBjb21wb25lbnRSZWYuaW5zdGFuY2U7XG5cbiAgICAvLyBSZW1vdmUgdGhlIGNvbXBvbmVudCdzIERPTSBiZWNhdXNlIGl0IHNob3VsZCBiZSBpbiB0aGUgb3ZlcmxheSBjb250YWluZXIuXG4gICAgdGhpcy5yZW5kZXJlci5yZW1vdmVDaGlsZCh0aGlzLnJlbmRlcmVyLnBhcmVudE5vZGUodGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpLCBjb21wb25lbnRSZWYubG9jYXRpb24ubmF0aXZlRWxlbWVudCk7XG4gICAgdGhpcy5jb21wb25lbnQuc2V0T3ZlcmxheU9yaWdpbih7IGVsZW1lbnRSZWY6IHRoaXMuc3BlY2lmaWNPcmlnaW4gfHwgdGhpcy5lbGVtZW50UmVmIH0pO1xuXG4gICAgdGhpcy51cGRhdGVDaGFuZ2VkUHJvcGVydGllcyh0aGlzLm5lZWRQcm94eVByb3BlcnRpZXMpO1xuXG4gICAgdGhpcy5jb21wb25lbnQubnpWaXNpYmxlQ2hhbmdlLnBpcGUoZGlzdGluY3RVbnRpbENoYW5nZWQoKSwgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKHZpc2libGU6IGJvb2xlYW4pID0+IHtcbiAgICAgIHRoaXMudmlzaWJsZSA9IHZpc2libGU7XG4gICAgICB0aGlzLm56VmlzaWJsZUNoYW5nZS5lbWl0KHZpc2libGUpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJlZ2lzdGVyVHJpZ2dlcnMoKTogdm9pZCB7XG4gICAgLy8gV2hlbiB0aGUgbWV0aG9kIGdldHMgaW52b2tlZCwgYWxsIHByb3BlcnRpZXMgaGFzIGJlZW4gc3luY2VkIHRvIHRoZSBkeW5hbWljIGNvbXBvbmVudC5cbiAgICAvLyBBZnRlciByZW1vdmluZyB0aGUgb2xkIEFQSSwgd2UgY2FuIGp1c3QgY2hlY2sgdGhlIGRpcmVjdGl2ZSdzIG93biBgbnpUcmlnZ2VyYC5cbiAgICBjb25zdCBlbCA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IHRyaWdnZXIgPSB0aGlzLnRyaWdnZXI7XG5cbiAgICB0aGlzLnJlbW92ZVRyaWdnZXJMaXN0ZW5lcnMoKTtcblxuICAgIGlmICh0cmlnZ2VyID09PSAnaG92ZXInKSB7XG4gICAgICBsZXQgb3ZlcmxheUVsZW1lbnQ6IEhUTUxFbGVtZW50O1xuICAgICAgdGhpcy50cmlnZ2VyRGlzcG9zYWJsZXMucHVzaChcbiAgICAgICAgdGhpcy5yZW5kZXJlci5saXN0ZW4oZWwsICdtb3VzZWVudGVyJywgKCkgPT4ge1xuICAgICAgICAgIHRoaXMuZGVsYXlFbnRlckxlYXZlKHRydWUsIHRydWUsIHRoaXMubnpNb3VzZUVudGVyRGVsYXkpO1xuICAgICAgICB9KVxuICAgICAgKTtcbiAgICAgIHRoaXMudHJpZ2dlckRpc3Bvc2FibGVzLnB1c2goXG4gICAgICAgIHRoaXMucmVuZGVyZXIubGlzdGVuKGVsLCAnbW91c2VsZWF2ZScsICgpID0+IHtcbiAgICAgICAgICB0aGlzLmRlbGF5RW50ZXJMZWF2ZSh0cnVlLCBmYWxzZSwgdGhpcy5uek1vdXNlTGVhdmVEZWxheSk7XG4gICAgICAgICAgaWYgKHRoaXMuY29tcG9uZW50Py5vdmVybGF5Lm92ZXJsYXlSZWYgJiYgIW92ZXJsYXlFbGVtZW50KSB7XG4gICAgICAgICAgICBvdmVybGF5RWxlbWVudCA9IHRoaXMuY29tcG9uZW50Lm92ZXJsYXkub3ZlcmxheVJlZi5vdmVybGF5RWxlbWVudDtcbiAgICAgICAgICAgIHRoaXMudHJpZ2dlckRpc3Bvc2FibGVzLnB1c2goXG4gICAgICAgICAgICAgIHRoaXMucmVuZGVyZXIubGlzdGVuKG92ZXJsYXlFbGVtZW50LCAnbW91c2VlbnRlcicsICgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLmRlbGF5RW50ZXJMZWF2ZShmYWxzZSwgdHJ1ZSk7XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy50cmlnZ2VyRGlzcG9zYWJsZXMucHVzaChcbiAgICAgICAgICAgICAgdGhpcy5yZW5kZXJlci5saXN0ZW4ob3ZlcmxheUVsZW1lbnQsICdtb3VzZWxlYXZlJywgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHRoaXMuZGVsYXlFbnRlckxlYXZlKGZhbHNlLCBmYWxzZSk7XG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSBlbHNlIGlmICh0cmlnZ2VyID09PSAnZm9jdXMnKSB7XG4gICAgICB0aGlzLnRyaWdnZXJEaXNwb3NhYmxlcy5wdXNoKHRoaXMucmVuZGVyZXIubGlzdGVuKGVsLCAnZm9jdXMnLCAoKSA9PiB0aGlzLnNob3coKSkpO1xuICAgICAgdGhpcy50cmlnZ2VyRGlzcG9zYWJsZXMucHVzaCh0aGlzLnJlbmRlcmVyLmxpc3RlbihlbCwgJ2JsdXInLCAoKSA9PiB0aGlzLmhpZGUoKSkpO1xuICAgIH0gZWxzZSBpZiAodHJpZ2dlciA9PT0gJ2NsaWNrJykge1xuICAgICAgdGhpcy50cmlnZ2VyRGlzcG9zYWJsZXMucHVzaChcbiAgICAgICAgdGhpcy5yZW5kZXJlci5saXN0ZW4oZWwsICdjbGljaycsIGUgPT4ge1xuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICB0aGlzLnNob3coKTtcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSAvLyBFbHNlIGRvIG5vdGhpbmcgYmVjYXVzZSB1c2VyIHdhbnRzIHRvIGNvbnRyb2wgdGhlIHZpc2liaWxpdHkgcHJvZ3JhbW1hdGljYWxseS5cbiAgfVxuXG4gIC8qKlxuICAgKiBTeW5jIGNoYW5nZWQgcHJvcGVydGllcyB0byB0aGUgY29tcG9uZW50IGFuZCB0cmlnZ2VyIGNoYW5nZSBkZXRlY3Rpb24gaW4gdGhhdCBjb21wb25lbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgdXBkYXRlQ2hhbmdlZFByb3BlcnRpZXMocHJvcGVydGllc09yQ2hhbmdlczogc3RyaW5nW10gfCBTaW1wbGVDaGFuZ2VzKTogdm9pZCB7XG4gICAgY29uc3QgaXNBcnJheSA9IEFycmF5LmlzQXJyYXkocHJvcGVydGllc09yQ2hhbmdlcyk7XG4gICAgY29uc3Qga2V5cyA9IGlzQXJyYXkgPyAocHJvcGVydGllc09yQ2hhbmdlcyBhcyBzdHJpbmdbXSkgOiBPYmplY3Qua2V5cyhwcm9wZXJ0aWVzT3JDaGFuZ2VzKTtcblxuICAgIGtleXMuZm9yRWFjaCgocHJvcGVydHk6IE56U2FmZUFueSkgPT4ge1xuICAgICAgaWYgKHRoaXMubmVlZFByb3h5UHJvcGVydGllcy5pbmRleE9mKHByb3BlcnR5KSAhPT0gLTEpIHtcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICB0aGlzLnVwZGF0ZUNvbXBvbmVudFZhbHVlKHByb3BlcnR5LCB0aGlzW3Byb3BlcnR5XSk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBpZiAoaXNBcnJheSkge1xuICAgICAgdGhpcy51cGRhdGVDb21wb25lbnRWYWx1ZSgnbnpUaXRsZScsIHRoaXMudGl0bGUpO1xuICAgICAgdGhpcy51cGRhdGVDb21wb25lbnRWYWx1ZSgnbnpDb250ZW50JywgdGhpcy5jb250ZW50KTtcbiAgICAgIHRoaXMudXBkYXRlQ29tcG9uZW50VmFsdWUoJ256UGxhY2VtZW50JywgdGhpcy5wbGFjZW1lbnQpO1xuICAgICAgdGhpcy51cGRhdGVDb21wb25lbnRWYWx1ZSgnbnpUcmlnZ2VyJywgdGhpcy50cmlnZ2VyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgYyA9IHByb3BlcnRpZXNPckNoYW5nZXMgYXMgU2ltcGxlQ2hhbmdlcztcbiAgICAgIGlmIChjLnNwZWNpZmljVGl0bGUgfHwgYy5kaXJlY3RpdmVOYW1lVGl0bGUgfHwgYy5uelRpdGxlKSB7XG4gICAgICAgIHRoaXMudXBkYXRlQ29tcG9uZW50VmFsdWUoJ256VGl0bGUnLCB0aGlzLnRpdGxlKTtcbiAgICAgIH1cbiAgICAgIGlmIChjLnNwZWNpZmljQ29udGVudCB8fCBjLmRpcmVjdGl2ZU5hbWVDb250ZW50IHx8IGMubnpDb250ZW50KSB7XG4gICAgICAgIHRoaXMudXBkYXRlQ29tcG9uZW50VmFsdWUoJ256Q29udGVudCcsIHRoaXMuY29udGVudCk7XG4gICAgICB9XG4gICAgICBpZiAoYy5zcGVjaWZpY1RyaWdnZXIgfHwgYy5uelRyaWdnZXIpIHtcbiAgICAgICAgdGhpcy51cGRhdGVDb21wb25lbnRWYWx1ZSgnbnpUcmlnZ2VyJywgdGhpcy50cmlnZ2VyKTtcbiAgICAgIH1cbiAgI