UNPKG

ngx-bootstrap

Version:
448 lines 37.9 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ // tslint:disable:max-file-line-count import { Directive, ElementRef, EventEmitter, Input, Output, Renderer2, ViewContainerRef } from '@angular/core'; import { filter } from 'rxjs/operators'; import { ComponentLoaderFactory } from 'ngx-bootstrap/component-loader'; import { BsDropdownConfig } from './bs-dropdown.config'; import { BsDropdownContainerComponent } from './bs-dropdown-container.component'; import { BsDropdownState } from './bs-dropdown.state'; import { isBs3 } from 'ngx-bootstrap/utils'; export class BsDropdownDirective { /** * @param {?} _elementRef * @param {?} _renderer * @param {?} _viewContainerRef * @param {?} _cis * @param {?} _config * @param {?} _state */ constructor(_elementRef, _renderer, _viewContainerRef, _cis, _config, _state) { this._elementRef = _elementRef; this._renderer = _renderer; this._viewContainerRef = _viewContainerRef; this._cis = _cis; this._config = _config; this._state = _state; // todo: move to component loader this._isInlineOpen = false; this._subscriptions = []; this._isInited = false; // set initial dropdown state from config this._state.autoClose = this._config.autoClose; this._state.insideClick = this._config.insideClick; // create dropdown component loader this._dropdown = this._cis .createLoader(this._elementRef, this._viewContainerRef, this._renderer) .provide({ provide: BsDropdownState, useValue: this._state }); this.onShown = this._dropdown.onShown; this.onHidden = this._dropdown.onHidden; this.isOpenChange = this._state.isOpenChange; } /** * Indicates that dropdown will be closed on item or document click, * and after pressing ESC * @param {?} value * @return {?} */ set autoClose(value) { this._state.autoClose = value; } /** * @return {?} */ get autoClose() { return this._state.autoClose; } /** * This attribute indicates that the dropdown shouldn't close on inside click when autoClose is set to true * @param {?} value * @return {?} */ set insideClick(value) { this._state.insideClick = value; } /** * @return {?} */ get insideClick() { return this._state.insideClick; } /** * Disables dropdown toggle and hides dropdown menu if opened * @param {?} value * @return {?} */ set isDisabled(value) { this._isDisabled = value; this._state.isDisabledChange.emit(value); if (value) { this.hide(); } } /** * @return {?} */ get isDisabled() { return this._isDisabled; } /** * Returns whether or not the popover is currently being shown * @return {?} */ get isOpen() { if (this._showInline) { return this._isInlineOpen; } return this._dropdown.isShown; } /** * @param {?} value * @return {?} */ set isOpen(value) { if (value) { this.show(); } else { this.hide(); } } /** * @return {?} */ get isBs4() { return !isBs3(); } /** * @private * @return {?} */ get _showInline() { return !this.container; } /** * @return {?} */ ngOnInit() { // fix: seems there are an issue with `routerLinkActive` // which result in duplicated call ngOnInit without call to ngOnDestroy // read more: https://github.com/valor-software/ngx-bootstrap/issues/1885 if (this._isInited) { return; } this._isInited = true; // attach DOM listeners this._dropdown.listen({ // because of dropdown inline mode outsideClick: false, triggers: this.triggers, show: () => this.show() }); // toggle visibility on toggle element click this._subscriptions.push(this._state.toggleClick.subscribe((value) => this.toggle(value))); // hide dropdown if set disabled while opened this._subscriptions.push(this._state.isDisabledChange .pipe(filter((value) => value)) .subscribe((value) => this.hide())); } /** * Opens an element’s popover. This is considered a “manual” triggering of * the popover. * @return {?} */ show() { if (this.isOpen || this.isDisabled) { return; } if (this._showInline) { if (!this._inlinedMenu) { this._state.dropdownMenu.then((dropdownMenu) => { this._dropdown.attachInline(dropdownMenu.viewContainer, dropdownMenu.templateRef); this._inlinedMenu = this._dropdown._inlineViewRef; this.addBs4Polyfills(); }) // swallow errors .catch(); } this.addBs4Polyfills(); this._isInlineOpen = true; this.onShown.emit(true); this._state.isOpenChange.emit(true); return; } this._state.dropdownMenu.then(dropdownMenu => { // check direction in which dropdown should be opened /** @type {?} */ const _dropup = this.dropup || (typeof this.dropup !== 'undefined' && this.dropup); this._state.direction = _dropup ? 'up' : 'down'; /** @type {?} */ const _placement = this.placement || (_dropup ? 'top left' : 'bottom left'); // show dropdown this._dropdown .attach(BsDropdownContainerComponent) .to(this.container) .position({ attachment: _placement }) .show({ content: dropdownMenu.templateRef, placement: _placement }); this._state.isOpenChange.emit(true); }) // swallow error .catch(); } /** * Closes an element’s popover. This is considered a “manual” triggering of * the popover. * @return {?} */ hide() { if (!this.isOpen) { return; } if (this._showInline) { this.removeShowClass(); this.removeDropupStyles(); this._isInlineOpen = false; this.onHidden.emit(true); } else { this._dropdown.hide(); } this._state.isOpenChange.emit(false); } /** * Toggles an element’s popover. This is considered a “manual” triggering of * the popover. With parameter <code>true</code> allows toggling, with parameter <code>false</code> * only hides opened dropdown. Parameter usage will be removed in ngx-bootstrap v3 * @param {?=} value * @return {?} */ toggle(value) { if (this.isOpen || !value) { return this.hide(); } return this.show(); } /** * \@internal * @param {?} event * @return {?} */ _contains(event) { return this._elementRef.nativeElement.contains(event.target) || (this._dropdown.instance && this._dropdown.instance._contains(event.target)); } /** * @return {?} */ ngOnDestroy() { // clean up subscriptions and destroy dropdown for (const sub of this._subscriptions) { sub.unsubscribe(); } this._dropdown.dispose(); } /** * @private * @return {?} */ addBs4Polyfills() { if (!isBs3()) { this.addShowClass(); this.checkRightAlignment(); this.addDropupStyles(); } } /** * @private * @return {?} */ addShowClass() { if (this._inlinedMenu && this._inlinedMenu.rootNodes[0]) { this._renderer.addClass(this._inlinedMenu.rootNodes[0], 'show'); } } /** * @private * @return {?} */ removeShowClass() { if (this._inlinedMenu && this._inlinedMenu.rootNodes[0]) { this._renderer.removeClass(this._inlinedMenu.rootNodes[0], 'show'); } } /** * @private * @return {?} */ checkRightAlignment() { if (this._inlinedMenu && this._inlinedMenu.rootNodes[0]) { /** @type {?} */ const isRightAligned = this._inlinedMenu.rootNodes[0].classList.contains('dropdown-menu-right'); this._renderer.setStyle(this._inlinedMenu.rootNodes[0], 'left', isRightAligned ? 'auto' : '0'); this._renderer.setStyle(this._inlinedMenu.rootNodes[0], 'right', isRightAligned ? '0' : 'auto'); } } /** * @private * @return {?} */ addDropupStyles() { if (this._inlinedMenu && this._inlinedMenu.rootNodes[0]) { // a little hack to not break support of bootstrap 4 beta this._renderer.setStyle(this._inlinedMenu.rootNodes[0], 'top', this.dropup ? 'auto' : '100%'); this._renderer.setStyle(this._inlinedMenu.rootNodes[0], 'transform', this.dropup ? 'translateY(-101%)' : 'translateY(0)'); this._renderer.setStyle(this._inlinedMenu.rootNodes[0], 'bottom', 'auto'); } } /** * @private * @return {?} */ removeDropupStyles() { if (this._inlinedMenu && this._inlinedMenu.rootNodes[0]) { this._renderer.removeStyle(this._inlinedMenu.rootNodes[0], 'top'); this._renderer.removeStyle(this._inlinedMenu.rootNodes[0], 'transform'); this._renderer.removeStyle(this._inlinedMenu.rootNodes[0], 'bottom'); } } } BsDropdownDirective.decorators = [ { type: Directive, args: [{ selector: '[bsDropdown],[dropdown]', exportAs: 'bs-dropdown', providers: [BsDropdownState], host: { '[class.dropup]': 'dropup', '[class.open]': 'isOpen', '[class.show]': 'isOpen && isBs4' } },] } ]; /** @nocollapse */ BsDropdownDirective.ctorParameters = () => [ { type: ElementRef }, { type: Renderer2 }, { type: ViewContainerRef }, { type: ComponentLoaderFactory }, { type: BsDropdownConfig }, { type: BsDropdownState } ]; BsDropdownDirective.propDecorators = { placement: [{ type: Input }], triggers: [{ type: Input }], container: [{ type: Input }], dropup: [{ type: Input }], autoClose: [{ type: Input }], insideClick: [{ type: Input }], isDisabled: [{ type: Input }], isOpen: [{ type: Input }], isOpenChange: [{ type: Output }], onShown: [{ type: Output }], onHidden: [{ type: Output }] }; if (false) { /** * Placement of a popover. Accepts: "top", "bottom", "left", "right" * @type {?} */ BsDropdownDirective.prototype.placement; /** * Specifies events that should trigger. Supports a space separated list of * event names. * @type {?} */ BsDropdownDirective.prototype.triggers; /** * A selector specifying the element the popover should be appended to. * Currently only supports "body". * @type {?} */ BsDropdownDirective.prototype.container; /** * This attribute indicates that the dropdown should be opened upwards * @type {?} */ BsDropdownDirective.prototype.dropup; /** * Emits an event when isOpen change * @type {?} */ BsDropdownDirective.prototype.isOpenChange; /** * Emits an event when the popover is shown * @type {?} */ BsDropdownDirective.prototype.onShown; /** * Emits an event when the popover is hidden * @type {?} */ BsDropdownDirective.prototype.onHidden; /** * @type {?} * @private */ BsDropdownDirective.prototype._dropdown; /** * @type {?} * @private */ BsDropdownDirective.prototype._isInlineOpen; /** * @type {?} * @private */ BsDropdownDirective.prototype._inlinedMenu; /** * @type {?} * @private */ BsDropdownDirective.prototype._isDisabled; /** * @type {?} * @private */ BsDropdownDirective.prototype._subscriptions; /** * @type {?} * @private */ BsDropdownDirective.prototype._isInited; /** * @type {?} * @private */ BsDropdownDirective.prototype._elementRef; /** * @type {?} * @private */ BsDropdownDirective.prototype._renderer; /** * @type {?} * @private */ BsDropdownDirective.prototype._viewContainerRef; /** * @type {?} * @private */ BsDropdownDirective.prototype._cis; /** * @type {?} * @private */ BsDropdownDirective.prototype._config; /** * @type {?} * @private */ BsDropdownDirective.prototype._state; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnMtZHJvcGRvd24uZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LWJvb3RzdHJhcC9kcm9wZG93bi8iLCJzb3VyY2VzIjpbImJzLWRyb3Bkb3duLmRpcmVjdGl2ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUNBLE9BQU8sRUFDTCxTQUFTLEVBQ1QsVUFBVSxFQUVWLFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUNOLFNBQVMsRUFDVCxnQkFBZ0IsRUFDakIsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXhDLE9BQU8sRUFBbUIsc0JBQXNCLEVBQWtCLE1BQU0sZ0NBQWdDLENBQUM7QUFFekcsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDeEQsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sbUNBQW1DLENBQUM7QUFDakYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXRELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQVk1QyxNQUFNLE9BQU8sbUJBQW1COzs7Ozs7Ozs7SUFtSDlCLFlBQW9CLFdBQXVCLEVBQ3ZCLFNBQW9CLEVBQ3BCLGlCQUFtQyxFQUNuQyxJQUE0QixFQUM1QixPQUF5QixFQUN6QixNQUF1QjtRQUx2QixnQkFBVyxHQUFYLFdBQVcsQ0FBWTtRQUN2QixjQUFTLEdBQVQsU0FBUyxDQUFXO1FBQ3BCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBa0I7UUFDbkMsU0FBSSxHQUFKLElBQUksQ0FBd0I7UUFDNUIsWUFBTyxHQUFQLE9BQU8sQ0FBa0I7UUFDekIsV0FBTSxHQUFOLE1BQU0sQ0FBaUI7O1FBWm5DLGtCQUFhLEdBQUcsS0FBSyxDQUFDO1FBSXRCLG1CQUFjLEdBQW1CLEVBQUUsQ0FBQztRQUNwQyxjQUFTLEdBQUcsS0FBSyxDQUFDO1FBUXhCLHlDQUF5QztR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aW1wb3J0IHtcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFbWJlZGRlZFZpZXdSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5wdXQsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFJlbmRlcmVyMixcbiAgVmlld0NvbnRhaW5lclJlZlxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGZpbHRlciB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgQ29tcG9uZW50TG9hZGVyLCBDb21wb25lbnRMb2FkZXJGYWN0b3J5LCBCc0NvbXBvbmVudFJlZiB9IGZyb20gJ25neC1ib290c3RyYXAvY29tcG9uZW50LWxvYWRlcic7XG5cbmltcG9ydCB7IEJzRHJvcGRvd25Db25maWcgfSBmcm9tICcuL2JzLWRyb3Bkb3duLmNvbmZpZyc7XG5pbXBvcnQgeyBCc0Ryb3Bkb3duQ29udGFpbmVyQ29tcG9uZW50IH0gZnJvbSAnLi9icy1kcm9wZG93bi1jb250YWluZXIuY29tcG9uZW50JztcbmltcG9ydCB7IEJzRHJvcGRvd25TdGF0ZSB9IGZyb20gJy4vYnMtZHJvcGRvd24uc3RhdGUnO1xuaW1wb3J0IHsgQnNEcm9wZG93bk1lbnVEaXJlY3RpdmUgfSBmcm9tICcuL2luZGV4JztcbmltcG9ydCB7IGlzQnMzIH0gZnJvbSAnbmd4LWJvb3RzdHJhcC91dGlscyc7XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogJ1tic0Ryb3Bkb3duXSxbZHJvcGRvd25dJyxcbiAgZXhwb3J0QXM6ICdicy1kcm9wZG93bicsXG4gIHByb3ZpZGVyczogW0JzRHJvcGRvd25TdGF0ZV0sXG4gIGhvc3Q6IHtcbiAgICAnW2NsYXNzLmRyb3B1cF0nOiAnZHJvcHVwJyxcbiAgICAnW2NsYXNzLm9wZW5dJzogJ2lzT3BlbicsXG4gICAgJ1tjbGFzcy5zaG93XSc6ICdpc09wZW4gJiYgaXNCczQnXG4gIH1cbn0pXG5leHBvcnQgY2xhc3MgQnNEcm9wZG93bkRpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgLyoqXG4gICAqIFBsYWNlbWVudCBvZiBhIHBvcG92ZXIuIEFjY2VwdHM6IFwidG9wXCIsIFwiYm90dG9tXCIsIFwibGVmdFwiLCBcInJpZ2h0XCJcbiAgICovXG4gIEBJbnB1dCgpIHBsYWNlbWVudDogc3RyaW5nO1xuICAvKipcbiAgICogU3BlY2lmaWVzIGV2ZW50cyB0aGF0IHNob3VsZCB0cmlnZ2VyLiBTdXBwb3J0cyBhIHNwYWNlIHNlcGFyYXRlZCBsaXN0IG9mXG4gICAqIGV2ZW50IG5hbWVzLlxuICAgKi9cbiAgQElucHV0KCkgdHJpZ2dlcnM6IHN0cmluZztcbiAgLyoqXG4gICAqIEEgc2VsZWN0b3Igc3BlY2lmeWluZyB0aGUgZWxlbWVudCB0aGUgcG9wb3ZlciBzaG91bGQgYmUgYXBwZW5kZWQgdG8uXG4gICAqIEN1cnJlbnRseSBvbmx5IHN1cHBvcnRzIFwiYm9keVwiLlxuICAgKi9cbiAgQElucHV0KCkgY29udGFpbmVyOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoaXMgYXR0cmlidXRlIGluZGljYXRlcyB0aGF0IHRoZSBkcm9wZG93biBzaG91bGQgYmUgb3BlbmVkIHVwd2FyZHNcbiAgICovXG4gIEBJbnB1dCgpIGRyb3B1cDogYm9vbGVhbjtcblxuICAvKipcbiAgICogSW5kaWNhdGVzIHRoYXQgZHJvcGRvd24gd2lsbCBiZSBjbG9zZWQgb24gaXRlbSBvciBkb2N1bWVudCBjbGljayxcbiAgICogYW5kIGFmdGVyIHByZXNzaW5nIEVTQ1xuICAgKi9cbiAgQElucHV0KClcbiAgc2V0IGF1dG9DbG9zZSh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX3N0YXRlLmF1dG9DbG9zZSA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IGF1dG9DbG9zZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5fc3RhdGUuYXV0b0Nsb3NlO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoaXMgYXR0cmlidXRlIGluZGljYXRlcyB0aGF0IHRoZSBkcm9wZG93biBzaG91bGRuJ3QgY2xvc2Ugb24gaW5zaWRlIGNsaWNrIHdoZW4gYXV0b0Nsb3NlIGlzIHNldCB0byB0cnVlXG4gICAqL1xuICBASW5wdXQoKVxuICBzZXQgaW5zaWRlQ2xpY2sodmFsdWU6IGJvb2xlYW4pIHtcbiAgICB0aGlzLl9zdGF0ZS5pbnNpZGVDbGljayA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IGluc2lkZUNsaWNrKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9zdGF0ZS5pbnNpZGVDbGljaztcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNhYmxlcyBkcm9wZG93biB0b2dnbGUgYW5kIGhpZGVzIGRyb3Bkb3duIG1lbnUgaWYgb3BlbmVkXG4gICAqL1xuICBASW5wdXQoKVxuICBzZXQgaXNEaXNhYmxlZCh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2lzRGlzYWJsZWQgPSB2YWx1ZTtcbiAgICB0aGlzLl9zdGF0ZS5pc0Rpc2FibGVkQ2hhbmdlLmVtaXQodmFsdWUpO1xuICAgIGlmICh2YWx1ZSkge1xuICAgICAgdGhpcy5oaWRlKCk7XG4gICAgfVxuICB9XG5cbiAgZ2V0IGlzRGlzYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2lzRGlzYWJsZWQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgcG9wb3ZlciBpcyBjdXJyZW50bHkgYmVpbmcgc2hvd25cbiAgICovXG4gIEBJbnB1dCgpXG4gIGdldCBpc09wZW4oKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuX3Nob3dJbmxpbmUpIHtcbiAgICAgIHJldHVybiB0aGlzLl9pc0lubGluZU9wZW47XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX2Ryb3Bkb3duLmlzU2hvd247XG4gIH1cblxuICBzZXQgaXNPcGVuKHZhbHVlOiBib29sZWFuKSB7XG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLnNob3coKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5oaWRlKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEVtaXRzIGFuIGV2ZW50IHdoZW4gaXNPcGVuIGNoYW5nZVxuICAgKi9cbiAgQE91dHB1dCgpIGlzT3BlbkNoYW5nZTogRXZlbnRFbWl0dGVyPGJvb2xlYW4+O1xuXG4gIC8qKlxuICAgKiBFbWl0cyBhbiBldmVudCB3aGVuIHRoZSBwb3BvdmVyIGlzIHNob3duXG4gICAqL1xuICBAT3V0cHV0KCkgb25TaG93bjogRXZlbnRFbWl0dGVyPGJvb2xlYW4+O1xuXG4gIC8qKlxuICAgKiBFbWl0cyBhbiBldmVudCB3aGVuIHRoZSBwb3BvdmVyIGlzIGhpZGRlblxuICAgKi9cbiAgQE91dHB1dCgpIG9uSGlkZGVuOiBFdmVudEVtaXR0ZXI8Ym9vbGVhbj47XG5cbiAgZ2V0IGlzQnM0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhaXNCczMoKTtcbiAgfVxuXG4gIHByaXZhdGUgX2Ryb3Bkb3duOiBDb21wb25lbnRMb2FkZXI8QnNEcm9wZG93bkNvbnRhaW5lckNvbXBvbmVudD47XG5cbiAgcHJpdmF0ZSBnZXQgX3Nob3dJbmxpbmUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICF0aGlzLmNvbnRhaW5lcjtcbiAgfVxuXG4gIC8vIHRvZG86IG1vdmUgdG8gY29tcG9uZW50IGxvYWRlclxuICBwcml2YXRlIF9pc0lubGluZU9wZW4gPSBmYWxzZTtcblxuICBwcml2YXRlIF9pbmxpbmVkTWVudTogRW1iZWRkZWRWaWV3UmVmPEJzRHJvcGRvd25NZW51RGlyZWN0aXZlPjtcbiAgcHJpdmF0ZSBfaXNEaXNhYmxlZDogYm9vbGVhbjtcbiAgcHJpdmF0ZSBfc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uW10gPSBbXTtcbiAgcHJpdmF0ZSBfaXNJbml0ZWQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgICAgICAgICAgICBwcml2YXRlIF9yZW5kZXJlcjogUmVuZGVyZXIyLFxuICAgICAgICAgICAgICBwcml2YXRlIF92aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmLFxuICAgICAgICAgICAgICBwcml2YXRlIF9jaXM6IENvbXBvbmVudExvYWRlckZhY3RvcnksXG4gICAgICAgICAgICAgIHByaXZhdGUgX2NvbmZpZzogQnNEcm9wZG93bkNvbmZpZyxcbiAgICAgICAgICAgICAgcHJpdmF0ZSBfc3RhdGU6IEJzRHJvcGRvd25TdGF0ZSkge1xuICAgIC8vIHNldCBpbml0aWFsIGRyb3Bkb3duIHN0YXRlIGZyb20gY29uZmlnXG4gICAgdGhpcy5fc3RhdGUuYXV0b0Nsb3NlID0gdGhpcy5fY29uZmlnLmF1dG9DbG9zZTtcbiAgICB0aGlzLl9zdGF0ZS5pbnNpZGVDbGljayA9IHRoaXMuX2NvbmZpZy5pbnNpZGVDbGljaztcblxuICAgIC8vIGNyZWF0ZSBkcm9wZG93biBjb21wb25lbnQgbG9hZGVyXG4gICAgdGhpcy5fZHJvcGRvd24gPSB0aGlzLl9jaXNcbiAgICAgIC5jcmVhdGVMb2FkZXI8QnNEcm9wZG93bkNvbnRhaW5lckNvbXBvbmVudD4oXG4gICAgICAgIHRoaXMuX2VsZW1lbnRSZWYsXG4gICAgICAgIHRoaXMuX3ZpZXdDb250YWluZXJSZWYsXG4gICAgICAgIHRoaXMuX3JlbmRlcmVyXG4gICAgICApXG4gICAgICAucHJvdmlkZSh7cHJvdmlkZTogQnNEcm9wZG93blN0YXRlLCB1c2VWYWx1ZTogdGhpcy5fc3RhdGV9KTtcblxuICAgIHRoaXMub25TaG93biA9IHRoaXMuX2Ryb3Bkb3duLm9uU2hvd247XG4gICAgdGhpcy5vbkhpZGRlbiA9IHRoaXMuX2Ryb3Bkb3duLm9uSGlkZGVuO1xuICAgIHRoaXMuaXNPcGVuQ2hhbmdlID0gdGhpcy5fc3RhdGUuaXNPcGVuQ2hhbmdlO1xuXG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAvLyBmaXg6IHNlZW1zIHRoZXJlIGFyZSBhbiBpc3N1ZSB3aXRoIGByb3V0ZXJMaW5rQWN0aXZlYFxuICAgIC8vIHdoaWNoIHJlc3VsdCBpbiBkdXBsaWNhdGVkIGNhbGwgbmdPbkluaXQgd2l0aG91dCBjYWxsIHRvIG5nT25EZXN0cm95XG4gICAgLy8gcmVhZCBtb3JlOiBodHRwczovL2dpdGh1Yi5jb20vdmFsb3Itc29mdHdhcmUvbmd4LWJvb3RzdHJhcC9pc3N1ZXMvMTg4NVxuICAgIGlmICh0aGlzLl9pc0luaXRlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLl9pc0luaXRlZCA9IHRydWU7XG5cbiAgICAvLyBhdHRhY2ggRE9NIGxpc3RlbmVyc1xuICAgIHRoaXMuX2Ryb3Bkb3duLmxpc3Rlbih7XG4gICAgICAvLyBiZWNhdXNlIG9mIGRyb3Bkb3duIGlubGluZSBtb2RlXG4gICAgICBvdXRzaWRlQ2xpY2s6IGZhbHNlLFxuICAgICAgdHJpZ2dlcnM6IHRoaXMudHJpZ2dlcnMsXG4gICAgICBzaG93OiAoKSA9PiB0aGlzLnNob3coKVxuICAgIH0pO1xuXG4gICAgLy8gdG9nZ2xlIHZpc2liaWxpdHkgb24gdG9nZ2xlIGVsZW1lbnQgY2xpY2tcbiAgICB0aGlzLl9zdWJzY3JpcHRpb25zLnB1c2goXG4gICAgICB0aGlzLl9zdGF0ZS50b2dnbGVDbGljay5zdWJzY3JpYmUoKHZhbHVlOiBib29sZWFuKSA9PiB0aGlzLnRvZ2dsZSh2YWx1ZSkpXG4gICAgKTtcblxuICAgIC8vIGhpZGUgZHJvcGRvd24gaWYgc2V0IGRpc2FibGVkIHdoaWxlIG9wZW5lZFxuICAgIHRoaXMuX3N1YnNjcmlwdGlvbnMucHVzaChcbiAgICAgIHRoaXMuX3N0YXRlLmlzRGlzYWJsZWRDaGFuZ2VcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgZmlsdGVyKCh2YWx1ZTogYm9vbGVhbikgPT4gdmFsdWUpXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZSgodmFsdWU6IGJvb2xlYW4pID0+IHRoaXMuaGlkZSgpKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogT3BlbnMgYW4gZWxlbWVudOKAmXMgcG9wb3Zlci4gVGhpcyBpcyBjb25zaWRlcmVkIGEg4oCcbWFudWFs4oCdIHRyaWdnZXJpbmcgb2ZcbiAgICogdGhlIHBvcG92ZXIuXG4gICAqL1xuICBzaG93KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzT3BlbiB8fCB0aGlzLmlzRGlzYWJsZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fc2hvd0lubGluZSkge1xuICAgICAgaWYgKCF0aGlzLl9pbmxpbmVkTWVudSkge1xuICAgICAgICB0aGlzLl9zdGF0ZS5kcm9wZG93bk1lbnUudGhlbihcbiAgICAgICAgICAoZHJvcGRvd25NZW51OiBCc0NvbXBvbmVudFJlZjxCc0Ryb3Bkb3duTWVudURpcmVjdGl2ZT4pID0+IHtcbiAgICAgICAgICAgIHRoaXMuX2Ryb3Bkb3duLmF0dGFjaElubGluZShcbiAgICAgICAgICAgICAgZHJvcGRvd25NZW51LnZpZXdDb250YWluZXIsXG4gICAgICAgICAgICAgIGRyb3Bkb3duTWVudS50ZW1wbGF0ZVJlZlxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHRoaXMuX2lubGluZWRNZW51ID0gdGhpcy5fZHJvcGRvd24uX2lubGluZVZpZXdSZWY7XG4gICAgICAgICAgICB0aGlzLmFkZEJzNFBvbHlmaWxscygpO1xuICAgICAgICAgIH1cbiAgICAgICAgKVxuICAgICAgICAvLyBzd2FsbG93IGVycm9yc1xuICAgICAgICAgIC5jYXRjaCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5hZGRCczRQb2x5ZmlsbHMoKTtcbiAgICAgIHRoaXMuX2lzSW5saW5lT3BlbiA9IHRydWU7XG4gICAgICB0aGlzLm9uU2hvd24uZW1pdCh0cnVlKTtcbiAgICAgIHRoaXMuX3N0YXRlLmlzT3BlbkNoYW5nZS5lbWl0KHRydWUpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuX3N0YXRlLmRyb3Bkb3duTWVudS50aGVuKGRyb3Bkb3duTWVudSA9PiB7XG4gICAgICAvLyBjaGVjayBkaXJlY3Rpb24gaW4gd2hpY2ggZHJvcGRvd24gc2hvdWxkIGJlIG9wZW5lZFxuICAgICAgY29uc3QgX2Ryb3B1cCA9XG4gICAgICAgIHRoaXMuZHJvcHVwIHx8XG4gICAgICAgICh0eXBlb2YgdGhpcy5kcm9wdXAgIT09ICd1bmRlZmluZWQnICYmIHRoaXMuZHJvcHVwKTtcbiAgICAgIHRoaXMuX3N0YXRlLmRpcmVjdGlvbiA9IF9kcm9wdXAgPyAndXAnIDogJ2Rvd24nO1xuICAgICAgY29uc3QgX3BsYWNlbWVudCA9XG4gICAgICAgIHRoaXMucGxhY2VtZW50IHx8IChfZHJvcHVwID8gJ3RvcCBsZWZ0JyA6ICdib3R0b20gbGVmdCcpO1xuXG4gICAgICAvLyBzaG93IGRyb3Bkb3duXG4gICAgICB0aGlzLl9kcm9wZG93blxuICAgICAgICAuYXR0YWNoKEJzRHJvcGRvd25Db250YWluZXJDb21wb25lbnQpXG4gICAgICAgIC50byh0aGlzLmNvbnRhaW5lcilcbiAgICAgICAgLnBvc2l0aW9uKHthdHRhY2htZW50OiBfcGxhY2VtZW50fSlcbiAgICAgICAgLnNob3coe1xuICAgICAgICAgIGNvbnRlbnQ6IGRyb3Bkb3duTWVudS50ZW1wbGF0ZVJlZixcbiAgICAgICAgICBwbGFjZW1lbnQ6IF9wbGFjZW1lbnRcbiAgICAgICAgfSk7XG5cbiAgICAgIHRoaXMuX3N0YXRlLmlzT3BlbkNoYW5nZS5lbWl0KHRydWUpO1xuICAgIH0pXG4gICAgLy8gc3dhbGxvdyBlcnJvclxuICAgICAgLmNhdGNoKCk7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIGFuIGVsZW1lbnTigJlzIHBvcG92ZXIuIFRoaXMgaXMgY29uc2lkZXJlZCBhIOKAnG1hbnVhbOKAnSB0cmlnZ2VyaW5nIG9mXG4gICAqIHRoZSBwb3BvdmVyLlxuICAgKi9cbiAgaGlkZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNPcGVuKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3Nob3dJbmxpbmUpIHtcbiAgICAgIHRoaXMucmVtb3ZlU2hvd0NsYXNzKCk7XG4gICAgICB0aGlzLnJlbW92ZURyb3B1cFN0eWxlcygpO1xuICAgICAgdGhpcy5faXNJbmxpbmVPcGVuID0gZmFsc2U7XG4gICAgICB0aGlzLm9uSGlkZGVuLmVtaXQodHJ1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX2Ryb3Bkb3duLmhpZGUoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9zdGF0ZS5pc09wZW5DaGFuZ2UuZW1pdChmYWxzZSk7XG4gIH1cblxuICAvKipcbiAgICogVG9nZ2xlcyBhbiBlbGVtZW504oCZcyBwb3BvdmVyLiBUaGlzIGlzIGNvbnNpZGVyZWQgYSDigJxtYW51YWzigJ0gdHJpZ2dlcmluZyBvZlxuICAgKiB0aGUgcG9wb3Zlci4gV2l0aCBwYXJhbWV0ZXIgPGNvZGU+dHJ1ZTwvY29kZT4gYWxsb3dzIHRvZ2dsaW5nLCB3aXRoIHBhcmFtZXRlciA8Y29kZT5mYWxzZTwvY29kZT5cbiAgICogb25seSBoaWRlcyBvcGVuZWQgZHJvcGRvd24uIFBhcmFtZXRlciB1c2FnZSB3aWxsIGJlIHJlbW92ZWQgaW4gbmd4LWJvb3RzdHJhcCB2M1xuICAgKi9cbiAgdG9nZ2xlKHZhbHVlPzogYm9vbGVhbik6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzT3BlbiB8fCAhdmFsdWUpIHtcbiAgICAgIHJldHVybiB0aGlzLmhpZGUoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5zaG93KCk7XG4gIH1cblxuICAvKiogQGludGVybmFsICovXG4gIF9jb250YWlucyhldmVudDogYW55KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQpIHx8XG4gICAgICAodGhpcy5fZHJvcGRvd24uaW5zdGFuY2UgJiYgdGhpcy5fZHJvcGRvd24uaW5zdGFuY2UuX2NvbnRhaW5zKGV2ZW50LnRhcmdldCkpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgLy8gY2xlYW4gdXAgc3Vic2NyaXB0aW9ucyBhbmQgZGVzdHJveSBkcm9wZG93blxuICAgIGZvciAoY29uc3Qgc3ViIG9mIHRoaXMuX3N1YnNjcmlwdGlvbnMpIHtcbiAgICAgIHN1Yi51bnN1YnNjcmliZSgpO1xuICAgIH1cbiAgICB0aGlzLl9kcm9wZG93bi5kaXNwb3NlKCk7XG4gIH1cblxuICBwcml2YXRlIGFkZEJzNFBvbHlmaWxscygpOiB2b2lkIHtcbiAgICBpZiAoIWlzQnMzKCkpIHtcbiAgICAgIHRoaXMuYWRkU2hvd0NsYXNzKCk7XG4gICAgICB0aGlzLmNoZWNrUmlnaHRBbGlnbm1lbnQoKTtcbiAgICAgIHRoaXMuYWRkRHJvcHVwU3R5bGVzKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhZGRTaG93Q2xhc3MoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2lubGluZWRNZW51ICYmIHRoaXMuX2lubGluZWRNZW51LnJvb3ROb2Rlc1swXSkge1xuICAgICAgdGhpcy5fcmVuZGVyZXIuYWRkQ2xhc3ModGhpcy5faW5saW5lZE1lbnUucm9vdE5vZGVzWzBdLCAnc2hvdycpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlU2hvd0NsYXNzKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9pbmxpbmVkTWVudSAmJiB0aGlzLl9pbmxpbmVkTWVudS5yb290Tm9kZXNbMF0pIHtcbiAgICAgIHRoaXMuX3JlbmRlcmVyLnJlbW92ZUNsYXNzKHRoaXMuX2lubGluZWRNZW51LnJvb3ROb2Rlc1swXSwgJ3Nob3cnKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNoZWNrUmlnaHRBbGlnbm1lbnQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2lubGluZWRNZW51ICYmIHRoaXMuX2lubGluZWRNZW51LnJvb3ROb2Rlc1swXSkge1xuICAgICAgY29uc3QgaXNSaWdodEFsaWduZWQgPSB0aGlzLl9pbmxpbmVkTWVudS5yb290Tm9kZXNbMF0uY2xhc3NMaXN0LmNvbnRhaW5zKFxuICAgICAgICAnZHJvcGRvd24tbWVudS1yaWdodCdcbiAgICAgICk7XG4gICAgICB0aGlzLl9yZW5kZXJlci5zZXRTdHlsZShcbiAgICAgICAgdGhpcy5faW5saW5lZE1lbnUucm9vdE5vZGVzWzBdLFxuICAgICAgICAnbGVmdCcsXG4gICAgICAgIGlzUmlnaHRBbGlnbmVkID8gJ2F1dG8nIDogJzAnXG4gICAgICApO1xuICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0U3R5bGUoXG4gICAgICAgIHRoaXMuX2lubGluZWRNZW51LnJvb3ROb2Rlc1swXSxcbiAgICAgICAgJ3JpZ2h0JyxcbiAgICAgICAgaXNSaWdodEFsaWduZWQgPyAnMCcgOiAnYXV0bydcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhZGREcm9wdXBTdHlsZXMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX2lubGluZWRNZW51ICYmIHRoaXMuX2lubGluZWRNZW51LnJvb3ROb2Rlc1swXSkge1xuICAgICAgLy8gYSBsaXR0bGUgaGFjayB0byBub3QgYnJlYWsgc3VwcG9ydCBvZiBib290c3RyYXAgNCBiZXRhXG4gICAgICB0aGlzLl9yZW5kZXJlci5zZXRTdHlsZShcbiAgICAgICAgdGhpcy5faW5saW5lZE1lbnUucm9vdE5vZGVzWzBdLFxuICAgICAgICAndG9wJyxcbiAgICAgICAgdGhpcy5kcm9wdXAgPyAnYXV0bycgOiAnMTAwJSdcbiAgICAgICk7XG4gICAgICB0aGlzLl9yZW5kZXJlci5zZXRTdHlsZShcbiAgICAgICAgdGhpcy5faW5saW5lZE1lbnUucm9vdE5vZGVzWzBdLFxuICAgICAgICAndHJhbnNmb3JtJyxcbiAgICAgICAgdGhpcy5kcm9wdXAgPyAndHJhbnNsYXRlWSgtMTAxJSknIDogJ3RyYW5zbGF0ZVkoMCknXG4gICAgICApO1xuICAgICAgdGhpcy5fcmVuZGVyZXIuc2V0U3R5bGUoXG4gICAgICAgIHRoaXMuX2lubGluZWRNZW51LnJvb3ROb2Rlc1swXSxcbiAgICAgICAgJ2JvdHRvbScsXG4gICAgICAgICdhdXRvJ1xuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZURyb3B1cFN0eWxlcygpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5faW5saW5lZE1lbnUgJiYgdGhpcy5faW5saW5lZE1lbnUucm9vdE5vZGVzWzBdKSB7XG4gICAgICB0aGlzLl9yZW5kZXJlci5yZW1vdmVTdHlsZSh0aGlzLl9pbmxpbmVkTWVudS5yb290Tm9kZXNbMF0sICd0b3AnKTtcbiAgICAgIHRoaXMuX3JlbmRlcmVyLnJlbW92ZVN0eWxlKHRoaXMuX2lubGluZWRNZW51LnJvb3ROb2Rlc1swXSwgJ3RyYW5zZm9ybScpO1xuICAgICAgdGhpcy5fcmVuZGVyZXIucmVtb3ZlU3R5bGUodGhpcy5faW5saW5lZE1lbnUucm9vdE5vZGVzWzBdLCAnYm90dG9tJyk7XG4gICAgfVxuICB9XG59XG4iXX0=