@ux-aspects/ux-aspects
Version:
Open source user interface framework for building modern, responsive, mobile big data applications
103 lines • 14.5 kB
JavaScript
import { DOWN_ARROW, LEFT_ARROW, RIGHT_ARROW, UP_ARROW } from '@angular/cdk/keycodes';
import { Injectable } from '@angular/core';
import { BehaviorSubject, Subject } from 'rxjs';
import * as i0 from "@angular/core";
export class SankeyFocusManager {
constructor() {
/** Store the node that can currently be tabbed to */
this.active$ = new BehaviorSubject(null);
/** Emit whenever an item should receive focus */
this.focused$ = new Subject();
/** Store the nodes */
this._nodes = [];
}
/** Get the current active item */
get _active() {
return this.active$.value;
}
ngOnDestroy() {
this.active$.complete();
this.focused$.complete();
}
/** Update the list of possible nodes */
setNodes(nodes) {
this._nodes = nodes;
// check if there is currently a tabbable node, if not we should make the first node tabbable
if (!this.hasActiveNode()) {
this.setActiveItem(this._nodes[0]);
}
}
/** Set the current active item */
setActiveItem(node) {
this.active$.next(node);
}
/** Handle keyboard input from nodes */
onKeydown(event) {
switch (event.which) {
case UP_ARROW:
this.shiftFocusVertically(-1);
event.preventDefault();
break;
case DOWN_ARROW:
this.shiftFocusVertically(1);
event.preventDefault();
break;
case LEFT_ARROW:
this.shiftFocusHorizontally(-1);
event.preventDefault();
break;
case RIGHT_ARROW:
this.shiftFocusHorizontally(1);
event.preventDefault();
break;
}
}
setFocusedItem(item) {
this.setActiveItem(item);
this.focused$.next(item);
}
shiftFocusVertically(delta) {
const nodes = this.getNodesInColumn(this._active.column);
// get the node below or above the active node
const target = nodes[nodes.findIndex(node => node.node.id === this._active.node.id) + delta];
if (target) {
this.setFocusedItem(target);
}
}
/** Shift the focus to a node in a sibling column */
shiftFocusHorizontally(delta) {
// get nodes in the sibling column in the desired direction
const nodes = this.getNodesInColumn(this._active.column + delta);
// if there are no nodes then do nothing as we cannot reduce an empty array
if (nodes.length === 0) {
return;
}
// get the node with the most similar y position
const target = nodes.reduce((closest, node) => {
const closestDiff = Math.max(closest.y, this._active.y) - Math.min(closest.y, this._active.y);
const currentDiff = Math.max(node.y, this._active.y) - Math.min(node.y, this._active.y);
return closestDiff < currentDiff ? closest : node;
});
if (target) {
this.setFocusedItem(target);
}
}
/** Get a list of nodes that are in a given column */
getNodesInColumn(column) {
return this.getNodesInOrder(this._nodes.filter(node => node.column === column));
}
/** Sort the nodes based on the Y position */
getNodesInOrder(nodes) {
return [...nodes].sort((nodeOne, nodeTwo) => nodeOne.y - nodeTwo.y);
}
/** Determine whether or not there is a not that is tabbable */
hasActiveNode() {
return !!this.active$.value && !!this._nodes.find(node => node.node.id === this.active$.value.node.id);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SankeyFocusManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SankeyFocusManager }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: SankeyFocusManager, decorators: [{
type: Injectable
}] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Fua2V5LWZvY3VzLW1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9zYW5rZXktY2hhcnQvc2Fua2V5LWZvY3VzLW1hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ3RGLE9BQU8sRUFBRSxVQUFVLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDdEQsT0FBTyxFQUFFLGVBQWUsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7O0FBSWhELE1BQU0sT0FBTyxrQkFBa0I7SUFEL0I7UUFHSSxxREFBcUQ7UUFDckQsWUFBTyxHQUFHLElBQUksZUFBZSxDQUFvQixJQUFJLENBQUMsQ0FBQztRQUV2RCxpREFBaUQ7UUFDakQsYUFBUSxHQUFHLElBQUksT0FBTyxFQUFxQixDQUFDO1FBRTVDLHVCQUF1QjtRQUNmLFdBQU0sR0FBcUMsRUFBRSxDQUFDO0tBMkd6RDtJQXpHRyxrQ0FBa0M7SUFDbEMsSUFBWSxPQUFPO1FBQ2YsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztJQUM5QixDQUFDO0lBRUQsV0FBVztRQUNQLElBQUksQ0FBQyxPQUFPLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQsd0NBQXdDO0lBQ3hDLFFBQVEsQ0FBQyxLQUF1QztRQUM1QyxJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQztRQUVwQiw2RkFBNkY7UUFDN0YsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLENBQUM7SUFDTCxDQUFDO0lBRUQsa0NBQWtDO0lBQ2xDLGFBQWEsQ0FBQyxJQUF1QjtRQUNqQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRUQsdUNBQXVDO0lBQ3ZDLFNBQVMsQ0FBQyxLQUFvQjtRQUUxQixRQUFRLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNsQixLQUFLLFFBQVE7Z0JBQ1QsSUFBSSxDQUFDLG9CQUFvQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzlCLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDdkIsTUFBTTtZQUVWLEtBQUssVUFBVTtnQkFDWCxJQUFJLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQzdCLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDdkIsTUFBTTtZQUVWLEtBQUssVUFBVTtnQkFDWCxJQUFJLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDaEMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN2QixNQUFNO1lBRVYsS0FBSyxXQUFXO2dCQUNaLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDL0IsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN2QixNQUFNO1FBQ2QsQ0FBQztJQUNMLENBQUM7SUFFTyxjQUFjLENBQUMsSUFBdUI7UUFDMUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM3QixDQUFDO0lBRU8sb0JBQW9CLENBQUMsS0FBYTtRQUN0QyxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUV6RCw4Q0FBOEM7UUFDOUMsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQztRQUU3RixJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoQyxDQUFDO0lBQ0wsQ0FBQztJQUVELG9EQUFvRDtJQUM1QyxzQkFBc0IsQ0FBQyxLQUFhO1FBRXhDLDJEQUEyRDtRQUMzRCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUM7UUFFakUsMkVBQTJFO1FBQzNFLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNyQixPQUFPO1FBQ1gsQ0FBQztRQUVELGdEQUFnRDtRQUNoRCxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxFQUFFO1lBQzFDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlGLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hGLE9BQU8sV0FBVyxHQUFHLFdBQVcsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFDdEQsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1QsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNoQyxDQUFDO0lBQ0wsQ0FBQztJQUVELHFEQUFxRDtJQUM3QyxnQkFBZ0IsQ0FBQyxNQUFjO1FBQ25DLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQztJQUNwRixDQUFDO0lBRUQsNkNBQTZDO0lBQ3JDLGVBQWUsQ0FBQyxLQUF1QztRQUMzRCxPQUFPLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBRUQsK0RBQStEO0lBQ3ZELGFBQWE7UUFDakIsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEtBQUssSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzNHLENBQUM7K0dBbEhRLGtCQUFrQjttSEFBbEIsa0JBQWtCOzs0RkFBbEIsa0JBQWtCO2tCQUQ5QixVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRE9XTl9BUlJPVywgTEVGVF9BUlJPVywgUklHSFRfQVJST1csIFVQX0FSUk9XIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcbmltcG9ydCB7IEluamVjdGFibGUsIE9uRGVzdHJveSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBTYW5rZXlOb2RlTGluayB9IGZyb20gJy4vaW50ZXJmYWNlcy9ub2RlLWxpbmsuaW50ZXJmYWNlJztcblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFNhbmtleUZvY3VzTWFuYWdlcjxUPiBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG5cbiAgICAvKiogU3RvcmUgdGhlIG5vZGUgdGhhdCBjYW4gY3VycmVudGx5IGJlIHRhYmJlZCB0byAqL1xuICAgIGFjdGl2ZSQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFNhbmtleU5vZGVMaW5rPFQ+PihudWxsKTtcblxuICAgIC8qKiBFbWl0IHdoZW5ldmVyIGFuIGl0ZW0gc2hvdWxkIHJlY2VpdmUgZm9jdXMgKi9cbiAgICBmb2N1c2VkJCA9IG5ldyBTdWJqZWN0PFNhbmtleU5vZGVMaW5rPFQ+PigpO1xuXG4gICAgLyoqIFN0b3JlIHRoZSBub2RlcyAgKi9cbiAgICBwcml2YXRlIF9ub2RlczogUmVhZG9ubHlBcnJheTxTYW5rZXlOb2RlTGluazxUPj4gPSBbXTtcblxuICAgIC8qKiBHZXQgdGhlIGN1cnJlbnQgYWN0aXZlIGl0ZW0gKi9cbiAgICBwcml2YXRlIGdldCBfYWN0aXZlKCk6IFNhbmtleU5vZGVMaW5rPFQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuYWN0aXZlJC52YWx1ZTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5hY3RpdmUkLmNvbXBsZXRlKCk7XG4gICAgICAgIHRoaXMuZm9jdXNlZCQuY29tcGxldGUoKTtcbiAgICB9XG5cbiAgICAvKiogVXBkYXRlIHRoZSBsaXN0IG9mIHBvc3NpYmxlIG5vZGVzICovXG4gICAgc2V0Tm9kZXMobm9kZXM6IFJlYWRvbmx5QXJyYXk8U2Fua2V5Tm9kZUxpbms8VD4+KTogdm9pZCB7XG4gICAgICAgIHRoaXMuX25vZGVzID0gbm9kZXM7XG5cbiAgICAgICAgLy8gY2hlY2sgaWYgdGhlcmUgaXMgY3VycmVudGx5IGEgdGFiYmFibGUgbm9kZSwgaWYgbm90IHdlIHNob3VsZCBtYWtlIHRoZSBmaXJzdCBub2RlIHRhYmJhYmxlXG4gICAgICAgIGlmICghdGhpcy5oYXNBY3RpdmVOb2RlKCkpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0QWN0aXZlSXRlbSh0aGlzLl9ub2Rlc1swXSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogU2V0IHRoZSBjdXJyZW50IGFjdGl2ZSBpdGVtICovXG4gICAgc2V0QWN0aXZlSXRlbShub2RlOiBTYW5rZXlOb2RlTGluazxUPik6IHZvaWQge1xuICAgICAgICB0aGlzLmFjdGl2ZSQubmV4dChub2RlKTtcbiAgICB9XG5cbiAgICAvKiogSGFuZGxlIGtleWJvYXJkIGlucHV0IGZyb20gbm9kZXMgKi9cbiAgICBvbktleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcblxuICAgICAgICBzd2l0Y2ggKGV2ZW50LndoaWNoKSB7XG4gICAgICAgICAgICBjYXNlIFVQX0FSUk9XOlxuICAgICAgICAgICAgICAgIHRoaXMuc2hpZnRGb2N1c1ZlcnRpY2FsbHkoLTEpO1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgRE9XTl9BUlJPVzpcbiAgICAgICAgICAgICAgICB0aGlzLnNoaWZ0Rm9jdXNWZXJ0aWNhbGx5KDEpO1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgTEVGVF9BUlJPVzpcbiAgICAgICAgICAgICAgICB0aGlzLnNoaWZ0Rm9jdXNIb3Jpem9udGFsbHkoLTEpO1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgICAgIGNhc2UgUklHSFRfQVJST1c6XG4gICAgICAgICAgICAgICAgdGhpcy5zaGlmdEZvY3VzSG9yaXpvbnRhbGx5KDEpO1xuICAgICAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHNldEZvY3VzZWRJdGVtKGl0ZW06IFNhbmtleU5vZGVMaW5rPFQ+KTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0QWN0aXZlSXRlbShpdGVtKTtcbiAgICAgICAgdGhpcy5mb2N1c2VkJC5uZXh0KGl0ZW0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgc2hpZnRGb2N1c1ZlcnRpY2FsbHkoZGVsdGE6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjb25zdCBub2RlcyA9IHRoaXMuZ2V0Tm9kZXNJbkNvbHVtbih0aGlzLl9hY3RpdmUuY29sdW1uKTtcblxuICAgICAgICAvLyBnZXQgdGhlIG5vZGUgYmVsb3cgb3IgYWJvdmUgdGhlIGFjdGl2ZSBub2RlXG4gICAgICAgIGNvbnN0IHRhcmdldCA9IG5vZGVzW25vZGVzLmZpbmRJbmRleChub2RlID0+IG5vZGUubm9kZS5pZCA9PT0gdGhpcy5fYWN0aXZlLm5vZGUuaWQpICsgZGVsdGFdO1xuXG4gICAgICAgIGlmICh0YXJnZXQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0Rm9jdXNlZEl0ZW0odGFyZ2V0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBTaGlmdCB0aGUgZm9jdXMgdG8gYSBub2RlIGluIGEgc2libGluZyBjb2x1bW4gKi9cbiAgICBwcml2YXRlIHNoaWZ0Rm9jdXNIb3Jpem9udGFsbHkoZGVsdGE6IG51bWJlcik6IHZvaWQge1xuXG4gICAgICAgIC8vIGdldCBub2RlcyBpbiB0aGUgc2libGluZyBjb2x1bW4gaW4gdGhlIGRlc2lyZWQgZGlyZWN0aW9uXG4gICAgICAgIGNvbnN0IG5vZGVzID0gdGhpcy5nZXROb2Rlc0luQ29sdW1uKHRoaXMuX2FjdGl2ZS5jb2x1bW4gKyBkZWx0YSk7XG5cbiAgICAgICAgLy8gaWYgdGhlcmUgYXJlIG5vIG5vZGVzIHRoZW4gZG8gbm90aGluZyBhcyB3ZSBjYW5ub3QgcmVkdWNlIGFuIGVtcHR5IGFycmF5XG4gICAgICAgIGlmIChub2Rlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGdldCB0aGUgbm9kZSB3aXRoIHRoZSBtb3N0IHNpbWlsYXIgeSBwb3NpdGlvblxuICAgICAgICBjb25zdCB0YXJnZXQgPSBub2Rlcy5yZWR1Y2UoKGNsb3Nlc3QsIG5vZGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGNsb3Nlc3REaWZmID0gTWF0aC5tYXgoY2xvc2VzdC55LCB0aGlzLl9hY3RpdmUueSkgLSBNYXRoLm1pbihjbG9zZXN0LnksIHRoaXMuX2FjdGl2ZS55KTtcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnREaWZmID0gTWF0aC5tYXgobm9kZS55LCB0aGlzLl9hY3RpdmUueSkgLSBNYXRoLm1pbihub2RlLnksIHRoaXMuX2FjdGl2ZS55KTtcbiAgICAgICAgICAgIHJldHVybiBjbG9zZXN0RGlmZiA8IGN1cnJlbnREaWZmID8gY2xvc2VzdCA6IG5vZGU7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICh0YXJnZXQpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0Rm9jdXNlZEl0ZW0odGFyZ2V0KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBHZXQgYSBsaXN0IG9mIG5vZGVzIHRoYXQgYXJlIGluIGEgZ2l2ZW4gY29sdW1uICovXG4gICAgcHJpdmF0ZSBnZXROb2Rlc0luQ29sdW1uKGNvbHVtbjogbnVtYmVyKTogUmVhZG9ubHlBcnJheTxTYW5rZXlOb2RlTGluazxUPj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXROb2Rlc0luT3JkZXIodGhpcy5fbm9kZXMuZmlsdGVyKG5vZGUgPT4gbm9kZS5jb2x1bW4gPT09IGNvbHVtbikpO1xuICAgIH1cblxuICAgIC8qKiBTb3J0IHRoZSBub2RlcyBiYXNlZCBvbiB0aGUgWSBwb3NpdGlvbiAqL1xuICAgIHByaXZhdGUgZ2V0Tm9kZXNJbk9yZGVyKG5vZGVzOiBSZWFkb25seUFycmF5PFNhbmtleU5vZGVMaW5rPFQ+Pik6IFJlYWRvbmx5QXJyYXk8U2Fua2V5Tm9kZUxpbms8VD4+IHtcbiAgICAgICAgcmV0dXJuIFsuLi5ub2Rlc10uc29ydCgobm9kZU9uZSwgbm9kZVR3bykgPT4gbm9kZU9uZS55IC0gbm9kZVR3by55KTtcbiAgICB9XG5cbiAgICAvKiogRGV0ZXJtaW5lIHdoZXRoZXIgb3Igbm90IHRoZXJlIGlzIGEgbm90IHRoYXQgaXMgdGFiYmFibGUgKi9cbiAgICBwcml2YXRlIGhhc0FjdGl2ZU5vZGUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuYWN0aXZlJC52YWx1ZSAmJiAhIXRoaXMuX25vZGVzLmZpbmQobm9kZSA9PiBub2RlLm5vZGUuaWQgPT09IHRoaXMuYWN0aXZlJC52YWx1ZS5ub2RlLmlkKTtcbiAgICB9XG5cbn1cbiJdfQ==