igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
683 lines • 48 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { ChangeDetectorRef, Directive, ElementRef, EventEmitter, HostBinding, HostListener, Input, NgModule, Optional, Output, Inject } from '@angular/core';
import { IgxNavigationService } from '../../core/navigation';
import { IgxOverlayService } from '../../services/overlay/overlay';
import { ConnectedPositioningStrategy, AbsoluteScrollStrategy } from '../../services';
import { filter, takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';
import { DeprecateProperty } from '../../core/deprecateDecorators';
export class IgxToggleDirective {
/**
* @hidden
* @param {?} elementRef
* @param {?} cdr
* @param {?} overlayService
* @param {?} navigationService
*/
constructor(elementRef, cdr, overlayService, navigationService) {
this.elementRef = elementRef;
this.cdr = cdr;
this.overlayService = overlayService;
this.navigationService = navigationService;
this.destroy$ = new Subject();
this._overlaySubFilter = [
filter(x => x.id === this._overlayId),
takeUntil(this.destroy$)
];
/**
* Emits an event after the toggle container is opened.
*
* ```typescript
* onToggleOpened(event) {
* alert("Toggle opened!");
* }
* ```
*
* ```html
* <div
* igxToggle
* (onOpened)='onToggleOpened($event)'>
* </div>
* ```
*/
this.onOpened = new EventEmitter();
/**
* Emits an event before the toggle container is opened.
*
* ```typescript
* onToggleOpening(event) {
* alert("Toggle opening!");
* }
* ```
*
* ```html
* <div
* igxToggle
* (onOpening)='onToggleOpening($event)'>
* </div>
* ```
*/
this.onOpening = new EventEmitter();
/**
* Emits an event after the toggle container is closed.
*
* ```typescript
* onToggleClosed(event) {
* alert("Toggle closed!");
* }
* ```
*
* ```html
* <div
* igxToggle
* (onClosed)='onToggleClosed($event)'>
* </div>
* ```
*/
this.onClosed = new EventEmitter();
/**
* Emits an event before the toggle container is closed.
*
* ```typescript
* onToggleClosing(event) {
* alert("Toggle closing!");
* }
* ```
*
* ```html
* <div
* igxToggle
* (onClosing)='onToggleClosing($event)'>
* </div>
* ```
*/
this.onClosing = new EventEmitter();
this._collapsed = true;
this.overlayClosed = () => {
this._collapsed = true;
this.cdr.detectChanges();
delete this._overlayId;
this.unsubscribe();
this.onClosed.emit();
};
}
/**
* @hidden
* @return {?}
*/
get collapsed() {
return this._collapsed;
}
/**
* @hidden
* @return {?}
*/
get element() {
return this.elementRef.nativeElement;
}
/**
* @hidden
* @return {?}
*/
get hiddenClass() {
return this.collapsed;
}
/**
* @hidden
* @return {?}
*/
get defaultClass() {
return !this.collapsed;
}
/**
* Opens the toggle.
*
* ```typescript
* this.myToggle.open();
* ```
* @param {?=} overlaySettings
* @return {?}
*/
open(overlaySettings) {
// if there is open animation do nothing
// if toggle is not collapsed and there is no close animation do nothing
/** @type {?} */
const info = this.overlayService.getOverlayById(this._overlayId);
/** @type {?} */
const hasOpenAnimation = info ? info.openAnimationPlayer : false;
/** @type {?} */
const hasCloseAnimation = info ? info.closeAnimationPlayer : false;
if (hasOpenAnimation || !(this._collapsed || hasCloseAnimation)) {
return;
}
if (!info) {
this._overlayId = this.overlayService.attach(this.elementRef, overlaySettings);
}
this._collapsed = false;
this.cdr.detectChanges();
/** @type {?} */
const openEventArgs = { cancel: false };
this.onOpening.emit(openEventArgs);
if (openEventArgs.cancel) {
this._collapsed = true;
this.cdr.detectChanges();
return;
}
this.overlayService.show(this._overlayId, overlaySettings);
this.unsubscribe();
this._overlayOpenedSub = this.overlayService.onOpened.pipe(...this._overlaySubFilter).subscribe(() => {
this.onOpened.emit();
});
this._overlayClosingSub = this.overlayService
.onClosing
.pipe(...this._overlaySubFilter)
.subscribe((e) => {
/** @type {?} */
const eventArgs = { cancel: false, event: e.event };
this.onClosing.emit(eventArgs);
e.cancel = eventArgs.cancel;
// in case event is not canceled this will close the toggle and we need to unsubscribe.
// Otherwise if for some reason, e.g. close on outside click, close() gets called before
// onClosed was fired we will end with calling onClosing more than once
if (!e.cancel) {
this.clearSubscription(this._overlayClosingSub);
}
});
this._overlayClosedSub = this.overlayService.onClosed
.pipe(...this._overlaySubFilter)
.subscribe(this.overlayClosed);
}
/**
* Closes the toggle.
*
* ```typescript
* this.myToggle.close();
* ```
* @return {?}
*/
close() {
// if toggle is collapsed do nothing
// if there is close animation do nothing, toggle will close anyway
/** @type {?} */
const info = this.overlayService.getOverlayById(this._overlayId);
/** @type {?} */
const hasCloseAnimation = info ? info.closeAnimationPlayer : false;
if (this._collapsed || hasCloseAnimation) {
return;
}
this.overlayService.hide(this._overlayId);
}
/**
* Opens or closes the toggle, depending on its current state.
*
* ```typescript
* this.myToggle.toggle();
* ```
* @param {?=} overlaySettings
* @return {?}
*/
toggle(overlaySettings) {
// if toggle is collapsed call open
// if there is close animation call open
if (this.collapsed || this.isClosing) {
this.open(overlaySettings);
}
else {
this.close();
}
}
/**
* @hidden \@internal
* @return {?}
*/
get isClosing() {
/** @type {?} */
const info = this.overlayService.getOverlayById(this._overlayId);
return info ? info.closeAnimationPlayer : false;
}
/**
* Repositions the toggle.
* ```typescript
* this.myToggle.reposition();
* ```
* @return {?}
*/
reposition() {
this.overlayService.reposition(this._overlayId);
}
/**
* @hidden
* @return {?}
*/
ngOnInit() {
if (this.navigationService && this.id) {
this.navigationService.add(this.id, this);
}
}
/**
* @hidden
* @return {?}
*/
ngOnDestroy() {
if (this.navigationService && this.id) {
this.navigationService.remove(this.id);
}
if (!this.collapsed && this._overlayId) {
this.overlayService.hide(this._overlayId);
}
this.unsubscribe();
this.destroy$.next(true);
this.destroy$.complete();
}
/**
* @private
* @return {?}
*/
unsubscribe() {
this.clearSubscription(this._overlayOpenedSub);
this.clearSubscription(this._overlayClosingSub);
this.clearSubscription(this._overlayClosedSub);
}
/**
* @private
* @param {?} subscription
* @return {?}
*/
clearSubscription(subscription) {
if (subscription && !subscription.closed) {
subscription.unsubscribe();
}
}
}
IgxToggleDirective.decorators = [
{ type: Directive, args: [{
exportAs: 'toggle',
selector: '[igxToggle]'
},] }
];
/** @nocollapse */
IgxToggleDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: ChangeDetectorRef },
{ type: IgxOverlayService, decorators: [{ type: Inject, args: [IgxOverlayService,] }] },
{ type: IgxNavigationService, decorators: [{ type: Optional }] }
];
IgxToggleDirective.propDecorators = {
onOpened: [{ type: Output }],
onOpening: [{ type: Output }],
onClosed: [{ type: Output }],
onClosing: [{ type: Output }],
id: [{ type: Input }],
hiddenClass: [{ type: HostBinding, args: ['class.igx-toggle--hidden',] }, { type: HostBinding, args: ['attr.aria-hidden',] }],
defaultClass: [{ type: HostBinding, args: ['class.igx-toggle',] }]
};
if (false) {
/**
* @type {?}
* @protected
*/
IgxToggleDirective.prototype._overlayId;
/**
* @type {?}
* @private
*/
IgxToggleDirective.prototype.destroy$;
/**
* @type {?}
* @private
*/
IgxToggleDirective.prototype._overlaySubFilter;
/**
* @type {?}
* @private
*/
IgxToggleDirective.prototype._overlayOpenedSub;
/**
* @type {?}
* @private
*/
IgxToggleDirective.prototype._overlayClosingSub;
/**
* @type {?}
* @private
*/
IgxToggleDirective.prototype._overlayClosedSub;
/**
* Emits an event after the toggle container is opened.
*
* ```typescript
* onToggleOpened(event) {
* alert("Toggle opened!");
* }
* ```
*
* ```html
* <div
* igxToggle
* (onOpened)='onToggleOpened($event)'>
* </div>
* ```
* @type {?}
*/
IgxToggleDirective.prototype.onOpened;
/**
* Emits an event before the toggle container is opened.
*
* ```typescript
* onToggleOpening(event) {
* alert("Toggle opening!");
* }
* ```
*
* ```html
* <div
* igxToggle
* (onOpening)='onToggleOpening($event)'>
* </div>
* ```
* @type {?}
*/
IgxToggleDirective.prototype.onOpening;
/**
* Emits an event after the toggle container is closed.
*
* ```typescript
* onToggleClosed(event) {
* alert("Toggle closed!");
* }
* ```
*
* ```html
* <div
* igxToggle
* (onClosed)='onToggleClosed($event)'>
* </div>
* ```
* @type {?}
*/
IgxToggleDirective.prototype.onClosed;
/**
* Emits an event before the toggle container is closed.
*
* ```typescript
* onToggleClosing(event) {
* alert("Toggle closing!");
* }
* ```
*
* ```html
* <div
* igxToggle
* (onClosing)='onToggleClosing($event)'>
* </div>
* ```
* @type {?}
*/
IgxToggleDirective.prototype.onClosing;
/**
* @type {?}
* @private
*/
IgxToggleDirective.prototype._collapsed;
/**
* Identifier which is registered into `IgxNavigationService`
*
* ```typescript
* let myToggleId = this.toggle.id;
* ```
* @type {?}
*/
IgxToggleDirective.prototype.id;
/**
* @type {?}
* @private
*/
IgxToggleDirective.prototype.overlayClosed;
/**
* @type {?}
* @private
*/
IgxToggleDirective.prototype.elementRef;
/**
* @type {?}
* @private
*/
IgxToggleDirective.prototype.cdr;
/**
* @type {?}
* @protected
*/
IgxToggleDirective.prototype.overlayService;
/**
* @type {?}
* @private
*/
IgxToggleDirective.prototype.navigationService;
}
export class IgxToggleActionDirective {
/**
* @param {?} element
* @param {?} navigationService
*/
constructor(element, navigationService) {
this.element = element;
this.navigationService = navigationService;
}
/**
* DEPRECATED. Determines whether the toggle should close when you click outside.
*
* ```typescript
* // get
* let closesOnOutsideClick = this.toggle.closeOnOutsideClick;
* ```
* @return {?}
*/
get closeOnOutsideClick() {
return this._closeOnOutsideClick;
}
/**
* ```html
* <!--set-->
* <div igxToggleAction [closeOnOutsideClick]="'true'"></div>
* ```
* @param {?} v
* @return {?}
*/
set closeOnOutsideClick(v) {
this._closeOnOutsideClick = v;
}
/**
* @hidden
* @param {?} target
* @return {?}
*/
set target(target) {
if (target !== null && target !== '') {
this._target = target;
}
}
/**
* @hidden
* @return {?}
*/
get target() {
if (typeof this._target === 'string') {
return this.navigationService.get(this._target);
}
return this._target;
}
/**
* @hidden
* @return {?}
*/
ngOnInit() {
this._overlayDefaults = {
positionStrategy: new ConnectedPositioningStrategy({ target: this.element.nativeElement }),
scrollStrategy: new AbsoluteScrollStrategy(),
closeOnOutsideClick: true,
modal: false,
excludePositionTarget: true
};
}
/**
* @hidden
* @return {?}
*/
onClick() {
if (this._closeOnOutsideClick !== undefined) {
this._overlayDefaults.closeOnOutsideClick = this._closeOnOutsideClick;
}
if (this.outlet) {
this._overlayDefaults.outlet = this.outlet;
}
/** @type {?} */
const clonedSettings = Object.assign({}, this._overlayDefaults, this.overlaySettings);
this.updateOverlaySettings(clonedSettings);
this.target.toggle(clonedSettings);
}
/**
* Updates provided overlay settings
* @protected
* @param {?} settings settings to update
* @return {?} returns updated copy of provided overlay settings
*/
updateOverlaySettings(settings) {
if (settings && settings.positionStrategy) {
/** @type {?} */
const positionStrategyClone = settings.positionStrategy.clone();
positionStrategyClone.settings.target = this.element.nativeElement;
settings.positionStrategy = positionStrategyClone;
}
return settings;
}
}
IgxToggleActionDirective.decorators = [
{ type: Directive, args: [{
exportAs: 'toggle-action',
selector: '[igxToggleAction]'
},] }
];
/** @nocollapse */
IgxToggleActionDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: IgxNavigationService, decorators: [{ type: Optional }] }
];
IgxToggleActionDirective.propDecorators = {
overlaySettings: [{ type: Input }],
closeOnOutsideClick: [{ type: Input }],
outlet: [{ type: Input, args: ['igxToggleOutlet',] }],
target: [{ type: Input, args: ['igxToggleAction',] }],
onClick: [{ type: HostListener, args: ['click',] }]
};
tslib_1.__decorate([
DeprecateProperty(`igxToggleAction 'closeOnOutsideClick' input is deprecated. Use 'overlaySettings' input object instead.`),
tslib_1.__metadata("design:type", Boolean),
tslib_1.__metadata("design:paramtypes", [Boolean])
], IgxToggleActionDirective.prototype, "closeOnOutsideClick", null);
if (false) {
/**
* @type {?}
* @protected
*/
IgxToggleActionDirective.prototype._overlayDefaults;
/**
* Provide settings that control the toggle overlay positioning, interaction and scroll behavior.
* ```typescript
* const settings: OverlaySettings = {
* closeOnOutsideClick: false,
* modal: false
* }
* ```
* ---
* ```html
* <!--set-->
* <div igxToggleAction [overlaySettings]="settings"></div>
* ```
* @type {?}
*/
IgxToggleActionDirective.prototype.overlaySettings;
/**
* @type {?}
* @private
*/
IgxToggleActionDirective.prototype._closeOnOutsideClick;
/**
* Determines where the toggle element overlay should be attached.
*
* ```html
* <!--set-->
* <div igxToggleAction [igxToggleOutlet]="outlet"></div>
* ```
* Where `outlet` in an instance of `IgxOverlayOutletDirective` or an `ElementRef`
* @type {?}
*/
IgxToggleActionDirective.prototype.outlet;
/**
* @type {?}
* @protected
*/
IgxToggleActionDirective.prototype._target;
/**
* @type {?}
* @private
*/
IgxToggleActionDirective.prototype.element;
/**
* @type {?}
* @private
*/
IgxToggleActionDirective.prototype.navigationService;
}
/**
* Mark an element as an igxOverlay outlet container.
* Directive instance is exported as `overlay-outlet` to be assigned to templates variables:
* ```html
* <div igxOverlayOutlet #outlet="overlay-outlet"></div>
* ```
*/
export class IgxOverlayOutletDirective {
/**
* @param {?} element
*/
constructor(element) {
this.element = element;
}
/**
* @hidden
* @return {?}
*/
get nativeElement() {
return this.element.nativeElement;
}
}
IgxOverlayOutletDirective.decorators = [
{ type: Directive, args: [{
exportAs: 'overlay-outlet',
selector: '[igxOverlayOutlet]'
},] }
];
/** @nocollapse */
IgxOverlayOutletDirective.ctorParameters = () => [
{ type: ElementRef }
];
if (false) {
/** @type {?} */
IgxOverlayOutletDirective.prototype.element;
}
/**
* @hidden
*/
export class IgxToggleModule {
}
IgxToggleModule.decorators = [
{ type: NgModule, args: [{
declarations: [IgxToggleDirective, IgxToggleActionDirective, IgxOverlayOutletDirective],
exports: [IgxToggleDirective, IgxToggleActionDirective, IgxOverlayOutletDirective],
providers: [IgxNavigationService]
},] }
];
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9nZ2xlLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2lnbml0ZXVpLWFuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvZGlyZWN0aXZlcy90b2dnbGUvdG9nZ2xlLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFDSCxpQkFBaUIsRUFDakIsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osV0FBVyxFQUNYLFlBQVksRUFDWixLQUFLLEVBQ0wsUUFBUSxFQUdSLFFBQVEsRUFDUixNQUFNLEVBQ04sTUFBTSxFQUNULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxvQkFBb0IsRUFBZSxNQUFNLHVCQUF1QixDQUFDO0FBQzFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ25FLE9BQU8sRUFBcUMsNEJBQTRCLEVBQUUsc0JBQXNCLEVBQXFCLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUksT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNuRCxPQUFPLEVBQWdCLE9BQU8sRUFBNEIsTUFBTSxNQUFNLENBQUM7QUFHdkUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFNbkUsTUFBTSxPQUFPLGtCQUFrQjs7Ozs7Ozs7SUFvSTNCLFlBQ1ksVUFBc0IsRUFDdEIsR0FBc0IsRUFDTyxjQUFpQyxFQUNsRCxpQkFBdUM7UUFIbkQsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0QixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUNPLG1CQUFjLEdBQWQsY0FBYyxDQUFtQjtRQUNsRCxzQkFBaUIsR0FBakIsaUJBQWlCLENBQXNCO1FBdEl2RCxhQUFRLEdBQUcsSUFBSSxPQUFPLEVBQVcsQ0FBQztRQUNsQyxzQkFBaUIsR0FBNkY7WUFDbEgsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsVUFBVSxDQUFDO1lBQ3JDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO1NBQzNCLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7O1FBc0JLLGFBQVEsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7OztRQW1COUIsY0FBUyxHQUFHLElBQUksWUFBWSxFQUF1QixDQUFDOzs7Ozs7Ozs7Ozs7Ozs7OztRQW1CcEQsYUFBUSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7O1FBbUI5QixjQUFTLEdBQUcsSUFBSSxZQUFZLEVBQThCLENBQUM7UUFFMUQsZUFBVSxHQUFHLElBQUksQ0FBQztRQTRMbEIsa0JBQWEsR0FBRyxHQUFHLEVBQUU7WUFDekIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7WUFDdkIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN6QixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7WUFDdkIsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ25CLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDekIsQ0FBQyxDQUFBO0lBaEpELENBQUM7Ozs7O0lBOUNELElBQVcsU0FBUztRQUNoQixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDM0IsQ0FBQzs7Ozs7SUFlRCxJQUFXLE9BQU87UUFDZCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDO0lBQ3pDLENBQUM7Ozs7O0lBS0QsSUFFVyxXQUFXO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUMxQixDQUFDOzs7OztJQUtELElBQ1csWUFBWTtRQUNuQixPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUMzQixDQUFDOzs7Ozs7Ozs7O0lBbUJNLElBQUksQ0FBQyxlQUFpQzs7OztjQUduQyxJQUFJLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQzs7Y0FDMUQsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDLEtBQUs7O2NBQzFELGlCQUFpQixHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxLQUFLO1FBQ2xFLElBQUksZ0JBQWdCLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLElBQUksaUJBQWlCLENBQUMsRUFBRTtZQUM3RCxPQUFPO1NBQ1Y7UUFFRCxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQ1AsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLGVBQWUsQ0FBQyxDQUFDO1NBQ2xGO1FBRUQsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7UUFDeEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsQ0FBQzs7Y0FFbkIsYUFBYSxHQUF3QixFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUU7UUFDNUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDbkMsSUFBSSxhQUFhLENBQUMsTUFBTSxFQUFFO1lBQ3RCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDekIsT0FBTztTQUNWO1FBRUQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUUzRCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDbkIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDakcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN6QixDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLENBQUMsY0FBYzthQUN4QyxTQUFTO2FBQ1QsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDO2FBQy9CLFNBQVMsQ0FBQyxDQUFDLENBQTBCLEVBQUUsRUFBRTs7a0JBQ2hDLFNBQVMsR0FBK0IsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSyxFQUFFO1lBQy9FLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQy9CLENBQUMsQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDLE1BQU0sQ0FBQztZQUU1Qix3RkFBd0Y7WUFDeEYseUZBQXlGO1lBQ3pGLHdFQUF3RTtZQUN4RSxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRTtnQkFDWCxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7YUFDbkQ7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVQLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVE7YUFDaEQsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixDQUFDO2FBQy9CLFNBQVMsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDdkMsQ0FBQzs7Ozs7Ozs7O0lBU00sS0FBSzs7OztjQUdGLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDOztjQUMxRCxpQkFBaUIsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsS0FBSztRQUNsRSxJQUFJLElBQUksQ0FBQyxVQUFVLElBQUksaUJBQWlCLEVBQUU7WUFDdEMsT0FBTztTQUNWO1FBRUQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQzlDLENBQUM7Ozs7Ozs7Ozs7SUFTTSxNQUFNLENBQUMsZUFBaUM7UUFDM0Msb0NBQW9DO1FBQ3BDLHlDQUF5QztRQUN6QyxJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNsQyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1NBQzlCO2FBQU07WUFDSCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7U0FDaEI7SUFDTCxDQUFDOzs7OztJQUdELElBQVcsU0FBUzs7Y0FDVixJQUFJLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQztRQUNoRSxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFDcEQsQ0FBQzs7Ozs7Ozs7SUFRTSxVQUFVO1FBQ2IsSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3BELENBQUM7Ozs7O0lBS00sUUFBUTtRQUNYLElBQUksSUFBSSxDQUFDLGlCQUFpQixJQUFJLElBQUksQ0FBQyxFQUFFLEVBQUU7WUFDbkMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO1NBQzdDO0lBQ0wsQ0FBQzs7Ozs7SUFLTSxXQUFXO1FBQ2QsSUFBSSxJQUFJLENBQUMsaUJBQWlCLElBQUksSUFBSSxDQUFDLEVBQUUsRUFBRTtZQUNuQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztTQUMxQztRQUNELElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUU7WUFDcEMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1NBQzdDO1FBQ0QsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25CLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDN0IsQ0FBQzs7Ozs7SUFVTyxXQUFXO1FBQ2YsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQy9DLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUNoRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDbkQsQ0FBQzs7Ozs7O0lBRU8saUJBQWlCLENBQUMsWUFBMEI7UUFDaEQsSUFBSSxZQUFZLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFO1lBQ3RDLFlBQVksQ0FBQyxXQUFXLEVBQUUsQ0FBQztTQUM5QjtJQUNMLENBQUM7OztZQXpTSixTQUFTLFNBQUM7Z0JBQ1AsUUFBUSxFQUFFLFFBQVE7Z0JBQ2xCLFFBQVEsRUFBRSxhQUFhO2FBQzFCOzs7O1lBeEJHLFVBQVU7WUFGVixpQkFBaUI7WUFlWixpQkFBaUIsdUJBbUpqQixNQUFNLFNBQUMsaUJBQWlCO1lBcEp4QixvQkFBb0IsdUJBcUpwQixRQUFROzs7dUJBN0daLE1BQU07d0JBbUJOLE1BQU07dUJBbUJOLE1BQU07d0JBbUJOLE1BQU07aUJBa0JOLEtBQUs7MEJBYUwsV0FBVyxTQUFDLDBCQUEwQixjQUN0QyxXQUFXLFNBQUMsa0JBQWtCOzJCQVE5QixXQUFXLFNBQUMsa0JBQWtCOzs7Ozs7O0lBM0gvQix3Q0FBNkI7Ozs7O0lBQzdCLHNDQUEwQzs7Ozs7SUFDMUMsK0NBR0U7Ozs7O0lBQ0YsK0NBQXdDOzs7OztJQUN4QyxnREFBeUM7Ozs7O0lBQ3pDLCtDQUF3Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBa0J4QyxzQ0FDcUM7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQWtCckMsdUNBQzJEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7SUFrQjNELHNDQUNxQzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBa0JyQyx1Q0FDa0U7Ozs7O0lBRWxFLHdDQUEwQjs7Ozs7Ozs7O0lBZTFCLGdDQUNrQjs7Ozs7SUE0S2xCLDJDQU1DOzs7OztJQXBKRyx3Q0FBOEI7Ozs7O0lBQzlCLGlDQUE4Qjs7Ozs7SUFDOUIsNENBQXNFOzs7OztJQUN0RSwrQ0FBMkQ7O0FBb0tuRSxNQUFNLE9BQU8sd0JBQXdCOzs7OztJQThFakMsWUFBb0IsT0FBbUIsRUFBc0IsaUJBQXVDO1FBQWhGLFlBQU8sR0FBUCxPQUFPLENBQVk7UUFBc0Isc0JBQWlCLEdBQWpCLGlCQUFpQixDQUFzQjtJQUFJLENBQUM7Ozs7Ozs7Ozs7SUEvQ3pHLElBQVcsbUJBQW1CO1FBQzFCLE9BQU8sSUFBSSxDQUFDLG9CQUFvQixDQUFDO0lBQ3JDLENBQUM7Ozs7Ozs7OztJQU9ELElBQVcsbUJBQW1CLENBQUMsQ0FBVTtRQUNyQyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7Ozs7OztJQWlCRCxJQUNJLE1BQU0sQ0FBQyxNQUFXO1FBQ2xCLElBQUksTUFBTSxLQUFLLElBQUksSUFBSSxNQUFNLEtBQUssRUFBRSxFQUFFO1lBQ2xDLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDO1NBQ3pCO0lBQ0wsQ0FBQzs7Ozs7SUFLRCxJQUFJLE1BQU07UUFDTixJQUFJLE9BQU8sSUFBSSxDQUFDLE9BQU8sS0FBSyxRQUFRLEVBQUU7WUFDbEMsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUNuRDtRQUNELE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQztJQUN4QixDQUFDOzs7OztJQVNNLFFBQVE7UUFDWCxJQUFJLENBQUMsZ0JBQWdCLEdBQUc7WUFDcEIsZ0JBQWdCLEVBQUUsSUFBSSw0QkFBNEIsQ0FBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzFGLGNBQWMsRUFBRSxJQUFJLHNCQUFzQixFQUFFO1lBQzVDLG1CQUFtQixFQUFFLElBQUk7WUFDekIsS0FBSyxFQUFFLEtBQUs7WUFDWixxQkFBcUIsRUFBRSxJQUFJO1NBQzlCLENBQUM7SUFDTixDQUFDOzs7OztJQU1NLE9BQU87UUFDVixJQUFJLElBQUksQ0FBQyxvQkFBb0IsS0FBSyxTQUFTLEVBQUU7WUFDekMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQztTQUN6RTtRQUNELElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNiLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztTQUM5Qzs7Y0FFSyxjQUFjLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxlQUFlLENBQUM7UUFDckYsSUFBSSxDQUFDLHFCQUFxQixDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQzNDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7Ozs7Ozs7SUFPUyxxQkFBcUIsQ0FBQyxRQUF5QjtRQUNyRCxJQUFJLFFBQVEsSUFBSSxRQUFRLENBQUMsZ0JBQWdCLEVBQUU7O2tCQUNqQyxxQkFBcUIsR0FBc0IsUUFBUSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRTtZQUNsRixxQkFBcUIsQ0FBQyxRQUFRLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDO1lBQ25FLFFBQVEsQ0FBQyxnQkFBZ0IsR0FBRyxxQkFBcUIsQ0FBQztTQUNyRDtRQUVELE9BQU8sUUFBUSxDQUFDO0lBQ3BCLENBQUM7OztZQS9ISixTQUFTLFNBQUM7Z0JBQ1AsUUFBUSxFQUFFLGVBQWU7Z0JBQ3pCLFFBQVEsRUFBRSxtQkFBbUI7YUFDaEM7Ozs7WUFwVUcsVUFBVTtZQVlMLG9CQUFvQix1QkF1WWlCLFFBQVE7Ozs4QkE3RGpELEtBQUs7a0NBWUwsS0FBSztxQkF3QkwsS0FBSyxTQUFDLGlCQUFpQjtxQkFNdkIsS0FBSyxTQUFDLGlCQUFpQjtzQkFxQ3ZCLFlBQVksU0FBQyxPQUFPOztBQWpFckI7SUFEQyxpQkFBaUIsQ0FBQyx3R0FBd0csQ0FBQzs7O21FQUczSDs7Ozs7O0lBaENELG9EQUE0Qzs7Ozs7Ozs7Ozs7Ozs7OztJQWdCNUMsbURBQ3dDOzs7OztJQUV4Qyx3REFBc0M7Ozs7Ozs7Ozs7O0lBaUN0QywwQ0FDc0Q7Ozs7O0lBc0J0RCwyQ0FBd0M7Ozs7O0lBRTVCLDJDQUEyQjs7Ozs7SUFBRSxxREFBMkQ7Ozs7Ozs7OztBQTJEeEcsTUFBTSxPQUFPLHlCQUF5Qjs7OztJQUNsQyxZQUFtQixPQUFtQjtRQUFuQixZQUFPLEdBQVAsT0FBTyxDQUFZO0lBQUksQ0FBQzs7Ozs7SUFHM0MsSUFBVyxhQUFhO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUM7SUFDdEMsQ0FBQzs7O1lBVkosU0FBUyxTQUFDO2dCQUNQLFFBQVEsRUFBRSxnQkFBZ0I7Z0JBQzFCLFFBQVEsRUFBRSxvQkFBb0I7YUFDakM7Ozs7WUE3Y0csVUFBVTs7OztJQStjRSw0Q0FBMEI7Ozs7O0FBZ0IxQyxNQUFNLE9BQU8sZUFBZTs7O1lBTDNCLFFBQVEsU0FBQztnQkFDTixZQUFZLEVBQUUsQ0FBQyxrQkFBa0IsRUFBRSx3QkFBd0IsRUFBRSx5QkFBeUIsQ0FBQztnQkFDdkYsT0FBTyxFQUFFLENBQUMsa0JBQWtCLEVBQUUsd0JBQXdCLEVBQUUseUJBQXlCLENBQUM7Z0JBQ2xGLFNBQVMsRUFBRSxDQUFDLG9CQUFvQixDQUFDO2FBQ3BDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBEaXJlY3RpdmUsXG4gICAgRWxlbWVudFJlZixcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgSG9zdEJpbmRpbmcsXG4gICAgSG9zdExpc3RlbmVyLFxuICAgIElucHV0LFxuICAgIE5nTW9kdWxlLFxuICAgIE9uRGVzdHJveSxcbiAgICBPbkluaXQsXG4gICAgT3B0aW9uYWwsXG4gICAgT3V0cHV0LFxuICAgIEluamVjdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IElneE5hdmlnYXRpb25TZXJ2aWNlLCBJVG9nZ2xlVmlldyB9IGZyb20gJy4uLy4uL2NvcmUvbmF2aWdhdGlvbic7XG5pbXBvcnQgeyBJZ3hPdmVybGF5U2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL292ZXJsYXkvb3ZlcmxheSc7XG5pbXBvcnQgeyBPdmVybGF5U2V0dGluZ3MsIE92ZXJsYXlFdmVudEFyZ3MsIENvbm5lY3RlZFBvc2l0aW9uaW5nU3RyYXRlZ3ksIEFic29sdXRlU2Nyb2xsU3RyYXRlZ3ksIElQb3NpdGlvblN0cmF0ZWd5IH0gZnJvbSAnLi4vLi4vc2VydmljZXMnO1xuaW1wb3J0IHsgZmlsdGVyLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24sIFN1YmplY3QsIE1vbm9UeXBlT3BlcmF0b3JGdW5jdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgT3ZlcmxheUNsb3NpbmdFdmVudEFyZ3MgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9vdmVybGF5L3V0aWxpdGllcyc7XG5pbXBvcnQgeyBDYW5jZWxhYmxlRXZlbnRBcmdzLCBDYW5jZWxhYmxlQnJvd3NlckV2ZW50QXJncyB9IGZyb20gJy4uLy4uL2NvcmUvdXRpbHMnO1xuaW1wb3J0IHsgRGVwcmVjYXRlUHJvcGVydHkgfSBmcm9tICcuLi8uLi9jb3JlL2RlcHJlY2F0ZURlY29yYXRvcnMnO1xuXG5ARGlyZWN0aXZlKHtcbiAgICBleHBvcnRBczogJ3RvZ2dsZScsXG4gICAgc2VsZWN0b3I6ICdbaWd4VG9nZ2xlXSdcbn0pXG5leHBvcnQgY2xhc3MgSWd4VG9nZ2xlRGlyZWN0aXZlIGltcGxlbWVudHMgSVRvZ2dsZVZpZXcsIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgICBwcm90ZWN0ZWQgX292ZXJsYXlJZDogc3RyaW5nO1xuICAgIHByaXZhdGUgZGVzdHJveSQgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuICAgIHByaXZhdGUgX292ZXJsYXlTdWJGaWx0ZXI6IFtNb25vVHlwZU9wZXJhdG9yRnVuY3Rpb248T3ZlcmxheUV2ZW50QXJncz4sIE1vbm9UeXBlT3BlcmF0b3JGdW5jdGlvbjxPdmVybGF5RXZlbnRBcmdzPl0gPSBbXG4gICAgICAgIGZpbHRlcih4ID0+IHguaWQgPT09IHRoaXMuX292ZXJsYXlJZCksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKVxuICAgIF07XG4gICAgcHJpdmF0ZSBfb3ZlcmxheU9wZW5lZFN1YjogU3Vic2NyaXB0aW9uO1xuICAgIHByaXZhdGUgX292ZXJsYXlDbG9zaW5nU3ViOiBTdWJzY3JpcHRpb247XG4gICAgcHJpdmF0ZSBfb3ZlcmxheUNsb3NlZFN1YjogU3Vic2NyaXB0aW9uO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgYW4gZXZlbnQgYWZ0ZXIgdGhlIHRvZ2dsZSBjb250YWluZXIgaXMgb3BlbmVkLlxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIG9uVG9nZ2xlT3BlbmVkKGV2ZW50KSB7XG4gICAgICogICAgYWxlcnQoXCJUb2dnbGUgb3BlbmVkIVwiKTtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPGRpdlxuICAgICAqICAgaWd4VG9nZ2xlXG4gICAgICogICAob25PcGVuZWQpPSdvblRvZ2dsZU9wZW5lZCgkZXZlbnQpJz5cbiAgICAgKiA8L2Rpdj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25PcGVuZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0cyBhbiBldmVudCBiZWZvcmUgdGhlIHRvZ2dsZSBjb250YWluZXIgaXMgb3BlbmVkLlxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIG9uVG9nZ2xlT3BlbmluZyhldmVudCkge1xuICAgICAqICBhbGVydChcIlRvZ2dsZSBvcGVuaW5nIVwiKTtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPGRpdlxuICAgICAqICAgaWd4VG9nZ2xlXG4gICAgICogICAob25PcGVuaW5nKT0nb25Ub2dnbGVPcGVuaW5nKCRldmVudCknPlxuICAgICAqIDwvZGl2PlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyBvbk9wZW5pbmcgPSBuZXcgRXZlbnRFbWl0dGVyPENhbmNlbGFibGVFdmVudEFyZ3M+KCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0cyBhbiBldmVudCBhZnRlciB0aGUgdG9nZ2xlIGNvbnRhaW5lciBpcyBjbG9zZWQuXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogb25Ub2dnbGVDbG9zZWQoZXZlbnQpIHtcbiAgICAgKiAgYWxlcnQoXCJUb2dnbGUgY2xvc2VkIVwiKTtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPGRpdlxuICAgICAqICAgaWd4VG9nZ2xlXG4gICAgICogICAob25DbG9zZWQpPSdvblRvZ2dsZUNsb3NlZCgkZXZlbnQpJz5cbiAgICAgKiA8L2Rpdj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25DbG9zZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0cyBhbiBldmVudCBiZWZvcmUgdGhlIHRvZ2dsZSBjb250YWluZXIgaXMgY2xvc2VkLlxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIG9uVG9nZ2xlQ2xvc2luZyhldmVudCkge1xuICAgICAqICBhbGVydChcIlRvZ2dsZSBjbG9zaW5nIVwiKTtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPGRpdlxuICAgICAqICBpZ3hUb2dnbGVcbiAgICAgKiAgKG9uQ2xvc2luZyk9J29uVG9nZ2xlQ2xvc2luZygkZXZlbnQpJz5cbiAgICAgKiA8L2Rpdj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25DbG9zaW5nID0gbmV3IEV2ZW50RW1pdHRlcjxDYW5jZWxhYmxlQnJvd3NlckV2ZW50QXJncz4oKTtcblxuICAgIHByaXZhdGUgX2NvbGxhcHNlZCA9IHRydWU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgY29sbGFwc2VkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29sbGFwc2VkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIElkZW50aWZpZXIgd2hpY2ggaXMgcmVnaXN0ZXJlZCBpbnRvIGBJZ3hOYXZpZ2F0aW9uU2VydmljZWBcbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgbXlUb2dnbGVJZCA9IHRoaXMudG9nZ2xlLmlkO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGdldCBlbGVtZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MuaWd4LXRvZ2dsZS0taGlkZGVuJylcbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuYXJpYS1oaWRkZW4nKVxuICAgIHB1YmxpYyBnZXQgaGlkZGVuQ2xhc3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbGxhcHNlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5pZ3gtdG9nZ2xlJylcbiAgICBwdWJsaWMgZ2V0IGRlZmF1bHRDbGFzcygpIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLmNvbGxhcHNlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICAgICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgICAgICBASW5qZWN0KElneE92ZXJsYXlTZXJ2aWNlKSBwcm90ZWN0ZWQgb3ZlcmxheVNlcnZpY2U6IElneE92ZXJsYXlTZXJ2aWNlLFxuICAgICAgICBAT3B0aW9uYWwoKSBwcml2YXRlIG5hdmlnYXRpb25TZXJ2aWNlOiBJZ3hOYXZpZ2F0aW9uU2VydmljZSkge1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9wZW5zIHRoZSB0b2dnbGUuXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogdGhpcy5teVRvZ2dsZS5vcGVuKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIG9wZW4ob3ZlcmxheVNldHRpbmdzPzogT3ZlcmxheVNldHRpbmdzKSB7XG4gICAgICAgIC8vICBpZiB0aGVyZSBpcyBvcGVuIGFuaW1hdGlvbiBkbyBub3RoaW5nXG4gICAgICAgIC8vICBpZiB0b2dnbGUgaXMgbm90IGNvbGxhcHNlZCBhbmQgdGhlcmUgaXMgbm8gY2xvc2UgYW5pbWF0aW9uIGRvIG5vdGhpbmdcbiAgICAgICAgY29uc3QgaW5mbyA9IHRoaXMub3ZlcmxheVNlcnZpY2UuZ2V0T3ZlcmxheUJ5SWQodGhpcy5fb3ZlcmxheUlkKTtcbiAgICAgICAgY29uc3QgaGFzT3BlbkFuaW1hdGlvbiA9IGluZm8gPyBpbmZvLm9wZW5BbmltYXRpb25QbGF5ZXIgOiBmYWxzZTtcbiAgICAgICAgY29uc3QgaGFzQ2xvc2VBbmltYXRpb24gPSBpbmZvID8gaW5mby5jbG9zZUFuaW1hdGlvblBsYXllciA6IGZhbHNlO1xuICAgICAgICBpZiAoaGFzT3BlbkFuaW1hdGlvbiB8fCAhKHRoaXMuX2NvbGxhcHNlZCB8fCBoYXNDbG9zZUFuaW1hdGlvbikpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaW5mbykge1xuICAgICAgICAgICAgdGhpcy5fb3ZlcmxheUlkID0gdGhpcy5vdmVybGF5U2VydmljZS5hdHRhY2godGhpcy5lbGVtZW50UmVmLCBvdmVybGF5U2V0dGluZ3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fY29sbGFwc2VkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcblxuICAgICAgICBjb25zdCBvcGVuRXZlbnRBcmdzOiBDYW5jZWxhYmxlRXZlbnRBcmdzID0geyBjYW5jZWw6IGZhbHNlIH07XG4gICAgICAgIHRoaXMub25PcGVuaW5nLmVtaXQob3BlbkV2ZW50QXJncyk7XG4gICAgICAgIGlmIChvcGVuRXZlbnRBcmdzLmNhbmNlbCkge1xuICAgICAgICAgICAgdGhpcy5fY29sbGFwc2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMub3ZlcmxheVNlcnZpY2Uuc2hvdyh0aGlzLl9vdmVybGF5SWQsIG92ZXJsYXlTZXR0aW5ncyk7XG5cbiAgICAgICAgdGhpcy51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLl9vdmVybGF5T3BlbmVkU3ViID0gdGhpcy5vdmVybGF5U2VydmljZS5vbk9wZW5lZC5waXBlKC4uLnRoaXMuX292ZXJsYXlTdWJGaWx0ZXIpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9uT3BlbmVkLmVtaXQoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5fb3ZlcmxheUNsb3NpbmdTdWIgPSB0aGlzLm92ZXJsYXlTZXJ2aWNlXG4gICAgICAgICAgICAub25DbG9zaW5nXG4gICAgICAgICAgICAucGlwZSguLi50aGlzLl9vdmVybGF5U3ViRmlsdGVyKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoZTogT3ZlcmxheUNsb3NpbmdFdmVudEFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBldmVudEFyZ3M6IENhbmNlbGFibGVCcm93c2VyRXZlbnRBcmdzID0geyBjYW5jZWw6IGZhbHNlLCBldmVudDogZS5ldmVudCB9O1xuICAgICAgICAgICAgICAgIHRoaXMub25DbG9zaW5nLmVtaXQoZXZlbnRBcmdzKTtcbiAgICAgICAgICAgICAgICBlLmNhbmNlbCA9IGV2ZW50QXJncy5jYW5jZWw7XG5cbiAgICAgICAgICAgICAgICAvLyAgaW4gY2FzZSBldmVudCBpcyBub3QgY2FuY2VsZWQgdGhpcyB3aWxsIGNsb3NlIHRoZSB0b2dnbGUgYW5kIHdlIG5lZWQgdG8gdW5zdWJzY3JpYmUuXG4gICAgICAgICAgICAgICAgLy8gIE90aGVyd2lzZSBpZiBmb3Igc29tZSByZWFzb24sIGUuZy4gY2xvc2Ugb24gb3V0c2lkZSBjbGljaywgY2xvc2UoKSBnZXRzIGNhbGxlZCBiZWZvcmVcbiAgICAgICAgICAgICAgICAvLyAgb25DbG9zZWQgd2FzIGZpcmVkIHdlIHdpbGwgZW5kIHdpdGggY2FsbGluZyBvbkNsb3NpbmcgbW9yZSB0aGFuIG9uY2VcbiAgICAgICAgICAgICAgICBpZiAoIWUuY2FuY2VsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2xlYXJTdWJzY3JpcHRpb24odGhpcy5fb3ZlcmxheUNsb3NpbmdTdWIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuX292ZXJsYXlDbG9zZWRTdWIgPSB0aGlzLm92ZXJsYXlTZXJ2aWNlLm9uQ2xvc2VkXG4gICAgICAgICAgICAucGlwZSguLi50aGlzLl9vdmVybGF5U3ViRmlsdGVyKVxuICAgICAgICAgICAgLnN1YnNjcmliZSh0aGlzLm92ZXJsYXlDbG9zZWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENsb3NlcyB0aGUgdG9nZ2xlLlxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIHRoaXMubXlUb2dnbGUuY2xvc2UoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgY2xvc2UoKSB7XG4gICAgICAgIC8vICBpZiB0b2dnbGUgaXMgY29sbGFwc2VkIGRvIG5vdGhpbmdcbiAgICAgICAgLy8gIGlmIHRoZXJlIGlzIGNsb3NlIGFuaW1hdGlvbiBkbyBub3RoaW5nLCB0b2dnbGUgd2lsbCBjbG9zZSBhbnl3YXlcbiAgICAgICAgY29uc3QgaW5mbyA9IHRoaXMub3ZlcmxheVNlcnZpY2UuZ2V0T3ZlcmxheUJ5SWQodGhpcy5fb3ZlcmxheUlkKTtcbiAgICAgICAgY29uc3QgaGFzQ2xvc2VBbmltYXRpb24gPSBpbmZvID8gaW5mby5jbG9zZUFuaW1hdGlvblBsYXllciA6IGZhbHNlO1xuICAgICAgICBpZiAodGhpcy5fY29sbGFwc2VkIHx8IGhhc0Nsb3NlQW5pbWF0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm92ZXJsYXlTZXJ2aWNlLmhpZGUodGhpcy5fb3ZlcmxheUlkKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPcGVucyBvciBjbG9zZXMgdGhlIHRvZ2dsZSwgZGVwZW5kaW5nIG9uIGl0cyBjdXJyZW50IHN0YXRlLlxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIHRoaXMubXlUb2dnbGUudG9nZ2xlKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIHRvZ2dsZShvdmVybGF5U2V0dGluZ3M/OiBPdmVybGF5U2V0dGluZ3MpIHtcbiAgICAgICAgLy8gIGlmIHRvZ2dsZSBpcyBjb2xsYXBzZWQgY2FsbCBvcGVuXG4gICAgICAgIC8vICBpZiB0aGVyZSBpcyBjbG9zZSBhbmltYXRpb24gY2FsbCBvcGVuXG4gICAgICAgIGlmICh0aGlzLmNvbGxhcHNlZCB8fCB0aGlzLmlzQ2xvc2luZykge1xuICAgICAgICAgICAgdGhpcy5vcGVuKG92ZXJsYXlTZXR0aW5ncyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbiAgICBwdWJsaWMgZ2V0IGlzQ2xvc2luZygpIHtcbiAgICAgICAgY29uc3QgaW5mbyA9IHRoaXMub3ZlcmxheVNlcnZpY2UuZ2V0T3ZlcmxheUJ5SWQodGhpcy5fb3ZlcmxheUlkKTtcbiAgICAgICAgcmV0dXJuIGluZm8gPyBpbmZvLmNsb3NlQW5pbWF0aW9uUGxheWVyIDogZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVwb3NpdGlvbnMgdGhlIHRvZ2dsZS5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogdGhpcy5teVRvZ2dsZS5yZXBvc2l0aW9uKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIHJlcG9zaXRpb24oKSB7XG4gICAgICAgIHRoaXMub3ZlcmxheVNlcnZpY2UucmVwb3NpdGlvbih0aGlzLl9vdmVybGF5SWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgbmdPbkluaXQoKSB7XG4gICAgICAgIGlmICh0aGlzLm5hdmlnYXRpb25TZXJ2aWNlICYmIHRoaXMuaWQpIHtcbiAgICAgICAgICAgIHRoaXMubmF2aWdhdGlvblNlcnZpY2UuYWRkKHRoaXMuaWQsIHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgaWYgKHRoaXMubmF2aWdhdGlvblNlcnZpY2UgJiYgdGhpcy5pZCkge1xuICAgICAgICAgICAgdGhpcy5uYXZpZ2F0aW9uU2VydmljZS5yZW1vdmUodGhpcy5pZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLmNvbGxhcHNlZCAmJiB0aGlzLl9vdmVybGF5SWQpIHtcbiAgICAgICAgICAgIHRoaXMub3ZlcmxheVNlcnZpY2UuaGlkZSh0aGlzLl9vdmVybGF5SWQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5kZXN0cm95JC5uZXh0KHRydWUpO1xuICAgICAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvdmVybGF5Q2xvc2VkID0gKCkgPT4ge1xuICAgICAgICB0aGlzLl9jb2xsYXBzZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIGRlbGV0ZSB0aGlzLl9vdmVybGF5SWQ7XG4gICAgICAgIHRoaXMudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5vbkNsb3NlZC5lbWl0KCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1bnN1YnNjcmliZSgpIHtcbiAgICAgICAgdGhpcy5jbGVhclN1YnNjcmlwdGlvbih0aGlzLl9vdmVybGF5T3BlbmVkU3ViKTtcbiAgICAgICAgdGhpcy5jbGVhclN1YnNjcmlwdGlvbih0aGlzLl9vdmVybGF5Q2xvc2luZ1N1Yik7XG4gICAgICAgIHRoaXMuY2xlYXJTdWJzY3JpcHRpb24odGhpcy5fb3ZlcmxheUNsb3NlZFN1Yik7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclN1YnNjcmlwdGlvbihzdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbikge1xuICAgICAgICBpZiAoc3Vic2NyaXB0aW9uICYmICFzdWJzY3JpcHRpb24uY2xvc2VkKSB7XG4gICAgICAgICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuQERpcmVjdGl2ZSh7XG4gICAgZXhwb3J0QXM6ICd0b2dnbGUtYWN0aW9uJyxcbiAgICBzZWxlY3RvcjogJ1tpZ3hUb2dnbGVBY3Rpb25dJ1xufSlcbmV4cG9ydCBjbGFzcyBJZ3hUb2dnbGVBY3Rpb25EaXJlY3RpdmUgaW1wbGVtZW50cyBPbkluaXQge1xuICAgIHByb3RlY3RlZCBfb3ZlcmxheURlZmF1bHRzOiBPdmVybGF5U2V0dGluZ3M7XG5cbiAgICAvKipcbiAgICAgKiBQcm92aWRlIHNldHRpbmdzIHRoYXQgY29udHJvbCB0aGUgdG9nZ2xlIG92ZXJsYXkgcG9zaXRpb25pbmcsIGludGVyYWN0aW9uIGFuZCBzY3JvbGwgYmVoYXZpb3IuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IHNldHRpbmdzOiBPdmVybGF5U2V0dGluZ3MgPSB7XG4gICAgICogICAgICBjbG9zZU9uT3V0c2lkZUNsaWNrOiBmYWxzZSxcbiAgICAgKiAgICAgIG1vZGFsOiBmYWxzZVxuICAgICAqICB9XG4gICAgICogYGBgXG4gICAgICogLS0tXG4gICAgICogYGBgaHRtbFxuICAgICAqIDwhLS1zZXQtLT5cbiAgICAgKiA8ZGl2IGlneFRvZ2dsZUFjdGlvbiBbb3ZlcmxheVNldHRpbmdzXT1cInNldHRpbmdzXCI+PC9kaXY+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgb3ZlcmxheVNldHRpbmdzOiBPdmVybGF5U2V0dGluZ3M7XG5cbiAgICBwcml2YXRlIF9jbG9zZU9uT3V0c2lkZUNsaWNrOiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIERFUFJFQ0FURUQuIERldGVybWluZXMgd2hldGhlciB0aGUgdG9nZ2xlIHNob3VsZCBjbG9zZSB3aGVuIHlvdSBjbGljayBvdXRzaWRlLlxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIC8vIGdldFxuICAgICAqIGxldCBjbG9zZXNPbk91dHNpZGVDbGljayA9IHRoaXMudG9nZ2xlLmNsb3NlT25PdXRzaWRlQ2xpY2s7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBARGVwcmVjYXRlUHJvcGVydHkoYGlneFRvZ2dsZUFjdGlvbiAnY2xvc2VPbk91dHNpZGVDbGljaycgaW5wdXQgaXMgZGVwcmVjYXRlZC4gVXNlICdvdmVybGF5U2V0dGluZ3MnIGlucHV0IG9iamVjdCBpbnN0ZWFkLmApXG4gICAgcHVibGljIGdldCBjbG9zZU9uT3V0c2lkZUNsaWNrKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2xvc2VPbk91dHNpZGVDbGljaztcbiAgICB9XG4gICAgLyoqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDwhLS1zZXQtLT5cbiAgICAgKiA8ZGl2IGlneFRvZ2dsZUFjdGlvbiBbY2xvc2VPbk91dHNpZGVDbGlja109XCIndHJ1ZSdcIj48L2Rpdj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0IGNsb3NlT25PdXRzaWRlQ2xpY2sodjogYm9vbGVhbikge1xuICAgICAgICB0aGlzLl9jbG9zZU9uT3V0c2lkZUNsaWNrID0gdjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXRlcm1pbmVzIHdoZXJlIHRoZSB0b2dnbGUgZWxlbWVudCBvdmVybGF5IHNob3VsZCBiZSBhdHRhY2hlZC5cbiAgICAgKlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8IS0tc2V0LS0+XG4gICAgICogPGRpdiBpZ3hUb2dnbGVBY3Rpb24gW2lneFRvZ2dsZU91dGxldF09XCJvdXRsZXRcIj48L2Rpdj5cbiAgICAgKiBgYGBcbiAgICAgKiBXaGVyZSBgb3V0bGV0YCBpbiBhbiBpbnN0YW5jZSBvZiBgSWd4T3ZlcmxheU91dGxldERpcmVjdGl2ZWAgb3IgYW4gYEVsZW1lbnRSZWZgXG4gICAgICovXG4gICAgQElucHV0KCdpZ3hUb2dnbGVPdXRsZXQnKVxuICAgIHB1YmxpYyBvdXRsZXQ6IElneE92ZXJsYXlPdXRsZXREaXJlY3RpdmUgfCBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBJbnB1dCgnaWd4VG9nZ2xlQWN0aW9uJylcbiAgICBzZXQgdGFyZ2V0KHRhcmdldDogYW55KSB7XG4gICAgICAgIGlmICh0YXJnZXQgIT09IG51bGwgJiYgdGFyZ2V0ICE9PSAnJykge1xuICAgICAgICAgICAgdGhpcy5fdGFyZ2V0ID0gdGFyZ2V0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldCB0YXJnZXQoKTogYW55IHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl90YXJnZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5uYXZpZ2F0aW9uU2VydmljZS5nZXQodGhpcy5fdGFyZ2V0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fdGFyZ2V0O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBfdGFyZ2V0OiBJVG9nZ2xlVmlldyB8IHN0cmluZztcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgZWxlbWVudDogRWxlbWVudFJlZiwgQE9wdGlvbmFsKCkgcHJpdmF0ZSBuYXZpZ2F0aW9uU2VydmljZTogSWd4TmF2aWdhdGlvblNlcnZpY2UpIHsgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBuZ09uSW5pdCgpIHtcbiAgICAgICAgdGhpcy5fb3ZlcmxheURlZmF1bHRzID0ge1xuICAgICAgICAgICAgcG9zaXRpb25TdHJhdGVneTogbmV3IENvbm5lY3RlZFBvc2l0aW9uaW5nU3RyYXRlZ3koeyB0YXJnZXQ6IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50IH0pLFxuICAgICAgICAgICAgc2Nyb2xsU3RyYXRlZ3k6IG5ldyBBYnNvbHV0ZVNjcm9sbFN0cmF0ZWd5KCksXG4gICAgICAgICAgICBjbG9zZU9uT3V0c2lkZUNsaWNrOiB0cnVlLFxuICAgICAgICAgICAgbW9kYWw6IGZhbHNlLFxuICAgICAgICAgICAgZXhjbHVkZVBvc2l0aW9uVGFyZ2V0OiB0cnVlXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBIb3N0TGlzdGVuZXIoJ2NsaWNrJylcbiAgICBwdWJsaWMgb25DbGljaygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2Nsb3NlT25PdXRzaWRlQ2xpY2sgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5fb3ZlcmxheURlZmF1bHRzLmNsb3NlT25PdXRzaWRlQ2xpY2sgPSB0aGlzLl9jbG9zZU9uT3V0c2lkZUNsaWNrO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm91dGxldCkge1xuICAgICAgICAgICAgdGhpcy5fb3ZlcmxheURlZmF1bHRzLm91dGxldCA9IHRoaXMub3V0bGV0O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2xvbmVkU2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLl9vdmVybGF5RGVmYXVsdHMsIHRoaXMub3ZlcmxheVNldHRpbmdzKTtcbiAgICAgICAgdGhpcy51cGRhdGVPdmVybGF5U2V0dGluZ3MoY2xvbmVkU2V0dGluZ3MpO1xuICAgICAgICB0aGlzLnRhcmdldC50b2dnbGUoY2xvbmVkU2V0dGluZ3MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZXMgcHJvdmlkZWQgb3ZlcmxheSBzZXR0aW5nc1xuICAgICAqIEBwYXJhbSBzZXR0aW5ncyBzZXR0aW5ncyB0byB1cGRhdGVcbiAgICAgKiBAcmV0dXJucyByZXR1cm5zIHVwZGF0ZWQgY29weSBvZiBwcm92aWRlZCBvdmVybGF5IHNldHRpbmdzXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHVwZGF0ZU92ZXJsYXlTZXR0aW5ncyhzZXR0aW5nczogT3ZlcmxheVNldHRpbmdzKTogT3ZlcmxheVNldHRpbmdzIHtcbiAgICAgICAgaWYgKHNldHRpbmdzICYmIHNldHRpbmdzLnBvc2l0aW9uU3RyYXRlZ3kpIHtcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uU3RyYXRlZ3lDbG9uZTogSVBvc2l0aW9uU3RyYXRlZ3kgPSBzZXR0aW5ncy5wb3NpdGlvblN0cmF0ZWd5LmNsb25lKCk7XG4gICAgICAgICAgICBwb3NpdGlvblN0cmF0ZWd5Q2xvbmUuc2V0dGluZ3MudGFyZ2V0ID0gdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgICBzZXR0aW5ncy5wb3NpdGlvblN0cmF0ZWd5ID0gcG9zaXRpb25TdHJhdGVneUNsb25lO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNldHRpbmdzO1xuICAgIH1cbn1cblxuLyoqXG4gKiBNYXJrIGFuIGVsZW1lbnQgYXMgYW4gaWd4T3ZlcmxheSBvdXRsZXQgY29udGFpbmVyLlxuICogRGlyZWN0aXZlIGluc3RhbmNlIGlzIGV4cG9ydGVkIGFzIGBvdmVybGF5LW91dGxldGAgdG8gYmUgYXNzaWduZWQgdG8gdGVtcGxhdGVzIHZhcmlhYmxlczpcbiAqIGBgYGh0bWxcbiAqIDxkaXYgaWd4T3ZlcmxheU91dGxldCAjb3V0bGV0PVwib3ZlcmxheS1vdXRsZXRcIj48L2Rpdj5cbiAqIGBgYFxuICovXG5ARGlyZWN0aXZlKHtcbiAgICBleHBvcnRBczogJ292ZXJsYXktb3V0bGV0JyxcbiAgICBzZWxlY3RvcjogJ1tpZ3hPdmVybGF5T3V0bGV0XSdcbn0pXG5leHBvcnQgY2xhc3MgSWd4T3ZlcmxheU91dGxldERpcmVjdGl2ZSB7XG4gICAgY29uc3RydWN0b3IocHVibGljIGVsZW1lbnQ6IEVsZW1lbnRSZWYpIHsgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBwdWJsaWMgZ2V0IG5hdGl2ZUVsZW1lbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudDtcbiAgICB9XG59XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5ATmdNb2R1bGUoe1xuICAgIGRlY2xhcmF0aW9uczogW0lneFRvZ2dsZURpcmVjdGl2ZSwgSWd4VG9nZ2xlQWN0aW9uRGlyZWN0aXZlLCBJZ3hPdmVybGF5T3V0bGV0RGlyZWN0aXZlXSxcbiAgICBleHBvcnRzOiBbSWd4VG9nZ2xlRGlyZWN0aXZlLCBJZ3hUb2dnbGVBY3Rpb25EaXJlY3RpdmUsIElneE92ZXJsYXlPdXRsZXREaXJlY3RpdmVdLFxuICAgIHByb3ZpZGVyczogW0lneE5hdmlnYXRpb25TZXJ2aWNlXVxufSlcbmV4cG9ydCBjbGFzcyBJZ3hUb2dnbGVNb2R1bGUgeyB9XG4iXX0=