igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
481 lines • 36.1 kB
JavaScript
/**
* @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==