UNPKG

igniteui-angular

Version:

Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps

683 lines • 48 kB
/** * @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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidG9nZ2xlLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2lnbml0ZXVpLWFuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvZGlyZWN0aXZlcy90b2dnbGUvdG9nZ2xlLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLE9BQU8sRUFDSCxpQkFBaUIsRUFDakIsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osV0FBVyxFQUNYLFlBQVksRUFDWixLQUFLLEVBQ0wsUUFBUSxFQUdSLFFBQVEsRUFDUixNQUFNLEVBQ04sTUFBTSxFQUNULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxvQkFBb0IsRUFBZSxNQUFNLHVCQUF1QixDQUFDO0FBQzFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ25FLE9BQU8sRUFBcUMsNEJBQTRCLEVBQUUsc0JBQXNCLEVBQXFCLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUksT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNuRCxPQUFPLEVBQWdCLE9BQU8sRUFBNEIsTUFBTSxNQUFNLENBQUM7QUFHdkUsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFNbkUsTUFBTSxPQUFPLGtCQUFrQjs7Ozs7Ozs7SUFvSTNCLFlBQ1ksVUFBc0IsRUFDdEIsR0FBc0IsRUFDTyxjQUFpQyxFQUNsRCxpQkFBdUM7UUFIbkQsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0QixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUNPLG1CQUFjLEdBQWQsY0FBYyxDQUFtQjtRQUNsRCxzQkFBaUIsR0FBakIsaUJBQWlCLENBQXNCO1FBdEl2RCxhQUFRLEdBQUcsSUFBSSxPQUFPLEVBQVcsQ0FBQztRQUNsQyxzQkFBaUIsR0FBNkY7WUFDbEgsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUs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VTtZQVlMLG9CQUFvQix1QkF1WWlCLFFBQVE7Ozs4QkE3RGpELEtBQUs7a0NBWUwsS0FBSztxQkF3QkwsS0FBSyxTQUFDLGlCQUFpQjtxQkFNdkIsS0FBSyxTQUFDLGlCQUFpQjtzQkFxQ3ZCLFlBQVksU0FBQyxPQUFPOztBQWpFckI7SUFEQyxpQkFBaUIsQ0FBQyx3R0FBd0csQ0FBQzs7O21FQUczSDs7Ozs7O0lBaENELG9EQUE0Qzs7Ozs7Ozs7Ozs7Ozs7OztJQWdCNUMsbURBQ3dDOzs7OztJQUV4Qyx3REFBc0M7Ozs7Ozs7Ozs7O0lBaUN0QywwQ0FDc0Q7Ozs7O0lBc0J0RCwyQ0FBd0M7Ozs7O0lBRTVCLDJDQUEyQjs7Ozs7SUFBRSxxREFBMkQ7Ozs7Ozs7OztBQTJEeEcsTUFBTSxPQUFPLHlCQUF5Qjs7OztJQUNsQyxZQUFtQixPQUFtQjtRQUFuQixZQUFPLEdBQVAsT0FBTyxDQUFZO0lBQUksQ0FBQzs7Ozs7SUFHM0MsSUFBVyxhQUFhO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUM7SUFDdEMsQ0FBQzs7O1lBVkosU0FBUyxTQUFDO2dCQUNQLFFBQVEsRUFBRSxnQkFBZ0I7Z0JBQzFCLFFBQVEsRUFBRSxvQkFBb0I7YUFDakM7Ozs7WUE3Y0csVUFBVTs7OztJQStjRSw0Q0FBMEI7Ozs7O0FBZ0IxQyxNQUFNLE9BQU8sZUFBZTs7O1lBTDNCLFFBQVEsU0FBQztnQkFDTixZQUFZLEVBQUUsQ0FBQyxrQkFBa0IsRUFBRSx3QkFBd0IsRUFBRSx5QkFBeUIsQ0FBQztnQkFDdkYsT0FBTyxFQUFFLENBQUMsa0JBQWtCLEVBQUUsd0JBQXdCLEVBQUUseUJBQXlCLENBQUM7Z0JBQ2xGLFNBQVMsRUFBRSxDQUFDLG9CQUFvQixDQUFDO2FBQ3BDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBEaXJlY3RpdmUsXG4gICAgRWxlbWVudFJlZixcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgSG9zdEJpbmRpbmcsXG4gICAgSG9zdExpc3RlbmVyLFxuICAgIElucHV0LFxuICAgIE5nTW9kdWxlLFxuICAgIE9uRGVzdHJveSxcbiAgICBPbkluaXQsXG4gICAgT3B0aW9uYWwsXG4gICAgT3V0cHV0LFxuICAgIEluamVjdFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IElneE5hdmlnYXRpb25TZXJ2aWNlLCBJVG9nZ2xlVmlldyB9IGZyb20gJy4uLy4uL2NvcmUvbmF2aWdhdGlvbic7XG5pbXBvcnQgeyBJZ3hPdmVybGF5U2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL292ZXJsYXkvb3ZlcmxheSc7XG5pbXBvcnQgeyBPdmVybGF5U2V0dGluZ3MsIE92ZXJsYXlFdmVudEFyZ3MsIENvbm5lY3RlZFBvc2l0aW9uaW5nU3RyYXRlZ3ksIEFic29sdXRlU2Nyb2xsU3RyYXRlZ3ksIElQb3NpdGlvblN0cmF0ZWd5IH0gZnJvbSAnLi4vLi4vc2VydmljZXMnO1xuaW1wb3J0IHsgZmlsdGVyLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24sIFN1YmplY3QsIE1vbm9UeXBlT3BlcmF0b3JGdW5jdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgT3ZlcmxheUNsb3NpbmdFdmVudEFyZ3MgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9vdmVybGF5L3V0aWxpdGllcyc7XG5pbXBvcnQgeyBDYW5jZWxhYmxlRXZlbnRBcmdzLCBDYW5jZWxhYmxlQnJvd3NlckV2ZW50QXJncyB9IGZyb20gJy4uLy4uL2NvcmUvdXRpbHMnO1xuaW1wb3J0IHsgRGVwcmVjYXRlUHJvcGVydHkgfSBmcm9tICcuLi8uLi9jb3JlL2RlcHJlY2F0ZURlY29yYXRvcnMnO1xuXG5ARGlyZWN0aXZlKHtcbiAgICBleHBvcnRBczogJ3RvZ2dsZScsXG4gICAgc2VsZWN0b3I6ICdbaWd4VG9nZ2xlXSdcbn0pXG5leHBvcnQgY2xhc3MgSWd4VG9nZ2xlRGlyZWN0aXZlIGltcGxlbWVudHMgSVRvZ2dsZVZpZXcsIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgICBwcm90ZWN0ZWQgX292ZXJsYXlJZDogc3RyaW5nO1xuICAgIHByaXZhdGUgZGVzdHJveSQgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuICAgIHByaXZhdGUgX292ZXJsYXlTdWJGaWx0ZXI6IFtNb25vVHlwZU9wZXJhdG9yRnVuY3Rpb248T3ZlcmxheUV2ZW50QXJncz4sIE1vbm9UeXBlT3BlcmF0b3JGdW5jdGlvbjxPdmVybGF5RXZlbnRBcmdzPl0gPSBbXG4gICAgICAgIGZpbHRlcih4ID0+IHguaWQgPT09IHRoaXMuX292ZXJsYXlJZCksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKVxuICAgIF07XG4gICAgcHJpdmF0ZSBfb3ZlcmxheU9wZW5lZFN1YjogU3Vic2NyaXB0aW9uO1xuICAgIHByaXZhdGUgX292ZXJsYXlDbG9zaW5nU3ViOiBTdWJzY3JpcHRpb247XG4gICAgcHJpdmF0ZSBfb3ZlcmxheUNsb3NlZFN1YjogU3Vic2NyaXB0aW9uO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHMgYW4gZXZlbnQgYWZ0ZXIgdGhlIHRvZ2dsZSBjb250YWluZXIgaXMgb3BlbmVkLlxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIG9uVG9nZ2xlT3BlbmVkKGV2ZW50KSB7XG4gICAgICogICAgYWxlcnQoXCJUb2dnbGUgb3BlbmVkIVwiKTtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPGRpdlxuICAgICAqICAgaWd4VG9nZ2xlXG4gICAgICogICAob25PcGVuZWQpPSdvblRvZ2dsZU9wZW5lZCgkZXZlbnQpJz5cbiAgICAgKiA8L2Rpdj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25PcGVuZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0cyBhbiBldmVudCBiZWZvcmUgdGhlIHRvZ2dsZSBjb250YWluZXIgaXMgb3BlbmVkLlxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIG9uVG9nZ2xlT3BlbmluZyhldmVudCkge1xuICAgICAqICBhbGVydChcIlRvZ2dsZSBvcGVuaW5nIVwiKTtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPGRpdlxuICAgICAqICAgaWd4VG9nZ2xlXG4gICAgICogICAob25PcGVuaW5nKT0nb25Ub2dnbGVPcGVuaW5nKCRldmVudCknPlxuICAgICAqIDwvZGl2PlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyBvbk9wZW5pbmcgPSBuZXcgRXZlbnRFbWl0dGVyPENhbmNlbGFibGVFdmVudEFyZ3M+KCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0cyBhbiBldmVudCBhZnRlciB0aGUgdG9nZ2xlIGNvbnRhaW5lciBpcyBjbG9zZWQuXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogb25Ub2dnbGVDbG9zZWQoZXZlbnQpIHtcbiAgICAgKiAgYWxlcnQoXCJUb2dnbGUgY2xvc2VkIVwiKTtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPGRpdlxuICAgICAqICAgaWd4VG9nZ2xlXG4gICAgICogICAob25DbG9zZWQpPSdvblRvZ2dsZUNsb3NlZCgkZXZlbnQpJz5cbiAgICAgKiA8L2Rpdj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25DbG9zZWQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0cyBhbiBldmVudCBiZWZvcmUgdGhlIHRvZ2dsZSBjb250YWluZXIgaXMgY2xvc2VkLlxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIG9uVG9nZ2xlQ2xvc2luZyhldmVudCkge1xuICAgICAqICBhbGVydChcIlRvZ2dsZSBjbG9zaW5nIVwiKTtcbiAgICAgKiB9XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPGRpdlxuICAgICAqICBpZ3hUb2dnbGVcbiAgICAgKiAgKG9uQ2xvc2luZyk9J29uVG9nZ2xlQ2xvc2luZygkZXZlbnQpJz5cbiAgICAgKiA8L2Rpdj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25DbG9zaW5nID0gbmV3IEV2ZW50RW1pdHRlcjxDYW5jZWxhYmxlQnJvd3NlckV2ZW50QXJncz4oKTtcblxuICAgIHByaXZhdGUgX2NvbGxhcHNlZCA9IHRydWU7XG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBnZXQgY29sbGFwc2VkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fY29sbGFwc2VkO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIElkZW50aWZpZXIgd2hpY2ggaXMgcmVnaXN0ZXJlZCBpbnRvIGBJZ3hOYXZpZ2F0aW9uU2VydmljZWBcbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgbXlUb2dnbGVJZCA9IHRoaXMudG9nZ2xlLmlkO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGlkOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgcHVibGljIGdldCBlbGVtZW50KCkge1xuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MuaWd4LXRvZ2dsZS0taGlkZGVuJylcbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuYXJpYS1oaWRkZW4nKVxuICAgIHB1YmxpYyBnZXQgaGlkZGVuQ2xhc3MoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmNvbGxhcHNlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5pZ3gtdG9nZ2xlJylcbiAgICBwdWJsaWMgZ2V0IGRlZmF1bHRDbGFzcygpIHtcbiAgICAgICAgcmV0dXJuICF0aGlzLmNvbGxhcHNlZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAaGlkZGVuXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICAgICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgICAgICBASW5qZWN0KElneE92ZXJsYXlTZXJ2aWNlKSBwcm90ZWN0ZWQgb3ZlcmxheVNlcnZpY2U6IElneE92ZXJsYXlTZXJ2aWNlLFxuICAgICAgICBAT3B0aW9uYWwoKSBwcml2YXRlIG5hdmlnYXRpb25TZXJ2aWNlOiBJZ3hOYXZpZ2F0aW9uU2VydmljZSkge1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9wZW5zIHRoZSB0b2dnbGUuXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogdGhpcy5teVRvZ2dsZS5vcGVuKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIG9wZW4ob3ZlcmxheVNldHRpbmdzPzogT3ZlcmxheVNldHRpbmdzKSB7XG4gICAgICAgIC8vICBpZiB0aGVyZSBpcyBvcGVuIGFuaW1hdGlvbiBkbyBub3RoaW5nXG4gICAgICAgIC8vICBpZiB0b2dnbGUgaXMgbm90IGNvbGxhcHNlZCBhbmQgdGhlcmUgaXMgbm8gY2xvc2UgYW5pbWF0aW9uIGRvIG5vdGhpbmdcbiAgICAgICAgY29uc3QgaW5mbyA9IHRoaXMub3ZlcmxheVNlcnZpY2UuZ2V0T3ZlcmxheUJ5SWQodGhpcy5fb3ZlcmxheUlkKTtcbiAgICAgICAgY29uc3QgaGFzT3BlbkFuaW1hdGlvbiA9IGluZm8gPyBpbmZvLm9wZW5BbmltYXRpb25QbGF5ZXIgOiBmYWxzZTtcbiAgICAgICAgY29uc3QgaGFzQ2xvc2VBbmltYXRpb24gPSBpbmZvID8gaW5mby5jbG9zZUFuaW1hdGlvblBsYXllciA6IGZhbHNlO1xuICAgICAgICBpZiAoaGFzT3BlbkFuaW1hdGlvbiB8fCAhKHRoaXMuX2NvbGxhcHNlZCB8fCBoYXNDbG9zZUFuaW1hdGlvbikpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghaW5mbykge1xuICAgICAgICAgICAgdGhpcy5fb3ZlcmxheUlkID0gdGhpcy5vdmVybGF5U2VydmljZS5hdHRhY2godGhpcy5lbGVtZW50UmVmLCBvdmVybGF5U2V0dGluZ3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5fY29sbGFwc2VkID0gZmFsc2U7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcblxuICAgICAgICBjb25zdCBvcGVuRXZlbnRBcmdzOiBDYW5jZWxhYmxlRXZlbnRBcmdzID0geyBjYW5jZWw6IGZhbHNlIH07XG4gICAgICAgIHRoaXMub25PcGVuaW5nLmVtaXQob3BlbkV2ZW50QXJncyk7XG4gICAgICAgIGlmIChvcGVuRXZlbnRBcmdzLmNhbmNlbCkge1xuICAgICAgICAgICAgdGhpcy5fY29sbGFwc2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMub3ZlcmxheVNlcnZpY2Uuc2hvdyh0aGlzLl9vdmVybGF5SWQsIG92ZXJsYXlTZXR0aW5ncyk7XG5cbiAgICAgICAgdGhpcy51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLl9vdmVybGF5T3BlbmVkU3ViID0gdGhpcy5vdmVybGF5U2VydmljZS5vbk9wZW5lZC5waXBlKC4uLnRoaXMuX292ZXJsYXlTdWJGaWx0ZXIpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLm9uT3BlbmVkLmVtaXQoKTtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgdGhpcy5fb3ZlcmxheUNsb3NpbmdTdWIgPSB0aGlzLm92ZXJsYXlTZXJ2aWNlXG4gICAgICAgICAgICAub25DbG9zaW5nXG4gICAgICAgICAgICAucGlwZSguLi50aGlzLl9vdmVybGF5U3ViRmlsdGVyKVxuICAgICAgICAgICAgLnN1YnNjcmliZSgoZTogT3ZlcmxheUNsb3NpbmdFdmVudEFyZ3MpID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBldmVudEFyZ3M6IENhbmNlbGFibGVCcm93c2VyRXZlbnRBcmdzID0geyBjYW5jZWw6IGZhbHNlLCBldmVudDogZS5ldmVudCB9O1xuICAgICAgICAgICAgICAgIHRoaXMub25DbG9zaW5nLmVtaXQoZXZlbnRBcmdzKTtcbiAgICAgICAgICAgICAgICBlLmNhbmNlbCA9IGV2ZW50QXJncy5jYW5jZWw7XG5cbiAgICAgICAgICAgICAgICAvLyAgaW4gY2FzZSBldmVudCBpcyBub3QgY2FuY2VsZWQgdGhpcyB3aWxsIGNsb3NlIHRoZSB0b2dnbGUgYW5kIHdlIG5lZWQgdG8gdW5zdWJzY3JpYmUuXG4gICAgICAgICAgICAgICAgLy8gIE90aGVyd2lzZSBpZiBmb3Igc29tZSByZWFzb24sIGUuZy4gY2xvc2Ugb24gb3V0c2lkZSBjbGljaywgY2xvc2UoKSBnZXRzIGNhbGxlZCBiZWZvcmVcbiAgICAgICAgICAgICAgICAvLyAgb25DbG9zZWQgd2FzIGZpcmVkIHdlIHdpbGwgZW5kIHdpdGggY2FsbGluZyBvbkNsb3NpbmcgbW9yZSB0aGFuIG9uY2VcbiAgICAgICAgICAgICAgICBpZiAoIWUuY2FuY2VsKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY2xlYXJTdWJzY3JpcHRpb24odGhpcy5fb3ZlcmxheUNsb3NpbmdTdWIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuX292ZXJsYXlDbG9zZWRTdWIgPSB0aGlzLm92ZXJsYXlTZXJ2aWNlLm9uQ2xvc2VkXG4gICAgICAgICAgICAucGlwZSguLi50aGlzLl9vdmVybGF5U3ViRmlsdGVyKVxuICAgICAgICAgICAgLnN1YnNjcmliZSh0aGlzLm92ZXJsYXlDbG9zZWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENsb3NlcyB0aGUgdG9nZ2xlLlxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIHRoaXMubXlUb2dnbGUuY2xvc2UoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgY2xvc2UoKSB7XG4gICAgICAgIC8vICBpZiB0b2dnbGUgaXMgY29sbGFwc2VkIGRvIG5vdGhpbmdcbiAgICAgICAgLy8gIGlmIHRoZXJlIGlzIGNsb3NlIGFuaW1hdGlvbiBkbyBub3RoaW5nLCB0b2dnbGUgd2lsbCBjbG9zZSBhbnl3YXlcbiAgICAgICAgY29uc3QgaW5mbyA9IHRoaXMub3ZlcmxheVNlcnZpY2UuZ2V0T3ZlcmxheUJ5SWQodGhpcy5fb3ZlcmxheUlkKTtcbiAgICAgICAgY29uc3QgaGFzQ2xvc2VBbmltYXRpb24gPSBpbmZvID8gaW5mby5jbG9zZUFuaW1hdGlvblBsYXllciA6IGZhbHNlO1xuICAgICAgICBpZiAodGhpcy5fY29sbGFwc2VkIHx8IGhhc0Nsb3NlQW5pbWF0aW9uKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm92ZXJsYXlTZXJ2aWNlLmhpZGUodGhpcy5fb3ZlcmxheUlkKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPcGVucyBvciBjbG9zZXMgdGhlIHRvZ2dsZSwgZGVwZW5kaW5nIG9uIGl0cyBjdXJyZW50IHN0YXRlLlxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIHRoaXMubXlUb2dnbGUudG9nZ2xlKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIHRvZ2dsZShvdmVybGF5U2V0dGluZ3M/OiBPdmVybGF5U2V0dGluZ3MpIHtcbiAgICAgICAgLy8gIGlmIHRvZ2dsZSBpcyBjb2xsYXBzZWQgY2FsbCBvcGVuXG4gICAgICAgIC8vICBpZiB0aGVyZSBpcyBjbG9zZSBhbmltYXRpb24gY2FsbCBvcGVuXG4gICAgICAgIGlmICh0aGlzLmNvbGxhcHNlZCB8fCB0aGlzLmlzQ2xvc2luZykge1xuICAgICAgICAgICAgdGhpcy5vcGVuKG92ZXJsYXlTZXR0aW5ncyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbiAgICBwdWJsaWMgZ2V0IGlzQ2xvc2luZygpIHtcbiAgICAgICAgY29uc3QgaW5mbyA9IHRoaXMub3ZlcmxheVNlcnZpY2UuZ2V0T3ZlcmxheUJ5SWQodGhpcy5fb3ZlcmxheUlkKTtcbiAgICAgICAgcmV0dXJuIGluZm8gPyBpbmZvLmNsb3NlQW5pbWF0aW9uUGxheWVyIDogZmFsc2U7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmVwb3NpdGlvbnMgdGhlIHRvZ2dsZS5cbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogdGhpcy5teVRvZ2dsZS5yZXBvc2l0aW9uKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIHJlcG9zaXRpb24oKSB7XG4gICAgICAgIHRoaXMub3ZlcmxheVNlcnZpY2UucmVwb3NpdGlvbih0aGlzLl9vdmVybGF5SWQpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKi9cbiAgICBwdWJsaWMgbmdPbkluaXQoKSB7XG4gICAgICAgIGlmICh0aGlzLm5hdmlnYXRpb25TZXJ2aWNlICYmIHRoaXMuaWQpIHtcbiAgICAgICAgICAgIHRoaXMubmF2aWdhdGlvblNlcnZpY2UuYWRkKHRoaXMuaWQsIHRoaXMpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgaWYgKHRoaXMubmF2aWdhdGlvblNlcnZpY2UgJiYgdGhpcy5pZCkge1xuICAgICAgICAgICAgdGhpcy5uYXZpZ2F0aW9uU2VydmljZS5yZW1vdmUodGhpcy5pZCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLmNvbGxhcHNlZCAmJiB0aGlzLl9vdmVybGF5SWQpIHtcbiAgICAgICAgICAgIHRoaXMub3ZlcmxheVNlcnZpY2UuaGlkZSh0aGlzLl9vdmVybGF5SWQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5kZXN0cm95JC5uZXh0KHRydWUpO1xuICAgICAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBvdmVybGF5Q2xvc2VkID0gKCkgPT4ge1xuICAgICAgICB0aGlzLl9jb2xsYXBzZWQgPSB0cnVlO1xuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIGRlbGV0ZSB0aGlzLl9vdmVybGF5SWQ7XG4gICAgICAgIHRoaXMudW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5vbkNsb3NlZC5lbWl0KCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1bnN1YnNjcmliZSgpIHtcbiAgICAgICAgdGhpcy5jbGVhclN1YnNjcmlwdGlvbih0aGlzLl9vdmVybGF5T3BlbmVkU3ViKTtcbiAgICAgICAgdGhpcy5jbGVhclN1YnNjcmlwdGlvbih0aGlzLl9vdmVybGF5Q2xvc2luZ1N1Yik7XG4gICAgICAgIHRoaXMuY2xlYXJTdWJzY3JpcHRpb24odGhpcy5fb3ZlcmxheUNsb3NlZFN1Yik7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjbGVhclN1YnNjcmlwdGlvbihzdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbikge1xuICAgICAgICBpZiAoc3Vic2NyaXB0aW9uICYmICFzdWJzY3JpcHRpb24uY2xvc2VkKSB7XG4gICAgICAgICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuQERpcmVjdGl2ZSh7XG4gICAgZXhwb3J0QXM6ICd0b2dnbGUtYWN0aW9uJyxcbiAgICBzZWxlY3RvcjogJ1tpZ3hUb2dnbGVBY3Rpb25dJ1xufSlcbmV4cG9ydCBjbGFzcyBJZ3hUb2dnbGVBY3Rpb25EaXJlY3RpdmUgaW1wbGVtZW50cyBPbkluaXQge1xuICAgIHByb3RlY3RlZCBfb3ZlcmxheURlZmF1bHRzOiBPdmVybGF5U2V0dGluZ3M7XG5cbiAgICAvKipcbiAgICAgKiBQcm92aWRlIHNldHRpbmdzIHRoYXQgY29udHJvbCB0aGUgdG9nZ2xlIG92ZXJsYXkgcG9zaXRpb25pbmcsIGludGVyYWN0aW9uIGFuZCBzY3JvbGwgYmVoYXZpb3IuXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIGNvbnN0IHNldHRpbmdzOiBPdmVybGF5U2V0dGluZ3MgPSB7XG4gICAgICogICAgICBjbG9zZU9uT3V0c2lkZUNsaWNrOiBmYWxzZSxcbiAgICAgKiAgICAgIG1vZGFsOiBmYWxzZVxuICAgICAqICB9XG4gICAgICogYGBgXG4gICAgICogLS0tXG4gICAgICogYGBgaHRtbFxuICAgICAqIDwhLS1zZXQtLT5cbiAgICAgKiA8ZGl2IGlneFRvZ2dsZUFjdGlvbiBbb3ZlcmxheVNldHRpbmdzXT1cInNldHRpbmdzXCI+PC9kaXY+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgb3ZlcmxheVNldHRpbmdzOiBPdmVybGF5U2V0dGluZ3M7XG5cbiAgICBwcml2YXRlIF9jbG9zZU9uT3V0c2lkZUNsaWNrOiBib29sZWFuO1xuICAgIC8qKlxuICAgICAqIERFUFJFQ0FURUQuIERldGVybWluZXMgd2hldGhlciB0aGUgdG9nZ2xlIHNob3VsZCBjbG9zZSB3aGVuIHlvdSBjbGljayBvdXRzaWRlLlxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIC8vIGdldFxuICAgICAqIGxldCBjbG9zZXNPbk91dHNpZGVDbGljayA9IHRoaXMudG9nZ2xlLmNsb3NlT25PdXRzaWRlQ2xpY2s7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBARGVwcmVjYXRlUHJvcGVydHkoYGlneFRvZ2dsZUFjdGlvbiAnY2xvc2VPbk91dHNpZGVDbGljaycgaW5wdXQgaXMgZGVwcmVjYXRlZC4gVXNlICdvdmVybGF5U2V0dGluZ3MnIGlucHV0IG9iamVjdCBpbnN0ZWFkLmApXG4gICAgcHVibGljIGdldCBjbG9zZU9uT3V0c2lkZUNsaWNrKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5fY2xvc2VPbk91dHNpZGVDbGljaztcbiAgICB9XG4gICAgLyoqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDwhLS1zZXQtLT5cbiAgICAgKiA8ZGl2IGlneFRvZ2dsZUFjdGlvbiBbY2xvc2VPbk91dHNpZGVDbGlja109XCIndHJ1ZSdcIj48L2Rpdj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgc2V0IGNsb3NlT25PdXRzaWRlQ2xpY2sodjogYm9vbGVhbikge1xuICAgICAgICB0aGlzLl9jbG9zZU9uT3V0c2lkZUNsaWNrID0gdjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXRlcm1pbmVzIHdoZXJlIHRoZSB0b2dnbGUgZWxlbWVudCBvdmVybGF5IHNob3VsZCBiZSBhdHRhY2hlZC5cbiAgICAgKlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8IS0tc2V0LS0+XG4gICAgICogPGRpdiBpZ3hUb2dnbGVBY3Rpb24gW2lneFRvZ2dsZU91dGxldF09XCJvdXRsZXRcIj48L2Rpdj5cbiAgICAgKiBgYGBcbiAgICAgKiBXaGVyZSBgb3V0bGV0YCBpbiBhbiBpbnN0YW5jZSBvZiBgSWd4T3ZlcmxheU91dGxldERpcmVjdGl2ZWAgb3IgYW4gYEVsZW1lbnRSZWZgXG4gICAgICovXG4gICAgQElucHV0KCdpZ3hUb2dnbGVPdXRsZXQnKVxuICAgIHB1YmxpYyBvdXRsZXQ6IElneE92ZXJsYXlPdXRsZXREaXJlY3RpdmUgfCBFbGVtZW50UmVmO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBJbnB1dCgnaWd4VG9nZ2xlQWN0aW9uJylcbiAgICBzZXQgdGFyZ2V0KHRhcmdldDogYW55KSB7XG4gICAgICAgIGlmICh0YXJnZXQgIT09IG51bGwgJiYgdGFyZ2V0ICE9PSAnJykge1xuICAgICAgICAgICAgdGhpcy5fdGFyZ2V0ID0gdGFyZ2V0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIGdldCB0YXJnZXQoKTogYW55IHtcbiAgICAgICAgaWYgKHR5cGVvZiB0aGlzLl90YXJnZXQgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5uYXZpZ2F0aW9uU2VydmljZS5nZXQodGhpcy5fdGFyZ2V0KTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhpcy5fdGFyZ2V0O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBfdGFyZ2V0OiBJVG9nZ2xlVmlldyB8IHN0cmluZztcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgZWxlbWVudDogRWxlbWVudFJlZiwgQE9wdGlvbmFsKCkgcHJpdmF0ZSBuYXZpZ2F0aW9uU2VydmljZTogSWd4TmF2aWdhdGlvblNlcnZpY2UpIHsgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIHB1YmxpYyBuZ09uSW5pdCgpIHtcbiAgICAgICAgdGhpcy5fb3ZlcmxheURlZmF1bHRzID0ge1xuICAgICAgICAgICAgcG9zaXRpb25TdHJhdGVneTogbmV3IENvbm5lY3RlZFBvc2l0aW9uaW5nU3RyYXRlZ3koeyB0YXJnZXQ6IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50IH0pLFxuICAgICAgICAgICAgc2Nyb2xsU3RyYXRlZ3k6IG5ldyBBYnNvbHV0ZVNjcm9sbFN0cmF0ZWd5KCksXG4gICAgICAgICAgICBjbG9zZU9uT3V0c2lkZUNsaWNrOiB0cnVlLFxuICAgICAgICAgICAgbW9kYWw6IGZhbHNlLFxuICAgICAgICAgICAgZXhjbHVkZVBvc2l0aW9uVGFyZ2V0OiB0cnVlXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqL1xuICAgIEBIb3N0TGlzdGVuZXIoJ2NsaWNrJylcbiAgICBwdWJsaWMgb25DbGljaygpIHtcbiAgICAgICAgaWYgKHRoaXMuX2Nsb3NlT25PdXRzaWRlQ2xpY2sgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5fb3ZlcmxheURlZmF1bHRzLmNsb3NlT25PdXRzaWRlQ2xpY2sgPSB0aGlzLl9jbG9zZU9uT3V0c2lkZUNsaWNrO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLm91dGxldCkge1xuICAgICAgICAgICAgdGhpcy5fb3ZlcmxheURlZmF1bHRzLm91dGxldCA9IHRoaXMub3V0bGV0O1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgY2xvbmVkU2V0dGluZ3MgPSBPYmplY3QuYXNzaWduKHt9LCB0aGlzLl9vdmVybGF5RGVmYXVsdHMsIHRoaXMub3ZlcmxheVNldHRpbmdzKTtcbiAgICAgICAgdGhpcy51cGRhdGVPdmVybGF5U2V0dGluZ3MoY2xvbmVkU2V0dGluZ3MpO1xuICAgICAgICB0aGlzLnRhcmdldC50b2dnbGUoY2xvbmVkU2V0dGluZ3MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFVwZGF0ZXMgcHJvdmlkZWQgb3ZlcmxheSBzZXR0aW5nc1xuICAgICAqIEBwYXJhbSBzZXR0aW5ncyBzZXR0aW5ncyB0byB1cGRhdGVcbiAgICAgKiBAcmV0dXJucyByZXR1cm5zIHVwZGF0ZWQgY29weSBvZiBwcm92aWRlZCBvdmVybGF5IHNldHRpbmdzXG4gICAgICovXG4gICAgcHJvdGVjdGVkIHVwZGF0ZU92ZXJsYXlTZXR0aW5ncyhzZXR0aW5nczogT3ZlcmxheVNldHRpbmdzKTogT3ZlcmxheVNldHRpbmdzIHtcbiAgICAgICAgaWYgKHNldHRpbmdzICYmIHNldHRpbmdzLnBvc2l0aW9uU3RyYXRlZ3kpIHtcbiAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uU3RyYXRlZ3lDbG9uZTogSVBvc2l0aW9uU3RyYXRlZ3kgPSBzZXR0aW5ncy5wb3NpdGlvblN0cmF0ZWd5LmNsb25lKCk7XG4gICAgICAgICAgICBwb3NpdGlvblN0cmF0ZWd5Q2xvbmUuc2V0dGluZ3MudGFyZ2V0ID0gdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgICAgICAgICBzZXR0aW5ncy5wb3NpdGlvblN0cmF0ZWd5ID0gcG9zaXRpb25TdHJhdGVneUNsb25lO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNldHRpbmdzO1xuICAgIH1cbn1cblxuLyoqXG4gKiBNYXJrIGFuIGVsZW1lbnQgYXMgYW4gaWd4T3ZlcmxheSBvdXRsZXQgY29udGFpbmVyLlxuICogRGlyZWN0aXZlIGluc3RhbmNlIGlzIGV4cG9ydGVkIGFzIGBvdmVybGF5LW91dGxldGAgdG8gYmUgYXNzaWduZWQgdG8gdGVtcGxhdGVzIHZhcmlhYmxlczpcbiAqIGBgYGh0bWxcbiAqIDxkaXYgaWd4T3ZlcmxheU91dGxldCAjb3V0bGV0PVwib3ZlcmxheS1vdXRsZXRcIj48L2Rpdj5cbiAqIGBgYFxuICovXG5ARGlyZWN0aXZlKHtcbiAgICBleHBvcnRBczogJ292ZXJsYXktb3V0bGV0JyxcbiAgICBzZWxlY3RvcjogJ1tpZ3hPdmVybGF5T3V0bGV0XSdcbn0pXG5leHBvcnQgY2xhc3MgSWd4T3ZlcmxheU91dGxldERpcmVjdGl2ZSB7XG4gICAgY29uc3RydWN0b3IocHVibGljIGVsZW1lbnQ6IEVsZW1lbnRSZWYpIHsgfVxuXG4gICAgLyoqIEBoaWRkZW4gKi9cbiAgICBwdWJsaWMgZ2V0IG5hdGl2ZUVsZW1lbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudDtcbiAgICB9XG59XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5ATmdNb2R1bGUoe1xuICAgIGRlY2xhcmF0aW9uczogW0lneFRvZ2dsZURpcmVjdGl2ZSwgSWd4VG9nZ2xlQWN0aW9uRGlyZWN0aXZlLCBJZ3hPdmVybGF5T3V0bGV0RGlyZWN0aXZlXSxcbiAgICBleHBvcnRzOiBbSWd4VG9nZ2xlRGlyZWN0aXZlLCBJZ3hUb2dnbGVBY3Rpb25EaXJlY3RpdmUsIElneE92ZXJsYXlPdXRsZXREaXJlY3RpdmVdLFxuICAgIHByb3ZpZGVyczogW0lneE5hdmlnYXRpb25TZXJ2aWNlXVxufSlcbmV4cG9ydCBjbGFzcyBJZ3hUb2dnbGVNb2R1bGUgeyB9XG4iXX0=