UNPKG

@ng-bootstrap/ng-bootstrap

Version:
539 lines 68.8 kB
import { ChangeDetectorRef, ContentChild, ContentChildren, Directive, ElementRef, EventEmitter, forwardRef, inject, Input, NgZone, Output, } from '@angular/core'; import { DOCUMENT } from '@angular/common'; import { fromEvent, Subject } from 'rxjs'; import { take } from 'rxjs/operators'; import { ngbPositioning } from '../util/positioning'; import { addPopperOffset } from '../util/positioning-util'; import { ngbAutoClose } from '../util/autoclose'; import { Key } from '../util/key'; import { NgbDropdownConfig } from './dropdown-config'; import { FOCUSABLE_ELEMENTS_SELECTOR } from '../util/focus-trap'; import { getActiveElement } from '../util/util'; import * as i0 from "@angular/core"; /** * A directive you should put on a dropdown item to enable keyboard navigation. * Arrow keys will move focus between items marked with this directive. * * @since 4.1.0 */ export class NgbDropdownItem { constructor() { this._disabled = false; this.nativeElement = inject(ElementRef).nativeElement; this.tabindex = 0; } set disabled(value) { this._disabled = value === '' || value === true; // accept an empty attribute as true } get disabled() { return this._disabled; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbDropdownItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.0", type: NgbDropdownItem, isStandalone: true, selector: "[ngbDropdownItem]", inputs: { tabindex: "tabindex", disabled: "disabled" }, host: { properties: { "class.disabled": "disabled", "tabIndex": "disabled ? -1 : tabindex" }, classAttribute: "dropdown-item" }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbDropdownItem, decorators: [{ type: Directive, args: [{ selector: '[ngbDropdownItem]', standalone: true, host: { class: 'dropdown-item', '[class.disabled]': 'disabled', '[tabIndex]': 'disabled ? -1 : tabindex', }, }] }], propDecorators: { tabindex: [{ type: Input }], disabled: [{ type: Input }] } }); /** * A directive that will be applied if dropdown item is a button. * It will only set the disabled property. */ export class NgbDropdownButtonItem { constructor() { this.item = inject(NgbDropdownItem); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbDropdownButtonItem, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.0", type: NgbDropdownButtonItem, isStandalone: true, selector: "button[ngbDropdownItem]", host: { properties: { "disabled": "item.disabled" } }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbDropdownButtonItem, decorators: [{ type: Directive, args: [{ selector: 'button[ngbDropdownItem]', standalone: true, host: { '[disabled]': 'item.disabled' }, }] }] }); /** * A directive that wraps dropdown menu content and dropdown items. */ export class NgbDropdownMenu { constructor() { this.dropdown = inject(NgbDropdown); this.nativeElement = inject(ElementRef).nativeElement; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbDropdownMenu, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.0", type: NgbDropdownMenu, isStandalone: true, selector: "[ngbDropdownMenu]", host: { listeners: { "keydown.ArrowUp": "dropdown.onKeyDown($event)", "keydown.ArrowDown": "dropdown.onKeyDown($event)", "keydown.Home": "dropdown.onKeyDown($event)", "keydown.End": "dropdown.onKeyDown($event)", "keydown.Enter": "dropdown.onKeyDown($event)", "keydown.Space": "dropdown.onKeyDown($event)", "keydown.Tab": "dropdown.onKeyDown($event)", "keydown.Shift.Tab": "dropdown.onKeyDown($event)" }, properties: { "class.dropdown-menu": "true", "class.show": "dropdown.isOpen()" } }, queries: [{ propertyName: "menuItems", predicate: NgbDropdownItem }], ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbDropdownMenu, decorators: [{ type: Directive, args: [{ selector: '[ngbDropdownMenu]', standalone: true, host: { '[class.dropdown-menu]': 'true', '[class.show]': 'dropdown.isOpen()', '(keydown.ArrowUp)': 'dropdown.onKeyDown($event)', '(keydown.ArrowDown)': 'dropdown.onKeyDown($event)', '(keydown.Home)': 'dropdown.onKeyDown($event)', '(keydown.End)': 'dropdown.onKeyDown($event)', '(keydown.Enter)': 'dropdown.onKeyDown($event)', '(keydown.Space)': 'dropdown.onKeyDown($event)', '(keydown.Tab)': 'dropdown.onKeyDown($event)', '(keydown.Shift.Tab)': 'dropdown.onKeyDown($event)', }, }] }], propDecorators: { menuItems: [{ type: ContentChildren, args: [NgbDropdownItem] }] } }); /** * A directive to mark an element to which dropdown menu will be anchored. * * This is a simple version of the `NgbDropdownToggle` directive. * It plays the same role, but doesn't listen to click events to toggle dropdown menu thus enabling support * for events other than click. * * @since 1.1.0 */ export class NgbDropdownAnchor { constructor() { this.dropdown = inject(NgbDropdown); this.nativeElement = inject(ElementRef).nativeElement; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbDropdownAnchor, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.0", type: NgbDropdownAnchor, isStandalone: true, selector: "[ngbDropdownAnchor]", host: { properties: { "class.show": "dropdown.isOpen()", "attr.aria-expanded": "dropdown.isOpen()" }, classAttribute: "dropdown-toggle" }, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbDropdownAnchor, decorators: [{ type: Directive, args: [{ selector: '[ngbDropdownAnchor]', standalone: true, host: { class: 'dropdown-toggle', '[class.show]': 'dropdown.isOpen()', '[attr.aria-expanded]': 'dropdown.isOpen()', }, }] }] }); /** * A directive to mark an element that will toggle dropdown via the `click` event. * * You can also use `NgbDropdownAnchor` as an alternative. */ export class NgbDropdownToggle extends NgbDropdownAnchor { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbDropdownToggle, deps: null, target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.0", type: NgbDropdownToggle, isStandalone: true, selector: "[ngbDropdownToggle]", host: { listeners: { "click": "dropdown.toggle()", "keydown.ArrowUp": "dropdown.onKeyDown($event)", "keydown.ArrowDown": "dropdown.onKeyDown($event)", "keydown.Home": "dropdown.onKeyDown($event)", "keydown.End": "dropdown.onKeyDown($event)", "keydown.Tab": "dropdown.onKeyDown($event)", "keydown.Shift.Tab": "dropdown.onKeyDown($event)" }, properties: { "class.show": "dropdown.isOpen()", "attr.aria-expanded": "dropdown.isOpen()" }, classAttribute: "dropdown-toggle" }, providers: [{ provide: NgbDropdownAnchor, useExisting: forwardRef(() => NgbDropdownToggle) }], usesInheritance: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbDropdownToggle, decorators: [{ type: Directive, args: [{ selector: '[ngbDropdownToggle]', standalone: true, host: { class: 'dropdown-toggle', '[class.show]': 'dropdown.isOpen()', '[attr.aria-expanded]': 'dropdown.isOpen()', '(click)': 'dropdown.toggle()', '(keydown.ArrowUp)': 'dropdown.onKeyDown($event)', '(keydown.ArrowDown)': 'dropdown.onKeyDown($event)', '(keydown.Home)': 'dropdown.onKeyDown($event)', '(keydown.End)': 'dropdown.onKeyDown($event)', '(keydown.Tab)': 'dropdown.onKeyDown($event)', '(keydown.Shift.Tab)': 'dropdown.onKeyDown($event)', }, providers: [{ provide: NgbDropdownAnchor, useExisting: forwardRef(() => NgbDropdownToggle) }], }] }] }); /** * A directive that provides contextual overlays for displaying lists of links and more. */ export class NgbDropdown { constructor() { this._changeDetector = inject(ChangeDetectorRef); this._config = inject(NgbDropdownConfig); this._document = inject(DOCUMENT); this._ngZone = inject(NgZone); this._nativeElement = inject(ElementRef).nativeElement; this._destroyCloseHandlers$ = new Subject(); this._bodyContainer = null; this._positioning = ngbPositioning(); /** * Indicates whether the dropdown should be closed when clicking one of dropdown items or pressing ESC. * * * `true` - the dropdown will close on both outside and inside (menu) clicks. * * `false` - the dropdown can only be closed manually via `close()` or `toggle()` methods. * * `"inside"` - the dropdown will close on inside menu clicks, but not outside clicks. * * `"outside"` - the dropdown will close only on the outside clicks and not on menu clicks. */ this.autoClose = this._config.autoClose; /** * Defines whether or not the dropdown menu is opened initially. */ this._open = false; /** * The preferred placement of the dropdown, among the [possible values](#/guides/positioning#api). * * The default order of preference is `"bottom-start bottom-end top-start top-end"` * * Please see the [positioning overview](#/positioning) for more details. */ this.placement = this._config.placement; /** * Allows to change default Popper options when positioning the dropdown. * Receives current popper options and returns modified ones. * * @since 13.1.0 */ this.popperOptions = this._config.popperOptions; /** * A selector specifying the element the dropdown should be appended to. * Currently only supports "body". * * @since 4.1.0 */ this.container = this._config.container; /** * An event fired when the dropdown is opened or closed. * * The event payload is a `boolean`: * * `true` - the dropdown was opened * * `false` - the dropdown was closed */ this.openChange = new EventEmitter(); } ngOnInit() { if (!this.display) { this.display = this._nativeElement.closest('.navbar') ? 'static' : 'dynamic'; } } ngAfterContentInit() { this._ngZone.onStable.pipe(take(1)).subscribe(() => { this._applyPlacementClasses(); if (this._open) { this._setCloseHandlers(); } }); } ngOnChanges(changes) { if (changes.container && this._open) { this._applyContainer(this.container); } if (changes.placement && !changes.placement.firstChange) { this._positioning.setOptions({ hostElement: this._anchor.nativeElement, targetElement: this._bodyContainer || this._menu.nativeElement, placement: this.placement, appendToBody: this.container === 'body', }); this._applyPlacementClasses(); } if (changes.dropdownClass) { const { currentValue, previousValue } = changes.dropdownClass; this._applyCustomDropdownClass(currentValue, previousValue); } if (changes.autoClose && this._open) { this.autoClose = changes.autoClose.currentValue; this._setCloseHandlers(); } } /** * Checks if the dropdown menu is open. */ isOpen() { return this._open; } /** * Opens the dropdown menu. */ open() { if (!this._open) { this._open = true; this._applyContainer(this.container); this.openChange.emit(true); this._setCloseHandlers(); if (this._anchor) { this._anchor.nativeElement.focus(); if (this.display === 'dynamic') { this._ngZone.runOutsideAngular(() => { this._positioning.createPopper({ hostElement: this._anchor.nativeElement, targetElement: this._bodyContainer || this._menu.nativeElement, placement: this.placement, appendToBody: this.container === 'body', updatePopperOptions: (options) => this.popperOptions(addPopperOffset([0, 2])(options)), }); this._applyPlacementClasses(); this._zoneSubscription = this._ngZone.onStable.subscribe(() => this._positionMenu()); }); } } } } _setCloseHandlers() { this._destroyCloseHandlers$.next(); // destroy any existing close handlers ngbAutoClose(this._ngZone, this._document, this.autoClose, (source) => { this.close(); if (source === 0 /* SOURCE.ESCAPE */) { this._anchor.nativeElement.focus(); } }, this._destroyCloseHandlers$, this._menu ? [this._menu.nativeElement] : [], this._anchor ? [this._anchor.nativeElement] : [], '.dropdown-item,.dropdown-divider'); } /** * Closes the dropdown menu. */ close() { if (this._open) { this._open = false; this._resetContainer(); this._positioning.destroy(); this._zoneSubscription?.unsubscribe(); this._destroyCloseHandlers$.next(); this.openChange.emit(false); this._changeDetector.markForCheck(); } } /** * Toggles the dropdown menu. */ toggle() { if (this.isOpen()) { this.close(); } else { this.open(); } } ngOnDestroy() { this.close(); } onKeyDown(event) { /* eslint-disable-next-line deprecation/deprecation */ const key = event.which; const itemElements = this._getMenuElements(); let position = -1; let itemElement = null; const isEventFromToggle = this._isEventFromToggle(event); if (!isEventFromToggle && itemElements.length) { itemElements.forEach((item, index) => { if (item.contains(event.target)) { itemElement = item; } if (item === getActiveElement(this._document)) { position = index; } }); } // closing on Enter / Space if (key === Key.Space || key === Key.Enter) { if (itemElement && (this.autoClose === true || this.autoClose === 'inside')) { // Item is either a button or a link, so click will be triggered by the browser on Enter or Space. // So we have to register a one-time click handler that will fire after any user defined click handlers // to close the dropdown fromEvent(itemElement, 'click') .pipe(take(1)) .subscribe(() => this.close()); } return; } if (key === Key.Tab) { if (event.target && this.isOpen() && this.autoClose) { if (this._anchor.nativeElement === event.target) { if (this.container === 'body' && !event.shiftKey) { /* This case is special: user is using [Tab] from the anchor/toggle. User expects the next focusable element in the dropdown menu to get focus. But the menu is not a sibling to anchor/toggle, it is at the end of the body. Trick is to synchronously focus the menu element, and let the [keydown.Tab] go so that browser will focus the proper element (first one focusable in the menu) */ this._menu.nativeElement.setAttribute('tabindex', '0'); this._menu.nativeElement.focus(); this._menu.nativeElement.removeAttribute('tabindex'); } else if (event.shiftKey) { this.close(); } return; } else if (this.container === 'body') { const focusableElements = this._menu.nativeElement.querySelectorAll(FOCUSABLE_ELEMENTS_SELECTOR); if (event.shiftKey && event.target === focusableElements[0]) { this._anchor.nativeElement.focus(); event.preventDefault(); } else if (!event.shiftKey && event.target === focusableElements[focusableElements.length - 1]) { this._anchor.nativeElement.focus(); this.close(); } } else { fromEvent(event.target, 'focusout') .pipe(take(1)) .subscribe(({ relatedTarget }) => { if (!this._nativeElement.contains(relatedTarget)) { this.close(); } }); } } return; } // opening / navigating if (isEventFromToggle || itemElement) { this.open(); if (itemElements.length) { switch (key) { case Key.ArrowDown: position = Math.min(position + 1, itemElements.length - 1); break; case Key.ArrowUp: if (this._isDropup() && position === -1) { position = itemElements.length - 1; break; } position = Math.max(position - 1, 0); break; case Key.Home: position = 0; break; case Key.End: position = itemElements.length - 1; break; } itemElements[position].focus(); } event.preventDefault(); } } _isDropup() { return this._nativeElement.classList.contains('dropup'); } _isEventFromToggle(event) { return this._anchor.nativeElement.contains(event.target); } _getMenuElements() { return this._menu ? this._menu.menuItems.filter(({ disabled }) => !disabled).map(({ nativeElement }) => nativeElement) : []; } _positionMenu() { const menu = this._menu; if (this.isOpen() && menu) { if (this.display === 'dynamic') { this._positioning.update(); this._applyPlacementClasses(); } else { this._applyPlacementClasses(this._getFirstPlacement(this.placement)); } } } _getFirstPlacement(placement) { return Array.isArray(placement) ? placement[0] : placement.split(' ')[0]; } _resetContainer() { if (this._menu) { this._nativeElement.appendChild(this._menu.nativeElement); } if (this._bodyContainer) { this._document.body.removeChild(this._bodyContainer); this._bodyContainer = null; } } _applyContainer(container = null) { this._resetContainer(); if (container === 'body') { const dropdownMenuElement = this._menu.nativeElement; const bodyContainer = (this._bodyContainer = this._bodyContainer || this._document.createElement('div')); // Override some styles to have the positioning working bodyContainer.style.position = 'absolute'; dropdownMenuElement.style.position = 'static'; bodyContainer.style.zIndex = '1055'; bodyContainer.appendChild(dropdownMenuElement); this._document.body.appendChild(bodyContainer); } this._applyCustomDropdownClass(this.dropdownClass); } _applyCustomDropdownClass(newClass, oldClass) { const targetElement = this.container === 'body' ? this._bodyContainer : this._nativeElement; if (targetElement) { if (oldClass) { targetElement.classList.remove(oldClass); } if (newClass) { targetElement.classList.add(newClass); } } } _applyPlacementClasses(placement) { if (this._menu) { if (!placement) { placement = this._getFirstPlacement(this.placement); } // remove the current placement classes this._nativeElement.classList.remove('dropup', 'dropdown'); if (this.display === 'static') { this._menu.nativeElement.setAttribute('data-bs-popper', 'static'); } else { this._menu.nativeElement.removeAttribute('data-bs-popper'); } /* * apply the new placement * in case of top use up-arrow or down-arrow otherwise */ const dropdownClass = placement.search('^top') !== -1 ? 'dropup' : 'dropdown'; this._nativeElement.classList.add(dropdownClass); if (this._bodyContainer) { this._bodyContainer.classList.remove('dropup', 'dropdown'); this._bodyContainer.classList.add(dropdownClass); } } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbDropdown, deps: [], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.0", type: NgbDropdown, isStandalone: true, selector: "[ngbDropdown]", inputs: { autoClose: "autoClose", dropdownClass: "dropdownClass", _open: ["open", "_open"], placement: "placement", popperOptions: "popperOptions", container: "container", display: "display" }, outputs: { openChange: "openChange" }, host: { properties: { "class.show": "isOpen()" } }, queries: [{ propertyName: "_menu", first: true, predicate: NgbDropdownMenu, descendants: true }, { propertyName: "_anchor", first: true, predicate: NgbDropdownAnchor, descendants: true }], exportAs: ["ngbDropdown"], usesOnChanges: true, ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.0", ngImport: i0, type: NgbDropdown, decorators: [{ type: Directive, args: [{ selector: '[ngbDropdown]', exportAs: 'ngbDropdown', standalone: true, host: { '[class.show]': 'isOpen()' }, }] }], propDecorators: { _menu: [{ type: ContentChild, args: [NgbDropdownMenu, { static: false }] }], _anchor: [{ type: ContentChild, args: [NgbDropdownAnchor, { static: false }] }], autoClose: [{ type: Input }], dropdownClass: [{ type: Input }], _open: [{ type: Input, args: ['open'] }], placement: [{ type: Input }], popperOptions: [{ type: Input }], container: [{ type: Input }], display: [{ type: Input }], openChange: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcGRvd24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZHJvcGRvd24vZHJvcGRvd24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVOLGlCQUFpQixFQUNqQixZQUFZLEVBQ1osZUFBZSxFQUNmLFNBQVMsRUFDVCxVQUFVLEVBQ1YsWUFBWSxFQUNaLFVBQVUsRUFDVixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFJTixNQUFNLEdBR04sTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFnQixNQUFNLE1BQU0sQ0FBQztBQUN4RCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFdEMsT0FBTyxFQUFFLGNBQWMsRUFBNkIsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDM0QsT0FBTyxFQUFFLFlBQVksRUFBVSxNQUFNLG1CQUFtQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFFbEMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDdEQsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDakUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sY0FBYyxDQUFDOztBQUVoRDs7Ozs7R0FLRztBQVVILE1BQU0sT0FBTyxlQUFlO0lBVDVCO1FBWVMsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUUxQixrQkFBYSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxhQUE0QixDQUFDO1FBRXZELGFBQVEsR0FBb0IsQ0FBQyxDQUFDO0tBVXZDO0lBUkEsSUFDSSxRQUFRLENBQUMsS0FBYztRQUMxQixJQUFJLENB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dGVudCI6WyJpbXBvcnQge1xuXHRBZnRlckNvbnRlbnRJbml0LFxuXHRDaGFuZ2VEZXRlY3RvclJlZixcblx0Q29udGVudENoaWxkLFxuXHRDb250ZW50Q2hpbGRyZW4sXG5cdERpcmVjdGl2ZSxcblx0RWxlbWVudFJlZixcblx0RXZlbnRFbWl0dGVyLFxuXHRmb3J3YXJkUmVmLFxuXHRpbmplY3QsXG5cdElucHV0LFxuXHROZ1pvbmUsXG5cdE9uQ2hhbmdlcyxcblx0T25EZXN0cm95LFxuXHRPbkluaXQsXG5cdE91dHB1dCxcblx0UXVlcnlMaXN0LFxuXHRTaW1wbGVDaGFuZ2VzLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IGZyb21FdmVudCwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBuZ2JQb3NpdGlvbmluZywgUGxhY2VtZW50LCBQbGFjZW1lbnRBcnJheSB9IGZyb20gJy4uL3V0aWwvcG9zaXRpb25pbmcnO1xuaW1wb3J0IHsgYWRkUG9wcGVyT2Zmc2V0IH0gZnJvbSAnLi4vdXRpbC9wb3NpdGlvbmluZy11dGlsJztcbmltcG9ydCB7IG5nYkF1dG9DbG9zZSwgU09VUkNFIH0gZnJvbSAnLi4vdXRpbC9hdXRvY2xvc2UnO1xuaW1wb3J0IHsgS2V5IH0gZnJvbSAnLi4vdXRpbC9rZXknO1xuXG5pbXBvcnQgeyBOZ2JEcm9wZG93bkNvbmZpZyB9IGZyb20gJy4vZHJvcGRvd24tY29uZmlnJztcbmltcG9ydCB7IEZPQ1VTQUJMRV9FTEVNRU5UU19TRUxFQ1RPUiB9IGZyb20gJy4uL3V0aWwvZm9jdXMtdHJhcCc7XG5pbXBvcnQgeyBnZXRBY3RpdmVFbGVtZW50IH0gZnJvbSAnLi4vdXRpbC91dGlsJztcblxuLyoqXG4gKiBBIGRpcmVjdGl2ZSB5b3Ugc2hvdWxkIHB1dCBvbiBhIGRyb3Bkb3duIGl0ZW0gdG8gZW5hYmxlIGtleWJvYXJkIG5hdmlnYXRpb24uXG4gKiBBcnJvdyBrZXlzIHdpbGwgbW92ZSBmb2N1cyBiZXR3ZWVuIGl0ZW1zIG1hcmtlZCB3aXRoIHRoaXMgZGlyZWN0aXZlLlxuICpcbiAqIEBzaW5jZSA0LjEuMFxuICovXG5ARGlyZWN0aXZlKHtcblx0c2VsZWN0b3I6ICdbbmdiRHJvcGRvd25JdGVtXScsXG5cdHN0YW5kYWxvbmU6IHRydWUsXG5cdGhvc3Q6IHtcblx0XHRjbGFzczogJ2Ryb3Bkb3duLWl0ZW0nLFxuXHRcdCdbY2xhc3MuZGlzYWJsZWRdJzogJ2Rpc2FibGVkJyxcblx0XHQnW3RhYkluZGV4XSc6ICdkaXNhYmxlZCA/IC0xIDogdGFiaW5kZXgnLFxuXHR9LFxufSlcbmV4cG9ydCBjbGFzcyBOZ2JEcm9wZG93bkl0ZW0ge1xuXHRzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfZGlzYWJsZWQ6IGJvb2xlYW4gfCAnJztcblxuXHRwcml2YXRlIF9kaXNhYmxlZCA9IGZhbHNlO1xuXG5cdG5hdGl2ZUVsZW1lbnQgPSBpbmplY3QoRWxlbWVudFJlZikubmF0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudDtcblxuXHRASW5wdXQoKSB0YWJpbmRleDogc3RyaW5nIHwgbnVtYmVyID0gMDtcblxuXHRASW5wdXQoKVxuXHRzZXQgZGlzYWJsZWQodmFsdWU6IGJvb2xlYW4pIHtcblx0XHR0aGlzLl9kaXNhYmxlZCA9IDxhbnk+dmFsdWUgPT09ICcnIHx8IHZhbHVlID09PSB0cnVlOyAvLyBhY2NlcHQgYW4gZW1wdHkgYXR0cmlidXRlIGFzIHRydWVcblx0fVxuXG5cdGdldCBkaXNhYmxlZCgpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5fZGlzYWJsZWQ7XG5cdH1cbn1cblxuLyoqXG4gKiBBIGRpcmVjdGl2ZSB0aGF0IHdpbGwgYmUgYXBwbGllZCBpZiBkcm9wZG93biBpdGVtIGlzIGEgYnV0dG9uLlxuICogSXQgd2lsbCBvbmx5IHNldCB0aGUgZGlzYWJsZWQgcHJvcGVydHkuXG4gKi9cbkBEaXJlY3RpdmUoe1xuXHRzZWxlY3RvcjogJ2J1dHRvbltuZ2JEcm9wZG93bkl0ZW1dJyxcblx0c3RhbmRhbG9uZTogdHJ1ZSxcblx0aG9zdDogeyAnW2Rpc2FibGVkXSc6ICdpdGVtLmRpc2FibGVkJyB9LFxufSlcbmV4cG9ydCBjbGFzcyBOZ2JEcm9wZG93bkJ1dHRvbkl0ZW0ge1xuXHRpdGVtID0gaW5qZWN0KE5nYkRyb3Bkb3duSXRlbSk7XG59XG5cbi8qKlxuICogQSBkaXJlY3RpdmUgdGhhdCB3cmFwcyBkcm9wZG93biBtZW51IGNvbnRlbnQgYW5kIGRyb3Bkb3duIGl0ZW1zLlxuICovXG5ARGlyZWN0aXZlKHtcblx0c2VsZWN0b3I6ICdbbmdiRHJvcGRvd25NZW51XScsXG5cdHN0YW5kYWxvbmU6IHRydWUsXG5cdGhvc3Q6IHtcblx0XHQnW2NsYXNzLmRyb3Bkb3duLW1lbnVdJzogJ3RydWUnLFxuXHRcdCdbY2xhc3Muc2hvd10nOiAnZHJvcGRvd24uaXNPcGVuKCknLFxuXHRcdCcoa2V5ZG93bi5BcnJvd1VwKSc6ICdkcm9wZG93bi5vbktleURvd24oJGV2ZW50KScsXG5cdFx0JyhrZXlkb3duLkFycm93RG93biknOiAnZHJvcGRvd24ub25LZXlEb3duKCRldmVudCknLFxuXHRcdCcoa2V5ZG93bi5Ib21lKSc6ICdkcm9wZG93bi5vbktleURvd24oJGV2ZW50KScsXG5cdFx0JyhrZXlkb3duLkVuZCknOiAnZHJvcGRvd24ub25LZXlEb3duKCRldmVudCknLFxuXHRcdCcoa2V5ZG93bi5FbnRlciknOiAnZHJvcGRvd24ub25LZXlEb3duKCRldmVudCknLFxuXHRcdCcoa2V5ZG93bi5TcGFjZSknOiAnZHJvcGRvd24ub25LZXlEb3duKCRldmVudCknLFxuXHRcdCcoa2V5ZG93bi5UYWIpJzogJ2Ryb3Bkb3duLm9uS2V5RG93bigkZXZlbnQpJyxcblx0XHQnKGtleWRvd24uU2hpZnQuVGFiKSc6ICdkcm9wZG93bi5vbktleURvd24oJGV2ZW50KScsXG5cdH0sXG59KVxuZXhwb3J0IGNsYXNzIE5nYkRyb3Bkb3duTWVudSB7XG5cdGRyb3Bkb3duID0gaW5qZWN0KE5nYkRyb3Bkb3duKTtcblx0bmF0aXZlRWxlbWVudCA9IGluamVjdChFbGVtZW50UmVmKS5uYXRpdmVFbGVtZW50IGFzIEhUTUxFbGVtZW50O1xuXG5cdEBDb250ZW50Q2hpbGRyZW4oTmdiRHJvcGRvd25JdGVtKSBtZW51SXRlbXM6IFF1ZXJ5TGlzdDxOZ2JEcm9wZG93bkl0ZW0+O1xufVxuXG4vKipcbiAqIEEgZGlyZWN0aXZlIHRvIG1hcmsgYW4gZWxlbWVudCB0byB3aGljaCBkcm9wZG93biBtZW51IHdpbGwgYmUgYW5jaG9yZWQuXG4gKlxuICogVGhpcyBpcyBhIHNpbXBsZSB2ZXJzaW9uIG9mIHRoZSBgTmdiRHJvcGRvd25Ub2dnbGVgIGRpcmVjdGl2ZS5cbiAqIEl0IHBsYXlzIHRoZSBzYW1lIHJvbGUsIGJ1dCBkb2Vzbid0IGxpc3RlbiB0byBjbGljayBldmVudHMgdG8gdG9nZ2xlIGRyb3Bkb3duIG1lbnUgdGh1cyBlbmFibGluZyBzdXBwb3J0XG4gKiBmb3IgZXZlbnRzIG90aGVyIHRoYW4gY2xpY2suXG4gKlxuICogQHNpbmNlIDEuMS4wXG4gKi9cbkBEaXJlY3RpdmUoe1xuXHRzZWxlY3RvcjogJ1tuZ2JEcm9wZG93bkFuY2hvcl0nLFxuXHRzdGFuZGFsb25lOiB0cnVlLFxuXHRob3N0OiB7XG5cdFx0Y2xhc3M6ICdkcm9wZG93bi10b2dnbGUnLFxuXHRcdCdbY2xhc3Muc2hvd10nOiAnZHJvcGRvd24uaXNPcGVuKCknLFxuXHRcdCdbYXR0ci5hcmlhLWV4cGFuZGVkXSc6ICdkcm9wZG93bi5pc09wZW4oKScsXG5cdH0sXG59KVxuZXhwb3J0IGNsYXNzIE5nYkRyb3Bkb3duQW5jaG9yIHtcblx0ZHJvcGRvd24gPSBpbmplY3QoTmdiRHJvcGRvd24pO1xuXHRuYXRpdmVFbGVtZW50ID0gaW5qZWN0KEVsZW1lbnRSZWYpLm5hdGl2ZUVsZW1lbnQgYXMgSFRNTEVsZW1lbnQ7XG59XG5cbi8qKlxuICogQSBkaXJlY3RpdmUgdG8gbWFyayBhbiBlbGVtZW50IHRoYXQgd2lsbCB0b2dnbGUgZHJvcGRvd24gdmlhIHRoZSBgY2xpY2tgIGV2ZW50LlxuICpcbiAqIFlvdSBjYW4gYWxzbyB1c2UgYE5nYkRyb3Bkb3duQW5jaG9yYCBhcyBhbiBhbHRlcm5hdGl2ZS5cbiAqL1xuQERpcmVjdGl2ZSh7XG5cdHNlbGVjdG9yOiAnW25nYkRyb3Bkb3duVG9nZ2xlXScsXG5cdHN0YW5kYWxvbmU6IHRydWUsXG5cdGhvc3Q6IHtcblx0XHRjbGFzczogJ2Ryb3Bkb3duLXRvZ2dsZScsXG5cdFx0J1tjbGFzcy5zaG93XSc6ICdkcm9wZG93bi5pc09wZW4oKScsXG5cdFx0J1thdHRyLmFyaWEtZXhwYW5kZWRdJzogJ2Ryb3Bkb3duLmlzT3BlbigpJyxcblx0XHQnKGNsaWNrKSc6ICdkcm9wZG93bi50b2dnbGUoKScsXG5cdFx0JyhrZXlkb3duLkFycm93VXApJzogJ2Ryb3Bkb3duLm9uS2V5RG93bigkZXZlbnQpJyxcblx0XHQnKGtleWRvd24uQXJyb3dEb3duKSc6ICdkcm9wZG93bi5vbktleURvd24oJGV2ZW50KScsXG5cdFx0JyhrZXlkb3duLkhvbWUpJzogJ2Ryb3Bkb3duLm9uS2V5RG93bigkZXZlbnQpJyxcblx0XHQnKGtleWRvd24uRW5kKSc6ICdkcm9wZG93bi5vbktleURvd24oJGV2ZW50KScsXG5cdFx0JyhrZXlkb3duLlRhYiknOiAnZHJvcGRvd24ub25LZXlEb3duKCRldmVudCknLFxuXHRcdCcoa2V5ZG93bi5TaGlmdC5UYWIpJzogJ2Ryb3Bkb3duLm9uS2V5RG93bigkZXZlbnQpJyxcblx0fSxcblx0cHJvdmlkZXJzOiBbeyBwcm92aWRlOiBOZ2JEcm9wZG93bkFuY2hvciwgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTmdiRHJvcGRvd25Ub2dnbGUpIH1dLFxufSlcbmV4cG9ydCBjbGFzcyBOZ2JEcm9wZG93blRvZ2dsZSBleHRlbmRzIE5nYkRyb3Bkb3duQW5jaG9yIHt9XG5cbi8qKlxuICogQSBkaXJlY3RpdmUgdGhhdCBwcm92aWRlcyBjb250ZXh0dWFsIG92ZXJsYXlzIGZvciBkaXNwbGF5aW5nIGxpc3RzIG9mIGxpbmtzIGFuZCBtb3JlLlxuICovXG5ARGlyZWN0aXZlKHtcblx0c2VsZWN0b3I6ICdbbmdiRHJvcGRvd25dJyxcblx0ZXhwb3J0QXM6ICduZ2JEcm9wZG93bicsXG5cdHN0YW5kYWxvbmU6IHRydWUsXG5cdGhvc3Q6IHsgJ1tjbGFzcy5zaG93XSc6ICdpc09wZW4oKScgfSxcbn0pXG5leHBvcnQgY2xhc3