UNPKG

@clr/angular

Version:

Angular components for Clarity

189 lines 21.9 kB
/* * Copyright (c) 2016-2023 VMware, Inc. All Rights Reserved. * This software is released under MIT license. * The full license information can be found in LICENSE in the root directory of this project. */ import { Injectable } from '@angular/core'; import { Subject } from 'rxjs'; import * as i0 from "@angular/core"; export class TreeFocusManagerService { constructor() { this._focusRequest = new Subject(); this._focusChange = new Subject(); } get focusRequest() { return this._focusRequest.asObservable(); } get focusChange() { return this._focusChange.asObservable(); } focusNode(model) { if (model) { this._focusRequest.next(model.nodeId); } } broadcastFocusedNode(nodeId) { if (this.focusedNodeId !== nodeId) { this.focusedNodeId = nodeId; this._focusChange.next(nodeId); } } focusParent(model) { if (model) { this.focusNode(model.parent); } } focusFirstVisibleNode() { const focusModel = this.rootNodeModels && this.rootNodeModels[0]; this.focusNode(focusModel); } focusLastVisibleNode() { this.focusNode(this.findLastVisibleInTree()); } focusNodeAbove(model) { this.focusNode(this.findNodeAbove(model)); } focusNodeBelow(model) { this.focusNode(this.findNodeBelow(model)); } focusNodeStartsWith(searchString, model) { this.focusNode(this.findClosestNodeStartsWith(searchString, model)); } findSiblings(model) { // the method will return not only sibling models but also itself among them if (model.parent) { return model.parent.children; } else { return this.rootNodeModels; } } findLastVisibleInNode(model) { // the method will traverse through until it finds the last visible node from the given node if (!model) { return null; } if (model.expanded && model.children.length > 0) { const children = model.children; const lastChild = children[children.length - 1]; return this.findLastVisibleInNode(lastChild); } else { return model; } } findNextFocusable(model) { if (!model) { return null; } const siblings = this.findSiblings(model); const selfIndex = siblings.indexOf(model); if (selfIndex < siblings.length - 1) { return siblings[selfIndex + 1]; } else if (selfIndex === siblings.length - 1) { return this.findNextFocusable(model.parent); } return null; } findLastVisibleInTree() { const lastRootNode = this.rootNodeModels && this.rootNodeModels.length && this.rootNodeModels[this.rootNodeModels.length - 1]; return this.findLastVisibleInNode(lastRootNode); } findNodeAbove(model) { if (!model) { return null; } const siblings = this.findSiblings(model); const selfIndex = siblings.indexOf(model); if (selfIndex === 0) { return model.parent; } else if (selfIndex > 0) { return this.findLastVisibleInNode(siblings[selfIndex - 1]); } return null; } findNodeBelow(model) { if (!model) { return null; } if (model.expanded && model.children.length > 0) { return model.children[0]; } else { return this.findNextFocusable(model); } } findDescendentNodeStartsWith(searchString, model) { if (model.expanded && model.children.length > 0) { for (const childModel of model.children) { const found = this.findNodeStartsWith(searchString, childModel); if (found) { return found; } } } return null; } findSiblingNodeStartsWith(searchString, model) { const siblings = this.findSiblings(model); const selfIndex = siblings.indexOf(model); // Look from sibling nodes for (let i = selfIndex + 1; i < siblings.length; i++) { const siblingModel = siblings[i]; const found = this.findNodeStartsWith(searchString, siblingModel); if (found) { return found; } } return null; } findRootNodeStartsWith(searchString, model) { for (const rootModel of this.rootNodeModels) { // Don't look from a parent yet if (model.parent && model.parent === rootModel) { continue; } const found = this.findNodeStartsWith(searchString, rootModel); if (found) { return found; } } return null; } findNodeStartsWith(searchString, model) { if (!model) { return null; } if (model.textContent.startsWith(searchString)) { return model; } return this.findDescendentNodeStartsWith(searchString, model); } findClosestNodeStartsWith(searchString, model) { if (!model) { return null; } const foundFromDescendents = this.findDescendentNodeStartsWith(searchString, model); if (foundFromDescendents) { return foundFromDescendents; } const foundFromSiblings = this.findSiblingNodeStartsWith(searchString, model); if (foundFromSiblings) { return foundFromSiblings; } const foundFromRootNodes = this.findRootNodeStartsWith(searchString, model); if (foundFromRootNodes) { return foundFromRootNodes; } // Now look from its own direct parent return this.findNodeStartsWith(searchString, model.parent); } } TreeFocusManagerService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: TreeFocusManagerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); TreeFocusManagerService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: TreeFocusManagerService }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.2", ngImport: i0, type: TreeFocusManagerService, decorators: [{ type: Injectable }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS1mb2N1cy1tYW5hZ2VyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyL3NyYy9kYXRhL3RyZWUtdmlldy90cmVlLWZvY3VzLW1hbmFnZXIuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUgsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDOztBQUszQyxNQUFNLE9BQU8sdUJBQXVCO0lBRHBDO1FBS1Usa0JBQWEsR0FBRyxJQUFJLE9BQU8sRUFBVSxDQUFDO1FBQ3RDLGlCQUFZLEdBQUcsSUFBSSxPQUFPLEVBQVUsQ0FBQztLQTBNOUM7SUF4TUMsSUFBSSxZQUFZO1FBQ2QsT0FBTyxJQUFJLENBQUMsYUFBYSxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzNDLENBQUM7SUFFRCxJQUFJLFdBQVc7UUFDYixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDMUMsQ0FBQztJQUVELFNBQVMsQ0FBQyxLQUF1QjtRQUMvQixJQUFJLEtBQUssRUFBRTtZQUNULElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUN2QztJQUNILENBQUM7SUFFRCxvQkFBb0IsQ0FBQyxNQUFjO1FBQ2pDLElBQUksSUFBSSxDQUFDLGFBQWEsS0FBSyxNQUFNLEVBQUU7WUFDakMsSUFBSSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUM7WUFDNUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7U0FDaEM7SUFDSCxDQUFDO0lBRUQsV0FBVyxDQUFDLEtBQXVCO1FBQ2pDLElBQUksS0FBSyxFQUFFO1lBQ1QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsTUFBTSxD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QUFPLEtBQUssQ0FBQztTQUNkO1FBRUQsT0FBTyxJQUFJLENBQUMsNEJBQTRCLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFFTyx5QkFBeUIsQ0FBQyxZQUFvQixFQUFFLEtBQXVCO1FBQzdFLElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDVixPQUFPLElBQUksQ0FBQztTQUNiO1FBRUQsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLENBQUMsNEJBQTRCLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBRXBGLElBQUksb0JBQW9CLEVBQUU7WUFDeEIsT0FBTyxvQkFBb0IsQ0FBQztTQUM3QjtRQUVELE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLHlCQUF5QixDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsQ0FBQztRQUU5RSxJQUFJLGlCQUFpQixFQUFFO1lBQ3JCLE9BQU8saUJBQWlCLENBQUM7U0FDMUI7UUFFRCxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxZQUFZLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFFNUUsSUFBSSxrQkFBa0IsRUFBRTtZQUN0QixPQUFPLGtCQUFrQixDQUFDO1NBQzNCO1FBQ0Qsc0NBQXNDO1FBQ3RDLE9BQU8sSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDN0QsQ0FBQzs7b0hBOU1VLHVCQUF1Qjt3SEFBdkIsdUJBQXVCOzJGQUF2Qix1QkFBdUI7a0JBRG5DLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE2LTIwMjMgVk13YXJlLCBJbmMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBUaGlzIHNvZnR3YXJlIGlzIHJlbGVhc2VkIHVuZGVyIE1JVCBsaWNlbnNlLlxuICogVGhlIGZ1bGwgbGljZW5zZSBpbmZvcm1hdGlvbiBjYW4gYmUgZm91bmQgaW4gTElDRU5TRSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBwcm9qZWN0LlxuICovXG5cbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgVHJlZU5vZGVNb2RlbCB9IGZyb20gJy4vbW9kZWxzL3RyZWUtbm9kZS5tb2RlbCc7XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBUcmVlRm9jdXNNYW5hZ2VyU2VydmljZTxUPiB7XG4gIHJvb3ROb2RlTW9kZWxzOiBUcmVlTm9kZU1vZGVsPFQ+W107XG5cbiAgcHJpdmF0ZSBmb2N1c2VkTm9kZUlkOiBzdHJpbmc7XG4gIHByaXZhdGUgX2ZvY3VzUmVxdWVzdCA9IG5ldyBTdWJqZWN0PHN0cmluZz4oKTtcbiAgcHJpdmF0ZSBfZm9jdXNDaGFuZ2UgPSBuZXcgU3ViamVjdDxzdHJpbmc+KCk7XG5cbiAgZ2V0IGZvY3VzUmVxdWVzdCgpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgIHJldHVybiB0aGlzLl9mb2N1c1JlcXVlc3QuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBnZXQgZm9jdXNDaGFuZ2UoKTogT2JzZXJ2YWJsZTxzdHJpbmc+IHtcbiAgICByZXR1cm4gdGhpcy5fZm9jdXNDaGFuZ2UuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBmb2N1c05vZGUobW9kZWw6IFRyZWVOb2RlTW9kZWw8VD4pOiB2b2lkIHtcbiAgICBpZiAobW9kZWwpIHtcbiAgICAgIHRoaXMuX2ZvY3VzUmVxdWVzdC5uZXh0KG1vZGVsLm5vZGVJZCk7XG4gICAgfVxuICB9XG5cbiAgYnJvYWRjYXN0Rm9jdXNlZE5vZGUobm9kZUlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5mb2N1c2VkTm9kZUlkICE9PSBub2RlSWQpIHtcbiAgICAgIHRoaXMuZm9jdXNlZE5vZGVJZCA9IG5vZGVJZDtcbiAgICAgIHRoaXMuX2ZvY3VzQ2hhbmdlLm5leHQobm9kZUlkKTtcbiAgICB9XG4gIH1cblxuICBmb2N1c1BhcmVudChtb2RlbDogVHJlZU5vZGVNb2RlbDxUPik6IHZvaWQge1xuICAgIGlmIChtb2RlbCkge1xuICAgICAgdGhpcy5mb2N1c05vZGUobW9kZWwucGFyZW50KTtcbiAgICB9XG4gIH1cblxuICBmb2N1c0ZpcnN0VmlzaWJsZU5vZGUoKTogdm9pZCB7XG4gICAgY29uc3QgZm9jdXNNb2RlbCA9IHRoaXMucm9vdE5vZGVNb2RlbHMgJiYgdGhpcy5yb290Tm9kZU1vZGVsc1swXTtcbiAgICB0aGlzLmZvY3VzTm9kZShmb2N1c01vZGVsKTtcbiAgfVxuXG4gIGZvY3VzTGFzdFZpc2libGVOb2RlKCk6IHZvaWQge1xuICAgIHRoaXMuZm9jdXNOb2RlKHRoaXMuZmluZExhc3RWaXNpYmxlSW5UcmVlKCkpO1xuICB9XG5cbiAgZm9jdXNOb2RlQWJvdmUobW9kZWw6IFRyZWVOb2RlTW9kZWw8VD4pOiB2b2lkIHtcbiAgICB0aGlzLmZvY3VzTm9kZSh0aGlzLmZpbmROb2RlQWJvdmUobW9kZWwpKTtcbiAgfVxuXG4gIGZvY3VzTm9kZUJlbG93KG1vZGVsOiBUcmVlTm9kZU1vZGVsPFQ+KTogdm9pZCB7XG4gICAgdGhpcy5mb2N1c05vZGUodGhpcy5maW5kTm9kZUJlbG93KG1vZGVsKSk7XG4gIH1cblxuICBmb2N1c05vZGVTdGFydHNXaXRoKHNlYXJjaFN0cmluZzogc3RyaW5nLCBtb2RlbDogVHJlZU5vZGVNb2RlbDxUPik6IHZvaWQge1xuICAgIHRoaXMuZm9jdXNOb2RlKHRoaXMuZmluZENsb3Nlc3ROb2RlU3RhcnRzV2l0aChzZWFyY2hTdHJpbmcsIG1vZGVsKSk7XG4gIH1cblxuICBwcml2YXRlIGZpbmRTaWJsaW5ncyhtb2RlbDogVHJlZU5vZGVNb2RlbDxUPik6IFRyZWVOb2RlTW9kZWw8VD5bXSB7XG4gICAgLy8gdGhlIG1ldGhvZCB3aWxsIHJldHVybiBub3Qgb25seSBzaWJsaW5nIG1vZGVscyBidXQgYWxzbyBpdHNlbGYgYW1vbmcgdGhlbVxuICAgIGlmIChtb2RlbC5wYXJlbnQpIHtcbiAgICAgIHJldHVybiBtb2RlbC5wYXJlbnQuY2hpbGRyZW47XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLnJvb3ROb2RlTW9kZWxzO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZmluZExhc3RWaXNpYmxlSW5Ob2RlKG1vZGVsOiBUcmVlTm9kZU1vZGVsPFQ+KTogVHJlZU5vZGVNb2RlbDxUPiB7XG4gICAgLy8gdGhlIG1ldGhvZCB3aWxsIHRyYXZlcnNlIHRocm91Z2ggdW50aWwgaXQgZmluZHMgdGhlIGxhc3QgdmlzaWJsZSBub2RlIGZyb20gdGhlIGdpdmVuIG5vZGVcbiAgICBpZiAoIW1vZGVsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYgKG1vZGVsLmV4cGFuZGVkICYmIG1vZGVsLmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGNoaWxkcmVuID0gbW9kZWwuY2hpbGRyZW47XG4gICAgICBjb25zdCBsYXN0Q2hpbGQgPSBjaGlsZHJlbltjaGlsZHJlbi5sZW5ndGggLSAxXTtcbiAgICAgIHJldHVybiB0aGlzLmZpbmRMYXN0VmlzaWJsZUluTm9kZShsYXN0Q2hpbGQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbW9kZWw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBmaW5kTmV4dEZvY3VzYWJsZShtb2RlbDogVHJlZU5vZGVNb2RlbDxUPik6IFRyZWVOb2RlTW9kZWw8VD4ge1xuICAgIGlmICghbW9kZWwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHNpYmxpbmdzID0gdGhpcy5maW5kU2libGluZ3MobW9kZWwpO1xuICAgIGNvbnN0IHNlbGZJbmRleCA9IHNpYmxpbmdzLmluZGV4T2YobW9kZWwpO1xuXG4gICAgaWYgKHNlbGZJbmRleCA8IHNpYmxpbmdzLmxlbmd0aCAtIDEpIHtcbiAgICAgIHJldHVybiBzaWJsaW5nc1tzZWxmSW5kZXggKyAxXTtcbiAgICB9IGVsc2UgaWYgKHNlbGZJbmRleCA9PT0gc2libGluZ3MubGVuZ3RoIC0gMSkge1xuICAgICAgcmV0dXJuIHRoaXMuZmluZE5leHRGb2N1c2FibGUobW9kZWwucGFyZW50KTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIGZpbmRMYXN0VmlzaWJsZUluVHJlZSgpOiBUcmVlTm9kZU1vZGVsPFQ+IHtcbiAgICBjb25zdCBsYXN0Um9vdE5vZGUgPVxuICAgICAgdGhpcy5yb290Tm9kZU1vZGVscyAmJiB0aGlzLnJvb3ROb2RlTW9kZWxzLmxlbmd0aCAmJiB0aGlzLnJvb3ROb2RlTW9kZWxzW3RoaXMucm9vdE5vZGVNb2RlbHMubGVuZ3RoIC0gMV07XG4gICAgcmV0dXJuIHRoaXMuZmluZExhc3RWaXNpYmxlSW5Ob2RlKGxhc3RSb290Tm9kZSk7XG4gIH1cblxuICBwcml2YXRlIGZpbmROb2RlQWJvdmUobW9kZWw6IFRyZWVOb2RlTW9kZWw8VD4pOiBUcmVlTm9kZU1vZGVsPFQ+IHtcbiAgICBpZiAoIW1vZGVsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBzaWJsaW5ncyA9IHRoaXMuZmluZFNpYmxpbmdzKG1vZGVsKTtcbiAgICBjb25zdCBzZWxmSW5kZXggPSBzaWJsaW5ncy5pbmRleE9mKG1vZGVsKTtcblxuICAgIGlmIChzZWxmSW5kZXggPT09IDApIHtcbiAgICAgIHJldHVybiBtb2RlbC5wYXJlbnQ7XG4gICAgfSBlbHNlIGlmIChzZWxmSW5kZXggPiAwKSB7XG4gICAgICByZXR1cm4gdGhpcy5maW5kTGFzdFZpc2libGVJbk5vZGUoc2libGluZ3Nbc2VsZkluZGV4IC0gMV0pO1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgZmluZE5vZGVCZWxvdyhtb2RlbDogVHJlZU5vZGVNb2RlbDxUPik6IFRyZWVOb2RlTW9kZWw8VD4ge1xuICAgIGlmICghbW9kZWwpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmIChtb2RlbC5leHBhbmRlZCAmJiBtb2RlbC5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gbW9kZWwuY2hpbGRyZW5bMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLmZpbmROZXh0Rm9jdXNhYmxlKG1vZGVsKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZpbmREZXNjZW5kZW50Tm9kZVN0YXJ0c1dpdGgoc2VhcmNoU3RyaW5nOiBzdHJpbmcsIG1vZGVsOiBUcmVlTm9kZU1vZGVsPFQ+KTogVHJlZU5vZGVNb2RlbDxUPiB7XG4gICAgaWYgKG1vZGVsLmV4cGFuZGVkICYmIG1vZGVsLmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgIGZvciAoY29uc3QgY2hpbGRNb2RlbCBvZiBtb2RlbC5jaGlsZHJlbikge1xuICAgICAgICBjb25zdCBmb3VuZCA9IHRoaXMuZmluZE5vZGVTdGFydHNXaXRoKHNlYXJjaFN0cmluZywgY2hpbGRNb2RlbCk7XG4gICAgICAgIGlmIChmb3VuZCkge1xuICAgICAgICAgIHJldHVybiBmb3VuZDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgZmluZFNpYmxpbmdOb2RlU3RhcnRzV2l0aChzZWFyY2hTdHJpbmc6IHN0cmluZywgbW9kZWw6IFRyZWVOb2RlTW9kZWw8VD4pOiBUcmVlTm9kZU1vZGVsPFQ+IHtcbiAgICBjb25zdCBzaWJsaW5ncyA9IHRoaXMuZmluZFNpYmxpbmdzKG1vZGVsKTtcbiAgICBjb25zdCBzZWxmSW5kZXggPSBzaWJsaW5ncy5pbmRleE9mKG1vZGVsKTtcblxuICAgIC8vIExvb2sgZnJvbSBzaWJsaW5nIG5vZGVzXG4gICAgZm9yIChsZXQgaSA9IHNlbGZJbmRleCArIDE7IGkgPCBzaWJsaW5ncy5sZW5ndGg7IGkrKykge1xuICAgICAgY29uc3Qgc2libGluZ01vZGVsID0gc2libGluZ3NbaV07XG4gICAgICBjb25zdCBmb3VuZCA9IHRoaXMuZmluZE5vZGVTdGFydHNXaXRoKHNlYXJjaFN0cmluZywgc2libGluZ01vZGVsKTtcbiAgICAgIGlmIChmb3VuZCkge1xuICAgICAgICByZXR1cm4gZm91bmQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBmaW5kUm9vdE5vZGVTdGFydHNXaXRoKHNlYXJjaFN0cmluZzogc3RyaW5nLCBtb2RlbDogVHJlZU5vZGVNb2RlbDxUPik6IFRyZWVOb2RlTW9kZWw8VD4ge1xuICAgIGZvciAoY29uc3Qgcm9vdE1vZGVsIG9mIHRoaXMucm9vdE5vZGVNb2RlbHMpIHtcbiAgICAgIC8vIERvbid0IGxvb2sgZnJvbSBhIHBhcmVudCB5ZXRcbiAgICAgIGlmIChtb2RlbC5wYXJlbnQgJiYgbW9kZWwucGFyZW50ID09PSByb290TW9kZWwpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZvdW5kID0gdGhpcy5maW5kTm9kZVN0YXJ0c1dpdGgoc2VhcmNoU3RyaW5nLCByb290TW9kZWwpO1xuICAgICAgaWYgKGZvdW5kKSB7XG4gICAgICAgIHJldHVybiBmb3VuZDtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIGZpbmROb2RlU3RhcnRzV2l0aChzZWFyY2hTdHJpbmc6IHN0cmluZywgbW9kZWw6IFRyZWVOb2RlTW9kZWw8VD4pOiBUcmVlTm9kZU1vZGVsPFQ+IHtcbiAgICBpZiAoIW1vZGVsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAobW9kZWwudGV4dENvbnRlbnQuc3RhcnRzV2l0aChzZWFyY2hTdHJpbmcpKSB7XG4gICAgICByZXR1cm4gbW9kZWw7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZmluZERlc2NlbmRlbnROb2RlU3RhcnRzV2l0aChzZWFyY2hTdHJpbmcsIG1vZGVsKTtcbiAgfVxuXG4gIHByaXZhdGUgZmluZENsb3Nlc3ROb2RlU3RhcnRzV2l0aChzZWFyY2hTdHJpbmc6IHN0cmluZywgbW9kZWw6IFRyZWVOb2RlTW9kZWw8VD4pOiBUcmVlTm9kZU1vZGVsPFQ+IHtcbiAgICBpZiAoIW1vZGVsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBmb3VuZEZyb21EZXNjZW5kZW50cyA9IHRoaXMuZmluZERlc2NlbmRlbnROb2RlU3RhcnRzV2l0aChzZWFyY2hTdHJpbmcsIG1vZGVsKTtcblxuICAgIGlmIChmb3VuZEZyb21EZXNjZW5kZW50cykge1xuICAgICAgcmV0dXJuIGZvdW5kRnJvbURlc2NlbmRlbnRzO1xuICAgIH1cblxuICAgIGNvbnN0IGZvdW5kRnJvbVNpYmxpbmdzID0gdGhpcy5maW5kU2libGluZ05vZGVTdGFydHNXaXRoKHNlYXJjaFN0cmluZywgbW9kZWwpO1xuXG4gICAgaWYgKGZvdW5kRnJvbVNpYmxpbmdzKSB7XG4gICAgICByZXR1cm4gZm91bmRGcm9tU2libGluZ3M7XG4gICAgfVxuXG4gICAgY29uc3QgZm91bmRGcm9tUm9vdE5vZGVzID0gdGhpcy5maW5kUm9vdE5vZGVTdGFydHNXaXRoKHNlYXJjaFN0cmluZywgbW9kZWwpO1xuXG4gICAgaWYgKGZvdW5kRnJvbVJvb3ROb2Rlcykge1xuICAgICAgcmV0dXJuIGZvdW5kRnJvbVJvb3ROb2RlcztcbiAgICB9XG4gICAgLy8gTm93IGxvb2sgZnJvbSBpdHMgb3duIGRpcmVjdCBwYXJlbnRcbiAgICByZXR1cm4gdGhpcy5maW5kTm9kZVN0YXJ0c1dpdGgoc2VhcmNoU3RyaW5nLCBtb2RlbC5wYXJlbnQpO1xuICB9XG59XG4iXX0=