UNPKG

igniteui-angular

Version:

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

481 lines • 36.1 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { ChangeDetectorRef, Component, ContentChildren, ElementRef, forwardRef, QueryList, Input, ViewChild, EventEmitter, Output, } from '@angular/core'; import { IgxToggleDirective } from '../directives/toggle/toggle.directive'; import { IgxDropDownItemComponent } from './drop-down-item.component'; import { IgxDropDownBase } from './drop-down.base'; import { IGX_DROPDOWN_BASE } from './drop-down.common'; import { isIE } from '../core/utils'; import { IgxSelectionAPIService } from '../core/selection'; import { Subject } from 'rxjs'; /** * **Ignite UI for Angular DropDown** - * [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/drop_down.html) * * The Ignite UI for Angular Drop Down displays a scrollable list of items which may be visually grouped and * supports selection of a single item. Clicking or tapping an item selects it and closes the Drop Down * * Example: * ```html * <igx-drop-down> * <igx-drop-down-item *ngFor="let item of items" disabled={{item.disabled}} isHeader={{item.header}}> * {{ item.value }} * </igx-drop-down-item> * </igx-drop-down> * ``` */ export class IgxDropDownComponent extends IgxDropDownBase { /** * @param {?} elementRef * @param {?} cdr * @param {?} selection */ constructor(elementRef, cdr, selection) { super(elementRef, cdr); this.elementRef = elementRef; this.cdr = cdr; this.selection = selection; this.destroy$ = new Subject(); /** * Gets/sets whether items take focus. Disabled by default. * When enabled, drop down items gain tab index and are focused when active - * this includes activating the selected item when opening the drop down and moving with keyboard navigation. * * Note: Keep that focus shift in mind when using the igxDropDownItemNavigation directive * and ensure it's placed either on each focusable item or a common ancestor to allow it to handle keyboard events. * * ```typescript * // get * let dropDownAllowsItemFocus = this.dropdown.allowItemsFocus; * ``` * * ```html * <!--set--> * <igx-drop-down [allowItemsFocus]='true'></igx-drop-down> * ``` */ this.allowItemsFocus = false; /** * Emitted before the dropdown is opened * * ```html * <igx-drop-down (onOpening)='handleOpening()'></igx-drop-down> * ``` */ this.onOpening = new EventEmitter(); /** * Emitted after the dropdown is opened * * ```html * <igx-drop-down (onOpened)='handleOpened()'></igx-drop-down> * ``` */ this.onOpened = new EventEmitter(); /** * Emitted before the dropdown is closed * * ```html * <igx-drop-down (onClosing)='handleClosing()'></igx-drop-down> * ``` */ this.onClosing = new EventEmitter(); /** * Emitted after the dropdown is closed * * ```html * <igx-drop-down (onClosed)='handleClosed()'></igx-drop-down> * ``` */ this.onClosed = new EventEmitter(); } /** * @return {?} */ get id() { return this._id; } /** * @param {?} value * @return {?} */ set id(value) { this.toggleDirective.id = value; this.selection.set(value, this.selection.get(this.id)); this.selection.clear(this.id); this._id = value; } /** * Id of the internal listbox of the drop down * @return {?} */ get listId() { return this.id + '-list'; } /** * Get currently selected item * * ```typescript * let currentItem = this.dropdown.selectedItem; * ``` * @return {?} */ get selectedItem() { /** @type {?} */ const selectedItem = this.selection.first_item(this.id); if (selectedItem) { if (selectedItem.selected) { return selectedItem; } this.selection.clear(this.id); } return null; } /** * Gets if the dropdown is collapsed * * ```typescript * let isCollapsed = this.dropdown.collapsed; * ``` * @return {?} */ get collapsed() { return this.toggleDirective.collapsed; } /** * @protected * @return {?} */ get scrollContainer() { return this.toggleDirective.element; } /** * Opens the dropdown * * ```typescript * this.dropdown.open(); * ``` * @param {?=} overlaySettings * @return {?} */ open(overlaySettings) { this.toggleDirective.open(overlaySettings); } /** * Closes the dropdown * * ```typescript * this.dropdown.close(); * ``` * @return {?} */ close() { this.toggleDirective.close(); } /** * Toggles the dropdown * * ```typescript * this.dropdown.toggle(); * ``` * @param {?=} overlaySettings * @return {?} */ toggle(overlaySettings) { if (this.collapsed || this.toggleDirective.isClosing) { this.open(overlaySettings); } else { this.close(); } } /** * Select an item by index * @param {?} index of the item to select * @return {?} */ setSelectedItem(index) { if (index < 0 || index >= this.items.length) { return; } /** @type {?} */ const newSelection = this.items[index]; this.selectItem(newSelection); } /** * Navigates to the item on the specified index * @param {?} index * @return {?} */ navigateItem(index) { super.navigateItem(index); if (this.allowItemsFocus && this.focusedItem) { this.focusedItem.element.nativeElement.focus(); this.cdr.markForCheck(); } } /** * @hidden \@internal * @param {?} e * @return {?} */ onToggleOpening(e) { this.onOpening.emit(e); if (e.cancel) { return; } this.scrollToItem(this.selectedItem); } /** * @hidden \@internal * @return {?} */ onToggleOpened() { if (this.selectedItem) { this._focusedItem = this.selectedItem; this._focusedItem.focused = true; } else if (this.allowItemsFocus) { this.navigateFirst(); } this.onOpened.emit(); } /** * @hidden \@internal * @param {?} e * @return {?} */ onToggleClosing(e) { this.onClosing.emit(e); } /** * @hidden \@internal * @return {?} */ onToggleClosed() { if (this._focusedItem) { this._focusedItem.focused = false; } this.onClosed.emit(); } /** * @hidden \@internal * @return {?} */ ngOnDestroy() { this.destroy$.next(true); this.destroy$.complete(); this.selection.clear(this.id); } /** * @protected * @param {?} item * @return {?} */ scrollToItem(item) { /** @type {?} */ const itemPosition = this.calculateScrollPosition(item); // in IE11 setting sctrollTop is somehow slow and forces dropdown // to appear on screen before animation start. As a result dropdown // flickers badly. This is why we set scrollTop just a little later // allowing animation to start and prevent dropdown flickering if (isIE()) { setTimeout(() => { this.scrollContainer.scrollTop = (itemPosition); }, 1); } else { this.scrollContainer.scrollTop = (itemPosition); } } /** * @hidden \@internal * @param {?} item * @return {?} */ calculateScrollPosition(item) { if (!item) { return 0; } /** @type {?} */ const elementRect = item.element.nativeElement.getBoundingClientRect(); /** @type {?} */ const parentRect = this.scrollContainer.getBoundingClientRect(); /** @type {?} */ const scrollDelta = parentRect.top - elementRect.top; /** @type {?} */ let scrollPosition = this.scrollContainer.scrollTop - scrollDelta; /** @type {?} */ const dropDownHeight = this.scrollContainer.clientHeight; scrollPosition -= dropDownHeight / 2; scrollPosition += item.elementHeight / 2; return Math.floor(scrollPosition); } /** * @hidden \@internal * @return {?} */ ngOnInit() { this.toggleDirective.id = this.id; } /** * Keydown Handler * @param {?} key * @param {?=} event * @return {?} */ onItemActionKey(key, event) { super.onItemActionKey(key, event); this.close(); } /** * Handles the `onSelection` emit and the drop down toggle when selection changes * @hidden * \@internal * @param {?=} newSelection * @param {?=} event * @return {?} */ selectItem(newSelection, event) { /** @type {?} */ const oldSelection = this.selectedItem; if (!newSelection) { newSelection = this._focusedItem; } if (newSelection === null) { return; } if (newSelection.isHeader) { return; } /** @type {?} */ const args = { oldSelection, newSelection, cancel: false }; this.onSelection.emit(args); if (!args.cancel) { this.selection.set(this.id, new Set([newSelection])); if (oldSelection) { oldSelection.selected = false; } if (newSelection) { newSelection.selected = true; } if (event) { this.toggleDirective.close(); } } } } IgxDropDownComponent.decorators = [ { type: Component, args: [{ selector: 'igx-drop-down', template: "<div class=\"igx-drop-down__list\" igxToggle [style.width]=\"width\" [style.height]=\"height\"\n[style.maxHeight]=\"maxHeight\" [attr.id]=\"this.listId\" role=\"listbox\"\n (onOpening)=\"onToggleOpening($event)\" (onOpened)=\"onToggleOpened()\"\n (onClosing)=\"onToggleClosing($event)\" (onClosed)=\"onToggleClosed()\">\n <ng-container *ngIf=\"!collapsed\">\n <ng-content></ng-content>\n </ng-container>\n</div>\n", providers: [{ provide: IGX_DROPDOWN_BASE, useExisting: IgxDropDownComponent }] }] } ]; /** @nocollapse */ IgxDropDownComponent.ctorParameters = () => [ { type: ElementRef }, { type: ChangeDetectorRef }, { type: IgxSelectionAPIService } ]; IgxDropDownComponent.propDecorators = { toggleDirective: [{ type: ViewChild, args: [IgxToggleDirective,] }], children: [{ type: ContentChildren, args: [forwardRef(() => IgxDropDownItemComponent), { descendants: true },] }], allowItemsFocus: [{ type: Input }], id: [{ type: Input }], onOpening: [{ type: Output }], onOpened: [{ type: Output }], onClosing: [{ type: Output }], onClosed: [{ type: Output }] }; if (false) { /** * @type {?} * @protected */ IgxDropDownComponent.prototype.destroy$; /** * @type {?} * @protected */ IgxDropDownComponent.prototype.toggleDirective; /** * @hidden * \@internal * @type {?} */ IgxDropDownComponent.prototype.children; /** * Gets/sets whether items take focus. Disabled by default. * When enabled, drop down items gain tab index and are focused when active - * this includes activating the selected item when opening the drop down and moving with keyboard navigation. * * Note: Keep that focus shift in mind when using the igxDropDownItemNavigation directive * and ensure it's placed either on each focusable item or a common ancestor to allow it to handle keyboard events. * * ```typescript * // get * let dropDownAllowsItemFocus = this.dropdown.allowItemsFocus; * ``` * * ```html * <!--set--> * <igx-drop-down [allowItemsFocus]='true'></igx-drop-down> * ``` * @type {?} */ IgxDropDownComponent.prototype.allowItemsFocus; /** * Emitted before the dropdown is opened * * ```html * <igx-drop-down (onOpening)='handleOpening()'></igx-drop-down> * ``` * @type {?} */ IgxDropDownComponent.prototype.onOpening; /** * Emitted after the dropdown is opened * * ```html * <igx-drop-down (onOpened)='handleOpened()'></igx-drop-down> * ``` * @type {?} */ IgxDropDownComponent.prototype.onOpened; /** * Emitted before the dropdown is closed * * ```html * <igx-drop-down (onClosing)='handleClosing()'></igx-drop-down> * ``` * @type {?} */ IgxDropDownComponent.prototype.onClosing; /** * Emitted after the dropdown is closed * * ```html * <igx-drop-down (onClosed)='handleClosed()'></igx-drop-down> * ``` * @type {?} */ IgxDropDownComponent.prototype.onClosed; /** * @type {?} * @protected */ IgxDropDownComponent.prototype.elementRef; /** * @type {?} * @protected */ IgxDropDownComponent.prototype.cdr; /** * @type {?} * @protected */ IgxDropDownComponent.prototype.selection; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcC1kb3duLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2lnbml0ZXVpLWFuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvZHJvcC1kb3duL2Ryb3AtZG93bi5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFDSCxpQkFBaUIsRUFDakIsU0FBUyxFQUNULGVBQWUsRUFDZixVQUFVLEVBQ1YsVUFBVSxFQUVWLFNBQVMsRUFFVCxLQUFLLEVBRUwsU0FBUyxFQUNULFlBQVksRUFDWixNQUFNLEdBQ1QsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sdUNBQXVDLENBQUM7QUFDM0UsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDdEUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRW5ELE9BQU8sRUFBRSxpQkFBaUIsRUFBaUIsTUFBTSxvQkFBb0IsQ0FBQztBQUV0RSxPQUFPLEVBQW1ELElBQUksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN0RixPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7OztBQTBCL0IsTUFBTSxPQUFPLG9CQUFxQixTQUFRLGVBQWU7Ozs7OztJQTJIckQsWUFDYyxVQUFzQixFQUN0QixHQUFzQixFQUN0QixTQUFpQztRQUMzQyxLQUFLLENBQUMsVUFBVSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBSGIsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUN0QixRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQUN0QixjQUFTLEdBQVQsU0FBUyxDQUF3QjtRQTdIckMsYUFBUSxHQUFHLElBQUksT0FBTyxFQUFXLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7UUErQnJDLG9CQUFlLEdBQUcsS0FBSyxDQUFD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QUFvQixFQUFFLENBQUM7YUFDakY7Ozs7WUE1Q0csVUFBVTtZQUhWLGlCQUFpQjtZQXFCWixzQkFBc0I7Ozs4QkE4QjFCLFNBQVMsU0FBQyxrQkFBa0I7dUJBTzVCLGVBQWUsU0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsd0JBQXdCLENBQUMsRUFBRSxFQUFFLFdBQVcsRUFBRSxJQUFJLEVBQUU7OEJBcUJqRixLQUFLO2lCQUdMLEtBQUs7d0JBdUJMLE1BQU07dUJBVU4sTUFBTTt3QkFVTixNQUFNO3VCQVVOLE1BQU07Ozs7Ozs7SUF0RlAsd0NBQTRDOzs7OztJQUU1QywrQ0FDOEM7Ozs7OztJQU05Qyx3Q0FDZ0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBb0JoRCwrQ0FDK0I7Ozs7Ozs7OztJQXlCL0IseUNBQzJEOzs7Ozs7Ozs7SUFTM0Qsd0NBQzJDOzs7Ozs7Ozs7SUFTM0MseUNBQ2tFOzs7Ozs7Ozs7SUFTbEUsd0NBQzJDOzs7OztJQW9DdkMsMENBQWdDOzs7OztJQUNoQyxtQ0FBZ0M7Ozs7O0lBQ2hDLHlDQUEyQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQ29tcG9uZW50LFxuICAgIENvbnRlbnRDaGlsZHJlbixcbiAgICBFbGVtZW50UmVmLFxuICAgIGZvcndhcmRSZWYsXG4gICAgTmdNb2R1bGUsXG4gICAgUXVlcnlMaXN0LFxuICAgIE9uSW5pdCxcbiAgICBJbnB1dCxcbiAgICBPbkRlc3Ryb3ksXG4gICAgVmlld0NoaWxkLFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBPdXRwdXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSWd4VG9nZ2xlRGlyZWN0aXZlIH0gZnJvbSAnLi4vZGlyZWN0aXZlcy90b2dnbGUvdG9nZ2xlLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBJZ3hEcm9wRG93bkl0ZW1Db21wb25lbnQgfSBmcm9tICcuL2Ryb3AtZG93bi1pdGVtLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJZ3hEcm9wRG93bkJhc2UgfSBmcm9tICcuL2Ryb3AtZG93bi5iYXNlJztcbmltcG9ydCB7IERyb3BEb3duQWN0aW9uS2V5IH0gZnJvbSAnLi9kcm9wLWRvd24uY29tbW9uJztcbmltcG9ydCB7IElHWF9EUk9QRE9XTl9CQVNFLCBJRHJvcERvd25CYXNlIH0gZnJvbSAnLi9kcm9wLWRvd24uY29tbW9uJztcbmltcG9ydCB7IElTZWxlY3Rpb25FdmVudEFyZ3MsIE5hdmlnYXRlIH0gZnJvbSAnLi9kcm9wLWRvd24uY29tbW9uJztcbmltcG9ydCB7IENhbmNlbGFibGVFdmVudEFyZ3MsIENhbmNlbGFibGVCcm93c2VyRXZlbnRBcmdzLCBpc0lFIH0gZnJvbSAnLi4vY29yZS91dGlscyc7XG5pbXBvcnQgeyBJZ3hTZWxlY3Rpb25BUElTZXJ2aWNlIH0gZnJvbSAnLi4vY29yZS9zZWxlY3Rpb24nO1xuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgSWd4RHJvcERvd25JdGVtQmFzZSB9IGZyb20gJy4vZHJvcC1kb3duLWl0ZW0uYmFzZSc7XG5pbXBvcnQgeyBPdmVybGF5U2V0dGluZ3MgfSBmcm9tICcuLi9zZXJ2aWNlcyc7XG5cblxuLyoqXG4gKiAqKklnbml0ZSBVSSBmb3IgQW5ndWxhciBEcm9wRG93bioqIC1cbiAqIFtEb2N1bWVudGF0aW9uXShodHRwczovL3d3dy5pbmZyYWdpc3RpY3MuY29tL3Byb2R1Y3RzL2lnbml0ZS11aS1hbmd1bGFyL2FuZ3VsYXIvY29tcG9uZW50cy9kcm9wX2Rvd24uaHRtbClcbiAqXG4gKiBUaGUgSWduaXRlIFVJIGZvciBBbmd1bGFyIERyb3AgRG93biBkaXNwbGF5cyBhIHNjcm9sbGFibGUgbGlzdCBvZiBpdGVtcyB3aGljaCBtYXkgYmUgdmlzdWFsbHkgZ3JvdXBlZCBhbmRcbiAqIHN1cHBvcnRzIHNlbGVjdGlvbiBvZiBhIHNpbmdsZSBpdGVtLiBDbGlja2luZyBvciB0YXBwaW5nIGFuIGl0ZW0gc2VsZWN0cyBpdCBhbmQgY2xvc2VzIHRoZSBEcm9wIERvd25cbiAqXG4gKiBFeGFtcGxlOlxuICogYGBgaHRtbFxuICogPGlneC1kcm9wLWRvd24+XG4gKiAgIDxpZ3gtZHJvcC1kb3duLWl0ZW0gKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbXNcIiBkaXNhYmxlZD17e2l0ZW0uZGlzYWJsZWR9fSBpc0hlYWRlcj17e2l0ZW0uaGVhZGVyfX0+XG4gKiAgICAge3sgaXRlbS52YWx1ZSB9fVxuICogICA8L2lneC1kcm9wLWRvd24taXRlbT5cbiAqIDwvaWd4LWRyb3AtZG93bj5cbiAqIGBgYFxuICovXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2lneC1kcm9wLWRvd24nLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9kcm9wLWRvd24uY29tcG9uZW50Lmh0bWwnLFxuICAgIHByb3ZpZGVyczogW3sgcHJvdmlkZTogSUdYX0RST1BET1dOX0JBU0UsIHVzZUV4aXN0aW5nOiBJZ3hEcm9wRG93bkNvbXBvbmVudCB9XVxufSlcbmV4cG9ydCBjbGFzcyBJZ3hEcm9wRG93bkNvbXBvbmVudCBleHRlbmRzIElneERyb3BEb3duQmFzZSBpbXBsZW1lbnRzIElEcm9wRG93bkJhc2UsIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgICBwcm90ZWN0ZWQgZGVzdHJveSQgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuXG4gICAgQFZpZXdDaGlsZChJZ3hUb2dnbGVEaXJlY3RpdmUpXG4gICAgcHJvdGVjdGVkIHRvZ2dsZURpcmVjdGl2ZTogSWd4VG9nZ2xlRGlyZWN0aXZlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlblxuICAgICAqIEBpbnRlcm5hbFxuICAgICAqL1xuICAgIEBDb250ZW50Q2hpbGRyZW4oZm9yd2FyZFJlZigoKSA9PiBJZ3hEcm9wRG93bkl0ZW1Db21wb25lbnQpLCB7IGRlc2NlbmRhbnRzOiB0cnVlIH0pXG4gICAgcHVibGljIGNoaWxkcmVuOiBRdWVyeUxpc3Q8SWd4RHJvcERvd25JdGVtQmFzZT47XG5cbiAgICAvKipcbiAgICAgKiBHZXRzL3NldHMgd2hldGhlciBpdGVtcyB0YWtlIGZvY3VzLiBEaXNhYmxlZCBieSBkZWZhdWx0LlxuICAgICAqIFdoZW4gZW5hYmxlZCwgZHJvcCBkb3duIGl0ZW1zIGdhaW4gdGFiIGluZGV4IGFuZCBhcmUgZm9jdXNlZCB3aGVuIGFjdGl2ZSAtXG4gICAgICogdGhpcyBpbmNsdWRlcyBhY3RpdmF0aW5nIHRoZSBzZWxlY3RlZCBpdGVtIHdoZW4gb3BlbmluZyB0aGUgZHJvcCBkb3duIGFuZCBtb3Zpbmcgd2l0aCBrZXlib2FyZCBuYXZpZ2F0aW9uLlxuICAgICAqXG4gICAgICogTm90ZTogS2VlcCB0aGF0IGZvY3VzIHNoaWZ0IGluIG1pbmQgd2hlbiB1c2luZyB0aGUgaWd4RHJvcERvd25JdGVtTmF2aWdhdGlvbiBkaXJlY3RpdmVcbiAgICAgKiBhbmQgZW5zdXJlIGl0J3MgcGxhY2VkIGVpdGhlciBvbiBlYWNoIGZvY3VzYWJsZSBpdGVtIG9yIGEgY29tbW9uIGFuY2VzdG9yIHRvIGFsbG93IGl0IHRvIGhhbmRsZSBrZXlib2FyZCBldmVudHMuXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogLy8gZ2V0XG4gICAgICogbGV0IGRyb3BEb3duQWxsb3dzSXRlbUZvY3VzID0gdGhpcy5kcm9wZG93bi5hbGxvd0l0ZW1zRm9jdXM7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBgYGBodG1sXG4gICAgICogPCEtLXNldC0tPlxuICAgICAqIDxpZ3gtZHJvcC1kb3duIFthbGxvd0l0ZW1zRm9jdXNdPSd0cnVlJz48L2lneC1kcm9wLWRvd24+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgYWxsb3dJdGVtc0ZvY3VzID0gZmFsc2U7XG5cbiAgICBASW5wdXQoKVxuICAgIGdldCBpZCgpOiBzdHJpbmcge1xuICAgICAgICByZXR1cm4gdGhpcy5faWQ7XG4gICAgfVxuICAgIHNldCBpZCh2YWx1ZTogc3RyaW5nKSB7XG4gICAgICAgIHRoaXMudG9nZ2xlRGlyZWN0aXZlLmlkID0gdmFsdWU7XG4gICAgICAgIHRoaXMuc2VsZWN0aW9uLnNldCh2YWx1ZSwgdGhpcy5zZWxlY3Rpb24uZ2V0KHRoaXMuaWQpKTtcbiAgICAgICAgdGhpcy5zZWxlY3Rpb24uY2xlYXIodGhpcy5pZCk7XG4gICAgICAgIHRoaXMuX2lkID0gdmFsdWU7XG4gICAgfVxuXG4gICAgLyoqIElkIG9mIHRoZSBpbnRlcm5hbCBsaXN0Ym94IG9mIHRoZSBkcm9wIGRvd24gKi9cbiAgICBwdWJsaWMgZ2V0IGxpc3RJZCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaWQgKyAnLWxpc3QnO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEVtaXR0ZWQgYmVmb3JlIHRoZSBkcm9wZG93biBpcyBvcGVuZWRcbiAgICAgKlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWRyb3AtZG93biAob25PcGVuaW5nKT0naGFuZGxlT3BlbmluZygpJz48L2lneC1kcm9wLWRvd24+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIG9uT3BlbmluZyA9IG5ldyBFdmVudEVtaXR0ZXI8Q2FuY2VsYWJsZUV2ZW50QXJncz4oKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXR0ZWQgYWZ0ZXIgdGhlIGRyb3Bkb3duIGlzIG9wZW5lZFxuICAgICAqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtZHJvcC1kb3duIChvbk9wZW5lZCk9J2hhbmRsZU9wZW5lZCgpJz48L2lneC1kcm9wLWRvd24+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIG9uT3BlbmVkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gICAgLyoqXG4gICAgICogRW1pdHRlZCBiZWZvcmUgdGhlIGRyb3Bkb3duIGlzIGNsb3NlZFxuICAgICAqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtZHJvcC1kb3duIChvbkNsb3NpbmcpPSdoYW5kbGVDbG9zaW5nKCknPjwvaWd4LWRyb3AtZG93bj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25DbG9zaW5nID0gbmV3IEV2ZW50RW1pdHRlcjxDYW5jZWxhYmxlQnJvd3NlckV2ZW50QXJncz4oKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXR0ZWQgYWZ0ZXIgdGhlIGRyb3Bkb3duIGlzIGNsb3NlZFxuICAgICAqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtZHJvcC1kb3duIChvbkNsb3NlZCk9J2hhbmRsZUNsb3NlZCgpJz48L2lneC1kcm9wLWRvd24+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIG9uQ2xvc2VkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gICAgLyoqXG4gICAgICogR2V0IGN1cnJlbnRseSBzZWxlY3RlZCBpdGVtXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbGV0IGN1cnJlbnRJdGVtID0gdGhpcy5kcm9wZG93bi5zZWxlY3RlZEl0ZW07XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCBzZWxlY3RlZEl0ZW0oKTogSWd4RHJvcERvd25JdGVtQmFzZSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkSXRlbSA9IHRoaXMuc2VsZWN0aW9uLmZpcnN0X2l0ZW0odGhpcy5pZCk7XG4gICAgICAgIGlmIChzZWxlY3RlZEl0ZW0pIHtcbiAgICAgICAgICAgIGlmIChzZWxlY3RlZEl0ZW0uc2VsZWN0ZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2VsZWN0ZWRJdGVtO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5zZWxlY3Rpb24uY2xlYXIodGhpcy5pZCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBpZiB0aGUgZHJvcGRvd24gaXMgY29sbGFwc2VkXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogbGV0IGlzQ29sbGFwc2VkID0gdGhpcy5kcm9wZG93bi5jb2xsYXBzZWQ7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGdldCBjb2xsYXBzZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLnRvZ2dsZURpcmVjdGl2ZS5jb2xsYXBzZWQ7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIGdldCBzY3JvbGxDb250YWluZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnRvZ2dsZURpcmVjdGl2ZS5lbGVtZW50O1xuICAgIH1cblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwcm90ZWN0ZWQgZWxlbWVudFJlZjogRWxlbWVudFJlZixcbiAgICAgICAgcHJvdGVjdGVkIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgICAgIHByb3RlY3RlZCBzZWxlY3Rpb246IElneFNlbGVjdGlvbkFQSVNlcnZpY2UpIHtcbiAgICAgICAgc3VwZXIoZWxlbWVudFJlZiwgY2RyKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBPcGVucyB0aGUgZHJvcGRvd25cbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiB0aGlzLmRyb3Bkb3duLm9wZW4oKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgb3BlbihvdmVybGF5U2V0dGluZ3M/OiBPdmVybGF5U2V0dGluZ3MpIHtcbiAgICAgICAgdGhpcy50b2dnbGVEaXJlY3RpdmUub3BlbihvdmVybGF5U2V0dGluZ3MpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENsb3NlcyB0aGUgZHJvcGRvd25cbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiB0aGlzLmRyb3Bkb3duLmNsb3NlKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIGNsb3NlKCkge1xuICAgICAgICB0aGlzLnRvZ2dsZURpcmVjdGl2ZS5jbG9zZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFRvZ2dsZXMgdGhlIGRyb3Bkb3duXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogdGhpcy5kcm9wZG93bi50b2dnbGUoKTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgdG9nZ2xlKG92ZXJsYXlTZXR0aW5ncz86IE92ZXJsYXlTZXR0aW5ncykge1xuICAgICAgICBpZiAodGhpcy5jb2xsYXBzZWQgfHwgdGhpcy50b2dnbGVEaXJlY3RpdmUuaXNDbG9zaW5nKSB7XG4gICAgICAgICAgICB0aGlzLm9wZW4ob3ZlcmxheVNldHRpbmdzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuY2xvc2UoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlbGVjdCBhbiBpdGVtIGJ5IGluZGV4XG4gICAgICogQHBhcmFtIGluZGV4IG9mIHRoZSBpdGVtIHRvIHNlbGVjdFxuICAgICAqL1xuICAgIHB1YmxpYyBzZXRTZWxlY3RlZEl0ZW0oaW5kZXg6IG51bWJlcikge1xuICAgICAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IHRoaXMuaXRlbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgbmV3U2VsZWN0aW9uID0gdGhpcy5pdGVtc1tpbmRleF07XG4gICAgICAgIHRoaXMuc2VsZWN0SXRlbShuZXdTZWxlY3Rpb24pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE5hdmlnYXRlcyB0byB0aGUgaXRlbSBvbiB0aGUgc3BlY2lmaWVkIGluZGV4XG4gICAgICogQHBhcmFtIG5ld0luZGV4IG51bWJlclxuICAgICAqL1xuICAgIHB1YmxpYyBuYXZpZ2F0ZUl0ZW0oaW5kZXg6IG51bWJlcikge1xuICAgICAgICBzdXBlci5uYXZpZ2F0ZUl0ZW0oaW5kZXgpO1xuICAgICAgICBpZiAodGhpcy5hbGxvd0l0ZW1zRm9jdXMgJiYgdGhpcy5mb2N1c2VkSXRlbSkge1xuICAgICAgICAgICAgdGhpcy5mb2N1c2VkSXRlbS5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICAgICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlbiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgb25Ub2dnbGVPcGVuaW5nKGU6IENhbmNlbGFibGVFdmVudEFyZ3MpIHtcbiAgICAgICAgdGhpcy5vbk9wZW5pbmcuZW1pdChlKTtcbiAgICAgICAgaWYgKGUuY2FuY2VsKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5zY3JvbGxUb0l0ZW0odGhpcy5zZWxlY3RlZEl0ZW0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW4gQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIG9uVG9nZ2xlT3BlbmVkKCkge1xuICAgICAgICBpZiAodGhpcy5zZWxlY3RlZEl0ZW0pIHtcbiAgICAgICAgICAgIHRoaXMuX2ZvY3VzZWRJdGVtID0gdGhpcy5zZWxlY3RlZEl0ZW07XG4gICAgICAgICAgICB0aGlzLl9mb2N1c2VkSXRlbS5mb2N1c2VkID0gdHJ1ZTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmFsbG93SXRlbXNGb2N1cykge1xuICAgICAgICAgICAgdGhpcy5uYXZpZ2F0ZUZpcnN0KCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vbk9wZW5lZC5lbWl0KCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlbiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgb25Ub2dnbGVDbG9zaW5nKGU6IENhbmNlbGFibGVCcm93c2VyRXZlbnRBcmdzKSB7XG4gICAgICAgIHRoaXMub25DbG9zaW5nLmVtaXQoZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQGhpZGRlbiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgb25Ub2dnbGVDbG9zZWQoKSB7XG4gICAgICAgIGlmICh0aGlzLl9mb2N1c2VkSXRlbSkge1xuICAgICAgICAgICAgdGhpcy5fZm9jdXNlZEl0ZW0uZm9jdXNlZCA9IGZhbHNlO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub25DbG9zZWQuZW1pdCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW4gQGludGVybmFsXG4gICAgICovXG4gICAgcHVibGljIG5nT25EZXN0cm95KCkge1xuICAgICAgICB0aGlzLmRlc3Ryb3kkLm5leHQodHJ1ZSk7XG4gICAgICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcbiAgICAgICAgdGhpcy5zZWxlY3Rpb24uY2xlYXIodGhpcy5pZCk7XG4gICAgfVxuXG4gICAgcHJvdGVjdGVkIHNjcm9sbFRvSXRlbShpdGVtOiBJZ3hEcm9wRG93bkl0ZW1CYXNlKSB7XG4gICAgICAgIGNvbnN0IGl0ZW1Qb3NpdGlvbiA9IHRoaXMuY2FsY3VsYXRlU2Nyb2xsUG9zaXRpb24oaXRlbSk7XG5cbiAgICAgICAgLy8gIGluIElFMTEgc2V0dGluZyBzY3Ryb2xsVG9wIGlzIHNvbWVob3cgc2xvdyBhbmQgZm9yY2VzIGRyb3Bkb3duXG4gICAgICAgIC8vICB0byBhcHBlYXIgb24gc2NyZWVuIGJlZm9yZSBhbmltYXRpb24gc3RhcnQuIEFzIGEgcmVzdWx0IGRyb3Bkb3duXG4gICAgICAgIC8vICBmbGlja2VycyBiYWRseS4gVGhpcyBpcyB3aHkgd2Ugc2V0IHNjcm9sbFRvcCBqdXN0IGEgbGl0dGxlIGxhdGVyXG4gICAgICAgIC8vICBhbGxvd2luZyBhbmltYXRpb24gdG8gc3RhcnQgYW5kIHByZXZlbnQgZHJvcGRvd24gZmxpY2tlcmluZ1xuICAgICAgICBpZiAoaXNJRSgpKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICAgICAgICB0aGlzLnNjcm9sbENvbnRhaW5lci5zY3JvbGxUb3AgPSAoaXRlbVBvc2l0aW9uKTtcbiAgICAgICAgICAgIH0sIDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5zY3JvbGxDb250YWluZXIuc2Nyb2xsVG9wID0gKGl0ZW1Qb3NpdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbiAgICBwdWJsaWMgY2FsY3VsYXRlU2Nyb2xsUG9zaXRpb24oaXRlbTogSWd4RHJvcERvd25JdGVtQmFzZSk6IG51bWJlciB7XG4gICAgICAgIGlmICghaXRlbSkge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBlbGVtZW50UmVjdCA9IGl0ZW0uZWxlbWVudC5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBjb25zdCBwYXJlbnRSZWN0ID0gdGhpcy5zY3JvbGxDb250YWluZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIGNvbnN0IHNjcm9sbERlbHRhID0gcGFyZW50UmVjdC50b3AgLSBlbGVtZW50UmVjdC50b3A7XG4gICAgICAgIGxldCBzY3JvbGxQb3NpdGlvbiA9IHRoaXMuc2Nyb2xsQ29udGFpbmVyLnNjcm9sbFRvcCAtIHNjcm9sbERlbHRhO1xuXG4gICAgICAgIGNvbnN0IGRyb3BEb3duSGVpZ2h0ID0gdGhpcy5zY3JvbGxDb250YWluZXIuY2xpZW50SGVpZ2h0O1xuICAgICAgICBzY3JvbGxQb3NpdGlvbiAtPSBkcm9wRG93bkhlaWdodCAvIDI7XG4gICAgICAgIHNjcm9sbFBvc2l0aW9uICs9IGl0ZW0uZWxlbWVudEhlaWdodCAvIDI7XG5cbiAgICAgICAgcmV0dXJuIE1hdGguZmxvb3Ioc2Nyb2xsUG9zaXRpb24pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW4gQGludGVybmFsXG4gICAgICovXG4gICAgbmdPbkluaXQoKSB7XG4gICAgICAgIHRoaXMudG9nZ2xlRGlyZWN0aXZlLmlkID0gdGhpcy5pZDtcbiAgICB9XG5cbiAgICAvKiogS2V5ZG93biBIYW5kbGVyICovXG4gICAgcHVibGljIG9uSXRlbUFjdGlvbktleShrZXk6IERyb3BEb3duQWN0aW9uS2V5LCBldmVudD86IEV2ZW50KSB7XG4gICAgICAgIHN1cGVyLm9uSXRlbUFjdGlvbktleShrZXksIGV2ZW50KTtcbiAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEhhbmRsZXMgdGhlIGBvblNlbGVjdGlvbmAgZW1pdCBhbmQgdGhlIGRyb3AgZG93biB0b2dnbGUgd2hlbiBzZWxlY3Rpb24gY2hhbmdlc1xuICAgICAqIEBoaWRkZW5cbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKiBAcGFyYW0gbmV3U2VsZWN0aW9uXG4gICAgICogQHBhcmFtIGV2ZW50XG4gICAgICovXG4gICAgcHVibGljIHNlbGVjdEl0ZW0obmV3U2VsZWN0aW9uPzogSWd4RHJvcERvd25JdGVtQmFzZSwgZXZlbnQ/OiBFdmVudCkge1xuICAgICAgICBjb25zdCBvbGRTZWxlY3Rpb24gPSB0aGlzLnNlbGVjdGVkSXRlbTtcbiAgICAgICAgaWYgKCFuZXdTZWxlY3Rpb24pIHtcbiAgICAgICAgICAgIG5ld1NlbGVjdGlvbiA9IHRoaXMuX2ZvY3VzZWRJdGVtO1xuICAgICAgICB9XG4gICAgICAgIGlmIChuZXdTZWxlY3Rpb24gPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAobmV3U2VsZWN0aW9uLmlzSGVhZGVyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYXJnczogSVNlbGVjdGlvbkV2ZW50QXJncyA9IHsgb2xkU2VsZWN0aW9uLCBuZXdTZWxlY3Rpb24sIGNhbmNlbDogZmFsc2UgfTtcbiAgICAgICAgdGhpcy5vblNlbGVjdGlvbi5lbWl0KGFyZ3MpO1xuXG4gICAgICAgIGlmICghYXJncy5jYW5jZWwpIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uLnNldCh0aGlzLmlkLCBuZXcgU2V0KFtuZXdTZWxlY3Rpb25dKSk7XG4gICAgICAgICAgICBpZiAob2xkU2VsZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgb2xkU2VsZWN0aW9uLnNlbGVjdGVkID0gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAobmV3U2VsZWN0aW9uKSB7XG4gICAgICAgICAgICAgICAgbmV3U2VsZWN0aW9uLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChldmVudCkge1xuICAgICAgICAgICAgICAgIHRoaXMudG9nZ2xlRGlyZWN0aXZlLmNsb3NlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbiJdfQ==