UNPKG

igniteui-angular

Version:

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

471 lines • 50.9 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { ChangeDetectorRef, Component, Input, TemplateRef, ViewChild, HostBinding, ElementRef, HostListener, ChangeDetectionStrategy } from '@angular/core'; import { IgxColumnComponent } from '../column.component'; import { IgxChipsAreaComponent, IgxChipComponent } from '../../chips'; import { IgxFilteringService } from './grid-filtering.service'; import { IgxGridNavigationService } from '../grid-navigation.service'; /** * @hidden */ export class IgxGridFilteringCellComponent { /** * @param {?} cdr * @param {?} filteringService * @param {?} navService */ constructor(cdr, filteringService, navService) { this.cdr = cdr; this.filteringService = filteringService; this.navService = navService; this.baseClass = 'igx-grid__filtering-cell-indicator'; this.currentTemplate = null; this.moreFiltersCount = 0; this.cssClass = 'igx-grid__filtering-cell'; this.filteringService.subscribeToEvents(); } /** * @return {?} */ ngOnInit() { this.filteringService.columnToMoreIconHidden.set(this.column.field, true); } /** * @return {?} */ ngAfterViewInit() { this.updateFilterCellArea(); } /** * @return {?} */ ngDoCheck() { this.updateFilterCellArea(); } /** * @param {?} eventArgs * @return {?} */ onTabKeyDown(eventArgs) { if (this.isLastElementFocused()) { this.filteringService.grid.navigation.navigateNextFilterCell(this.column, eventArgs); } eventArgs.stopPropagation(); } /** * @param {?} eventArgs * @return {?} */ onShiftTabKeyDown(eventArgs) { if (this.isFirstElementFocused()) { this.filteringService.grid.navigation.navigatePrevFilterCell(this.column, eventArgs); } eventArgs.stopPropagation(); } /** * Returns whether a chip with a given index is visible or not. * @param {?} index * @return {?} */ isChipVisible(index) { /** @type {?} */ const expression = this.expressionsList[index]; return !!(expression && expression.isVisible); } /** * Updates the filtering cell area. * @return {?} */ updateFilterCellArea() { this.expressionsList = this.filteringService.getExpressions(this.column.field); this.updateVisibleFilters(); } /** * @return {?} */ get template() { if (!this.column.filterable) { this.currentTemplate = null; return null; } if (this.column.filterCellTemplate) { this.currentTemplate = this.column.filterCellTemplate; return this.column.filterCellTemplate; } /** @type {?} */ const expressionTree = this.column.filteringExpressionsTree; if (!expressionTree || expressionTree.filteringOperands.length === 0) { this.currentTemplate = this.emptyFilter; return this.emptyFilter; } if (this.filteringService.isFilterComplex(this.column.field)) { this.currentTemplate = this.complexFilter; return this.complexFilter; } this.currentTemplate = this.defaultFilter; return this.defaultFilter; } /** * Gets the context passed to the filter template. * \@memberof IgxGridFilteringCellComponent * @return {?} */ get context() { return { column: this.column }; } /** * Chip clicked event handler. * @param {?=} expression * @return {?} */ onChipClicked(expression) { if (expression) { this.expressionsList.forEach((item) => { item.isSelected = (item.expression === expression); }); } else if (this.expressionsList.length > 0) { this.expressionsList.forEach((item) => { item.isSelected = false; }); this.expressionsList[0].isSelected = true; } /** @type {?} */ const index = this.filteringService.unpinnedFilterableColumns.indexOf(this.column); if (index >= 0 && !this.isColumnRightVisible(index)) { this.filteringService.scrollToFilterCell(this.filteringService.unpinnedFilterableColumns[index], true); } else if (index >= 0 && !this.isColumnLeftVisible(index)) { this.filteringService.scrollToFilterCell(this.filteringService.unpinnedFilterableColumns[index], false); } this.filteringService.filteredColumn = this.column; this.filteringService.isFilterRowVisible = true; this.filteringService.selectedExpression = expression; } /** * Chip removed event handler. * @param {?} eventArgs * @param {?} item * @return {?} */ onChipRemoved(eventArgs, item) { /** @type {?} */ const indexToRemove = this.expressionsList.indexOf(item); this.removeExpression(indexToRemove); this.focusChip(); } /** * Clears the filtering. * @return {?} */ clearFiltering() { this.filteringService.clearFilter(this.column.field); this.cdr.detectChanges(); } /** * Chip keydown event handler. * @param {?} eventArgs * @param {?=} expression * @return {?} */ onChipKeyDown(eventArgs, expression) { if (eventArgs.key === "Enter" /* ENTER */) { eventArgs.preventDefault(); this.onChipClicked(expression); } } /** * Returns the filtering indicator class. * @return {?} */ filteringIndicatorClass() { return { [this.baseClass]: !this.isMoreIconHidden(), [`${this.baseClass}--hidden`]: this.isMoreIconHidden() }; } /** * Focus a chip depending on the current visible template. * @param {?=} focusFirst * @return {?} */ focusChip(focusFirst = false) { if (this.currentTemplate === this.defaultFilter) { if (focusFirst) { this.focusFirstElement(); } else { this.focusElement(); } } else if (this.currentTemplate === this.emptyFilter) { this.ghostChip.elementRef.nativeElement.querySelector(`.igx-chip__item`).focus(); } else if (this.currentTemplate === this.complexFilter) { this.complexChip.elementRef.nativeElement.querySelector(`.igx-chip__item`).focus(); } } /** * @private * @param {?} indexToRemove * @return {?} */ removeExpression(indexToRemove) { if (indexToRemove === 0 && this.expressionsList.length === 1) { this.clearFiltering(); return; } this.filteringService.removeExpression(this.column.field, indexToRemove); this.updateVisibleFilters(); this.filteringService.filterInternal(this.column.field); } /** * @private * @return {?} */ isMoreIconHidden() { return this.filteringService.columnToMoreIconHidden.get(this.column.field); } /** * @private * @return {?} */ updateVisibleFilters() { this.expressionsList.forEach((ex) => ex.isVisible = true); if (this.moreIcon) { this.filteringService.columnToMoreIconHidden.set(this.column.field, true); } this.cdr.detectChanges(); if (this.chipsArea && this.expressionsList.length > 1) { /** @type {?} */ const areaWidth = this.chipsArea.element.nativeElement.offsetWidth; /** @type {?} */ let viewWidth = 0; /** @type {?} */ const chipsAreaElements = this.chipsArea.element.nativeElement.children; /** @type {?} */ let visibleChipsCount = 0; /** @type {?} */ const moreIconWidth = this.moreIcon.nativeElement.offsetWidth - parseInt(document.defaultView.getComputedStyle(this.moreIcon.nativeElement)['margin-left'], 10); for (let index = 0; index < chipsAreaElements.length - 1; index++) { if (viewWidth + chipsAreaElements[index].offsetWidth < areaWidth) { viewWidth += chipsAreaElements[index].offsetWidth; if (index % 2 === 0) { visibleChipsCount++; } else { viewWidth += parseInt(document.defaultView.getComputedStyle(chipsAreaElements[index])['margin-left'], 10); viewWidth += parseInt(document.defaultView.getComputedStyle(chipsAreaElements[index])['margin-right'], 10); } } else { if (index % 2 !== 0 && viewWidth + moreIconWidth > areaWidth) { visibleChipsCount--; } else if (visibleChipsCount > 0 && viewWidth - chipsAreaElements[index - 1].offsetWidth + moreIconWidth > areaWidth) { visibleChipsCount--; } this.moreFiltersCount = this.expressionsList.length - visibleChipsCount; this.filteringService.columnToMoreIconHidden.set(this.column.field, false); break; } } for (let i = visibleChipsCount; i < this.expressionsList.length; i++) { this.expressionsList[i].isVisible = false; } this.cdr.detectChanges(); } } /** * @private * @return {?} */ isFirstElementFocused() { return !(this.chipsArea && this.chipsArea.chipsList.length > 0 && this.chipsArea.chipsList.first.elementRef.nativeElement.querySelector(`.igx-chip__item`) !== document.activeElement); } /** * @private * @return {?} */ isLastElementFocused() { if (this.chipsArea) { if (this.isMoreIconHidden() && this.chipsArea.chipsList.last.elementRef.nativeElement.querySelector(`.igx-chip__remove`) !== document.activeElement) { return false; } else if (!this.isMoreIconHidden() && this.moreIcon.nativeElement !== document.activeElement) { return false; } } return true; } /** * @private * @return {?} */ focusFirstElement() { if (this.chipsArea.chipsList.length > 0) { this.chipsArea.chipsList.first.elementRef.nativeElement.querySelector(`.igx-chip__item`).focus(); } else { this.moreIcon.nativeElement.focus(); } } /** * @private * @return {?} */ focusElement() { if (this.filteringService.shouldFocusNext) { if (!this.isMoreIconHidden() && this.chipsArea.chipsList.length === 0) { this.moreIcon.nativeElement.focus(); } else { this.chipsArea.chipsList.first.elementRef.nativeElement.querySelector(`.igx-chip__item`).focus(); } } else { if (!this.isMoreIconHidden()) { this.moreIcon.nativeElement.focus(); } else { this.chipsArea.chipsList.last.elementRef.nativeElement.querySelector(`.igx-chip__remove`).focus(); } } } /** * @private * @param {?} columnIndex * @return {?} */ isColumnRightVisible(columnIndex) { if (this.filteringService.areAllColumnsInView) { return true; } /** @type {?} */ let currentColumnRight = 0; for (let index = 0; index < this.filteringService.unpinnedColumns.length; index++) { currentColumnRight += parseInt(this.filteringService.unpinnedColumns[index].width, 10); if (this.filteringService.unpinnedColumns[index] === this.filteringService.unpinnedFilterableColumns[columnIndex]) { break; } } /** @type {?} */ const width = this.filteringService.displayContainerWidth + this.filteringService.displayContainerScrollLeft; return currentColumnRight <= width; } /** * @private * @param {?} columnIndex * @return {?} */ isColumnLeftVisible(columnIndex) { if (this.filteringService.areAllColumnsInView) { return true; } /** @type {?} */ let currentColumnLeft = 0; for (let index = 0; index < this.filteringService.unpinnedColumns.length; index++) { if (this.filteringService.unpinnedColumns[index] === this.filteringService.unpinnedFilterableColumns[columnIndex]) { break; } currentColumnLeft += parseInt(this.filteringService.unpinnedColumns[index].width, 10); } return currentColumnLeft >= this.filteringService.displayContainerScrollLeft; } } IgxGridFilteringCellComponent.decorators = [ { type: Component, args: [{ changeDetection: ChangeDetectionStrategy.OnPush, preserveWhitespaces: false, selector: 'igx-grid-filtering-cell', template: "<ng-template #emptyFilter>\n <igx-chips-area [attr.draggable]=\"false\" class=\"igx-filtering-chips\">\n <igx-chip #ghostChip [attr.draggable]=\"false\" (click)=\"onChipClicked()\" (keydown)=\"onChipKeyDown($event)\" [displayDensity]=\"'cosy'\">\n <igx-icon [attr.draggable]=\"false\" igxPrefix>filter_list</igx-icon>\n <span [attr.draggable]=\"false\">{{filteringService.grid.resourceStrings.igx_grid_filter}}</span>\n </igx-chip>\n </igx-chips-area>\n</ng-template>\n\n<ng-template #defaultFilter>\n <igx-chips-area #chipsArea class=\"igx-filtering-chips\">\n <ng-container *ngFor=\"let item of expressionsList; let last = last; let index = index;\" >\n <igx-chip\n *ngIf=\"isChipVisible(index)\"\n [removable]=\"true\"\n [displayDensity]=\"'cosy'\"\n (click)=\"onChipClicked(item.expression)\"\n (keydown)=\"onChipKeyDown($event, item.expression)\"\n (onRemove)=\"onChipRemoved($event, item)\">\n <igx-icon igxPrefix\n fontSet=\"filtering-icons\"\n [name]=\"item.expression.condition.iconName\">\n </igx-icon>\n <span #label>\n {{filteringService.getChipLabel(item.expression)}}\n </span>\n </igx-chip>\n <span class=\"igx-filtering-chips__connector\" *ngIf=\"!last && isChipVisible(index + 1)\">{{filteringService.getOperatorAsString(item.afterOperator)}}</span>\n </ng-container>\n <div #moreIcon [ngClass]=\"filteringIndicatorClass()\" (click)=\"onChipClicked()\" (keydown)=\"onChipKeyDown($event)\" tabindex=\"0\">\n <igx-icon>filter_list</igx-icon>\n <igx-badge [value]=\"moreFiltersCount\"></igx-badge>\n </div>\n </igx-chips-area>\n</ng-template>\n\n<ng-template #complexFilter>\n <igx-chip #complexChip [removable]=\"true\" [displayDensity]=\"'cosy'\" (onRemove)=\"clearFiltering()\">\n <igx-icon igxPrefix>filter_list</igx-icon>\n <span>{{filteringService.grid.resourceStrings.igx_grid_complex_filter}}</span>\n </igx-chip>\n</ng-template>\n\n<ng-container *ngTemplateOutlet=\"template; context: context\"></ng-container>\n" }] } ]; /** @nocollapse */ IgxGridFilteringCellComponent.ctorParameters = () => [ { type: ChangeDetectorRef }, { type: IgxFilteringService }, { type: IgxGridNavigationService } ]; IgxGridFilteringCellComponent.propDecorators = { column: [{ type: Input }], emptyFilter: [{ type: ViewChild, args: ['emptyFilter', { read: TemplateRef },] }], defaultFilter: [{ type: ViewChild, args: ['defaultFilter', { read: TemplateRef },] }], complexFilter: [{ type: ViewChild, args: ['complexFilter', { read: TemplateRef },] }], chipsArea: [{ type: ViewChild, args: ['chipsArea', { read: IgxChipsAreaComponent },] }], moreIcon: [{ type: ViewChild, args: ['moreIcon', { read: ElementRef },] }], ghostChip: [{ type: ViewChild, args: ['ghostChip', { read: IgxChipComponent },] }], complexChip: [{ type: ViewChild, args: ['complexChip', { read: IgxChipComponent },] }], cssClass: [{ type: HostBinding, args: ['class.igx-grid__filtering-cell',] }], onTabKeyDown: [{ type: HostListener, args: ['keydown.tab', ['$event'],] }], onShiftTabKeyDown: [{ type: HostListener, args: ['keydown.shift.tab', ['$event'],] }] }; if (false) { /** * @type {?} * @private */ IgxGridFilteringCellComponent.prototype.baseClass; /** * @type {?} * @private */ IgxGridFilteringCellComponent.prototype.currentTemplate; /** @type {?} */ IgxGridFilteringCellComponent.prototype.expressionsList; /** @type {?} */ IgxGridFilteringCellComponent.prototype.moreFiltersCount; /** @type {?} */ IgxGridFilteringCellComponent.prototype.column; /** * @type {?} * @protected */ IgxGridFilteringCellComponent.prototype.emptyFilter; /** * @type {?} * @protected */ IgxGridFilteringCellComponent.prototype.defaultFilter; /** * @type {?} * @protected */ IgxGridFilteringCellComponent.prototype.complexFilter; /** * @type {?} * @protected */ IgxGridFilteringCellComponent.prototype.chipsArea; /** * @type {?} * @protected */ IgxGridFilteringCellComponent.prototype.moreIcon; /** * @type {?} * @protected */ IgxGridFilteringCellComponent.prototype.ghostChip; /** * @type {?} * @protected */ IgxGridFilteringCellComponent.prototype.complexChip; /** @type {?} */ IgxGridFilteringCellComponent.prototype.cssClass; /** @type {?} */ IgxGridFilteringCellComponent.prototype.cdr; /** @type {?} */ IgxGridFilteringCellComponent.prototype.filteringService; /** @type {?} */ IgxGridFilteringCellComponent.prototype.navService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JpZC1maWx0ZXJpbmctY2VsbC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9pZ25pdGV1aS1hbmd1bGFyLyIsInNvdXJjZXMiOlsibGliL2dyaWRzL2ZpbHRlcmluZy9ncmlkLWZpbHRlcmluZy1jZWxsLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsT0FBTyxFQUNILGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsS0FBSyxFQUNMLFdBQVcsRUFDWCxTQUFTLEVBQ1QsV0FBVyxFQUVYLFVBQVUsRUFDVixZQUFZLEVBRVosdUJBQXVCLEVBRTFCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxrQkFBa0IsRUFBMkIsTUFBTSxxQkFBcUIsQ0FBQztBQUVsRixPQUFPLEVBQXNCLHFCQUFxQixFQUFFLGdCQUFnQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzFGLE9BQU8sRUFBRSxtQkFBbUIsRUFBZ0IsTUFBTSwwQkFBMEIsQ0FBQztBQUU3RSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQzs7OztBQVl0RSxNQUFNLE9BQU8sNkJBQTZCOzs7Ozs7SUFtQ3RDLFlBQW1CLEdBQXNCLEVBQVMsZ0JBQXFDLEVBQVMsVUFBb0M7UUFBakgsUUFBRyxHQUFILEdBQUcsQ0FBbUI7UUFBUyxxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQXFCO1FBQVMsZUFBVSxHQUFWLFVBQVUsQ0FBMEI7UUFqQzVILGNBQVMsR0FBRyxvQ0FBb0MsQ0FBQztRQUNqRCxvQkFBZSxHQUFHLElBQUksQ0FBQztRQUd4QixxQkFBZ0IsR0FBRyxDQUFDLENBQUM7UUEyQnJCLGFBQVEsR0FBRywwQkFBMEIsQ0FBQztRQUd6QyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUM5QyxDQUFDOzs7O0lBRUQsUUFBUTtRQUNKLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxD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ZSxFQUFFLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRTs0QkFHaEQsU0FBUyxTQUFDLGVBQWUsRUFBRSxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUU7d0JBR2hELFNBQVMsU0FBQyxXQUFXLEVBQUUsRUFBRSxJQUFJLEVBQUUscUJBQXFCLEVBQUU7dUJBR3RELFNBQVMsU0FBQyxVQUFVLEVBQUUsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFO3dCQUcxQyxTQUFTLFNBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFOzBCQUdqRCxTQUFTLFNBQUMsYUFBYSxFQUFFLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFO3VCQUduRCxXQUFXLFNBQUMsZ0NBQWdDOzJCQW1CNUMsWUFBWSxTQUFDLGFBQWEsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQ0FTdEMsWUFBWSxTQUFDLG1CQUFtQixFQUFFLENBQUMsUUFBUSxDQUFDOzs7Ozs7O0lBMUQ3QyxrREFBeUQ7Ozs7O0lBQ3pELHdEQUErQjs7SUFFL0Isd0RBQXVDOztJQUN2Qyx5REFBNEI7O0lBRTVCLCtDQUNrQzs7Ozs7SUFFbEMsb0RBQ3dDOzs7OztJQUV4QyxzREFDMEM7Ozs7O0lBRTFDLHNEQUMwQzs7Ozs7SUFFMUMsa0RBQzJDOzs7OztJQUUzQyxpREFDK0I7Ozs7O0lBRS9CLGtEQUNzQzs7Ozs7SUFFdEMsb0RBQ3dDOztJQUV4QyxpREFDNkM7O0lBRWpDLDRDQUE2Qjs7SUFBRSx5REFBNEM7O0lBQUUsbURBQTJDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBDb21wb25lbnQsXG4gICAgSW5wdXQsXG4gICAgVGVtcGxhdGVSZWYsXG4gICAgVmlld0NoaWxkLFxuICAgIEhvc3RCaW5kaW5nLFxuICAgIEFmdGVyVmlld0luaXQsXG4gICAgRWxlbWVudFJlZixcbiAgICBIb3N0TGlzdGVuZXIsXG4gICAgT25Jbml0LFxuICAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICAgIERvQ2hlY2tcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBJZ3hDb2x1bW5Db21wb25lbnQsIElneENvbHVtbkdyb3VwQ29tcG9uZW50IH0gZnJvbSAnLi4vY29sdW1uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBJRmlsdGVyaW5nRXhwcmVzc2lvbiB9IGZyb20gJy4uLy4uL2RhdGEtb3BlcmF0aW9ucy9maWx0ZXJpbmctZXhwcmVzc2lvbi5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgSUJhc2VDaGlwRXZlbnRBcmdzLCBJZ3hDaGlwc0FyZWFDb21wb25lbnQsIElneENoaXBDb21wb25lbnQgfSBmcm9tICcuLi8uLi9jaGlwcyc7XG5pbXBvcnQgeyBJZ3hGaWx0ZXJpbmdTZXJ2aWNlLCBFeHByZXNzaW9uVUkgfSBmcm9tICcuL2dyaWQtZmlsdGVyaW5nLnNlcnZpY2UnO1xuaW1wb3J0IHsgS0VZUyB9IGZyb20gJy4uLy4uL2NvcmUvdXRpbHMnO1xuaW1wb3J0IHsgSWd4R3JpZE5hdmlnYXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vZ3JpZC1uYXZpZ2F0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgSWd4R3JpZEdyb3VwQnlSb3dDb21wb25lbnQgfSBmcm9tICcuLi9ncmlkL2dyb3VwYnktcm93LmNvbXBvbmVudCc7XG5cbi8qKlxuICogQGhpZGRlblxuICovXG5AQ29tcG9uZW50KHtcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBmYWxzZSxcbiAgICBzZWxlY3RvcjogJ2lneC1ncmlkLWZpbHRlcmluZy1jZWxsJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vZ3JpZC1maWx0ZXJpbmctY2VsbC5jb21wb25lbnQuaHRtbCdcbn0pXG5leHBvcnQgY2xhc3MgSWd4R3JpZEZpbHRlcmluZ0NlbGxDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkluaXQsIERvQ2hlY2sge1xuXG4gICAgcHJpdmF0ZSBiYXNlQ2xhc3MgPSAnaWd4LWdyaWRfX2ZpbHRlcmluZy1jZWxsLWluZGljYXRvcic7XG4gICAgcHJpdmF0ZSBjdXJyZW50VGVtcGxhdGUgPSBudWxsO1xuXG4gICAgcHVibGljIGV4cHJlc3Npb25zTGlzdDogRXhwcmVzc2lvblVJW107XG4gICAgcHVibGljIG1vcmVGaWx0ZXJzQ291bnQgPSAwO1xuXG4gICAgQElucHV0KClcbiAgICBwdWJsaWMgY29sdW1uOiBJZ3hDb2x1bW5Db21wb25lbnQ7XG5cbiAgICBAVmlld0NoaWxkKCdlbXB0eUZpbHRlcicsIHsgcmVhZDogVGVtcGxhdGVSZWYgfSlcbiAgICBwcm90ZWN0ZWQgZW1wdHlGaWx0ZXI6IFRlbXBsYXRlUmVmPGFueT47XG5cbiAgICBAVmlld0NoaWxkKCdkZWZhdWx0RmlsdGVyJywgeyByZWFkOiBUZW1wbGF0ZVJlZiB9KVxuICAgIHByb3RlY3RlZCBkZWZhdWx0RmlsdGVyOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gICAgQFZpZXdDaGlsZCgnY29tcGxleEZpbHRlcicsIHsgcmVhZDogVGVtcGxhdGVSZWYgfSlcbiAgICBwcm90ZWN0ZWQgY29tcGxleEZpbHRlcjogVGVtcGxhdGVSZWY8YW55PjtcblxuICAgIEBWaWV3Q2hpbGQoJ2NoaXBzQXJlYScsIHsgcmVhZDogSWd4Q2hpcHNBcmVhQ29tcG9uZW50IH0pXG4gICAgcHJvdGVjdGVkIGNoaXBzQXJlYTogSWd4Q2hpcHNBcmVhQ29tcG9uZW50O1xuXG4gICAgQFZpZXdDaGlsZCgnbW9yZUljb24nLCB7IHJlYWQ6IEVsZW1lbnRSZWYgfSlcbiAgICBwcm90ZWN0ZWQgbW9yZUljb246IEVsZW1lbnRSZWY7XG5cbiAgICBAVmlld0NoaWxkKCdnaG9zdENoaXAnLCB7IHJlYWQ6IElneENoaXBDb21wb25lbnQgfSlcbiAgICBwcm90ZWN0ZWQgZ2hvc3RDaGlwOiBJZ3hDaGlwQ29tcG9uZW50O1xuXG4gICAgQFZpZXdDaGlsZCgnY29tcGxleENoaXAnLCB7IHJlYWQ6IElneENoaXBDb21wb25lbnQgfSlcbiAgICBwcm90ZWN0ZWQgY29tcGxleENoaXA6IElneENoaXBDb21wb25lbnQ7XG5cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLmlneC1ncmlkX19maWx0ZXJpbmctY2VsbCcpXG4gICAgcHVibGljIGNzc0NsYXNzID0gJ2lneC1ncmlkX19maWx0ZXJpbmctY2VsbCc7XG5cbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZiwgcHVibGljIGZpbHRlcmluZ1NlcnZpY2U6IElneEZpbHRlcmluZ1NlcnZpY2UsIHB1YmxpYyBuYXZTZXJ2aWNlOiBJZ3hHcmlkTmF2aWdhdGlvblNlcnZpY2UpIHtcbiAgICAgICAgdGhpcy5maWx0ZXJpbmdTZXJ2aWNlLnN1YnNjcmliZVRvRXZlbnRzKCk7XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuZmlsdGVyaW5nU2VydmljZS5jb2x1bW5Ub01vcmVJY29uSGlkZGVuLnNldCh0aGlzLmNvbHVtbi5maWVsZCwgdHJ1ZSk7XG4gICAgfVxuXG4gICAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgICAgICB0aGlzLnVwZGF0ZUZpbHRlckNlbGxBcmVhKCk7XG4gICAgfVxuXG4gICAgcHVibGljIG5nRG9DaGVjaygpIHtcbiAgICAgICAgdGhpcy51cGRhdGVGaWx0ZXJDZWxsQXJlYSgpO1xuICAgIH1cblxuICAgIEBIb3N0TGlzdGVuZXIoJ2tleWRvd24udGFiJywgWyckZXZlbnQnXSlcbiAgICBwdWJsaWMgb25UYWJLZXlEb3duKGV2ZW50QXJncykge1xuXG4gICAgICAgIGlmICh0aGlzLmlzTGFzdEVsZW1lbnRGb2N1c2VkKCkpIHtcbiAgICAgICAgICAgIHRoaXMuZmlsdGVyaW5nU2VydmljZS5ncmlkLm5hdmlnYXRpb24ubmF2aWdhdGVOZXh0RmlsdGVyQ2VsbCh0aGlzLmNvbHVtbiwgZXZlbnRBcmdzKTtcbiAgICAgICAgfVxuICAgICAgICBldmVudEFyZ3Muc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfVxuXG4gICAgQEhvc3RMaXN0ZW5lcigna2V5ZG93bi5zaGlmdC50YWInLCBbJyRldmVudCddKVxuICAgIHB1YmxpYyBvblNoaWZ0VGFiS2V5RG93bihldmVudEFyZ3MpIHtcbiAgICAgICAgaWYgKHRoaXMuaXNGaXJzdEVsZW1lbnRGb2N1c2VkKCkpIHtcbiAgICAgICAgICAgIHRoaXMuZmlsdGVyaW5nU2VydmljZS5ncmlkLm5hdmlnYXRpb24ubmF2aWdhdGVQcmV2RmlsdGVyQ2VsbCh0aGlzLmNvbHVtbiwgZXZlbnRBcmdzKTtcbiAgICAgICAgfVxuICAgICAgICBldmVudEFyZ3Muc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB3aGV0aGVyIGEgY2hpcCB3aXRoIGEgZ2l2ZW4gaW5kZXggaXMgdmlzaWJsZSBvciBub3QuXG4gICAgICovXG4gICAgcHVibGljIGlzQ2hpcFZpc2libGUoaW5kZXg6IG51bWJlcikge1xuICAgICAgICBjb25zdCBleHByZXNzaW9uID0gdGhpcy5leHByZXNzaW9uc0xpc3RbaW5kZXhdO1xuICAgICAgICByZXR1cm4gISEoZXhwcmVzc2lvbiAmJiBleHByZXNzaW9uLmlzVmlzaWJsZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogVXBkYXRlcyB0aGUgZmlsdGVyaW5nIGNlbGwgYXJlYS5cbiAgICAgKi9cbiAgICBwdWJsaWMgdXBkYXRlRmlsdGVyQ2VsbEFyZWEoKSB7XG4gICAgICAgIHRoaXMuZXhwcmVzc2lvbnNMaXN0ID0gdGhpcy5maWx0ZXJpbmdTZXJ2aWNlLmdldEV4cHJlc3Npb25zKHRoaXMuY29sdW1uLmZpZWxkKTtcbiAgICAgICAgdGhpcy51cGRhdGVWaXNpYmxlRmlsdGVycygpO1xuICAgIH1cblxuICAgIGdldCB0ZW1wbGF0ZSgpOiBUZW1wbGF0ZVJlZjxhbnk+IHtcbiAgICAgICAgaWYgKCF0aGlzLmNvbHVtbi5maWx0ZXJhYmxlKSB7XG4gICAgICAgICAgICB0aGlzLmN1cnJlbnRUZW1wbGF0ZSA9IG51bGw7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmNvbHVtbi5maWx0ZXJDZWxsVGVtcGxhdGUpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFRlbXBsYXRlID0gdGhpcy5jb2x1bW4uZmlsdGVyQ2VsbFRlbXBsYXRlO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29sdW1uLmZpbHRlckNlbGxUZW1wbGF0ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGV4cHJlc3Npb25UcmVlID0gdGhpcy5jb2x1bW4uZmlsdGVyaW5nRXhwcmVzc2lvbnNUcmVlO1xuICAgICAgICBpZiAoIWV4cHJlc3Npb25UcmVlIHx8IGV4cHJlc3Npb25UcmVlLmZpbHRlcmluZ09wZXJhbmRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhpcy5jdXJyZW50VGVtcGxhdGUgPSB0aGlzLmVtcHR5RmlsdGVyO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW1wdHlGaWx0ZXI7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5maWx0ZXJpbmdTZXJ2aWNlLmlzRmlsdGVyQ29tcGxleCh0aGlzLmNvbHVtbi5maWVsZCkpIHtcbiAgICAgICAgICAgIHRoaXMuY3VycmVudFRlbXBsYXRlID0gdGhpcy5jb21wbGV4RmlsdGVyO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcGxleEZpbHRlcjtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuY3VycmVudFRlbXBsYXRlID0gdGhpcy5kZWZhdWx0RmlsdGVyO1xuICAgICAgICByZXR1cm4gdGhpcy5kZWZhdWx0RmlsdGVyO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGNvbnRleHQgcGFzc2VkIHRvIHRoZSBmaWx0ZXIgdGVtcGxhdGUuXG4gICAgICogQG1lbWJlcm9mIElneEdyaWRGaWx0ZXJpbmdDZWxsQ29tcG9uZW50XG4gICAgICovXG4gICAgZ2V0IGNvbnRleHQoKSB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBjb2x1bW46IHRoaXMuY29sdW1uXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hpcCBjbGlja2VkIGV2ZW50IGhhbmRsZXIuXG4gICAgICovXG4gICAgcHVibGljIG9uQ2hpcENsaWNrZWQoZXhwcmVzc2lvbj86IElGaWx0ZXJpbmdFeHByZXNzaW9uKSB7XG4gICAgICAgIGlmIChleHByZXNzaW9uKSB7XG4gICAgICAgICAgICB0aGlzLmV4cHJlc3Npb25zTGlzdC5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICAgICAgICAgICAgaXRlbS5pc1NlbGVjdGVkID0gKGl0ZW0uZXhwcmVzc2lvbiA9PT0gZXhwcmVzc2lvbik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmV4cHJlc3Npb25zTGlzdC5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0aGlzLmV4cHJlc3Npb25zTGlzdC5mb3JFYWNoKChpdGVtKSA9PiB7XG4gICAgICAgICAgICAgICAgaXRlbS5pc1NlbGVjdGVkID0gZmFsc2U7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMuZXhwcmVzc2lvbnNMaXN0WzBdLmlzU2VsZWN0ZWQgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaW5kZXggPSB0aGlzLmZpbHRlcmluZ1NlcnZpY2UudW5waW5uZWRGaWx0ZXJhYmxlQ29sdW1ucy5pbmRleE9mKHRoaXMuY29sdW1uKTtcbiAgICAgICAgaWYgKGluZGV4ID49IDAgJiYgIXRoaXMuaXNDb2x1bW5SaWdodFZpc2libGUoaW5kZXgpKSB7XG4gICAgICAgICAgICB0aGlzLmZpbHRlcmluZ1NlcnZpY2Uuc2Nyb2xsVG9GaWx0ZXJDZWxsKHRoaXMuZmlsdGVyaW5nU2VydmljZS51bnBpbm5lZEZpbHRlcmFibGVDb2x1bW5zW2luZGV4XSwgdHJ1ZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaW5kZXggPj0gMCAmJiAhdGhpcy5pc0NvbHVtbkxlZnRWaXNpYmxlKGluZGV4KSkge1xuICAgICAgICAgICAgdGhpcy5maWx0ZXJpbmdTZXJ2aWNlLnNjcm9sbFRvRmlsdGVyQ2VsbCh0aGlzLmZpbHRlcmluZ1NlcnZpY2UudW5waW5uZWRGaWx0ZXJhYmxlQ29sdW1uc1tpbmRleF0sIGZhbHNlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZmlsdGVyaW5nU2VydmljZS5maWx0ZXJlZENvbHVtbiA9IHRoaXMuY29sdW1uO1xuICAgICAgICB0aGlzLmZpbHRlcmluZ1NlcnZpY2UuaXNGaWx0ZXJSb3dWaXNpYmxlID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5maWx0ZXJpbmdTZXJ2aWNlLnNlbGVjdGVkRXhwcmVzc2lvbiA9IGV4cHJlc3Npb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ2hpcCByZW1vdmVkIGV2ZW50IGhhbmRsZXIuXG4gICAgICovXG4gICAgcHVibGljIG9uQ2hpcFJlbW92ZWQoZXZlbnRBcmdzOiBJQmFzZUNoaXBFdmVudEFyZ3MsIGl0ZW06IEV4cHJlc3Npb25VSSk6IHZvaWQge1xuICAgICAgICBjb25zdCBpbmRleFRvUmVtb3ZlID0gdGhpcy5leHByZXNzaW9uc0xpc3QuaW5kZXhPZihpdGVtKTtcbiAgICAgICAgdGhpcy5yZW1vdmVFeHByZXNzaW9uKGluZGV4VG9SZW1vdmUpO1xuICAgICAgICB0aGlzLmZvY3VzQ2hpcCgpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENsZWFycyB0aGUgZmlsdGVyaW5nLlxuICAgICAqL1xuICAgIHB1YmxpYyBjbGVhckZpbHRlcmluZygpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5maWx0ZXJpbmdTZXJ2aWNlLmNsZWFyRmlsdGVyKHRoaXMuY29sdW1uLmZpZWxkKTtcbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENoaXAga2V5ZG93biBldmVudCBoYW5kbGVyLlxuICAgICAqL1xuICAgIHB1YmxpYyBvbkNoaXBLZXlEb3duKGV2ZW50QXJnczogS2V5Ym9hcmRFdmVudCwgZXhwcmVzc2lvbj86IElGaWx0ZXJpbmdFeHByZXNzaW9uKSB7XG4gICAgICAgIGlmIChldmVudEFyZ3Mua2V5ID09PSBLRVlTLkVOVEVSKSB7XG4gICAgICAgICAgICBldmVudEFyZ3MucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgIHRoaXMub25DaGlwQ2xpY2tlZChleHByZXNzaW9uKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGZpbHRlcmluZyBpbmRpY2F0b3IgY2xhc3MuXG4gICAgICovXG4gICAgcHVibGljIGZpbHRlcmluZ0luZGljYXRvckNsYXNzKCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgW3RoaXMuYmFzZUNsYXNzXTogIXRoaXMuaXNNb3JlSWNvbkhpZGRlbigpLFxuICAgICAgICAgICAgW2Ake3RoaXMuYmFzZUNsYXNzfS0taGlkZGVuYF06IHRoaXMuaXNNb3JlSWNvbkhpZGRlbigpXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogRm9jdXMgYSBjaGlwIGRlcGVuZGluZyBvbiB0aGUgY3VycmVudCB2aXNpYmxlIHRlbXBsYXRlLlxuICAgICAqL1xuICAgIHB1YmxpYyBmb2N1c0NoaXAoZm9jdXNGaXJzdDogYm9vbGVhbiA9IGZhbHNlKSB7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRUZW1wbGF0ZSA9PT0gdGhpcy5kZWZhdWx0RmlsdGVyKSB7XG4gICAgICAgICAgICBpZiAoZm9jdXNGaXJzdCkge1xuICAgICAgICAgICAgICAgIHRoaXMuZm9jdXNGaXJzdEVsZW1lbnQoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mb2N1c0VsZW1lbnQoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmN1cnJlbnRUZW1wbGF0ZSA9PT0gdGhpcy5lbXB0eUZpbHRlcikge1xuICAgICAgICAgICAgdGhpcy5naG9zdENoaXAuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoYC5pZ3gtY2hpcF9faXRlbWApLmZvY3VzKCk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5jdXJyZW50VGVtcGxhdGUgPT09IHRoaXMuY29tcGxleEZpbHRlcikge1xuICAgICAgICAgICAgdGhpcy5jb21wbGV4Q2hpcC5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihgLmlneC1jaGlwX19pdGVtYCkuZm9jdXMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgcmVtb3ZlRXhwcmVzc2lvbihpbmRleFRvUmVtb3ZlOiBudW1iZXIpIHtcbiAgICAgICAgaWYgKGluZGV4VG9SZW1vdmUgPT09IDAgJiYgdGhpcy5leHByZXNzaW9uc0xpc3QubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICB0aGlzLmNsZWFyRmlsdGVyaW5nKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZpbHRlcmluZ1NlcnZpY2UucmVtb3ZlRXhwcmVzc2lvbih0aGlzLmNvbHVtbi5maWVsZCwgaW5kZXhUb1JlbW92ZSk7XG5cbiAgICAgICAgdGhpcy51cGRhdGVWaXNpYmxlRmlsdGVycygpO1xuICAgICAgICB0aGlzLmZpbHRlcmluZ1NlcnZpY2UuZmlsdGVySW50ZXJuYWwodGhpcy5jb2x1bW4uZmllbGQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaXNNb3JlSWNvbkhpZGRlbigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZmlsdGVyaW5nU2VydmljZS5jb2x1bW5Ub01vcmVJY29uSGlkZGVuLmdldCh0aGlzLmNvbHVtbi5maWVsZCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1cGRhdGVWaXNpYmxlRmlsdGVycygpIHtcbiAgICAgICAgdGhpcy5leHByZXNzaW9uc0xpc3QuZm9yRWFjaCgoZXgpID0+IGV4LmlzVmlzaWJsZSA9IHRydWUpO1xuXG4gICAgICAgIGlmICh0aGlzLm1vcmVJY29uKSB7XG4gICAgICAgICAgICB0aGlzLmZpbHRlcmluZ1NlcnZpY2UuY29sdW1uVG9Nb3JlSWNvbkhpZGRlbi5zZXQodGhpcy5jb2x1bW4uZmllbGQsIHRydWUpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcblxuICAgICAgICBpZiAodGhpcy5jaGlwc0FyZWEgJiYgdGhpcy5leHByZXNzaW9uc0xpc3QubGVuZ3RoID4gMSkge1xuICAgICAgICAgICAgY29uc3QgYXJlYVdpZHRoID0gdGhpcy5jaGlwc0FyZWEuZWxlbWVudC5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoO1xuICAgICAgICAgICAgbGV0IHZpZXdXaWR0aCA9IDA7XG4gICAgICAgICAgICBjb25zdCBjaGlwc0FyZWFFbGVtZW50cyA9IHRoaXMuY2hpcHNBcmVhLmVsZW1lbnQubmF0aXZlRWxlbWVudC5jaGlsZHJlbjtcbiAgICAgICAgICAgIGxldCB2aXNpYmxlQ2hpcHNDb3VudCA9IDA7XG4gICAgICAgICAgICBjb25zdCBtb3JlSWNvbldpZHRoID0gdGhpcy5tb3JlSWNvbi5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoIC1cbiAgICAgICAgICAgICAgICBwYXJzZUludChkb2N1bWVudC5kZWZhdWx0Vmlldy5nZXRDb21wdXRlZFN0eWxlKHRoaXMubW9yZUljb24ubmF0aXZlRWxlbWVudClbJ21hcmdpbi1sZWZ0J10sIDEwKTtcblxuICAgICAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGNoaXBzQXJlYUVsZW1lbnRzLmxlbmd0aCAtIDE7IGluZGV4KyspIHtcbiAgICAgICAgICAgICAgICBpZiAodmlld1dpZHRoICsgY2hpcHNBcmVhRWxlbWVudHNbaW5kZXhdLm9mZnNldFdpZHRoIDwgYXJlYVdpZHRoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZpZXdXaWR0aCArPSBjaGlwc0FyZWFFbGVtZW50c1tpbmRleF0ub2Zmc2V0V2lkdGg7XG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleCAlIDIgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHZpc2libGVDaGlwc0NvdW50Kys7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2aWV3V2lkdGggKz0gcGFyc2VJbnQoZG9jdW1lbnQuZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZShjaGlwc0FyZWFFbGVtZW50c1tpbmRleF0pWydtYXJnaW4tbGVmdCddLCAxMCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB2aWV3V2lkdGggKz0gcGFyc2VJbnQoZG9jdW1lbnQuZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZShjaGlwc0FyZWFFbGVtZW50c1tpbmRleF0pWydtYXJnaW4tcmlnaHQnXSwgMTApO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluZGV4ICUgMiAhPT0gMCAmJiB2aWV3V2lkdGggKyBtb3JlSWNvbldpZHRoID4gYXJlYVdpZHRoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2aXNpYmxlQ2hpcHNDb3VudC0tO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHZpc2libGVDaGlwc0NvdW50ID4gMCAmJiB2aWV3V2lkdGggLSBjaGlwc0FyZWFFbGVtZW50c1tpbmRleCAtIDFdLm9mZnNldFdpZHRoICsgbW9yZUljb25XaWR0aCA+IGFyZWFXaWR0aCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdmlzaWJsZUNoaXBzQ291bnQtLTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB0aGlzLm1vcmVGaWx0ZXJzQ291bnQgPSB0aGlzLmV4cHJlc3Npb25zTGlzdC5sZW5ndGggLSB2aXNpYmxlQ2hpcHNDb3VudDtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXJpbmdTZXJ2aWNlLmNvbHVtblRvTW9yZUljb25IaWRkZW4uc2V0KHRoaXMuY29sdW1uLmZpZWxkLCBmYWxzZSk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm9yIChsZXQgaSA9IHZpc2libGVDaGlwc0NvdW50OyBpIDwgdGhpcy5leHByZXNzaW9uc0xpc3QubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0aGlzLmV4cHJlc3Npb25zTGlzdFtpXS5pc1Zpc2libGUgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaXNGaXJzdEVsZW1lbnRGb2N1c2VkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISh0aGlzLmNoaXBzQXJlYSAmJiB0aGlzLmNoaXBzQXJlYS5jaGlwc0xpc3QubGVuZ3RoID4gMCAmJlxuICAgICAgICAgICAgdGhpcy5jaGlwc0FyZWEuY2hpcHNMaXN0LmZpcnN0LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKGAuaWd4LWNoaXBfX2l0ZW1gKSAhPT0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc0xhc3RFbGVtZW50Rm9jdXNlZCgpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKHRoaXMuY2hpcHNBcmVhKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc01vcmVJY29uSGlkZGVuKCkgJiYgdGhpcy5jaGlwc0FyZWEuY2hpcHNMaXN0Lmxhc3QuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoYC5pZ3gtY2hpcF9fcmVtb3ZlYCkgIT09XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuYWN0aXZlRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIXRoaXMuaXNNb3JlSWNvbkhpZGRlbigpICYmIHRoaXMubW9yZUljb24ubmF0aXZlRWxlbWVudCAhPT0gZG9jdW1lbnQuYWN0aXZlRWxlbWVudCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGZvY3VzRmlyc3RFbGVtZW50KCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5jaGlwc0FyZWEuY2hpcHNMaXN0Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHRoaXMuY2hpcHNBcmVhLmNoaXBzTGlzdC5maXJzdC5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihgLmlneC1jaGlwX19pdGVtYCkuZm9jdXMoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMubW9yZUljb24ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBmb2N1c0VsZW1lbnQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmZpbHRlcmluZ1NlcnZpY2Uuc2hvdWxkRm9jdXNOZXh0KSB7XG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNNb3JlSWNvbkhpZGRlbigpICYmIHRoaXMuY2hpcHNBcmVhLmNoaXBzTGlzdC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1vcmVJY29uLm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jaGlwc0FyZWEuY2hpcHNMaXN0LmZpcnN0LmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKGAuaWd4LWNoaXBfX2l0ZW1gKS5mb2N1cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKCF0aGlzLmlzTW9yZUljb25IaWRkZW4oKSkge1xuICAgICAgICAgICAgICAgIHRoaXMubW9yZUljb24ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aGlzLmNoaXBzQXJlYS5jaGlwc0xpc3QubGFzdC5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcihgLmlneC1jaGlwX19yZW1vdmVgKS5mb2N1cygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc0NvbHVtblJpZ2h0VmlzaWJsZShjb2x1bW5JbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICh0aGlzLmZpbHRlcmluZ1NlcnZpY2UuYXJlQWxsQ29sdW1uc0luVmlldykge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgbGV0IGN1cnJlbnRDb2x1bW5SaWdodCA9IDA7XG4gICAgICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCB0aGlzLmZpbHRlcmluZ1NlcnZpY2UudW5waW5uZWRDb2x1bW5zLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgY3VycmVudENvbHVtblJpZ2h0ICs9IHBhcnNlSW50KHRoaXMuZmlsdGVyaW5nU2VydmljZS51bnBpbm5lZENvbHVtbnNbaW5kZXhdLndpZHRoLCAxMCk7XG4gICAgICAgICAgICBpZiAodGhpcy5maWx0ZXJpbmdTZXJ2aWNlLnVucGlubmVkQ29sdW1uc1tpbmRleF0gPT09IHRoaXMuZmlsdGVyaW5nU2VydmljZS51bnBpbm5lZEZpbHRlcmFibGVDb2x1bW5zW2NvbHVtbkluZGV4XSkge1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHdpZHRoID0gdGhpcy5maWx0ZXJpbmdTZXJ2aWNlLmRpc3BsYXlDb250YWluZXJXaWR0aCArIHRoaXMuZmlsdGVyaW5nU2VydmljZS5kaXNwbGF5Q29udGFpbmVyU2Nyb2xsTGVmdDtcbiAgICAgICAgcmV0dXJuIGN1cnJlbnRDb2x1bW5SaWdodCA8PSB3aWR0aDtcbiAgICB9XG5cb