@catull/igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
558 lines • 59.1 kB
JavaScript
var IgxDropDownComponent_1;
import { __decorate, __metadata, __param } from "tslib";
import { ChangeDetectorRef, Component, ContentChildren, ElementRef, forwardRef, QueryList, OnInit, Input, OnDestroy, ViewChild, ContentChild, AfterViewInit, Output, EventEmitter, Optional, Inject } from '@angular/core';
import { IgxToggleDirective } from '../directives/toggle/toggle.directive';
import { IgxDropDownItemComponent } from './drop-down-item.component';
import { IgxDropDownBaseDirective } from './drop-down.base';
import { Navigate } from './drop-down.common';
import { IGX_DROPDOWN_BASE } from './drop-down.common';
import { isIE } from '../core/utils';
import { IgxSelectionAPIService } from '../core/selection';
import { Subject } from 'rxjs';
import { IgxDropDownItemBaseDirective } from './drop-down-item.base';
import { IgxForOfDirective } from '../directives/for-of/for_of.directive';
import { take } from 'rxjs/operators';
import { DisplayDensityToken } from '../core/density';
/**
* **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>
* ```
*/
let IgxDropDownComponent = IgxDropDownComponent_1 = class IgxDropDownComponent extends IgxDropDownBaseDirective {
constructor(elementRef, cdr, selection, _displayDensityOptions) {
super(elementRef, cdr, _displayDensityOptions);
this.elementRef = elementRef;
this.cdr = cdr;
this.selection = selection;
this._displayDensityOptions = _displayDensityOptions;
this.destroy$ = new Subject();
/**
* 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();
/**
* 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;
}
/**
* @hidden @internal
*/
get focusedItem() {
if (this.virtDir) {
return this._focusedItem && this._focusedItem.index !== -1 ?
(this.children.find(e => e.index === this._focusedItem.index) || null) :
null;
}
return this._focusedItem;
}
set focusedItem(value) {
if (!value) {
this.selection.clear(`${this.id}-active`);
this._focusedItem = null;
return;
}
this._focusedItem = value;
if (this.virtDir) {
this._focusedItem = {
value: value.value,
index: value.index
};
}
this.selection.set(`${this.id}-active`, new Set([this._focusedItem]));
}
get id() {
return this._id;
}
set id(value) {
this.toggleDirective.id = value;
this.selection.set(value, this.selection.get(this.id));
this.selection.clear(this.id);
this.selection.set(value, this.selection.get(`${this.id}-active`));
this.selection.clear(`${this.id}-active`);
this._id = value;
}
/** Id of the internal listbox of the drop down */
get listId() {
return this.id + '-list';
}
/**
* Get currently selected item
*
* ```typescript
* let currentItem = this.dropdown.selectedItem;
* ```
*/
get selectedItem() {
const selectedItem = this.selection.first_item(this.id);
if (selectedItem) {
return selectedItem;
}
return null;
}
/**
* Gets if the dropdown is collapsed
*
* ```typescript
* let isCollapsed = this.dropdown.collapsed;
* ```
*/
get collapsed() {
return this.toggleDirective.collapsed;
}
/** @hidden @internal */
get scrollContainer() {
return this.scrollContainerRef.nativeElement;
}
get collectionLength() {
if (this.virtDir) {
return this.virtDir.totalItemCount || this.virtDir.igxForOf.length;
}
}
/**
* Opens the dropdown
*
* ```typescript
* this.dropdown.open();
* ```
*/
open(overlaySettings) {
this.toggleDirective.open(overlaySettings);
this.updateScrollPosition();
}
/**
* Closes the dropdown
*
* ```typescript
* this.dropdown.close();
* ```
*/
close() {
this.toggleDirective.close();
}
/**
* Toggles the dropdown
*
* ```typescript
* this.dropdown.toggle();
* ```
*/
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; If the drop down uses *igxFor, pass the index in data
*/
setSelectedItem(index) {
if (index < 0 || index >= this.items.length) {
return;
}
let newSelection;
if (this.virtDir) {
newSelection = {
value: this.virtDir.igxForOf[index],
index
};
}
else {
newSelection = this.items[index];
}
this.selectItem(newSelection);
}
/**
* Navigates to the item on the specified index
* If the data in the drop-down is virtualized, pass the index of the item in the virtualized data.
* @param newIndex number
*/
navigateItem(index) {
if (this.virtDir) {
if (index === -1 || index >= this.collectionLength) {
return;
}
const direction = index > (this.focusedItem ? this.focusedItem.index : -1) ? Navigate.Down : Navigate.Up;
const subRequired = this.isIndexOutOfBounds(index, direction);
this.focusedItem = {
value: this.virtDir.igxForOf[index],
index: index
};
if (subRequired) {
this.virtDir.scrollTo(index);
}
if (subRequired) {
this.virtDir.onChunkLoad.pipe(take(1)).subscribe(() => {
this.skipHeader(direction);
});
}
else {
this.skipHeader(direction);
}
}
else {
super.navigateItem(index);
}
if (this.allowItemsFocus && this.focusedItem) {
this.focusedItem.element.nativeElement.focus();
this.cdr.markForCheck();
}
}
isIndexOutOfBounds(index, direction) {
const virtState = this.virtDir.state;
const currentPosition = this.virtDir.getScroll().scrollTop;
const itemPosition = this.virtDir.getScrollForIndex(index, direction === Navigate.Down);
const indexOutOfChunk = index < virtState.startIndex || index > virtState.chunkSize + virtState.startIndex;
const scrollNeeded = direction === Navigate.Down ? currentPosition < itemPosition : currentPosition > itemPosition;
const subRequired = indexOutOfChunk || scrollNeeded;
return subRequired;
}
skipHeader(direction) {
if (!this.focusedItem) {
return;
}
if (this.focusedItem.isHeader || this.focusedItem.disabled) {
if (direction === Navigate.Up) {
this.navigatePrev();
}
else {
this.navigateNext();
}
}
}
/**
* @hidden @internal
*/
updateScrollPosition() {
if (!this.virtDir) {
return;
}
if (!this.selectedItem) {
this.virtDir.scrollTo(0);
return;
}
let targetScroll = this.virtDir.getScrollForIndex(this.selectedItem.index);
const itemsInView = this.virtDir.igxForContainerSize / this.virtDir.igxForItemSize;
targetScroll -= (itemsInView / 2 - 1) * this.virtDir.igxForItemSize;
this.virtDir.getScroll().scrollTop = targetScroll;
}
/**
* @hidden @internal
*/
onToggleOpening(e) {
this.onOpening.emit(e);
if (e.cancel) {
return;
}
if (!this.virtDir && this.selectedItem) {
this.scrollToItem(this.selectedItem);
}
if (this.virtDir) {
this.virtDir.scrollPosition = this._scrollPosition;
}
}
/**
* @hidden @internal
*/
onToggleOpened() {
if (this.selectedItem) {
this.focusedItem = this.selectedItem;
this._focusedItem.focused = true;
}
else if (this.allowItemsFocus) {
this.navigateFirst();
}
this.onOpened.emit();
}
/**
* @hidden @internal
*/
onToggleClosing(e) {
this.onClosing.emit(e);
if (this.virtDir) {
this._scrollPosition = this.virtDir.scrollPosition;
}
}
/**
* @hidden @internal
*/
onToggleClosed() {
if (this._focusedItem) {
this._focusedItem.focused = false;
}
this.onClosed.emit();
}
/**
* @hidden @internal
*/
ngOnDestroy() {
this.destroy$.next(true);
this.destroy$.complete();
this.selection.clear(this.id);
this.selection.clear(`${this.id}-active`);
}
scrollToItem(item) {
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 */
calculateScrollPosition(item) {
if (!item) {
return 0;
}
const elementRect = item.element.nativeElement.getBoundingClientRect();
const parentRect = this.scrollContainer.getBoundingClientRect();
const scrollDelta = parentRect.top - elementRect.top;
let scrollPosition = this.scrollContainer.scrollTop - scrollDelta;
const dropDownHeight = this.scrollContainer.clientHeight;
scrollPosition -= dropDownHeight / 2;
scrollPosition += item.elementHeight / 2;
return Math.floor(scrollPosition);
}
/**
* @hidden @internal
*/
ngOnInit() {
this.toggleDirective.id = this.id;
}
ngAfterViewInit() {
if (this.virtDir) {
this.virtDir.igxForItemSize = 28;
}
}
/** Keydown Handler */
onItemActionKey(key, event) {
super.onItemActionKey(key, event);
this.close();
}
/**
* Virtual scroll implementation
* @hidden @internal
*/
navigateFirst() {
if (this.virtDir) {
this.navigateItem(0);
}
else {
super.navigateFirst();
}
}
/**
* @hidden @internal
*/
navigateLast() {
if (this.virtDir) {
this.navigateItem(this.virtDir.totalItemCount ? this.virtDir.totalItemCount - 1 : this.virtDir.igxForOf.length - 1);
}
else {
super.navigateLast();
}
}
/**
* @hidden @internal
*/
navigateNext() {
if (this.virtDir) {
this.navigateItem(this._focusedItem ? this._focusedItem.index + 1 : 0);
}
else {
super.navigateNext();
}
}
/**
* @hidden @internal
*/
navigatePrev() {
if (this.virtDir) {
this.navigateItem(this._focusedItem ? this._focusedItem.index - 1 : 0);
}
else {
super.navigatePrev();
}
}
/**
* Handles the `onSelection` emit and the drop down toggle when selection changes
* @hidden
* @internal
* @param newSelection
* @param event
*/
selectItem(newSelection, event) {
const oldSelection = this.selectedItem;
if (!newSelection) {
newSelection = this.focusedItem;
}
if (newSelection === null) {
return;
}
if (newSelection instanceof IgxDropDownItemBaseDirective && newSelection.isHeader) {
return;
}
if (this.virtDir) {
newSelection = {
value: newSelection.value,
index: newSelection.index
};
}
const args = { oldSelection, newSelection, cancel: false };
this.onSelection.emit(args);
if (!args.cancel) {
if (this.isSelectionValid(args.newSelection)) {
this.selection.set(this.id, new Set([args.newSelection]));
if (!this.virtDir) {
if (oldSelection) {
oldSelection.selected = false;
}
if (args.newSelection) {
args.newSelection.selected = true;
}
}
if (event) {
this.toggleDirective.close();
}
}
else {
throw new Error('Please provide a valid drop-down item for the selection!');
}
}
}
/**
* Checks whether the selection is valid
* `null` - the selection should be emptied
* Virtual? - the selection should at least have and `index` and `value` property
* Non-virtual? - the selection should be a valid drop-down item and **not** be a header
*/
isSelectionValid(selection) {
return selection === null
|| (this.virtDir && selection.hasOwnProperty('value') && selection.hasOwnProperty('index'))
|| (selection instanceof IgxDropDownItemComponent && !selection.isHeader);
}
};
IgxDropDownComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: ChangeDetectorRef },
{ type: IgxSelectionAPIService },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DisplayDensityToken,] }] }
];
__decorate([
ContentChild(IgxForOfDirective, { read: IgxForOfDirective }),
__metadata("design:type", IgxForOfDirective)
], IgxDropDownComponent.prototype, "virtDir", void 0);
__decorate([
ViewChild(IgxToggleDirective, { static: true }),
__metadata("design:type", IgxToggleDirective)
], IgxDropDownComponent.prototype, "toggleDirective", void 0);
__decorate([
ViewChild('scrollContainer', { static: true }),
__metadata("design:type", ElementRef)
], IgxDropDownComponent.prototype, "scrollContainerRef", void 0);
__decorate([
ContentChildren(forwardRef(() => IgxDropDownItemComponent), { descendants: true }),
__metadata("design:type", QueryList)
], IgxDropDownComponent.prototype, "children", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxDropDownComponent.prototype, "onOpening", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxDropDownComponent.prototype, "onOpened", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxDropDownComponent.prototype, "onClosing", void 0);
__decorate([
Output(),
__metadata("design:type", Object)
], IgxDropDownComponent.prototype, "onClosed", void 0);
__decorate([
Input(),
__metadata("design:type", Object)
], IgxDropDownComponent.prototype, "allowItemsFocus", void 0);
__decorate([
Input(),
__metadata("design:type", String),
__metadata("design:paramtypes", [String])
], IgxDropDownComponent.prototype, "id", null);
IgxDropDownComponent = IgxDropDownComponent_1 = __decorate([
Component({
selector: 'igx-drop-down',
template: "<div #scrollContainer 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_1 }]
}),
__param(3, Optional()), __param(3, Inject(DisplayDensityToken)),
__metadata("design:paramtypes", [ElementRef,
ChangeDetectorRef,
IgxSelectionAPIService, Object])
], IgxDropDownComponent);
export { IgxDropDownComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJvcC1kb3duLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2lnbml0ZXVpLWFuZ3VsYXIvIiwic291cmNlcyI6WyJsaWIvZHJvcC1kb3duL2Ryb3AtZG93bi5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxPQUFPLEVBQ0gsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxlQUFlLEVBQ2YsVUFBVSxFQUNWLFVBQVUsRUFDVixTQUFTLEVBQ1QsTUFBTSxFQUNOLEtBQUssRUFDTCxTQUFTLEVBQ1QsU0FBUyxFQUNULFlBQVksRUFDWixhQUFhLEVBQ2IsTUFBTSxFQUNOLFlBQVksRUFDWixRQUFRLEVBQ1IsTUFBTSxFQUNULE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzNFLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3RFLE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzVELE9BQU8sRUFBcUIsUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDakUsT0FBTyxFQUFFLGlCQUFpQixFQUFpQixNQUFNLG9CQUFvQixDQUFDO0FBRXRFLE9BQU8sRUFBbUQsSUFBSSxFQUFrQixNQUFNLGVBQWUsQ0FBQztBQUN0RyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSw0QkFBNEIsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBRXJFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN0QyxPQUFPLEVBQUUsbUJBQW1CLEVBQTBCLE1BQU0saUJBQWlCLENBQUM7QUFFOUU7Ozs7Ozs7Ozs7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QjNDO0lBREMsS0FBSyxFQUFFOzs2REFDdUI7QUErQi9CO0lBREMsS0FBSyxFQUFFOzs7OENBR1A7QUFoSFEsb0JBQW9CO0lBTGhDLFNBQVMsQ0FBQztRQUNQLFFBQVEsRUFBRSxlQUFlO1FBQ3pCLDZjQUF5QztRQUN6QyxTQUFTLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsc0JBQW9CLEVBQUUsQ0FBQztLQUNqRixDQUFDO0lBeUtPLFdBQUEsUUFBUSxFQUFFLENBQUEsRUFBRSxXQUFBLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO3FDQUhsQixVQUFVO1FBQ2pCLGlCQUFpQjtRQUNYLHNCQUFzQjtHQXZLdEMsb0JBQW9CLENBd2dCaEM7U0F4Z0JZLG9CQUFvQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gICAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgQ29tcG9uZW50LFxuICAgIENvbnRlbnRDaGlsZHJlbixcbiAgICBFbGVtZW50UmVmLFxuICAgIGZvcndhcmRSZWYsXG4gICAgUXVlcnlMaXN0LFxuICAgIE9uSW5pdCxcbiAgICBJbnB1dCxcbiAgICBPbkRlc3Ryb3ksXG4gICAgVmlld0NoaWxkLFxuICAgIENvbnRlbnRDaGlsZCxcbiAgICBBZnRlclZpZXdJbml0LFxuICAgIE91dHB1dCxcbiAgICBFdmVudEVtaXR0ZXIsXG4gICAgT3B0aW9uYWwsXG4gICAgSW5qZWN0XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSWd4VG9nZ2xlRGlyZWN0aXZlIH0gZnJvbSAnLi4vZGlyZWN0aXZlcy90b2dnbGUvdG9nZ2xlLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBJZ3hEcm9wRG93bkl0ZW1Db21wb25lbnQgfSBmcm9tICcuL2Ryb3AtZG93bi1pdGVtLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJZ3hEcm9wRG93bkJhc2VEaXJlY3RpdmUgfSBmcm9tICcuL2Ryb3AtZG93bi5iYXNlJztcbmltcG9ydCB7IERyb3BEb3duQWN0aW9uS2V5LCBOYXZpZ2F0ZSB9IGZyb20gJy4vZHJvcC1kb3duLmNvbW1vbic7XG5pbXBvcnQgeyBJR1hfRFJPUERPV05fQkFTRSwgSURyb3BEb3duQmFzZSB9IGZyb20gJy4vZHJvcC1kb3duLmNvbW1vbic7XG5pbXBvcnQgeyBJU2VsZWN0aW9uRXZlbnRBcmdzIH0gZnJvbSAnLi9kcm9wLWRvd24uY29tbW9uJztcbmltcG9ydCB7IENhbmNlbGFibGVFdmVudEFyZ3MsIENhbmNlbGFibGVCcm93c2VyRXZlbnRBcmdzLCBpc0lFLCBJQmFzZUV2ZW50QXJncyB9IGZyb20gJy4uL2NvcmUvdXRpbHMnO1xuaW1wb3J0IHsgSWd4U2VsZWN0aW9uQVBJU2VydmljZSB9IGZyb20gJy4uL2NvcmUvc2VsZWN0aW9uJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IElneERyb3BEb3duSXRlbUJhc2VEaXJlY3RpdmUgfSBmcm9tICcuL2Ryb3AtZG93bi1pdGVtLmJhc2UnO1xuaW1wb3J0IHsgT3ZlcmxheVNldHRpbmdzIH0gZnJvbSAnLi4vc2VydmljZXMnO1xuaW1wb3J0IHsgSWd4Rm9yT2ZEaXJlY3RpdmUgfSBmcm9tICcuLi9kaXJlY3RpdmVzL2Zvci1vZi9mb3Jfb2YuZGlyZWN0aXZlJztcbmltcG9ydCB7IHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBEaXNwbGF5RGVuc2l0eVRva2VuLCBJRGlzcGxheURlbnNpdHlPcHRpb25zIH0gZnJvbSAnLi4vY29yZS9kZW5zaXR5JztcblxuLyoqXG4gKiAqKklnbml0ZSBVSSBmb3IgQW5ndWxhciBEcm9wRG93bioqIC1cbiAqIFtEb2N1bWVudGF0aW9uXShodHRwczovL3d3dy5pbmZyYWdpc3RpY3MuY29tL3Byb2R1Y3RzL2lnbml0ZS11aS1hbmd1bGFyL2FuZ3VsYXIvY29tcG9uZW50cy9kcm9wX2Rvd24uaHRtbClcbiAqXG4gKiBUaGUgSWduaXRlIFVJIGZvciBBbmd1bGFyIERyb3AgRG93biBkaXNwbGF5cyBhIHNjcm9sbGFibGUgbGlzdCBvZiBpdGVtcyB3aGljaCBtYXkgYmUgdmlzdWFsbHkgZ3JvdXBlZCBhbmRcbiAqIHN1cHBvcnRzIHNlbGVjdGlvbiBvZiBhIHNpbmdsZSBpdGVtLiBDbGlja2luZyBvciB0YXBwaW5nIGFuIGl0ZW0gc2VsZWN0cyBpdCBhbmQgY2xvc2VzIHRoZSBEcm9wIERvd25cbiAqXG4gKiBFeGFtcGxlOlxuICogYGBgaHRtbFxuICogPGlneC1kcm9wLWRvd24+XG4gKiAgIDxpZ3gtZHJvcC1kb3duLWl0ZW0gKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbXNcIiBkaXNhYmxlZD17e2l0ZW0uZGlzYWJsZWR9fSBpc0hlYWRlcj17e2l0ZW0uaGVhZGVyfX0+XG4gKiAgICAge3sgaXRlbS52YWx1ZSB9fVxuICogICA8L2lneC1kcm9wLWRvd24taXRlbT5cbiAqIDwvaWd4LWRyb3AtZG93bj5cbiAqIGBgYFxuICovXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2lneC1kcm9wLWRvd24nLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9kcm9wLWRvd24uY29tcG9uZW50Lmh0bWwnLFxuICAgIHByb3ZpZGVyczogW3sgcHJvdmlkZTogSUdYX0RST1BET1dOX0JBU0UsIHVzZUV4aXN0aW5nOiBJZ3hEcm9wRG93bkNvbXBvbmVudCB9XVxufSlcbmV4cG9ydCBjbGFzcyBJZ3hEcm9wRG93bkNvbXBvbmVudCBleHRlbmRzIElneERyb3BEb3duQmFzZURpcmVjdGl2ZSBpbXBsZW1lbnRzIElEcm9wRG93bkJhc2UsIE9uSW5pdCwgT25EZXN0cm95LCBBZnRlclZpZXdJbml0IHtcbiAgICBwcm90ZWN0ZWQgZGVzdHJveSQgPSBuZXcgU3ViamVjdDxib29sZWFuPigpO1xuICAgIHByb3RlY3RlZCBfc2Nyb2xsUG9zaXRpb246IG51bWJlcjtcblxuICAgIEBDb250ZW50Q2hpbGQoSWd4Rm9yT2ZEaXJlY3RpdmUsIHsgcmVhZDogSWd4Rm9yT2ZEaXJlY3RpdmUgfSlcbiAgICBwcm90ZWN0ZWQgdmlydERpcjogSWd4Rm9yT2ZEaXJlY3RpdmU8YW55PjtcblxuICAgIEBWaWV3Q2hpbGQoSWd4VG9nZ2xlRGlyZWN0aXZlLCB7IHN0YXRpYzogdHJ1ZSB9KVxuICAgIHByb3RlY3RlZCB0b2dnbGVEaXJlY3RpdmU6IElneFRvZ2dsZURpcmVjdGl2ZTtcblxuICAgIEBWaWV3Q2hpbGQoJ3Njcm9sbENvbnRhaW5lcicsIHsgc3RhdGljOiB0cnVlIH0pXG4gICAgcHJvdGVjdGVkIHNjcm9sbENvbnRhaW5lclJlZjogRWxlbWVudFJlZjtcblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW5cbiAgICAgKiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBAQ29udGVudENoaWxkcmVuKGZvcndhcmRSZWYoKCkgPT4gSWd4RHJvcERvd25JdGVtQ29tcG9uZW50KSwgeyBkZXNjZW5kYW50czogdHJ1ZSB9KVxuICAgIHB1YmxpYyBjaGlsZHJlbjogUXVlcnlMaXN0PElneERyb3BEb3duSXRlbUJhc2VEaXJlY3RpdmU+O1xuXG4gICAgLyoqXG4gICAgICogRW1pdHRlZCBiZWZvcmUgdGhlIGRyb3Bkb3duIGlzIG9wZW5lZFxuICAgICAqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtZHJvcC1kb3duIChvbk9wZW5pbmcpPSdoYW5kbGVPcGVuaW5nKCknPjwvaWd4LWRyb3AtZG93bj5cbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBAT3V0cHV0KClcbiAgICBwdWJsaWMgb25PcGVuaW5nID0gbmV3IEV2ZW50RW1pdHRlcjxDYW5jZWxhYmxlRXZlbnRBcmdzICYgSUJhc2VFdmVudEFyZ3M+KCk7XG5cbiAgICAvKipcbiAgICAgKiBFbWl0dGVkIGFmdGVyIHRoZSBkcm9wZG93biBpcyBvcGVuZWRcbiAgICAgKlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWRyb3AtZG93biAob25PcGVuZWQpPSdoYW5kbGVPcGVuZWQoKSc+PC9pZ3gtZHJvcC1kb3duPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBPdXRwdXQoKVxuICAgIHB1YmxpYyBvbk9wZW5lZCA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXR0ZWQgYmVmb3JlIHRoZSBkcm9wZG93biBpcyBjbG9zZWRcbiAgICAgKlxuICAgICAqIGBgYGh0bWxcbiAgICAgKiA8aWd4LWRyb3AtZG93biAob25DbG9zaW5nKT0naGFuZGxlQ2xvc2luZygpJz48L2lneC1kcm9wLWRvd24+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIG9uQ2xvc2luZyA9IG5ldyBFdmVudEVtaXR0ZXI8Q2FuY2VsYWJsZUJyb3dzZXJFdmVudEFyZ3MgJiBJQmFzZUV2ZW50QXJncz4oKTtcblxuICAgIC8qKlxuICAgICAqIEVtaXR0ZWQgYWZ0ZXIgdGhlIGRyb3Bkb3duIGlzIGNsb3NlZFxuICAgICAqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDxpZ3gtZHJvcC1kb3duIChvbkNsb3NlZCk9J2hhbmRsZUNsb3NlZCgpJz48L2lneC1kcm9wLWRvd24+XG4gICAgICogYGBgXG4gICAgICovXG4gICAgQE91dHB1dCgpXG4gICAgcHVibGljIG9uQ2xvc2VkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gICAgLyoqXG4gICAgICogR2V0cy9zZXRzIHdoZXRoZXIgaXRlbXMgdGFrZSBmb2N1cy4gRGlzYWJsZWQgYnkgZGVmYXVsdC5cbiAgICAgKiBXaGVuIGVuYWJsZWQsIGRyb3AgZG93biBpdGVtcyBnYWluIHRhYiBpbmRleCBhbmQgYXJlIGZvY3VzZWQgd2hlbiBhY3RpdmUgLVxuICAgICAqIHRoaXMgaW5jbHVkZXMgYWN0aXZhdGluZyB0aGUgc2VsZWN0ZWQgaXRlbSB3aGVuIG9wZW5pbmcgdGhlIGRyb3AgZG93biBhbmQgbW92aW5nIHdpdGgga2V5Ym9hcmQgbmF2aWdhdGlvbi5cbiAgICAgKlxuICAgICAqIE5vdGU6IEtlZXAgdGhhdCBmb2N1cyBzaGlmdCBpbiBtaW5kIHdoZW4gdXNpbmcgdGhlIGlneERyb3BEb3duSXRlbU5hdmlnYXRpb24gZGlyZWN0aXZlXG4gICAgICogYW5kIGVuc3VyZSBpdCdzIHBsYWNlZCBlaXRoZXIgb24gZWFjaCBmb2N1c2FibGUgaXRlbSBvciBhIGNvbW1vbiBhbmNlc3RvciB0byBhbGxvdyBpdCB0byBoYW5kbGUga2V5Ym9hcmQgZXZlbnRzLlxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIC8vIGdldFxuICAgICAqIGxldCBkcm9wRG93bkFsbG93c0l0ZW1Gb2N1cyA9IHRoaXMuZHJvcGRvd24uYWxsb3dJdGVtc0ZvY3VzO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogYGBgaHRtbFxuICAgICAqIDwhLS1zZXQtLT5cbiAgICAgKiA8aWd4LWRyb3AtZG93biBbYWxsb3dJdGVtc0ZvY3VzXT0ndHJ1ZSc+PC9pZ3gtZHJvcC1kb3duPlxuICAgICAqIGBgYFxuICAgICAqL1xuICAgIEBJbnB1dCgpXG4gICAgcHVibGljIGFsbG93SXRlbXNGb2N1cyA9IGZhbHNlO1xuXG4gICAgLyoqXG4gICAgICogQGhpZGRlbiBAaW50ZXJuYWxcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGZvY3VzZWRJdGVtKCk6IElneERyb3BEb3duSXRlbUJhc2VEaXJlY3RpdmUge1xuICAgICAgICBpZiAodGhpcy52aXJ0RGlyKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZm9jdXNlZEl0ZW0gJiYgdGhpcy5fZm9jdXNlZEl0ZW0uaW5kZXggIT09IC0xID9cbiAgICAgICAgICAgICAgICAodGhpcy5jaGlsZHJlbi5maW5kKGUgPT4gZS5pbmRleCA9PT0gdGhpcy5fZm9jdXNlZEl0ZW0uaW5kZXgpIHx8IG51bGwpIDpcbiAgICAgICAgICAgICAgICBudWxsO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzLl9mb2N1c2VkSXRlbTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0IGZvY3VzZWRJdGVtKHZhbHVlOiBJZ3hEcm9wRG93bkl0ZW1CYXNlRGlyZWN0aXZlKSB7XG4gICAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0aW9uLmNsZWFyKGAke3RoaXMuaWR9LWFjdGl2ZWApO1xuICAgICAgICAgICAgdGhpcy5fZm9jdXNlZEl0ZW0gPSBudWxsO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX2ZvY3VzZWRJdGVtID0gdmFsdWU7XG4gICAgICAgIGlmICh0aGlzLnZpcnREaXIpIHtcbiAgICAgICAgICAgIHRoaXMuX2ZvY3VzZWRJdGVtID0ge1xuICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZS52YWx1ZSxcbiAgICAgICAgICAgICAgICBpbmRleDogdmFsdWUuaW5kZXhcbiAgICAgICAgICAgIH0gYXMgSWd4RHJvcERvd25JdGVtQmFzZURpcmVjdGl2ZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnNlbGVjdGlvbi5zZXQoYCR7dGhpcy5pZH0tYWN0aXZlYCwgbmV3IFNldChbdGhpcy5fZm9jdXNlZEl0ZW1dKSk7XG4gICAgfVxuXG4gICAgQElucHV0KClcbiAgICBnZXQgaWQoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2lkO1xuICAgIH1cbiAgICBzZXQgaWQodmFsdWU6IHN0cmluZykge1xuICAgICAgICB0aGlzLnRvZ2dsZURpcmVjdGl2ZS5pZCA9IHZhbHVlO1xuICAgICAgICB0aGlzLnNlbGVjdGlvbi5zZXQodmFsdWUsIHRoaXMuc2VsZWN0aW9uLmdldCh0aGlzLmlkKSk7XG4gICAgICAgIHRoaXMuc2VsZWN0aW9uLmNsZWFyKHRoaXMuaWQpO1xuICAgICAgICB0aGlzLnNlbGVjdGlvbi5zZXQodmFsdWUsIHRoaXMuc2VsZWN0aW9uLmdldChgJHt0aGlzLmlkfS1hY3RpdmVgKSk7XG4gICAgICAgIHRoaXMuc2VsZWN0aW9uLmNsZWFyKGAke3RoaXMuaWR9LWFjdGl2ZWApO1xuICAgICAgICB0aGlzLl9pZCA9IHZhbHVlO1xuICAgIH1cblxuICAgIC8qKiBJZCBvZiB0aGUgaW50ZXJuYWwgbGlzdGJveCBvZiB0aGUgZHJvcCBkb3duICovXG4gICAgcHVibGljIGdldCBsaXN0SWQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmlkICsgJy1saXN0JztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXQgY3VycmVudGx5IHNlbGVjdGVkIGl0ZW1cbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgY3VycmVudEl0ZW0gPSB0aGlzLmRyb3Bkb3duLnNlbGVjdGVkSXRlbTtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IHNlbGVjdGVkSXRlbSgpOiBJZ3hEcm9wRG93bkl0ZW1CYXNlRGlyZWN0aXZlIHtcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRJdGVtID0gdGhpcy5zZWxlY3Rpb24uZmlyc3RfaXRlbSh0aGlzLmlkKTtcbiAgICAgICAgaWYgKHNlbGVjdGVkSXRlbSkge1xuICAgICAgICAgICAgcmV0dXJuIHNlbGVjdGVkSXRlbTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGlmIHRoZSBkcm9wZG93biBpcyBjb2xsYXBzZWRcbiAgICAgKlxuICAgICAqIGBgYHR5cGVzY3JpcHRcbiAgICAgKiBsZXQgaXNDb2xsYXBzZWQgPSB0aGlzLmRyb3Bkb3duLmNvbGxhcHNlZDtcbiAgICAgKiBgYGBcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0IGNvbGxhcHNlZCgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudG9nZ2xlRGlyZWN0aXZlLmNvbGxhcHNlZDtcbiAgICB9XG5cbiAgICAvKiogQGhpZGRlbiBAaW50ZXJuYWwgKi9cbiAgICBwdWJsaWMgZ2V0IHNjcm9sbENvbnRhaW5lcigpOiBIVE1MRWxlbWVudCB7XG4gICAgICAgIHJldHVybiB0aGlzLnNjcm9sbENvbnRhaW5lclJlZi5uYXRpdmVFbGVtZW50O1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBnZXQgY29sbGVjdGlvbkxlbmd0aCgpIHtcbiAgICAgICAgaWYgKHRoaXMudmlydERpcikge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMudmlydERpci50b3RhbEl0ZW1Db3VudCB8fCB0aGlzLnZpcnREaXIuaWd4Rm9yT2YubGVuZ3RoO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByb3RlY3RlZCBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgICAgICBwcm90ZWN0ZWQgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICAgICAgcHJvdGVjdGVkIHNlbGVjdGlvbjogSWd4U2VsZWN0aW9uQVBJU2VydmljZSxcbiAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChEaXNwbGF5RGVuc2l0eVRva2VuKSBwcm90ZWN0ZWQgX2Rpc3BsYXlEZW5zaXR5T3B0aW9uczogSURpc3BsYXlEZW5zaXR5T3B0aW9ucykge1xuICAgICAgICBzdXBlcihlbGVtZW50UmVmLCBjZHIsIF9kaXNwbGF5RGVuc2l0eU9wdGlvbnMpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE9wZW5zIHRoZSBkcm9wZG93blxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIHRoaXMuZHJvcGRvd24ub3BlbigpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyBvcGVuKG92ZXJsYXlTZXR0aW5ncz86IE92ZXJsYXlTZXR0aW5ncykge1xuICAgICAgICB0aGlzLnRvZ2dsZURpcmVjdGl2ZS5vcGVuKG92ZXJsYXlTZXR0aW5ncyk7XG4gICAgICAgIHRoaXMudXBkYXRlU2Nyb2xsUG9zaXRpb24oKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDbG9zZXMgdGhlIGRyb3Bkb3duXG4gICAgICpcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogdGhpcy5kcm9wZG93bi5jbG9zZSgpO1xuICAgICAqIGBgYFxuICAgICAqL1xuICAgIHB1YmxpYyBjbG9zZSgpIHtcbiAgICAgICAgdGhpcy50b2dnbGVEaXJlY3RpdmUuY2xvc2UoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBUb2dnbGVzIHRoZSBkcm9wZG93blxuICAgICAqXG4gICAgICogYGBgdHlwZXNjcmlwdFxuICAgICAqIHRoaXMuZHJvcGRvd24udG9nZ2xlKCk7XG4gICAgICogYGBgXG4gICAgICovXG4gICAgcHVibGljIHRvZ2dsZShvdmVybGF5U2V0dGluZ3M/OiBPdmVybGF5U2V0dGluZ3MpIHtcbiAgICAgICAgaWYgKHRoaXMuY29sbGFwc2VkIHx8IHRoaXMudG9nZ2xlRGlyZWN0aXZlLmlzQ2xvc2luZykge1xuICAgICAgICAgICAgdGhpcy5vcGVuKG92ZXJsYXlTZXR0aW5ncyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBTZWxlY3QgYW4gaXRlbSBieSBpbmRleFxuICAgICAqIEBwYXJhbSBpbmRleCBvZiB0aGUgaXRlbSB0byBzZWxlY3Q7IElmIHRoZSBkcm9wIGRvd24gdXNlcyAqaWd4Rm9yLCBwYXNzIHRoZSBpbmRleCBpbiBkYXRhXG4gICAgICovXG4gICAgcHVibGljIHNldFNlbGVjdGVkSXRlbShpbmRleDogbnVtYmVyKSB7XG4gICAgICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gdGhpcy5pdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgbmV3U2VsZWN0aW9uOiBJZ3hEcm9wRG93bkl0ZW1CYXNlRGlyZWN0aXZlO1xuICAgICAgICBpZiAodGhpcy52aXJ0RGlyKSB7XG4gICAgICAgICAgICBuZXdTZWxlY3Rpb24gPSB7XG4gICAgICAgICAgICAgICAgdmFsdWU6IHRoaXMudmlydERpci5pZ3hGb3JPZltpbmRleF0sXG4gICAgICAgICAgICAgICAgaW5kZXhcbiAgICAgICAgICAgIH0gYXMgSWd4RHJvcERvd25JdGVtQmFzZURpcmVjdGl2ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG5ld1NlbGVjdGlvbiA9IHRoaXMuaXRlbXNbaW5kZXhdO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc2VsZWN0SXRlbShuZXdTZWxlY3Rpb24pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIE5hdmlnYXRlcyB0byB0aGUgaXRlbSBvbiB0aGUgc3BlY2lmaWVkIGluZGV4XG4gICAgICogSWYgdGhlIGRhdGEgaW4gdGhlIGRyb3AtZG93biBpcyB2aXJ0dWFsaXplZCwgcGFzcyB0aGUgaW5kZXggb2YgdGhlIGl0ZW0gaW4gdGhlIHZpcnR1YWxpemVkIGRhdGEuXG4gICAgICogQHBhcmFtIG5ld0luZGV4IG51bWJlclxuICAgICAqL1xuICAgIHB1YmxpYyBuYXZpZ2F0ZUl0ZW0oaW5kZXg6IG51bWJlcikge1xuICAgICAgICBpZiAodGhpcy52aXJ0RGlyKSB7XG4gICAgICAgICAgICBpZiAoaW5kZXggPT09IC0xIHx8IGluZGV4ID49IHRoaXMuY29sbGVjdGlvbkxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGRpcmVjdGlvbiA9IGluZGV4ID4gKHRoaXMuZm9jdXNlZEl0ZW0gPyB0aGlzLmZvY3VzZWRJdGVtLmluZGV4IDogLTEpID8gTmF2aWdhdGUuRG93biA6IE5hdmlnYXRlLlVwO1xuICAgICAgICAgICAgY29uc3Qgc3ViUmVxdWlyZWQgPSB0aGlzLmlzSW5kZXhPdXRPZkJvdW5kcyhpbmRleCwgZGlyZWN0aW9uKTtcbiAgICAgICAgICAgIHRoaXMuZm9jdXNlZEl0ZW0gPSB7XG4gICAgICAgICAgICAgICAgdmFsdWU6IHRoaXMudmlydERpci5pZ3hGb3JPZltpbmRleF0sXG4gICAgICAgICAgICAgICAgaW5kZXg6IGluZGV4XG4gICAgICAgICAgICB9IGFzIElneERyb3BEb3duSXRlbUJhc2VEaXJlY3RpdmU7XG4gICAgICAgICAgICBpZiAoc3ViUmVxdWlyZWQpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnZpcnREaXIuc2Nyb2xsVG8oaW5kZXgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHN1YlJlcXVpcmVkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy52aXJ0RGlyLm9uQ2h1bmtMb2FkLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5za2lwSGVhZGVyKGRpcmVjdGlvbik7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc2tpcEhlYWRlcihkaXJlY3Rpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3VwZXIubmF2aWdhdGVJdGVtKGluZGV4KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5hbGxvd0l0ZW1zRm9jdXMgJiYgdGhpcy5mb2N1c2VkSXRlbSkge1xuICAgICAgICAgICAgdGhpcy5mb2N1c2VkSXRlbS5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICAgICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc0luZGV4T3V0T2ZCb3VuZHMoaW5kZXg6IG51bWJlciwgZGlyZWN0aW9uOiBOYXZpZ2F0ZSkge1xuICAgICAgICBjb25zdCB2aXJ0U3RhdGUgPSB0aGlzLnZpcnREaXIuc3RhdGU7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRQb3NpdGlvbiA9IHRoaXMudmlydERpci5nZXRTY3JvbGwoKS5zY3JvbGxUb3A7XG4gICAgICAgIGNvbnN0IGl0ZW1Qb3NpdGlvbiA9IHRoaXMudmlydERpci5nZXRTY3JvbGxGb3JJbmRleChpbmRleCwgZGlyZWN0aW9uID09PSBOYXZpZ2F0ZS5Eb3duKTtcbiAgICAgICAgY29uc3QgaW5kZXhPdXRPZkNodW5rID0gaW5kZXggPCB2aXJ0U3RhdGUuc3RhcnRJbmRleCB8fCBpbmRleCA+IHZpcnRTdGF0ZS5jaHVua1NpemUgKyB2aXJ0U3RhdGUuc3RhcnRJbmRleDtcbiAgICAgICAgY29uc3Qgc2Nyb2xsTmVlZGVkID0gZGlyZWN0aW9uID09PSBOYXZpZ2F0ZS5Eb3duID8gY3VycmVudFBvc2l0aW9uIDwgaXRlbVBvc2l0aW9uIDogY3VycmVudFBvc2l0aW9uID4gaXRlbVBvc2l0aW9uO1xuICAgICAgICBjb25zdCBzdWJSZXF1aXJlZCA9IGluZGV4T3V0T2ZDaHVuayB8fCBzY3JvbGxOZWVkZWQ7XG4gICAgICAgIHJldHVybiBzdWJSZXF1aXJlZDtcbiAgICB9XG5cbiAgICBwcm90ZWN0ZWQgc2tpcEhlYWRlcihkaXJlY3Rpb246IE5hdmlnYXRlKSB7XG4gICAgICAgIGlmICghdGhpcy5mb2N1c2VkSXRlbSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0aGlzLmZvY3VzZWRJdGVtLmlzSGVhZGVyIHx8IHRoaXMuZm9jdXNlZEl0ZW0uZGlzYWJsZWQpIHtcbiAgICAgICAgICAgIGlmIChkaXJlY3Rpb24gPT09IE5hdmlnYXRlLlVwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5uYXZpZ2F0ZVByZXYoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5uYXZpZ2F0ZU5leHQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEBoaWRkZW4gQGludGVybmFsXG4gICAgICovXG4gICAgdXBkYXRlU2Nyb2xsUG9zaXRpb24oKSB7XG4gICAgICAgIGlmICghdGhpcy52aXJ0RGlyKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCF0aGlzLnNlbGVjdGVkSXRlbSkge1xuICAgICAgICAgICAgdGhpcy52aXJ0RGlyLnNjcm9sbFRvKDApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGxldCB0YXJnZXRTY3JvbGwgPSB0aGlzLnZpcnREaXIuZ2V0U2Nyb2xsRm9ySW5kZXg