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