@odymaui/angular-tree-component
Version:
A simple yet powerful tree component for Angular16. WARNING: This is an unsupported fork for use in a dependent project to upgrade it to Angular 16. Unit tests pass and the example-app works as expected.
481 lines • 61.4 kB
JavaScript
import { Injectable } from '@angular/core';
import { observable, computed, action, autorun, makeObservable } from 'mobx';
import { TreeNode } from './tree-node.model';
import { TreeOptions } from './tree-options.model';
import { TREE_EVENTS } from '../constants/events';
import * as i0 from "@angular/core";
export class TreeModel {
static focusedTree = null;
options = new TreeOptions();
nodes;
eventNames = Object.keys(TREE_EVENTS);
virtualScroll;
roots;
expandedNodeIds = {};
selectedLeafNodeIds = {};
activeNodeIds = {};
hiddenNodeIds = {};
focusedNodeId = null;
virtualRoot;
firstUpdate = true;
events;
subscriptions = [];
constructor() {
makeObservable(this, {
roots: observable,
expandedNodeIds: observable,
selectedLeafNodeIds: observable,
activeNodeIds: observable,
hiddenNodeIds: observable,
focusedNodeId: observable,
virtualRoot: observable,
focusedNode: computed,
expandedNodes: computed,
activeNodes: computed,
hiddenNodes: computed,
selectedLeafNodes: computed,
setData: action,
update: action,
setFocusedNode: action,
setFocus: action,
doForAll: action,
focusNextNode: action,
focusPreviousNode: action,
focusDrillDown: action,
focusDrillUp: action,
setActiveNode: action,
setSelectedNode: action,
setExpandedNode: action,
expandAll: action,
collapseAll: action,
setIsHidden: action,
setHiddenNodeIds: action,
filterNodes: action,
clearFilter: action,
moveNode: action,
copyNode: action,
setState: action,
});
}
// events
fireEvent(event) {
event.treeModel = this;
this.events[event.eventName].emit(event);
this.events.event.emit(event);
}
subscribe(eventName, fn) {
const subscription = this.events[eventName].subscribe(fn);
this.subscriptions.push(subscription);
}
// getters
getFocusedNode() {
return this.focusedNode;
}
getActiveNode() {
return this.activeNodes[0];
}
getActiveNodes() {
return this.activeNodes;
}
getVisibleRoots() {
return this.virtualRoot.visibleChildren;
}
getFirstRoot(skipHidden = false) {
const root = skipHidden ? this.getVisibleRoots() : this.roots;
return root != null && root.length ? root[0] : null;
}
getLastRoot(skipHidden = false) {
const root = skipHidden ? this.getVisibleRoots() : this.roots;
return root != null && root.length ? root[root.length - 1] : null;
}
get isFocused() {
return TreeModel.focusedTree === this;
}
isNodeFocused(node) {
return this.focusedNode === node;
}
isEmptyTree() {
return this.roots && this.roots.length === 0;
}
get focusedNode() {
return this.focusedNodeId ? this.getNodeById(this.focusedNodeId) : null;
}
get expandedNodes() {
const nodes = Object.keys(this.expandedNodeIds)
.filter((id) => this.expandedNodeIds[id])
.map((id) => this.getNodeById(id));
return nodes.filter(Boolean);
}
get activeNodes() {
const nodes = Object.keys(this.activeNodeIds)
.filter((id) => this.activeNodeIds[id])
.map((id) => this.getNodeById(id));
return nodes.filter(Boolean);
}
get hiddenNodes() {
const nodes = Object.keys(this.hiddenNodeIds)
.filter((id) => this.hiddenNodeIds[id])
.map((id) => this.getNodeById(id));
return nodes.filter(Boolean);
}
get selectedLeafNodes() {
const nodes = Object.keys(this.selectedLeafNodeIds)
.filter((id) => this.selectedLeafNodeIds[id])
.map((id) => this.getNodeById(id));
return nodes.filter(Boolean);
}
// locating nodes
getNodeByPath(path, startNode = null) {
if (!path)
return null;
startNode = startNode || this.virtualRoot;
if (path.length === 0)
return startNode;
if (!startNode.children)
return null;
const childId = path.shift();
const childNode = startNode.children.find(c => c.id === childId);
if (!childNode)
return null;
return this.getNodeByPath(path, childNode);
}
getNodeById(id) {
const idStr = id.toString();
return this.getNodeBy((node) => node.id.toString() === idStr);
}
getNodeBy(predicate, startNode = null) {
startNode = startNode || this.virtualRoot;
if (!startNode.children)
return null;
const found = startNode.children.find(predicate);
if (found) { // found in children
return found;
}
else { // look in children's children
for (let child of startNode.children) {
const foundInChildren = this.getNodeBy(predicate, child);
if (foundInChildren)
return foundInChildren;
}
}
}
isExpanded(node) {
return this.expandedNodeIds[node.id];
}
isHidden(node) {
return this.hiddenNodeIds[node.id];
}
isActive(node) {
return this.activeNodeIds[node.id];
}
isSelected(node) {
return this.selectedLeafNodeIds[node.id];
}
ngOnDestroy() {
this.dispose();
this.unsubscribeAll();
}
dispose() {
// Dispose reactions of the replaced nodes
if (this.virtualRoot) {
this.virtualRoot.dispose();
}
}
unsubscribeAll() {
this.subscriptions.forEach(subscription => subscription.unsubscribe());
this.subscriptions = [];
}
// actions
setData({ nodes, options = null, events = null }) {
if (options) {
this.options = new TreeOptions(options);
}
if (events) {
this.events = events;
}
if (nodes) {
this.nodes = nodes;
}
this.update();
}
update() {
// Rebuild tree:
let virtualRootConfig = {
id: this.options.rootId,
virtual: true,
[this.options.childrenField]: this.nodes
};
this.dispose();
this.virtualRoot = new TreeNode(virtualRootConfig, null, this, 0);
this.roots = this.virtualRoot.children;
// Fire event:
if (this.firstUpdate) {
if (this.roots) {
this.firstUpdate = false;
this._calculateExpandedNodes();
}
}
else {
this.fireEvent({ eventName: TREE_EVENTS.updateData });
}
}
setFocusedNode(node) {
this.focusedNodeId = node ? node.id : null;
}
setFocus(value) {
TreeModel.focusedTree = value ? this : null;
}
doForAll(fn) {
this.roots.forEach((root) => root.doForAll(fn));
}
focusNextNode() {
let previousNode = this.getFocusedNode();
let nextNode = previousNode ? previousNode.findNextNode(true, true) : this.getFirstRoot(true);
if (nextNode)
nextNode.focus();
}
focusPreviousNode() {
let previousNode = this.getFocusedNode();
let nextNode = previousNode ? previousNode.findPreviousNode(true) : this.getLastRoot(true);
if (nextNode)
nextNode.focus();
}
focusDrillDown() {
let previousNode = this.getFocusedNode();
if (previousNode && previousNode.isCollapsed && previousNode.hasChildren) {
previousNode.toggleExpanded();
}
else {
let nextNode = previousNode ? previousNode.getFirstChild(true) : this.getFirstRoot(true);
if (nextNode)
nextNode.focus();
}
}
focusDrillUp() {
let previousNode = this.getFocusedNode();
if (!previousNode)
return;
if (previousNode.isExpanded) {
previousNode.toggleExpanded();
}
else {
let nextNode = previousNode.realParent;
if (nextNode)
nextNode.focus();
}
}
setActiveNode(node, value, multi = false) {
if (multi) {
this._setActiveNodeMulti(node, value);
}
else {
this._setActiveNodeSingle(node, value);
}
if (value) {
node.focus(this.options.scrollOnActivate);
this.fireEvent({ eventName: TREE_EVENTS.activate, node });
this.fireEvent({ eventName: TREE_EVENTS.nodeActivate, node }); // For IE11
}
else {
this.fireEvent({ eventName: TREE_EVENTS.deactivate, node });
this.fireEvent({ eventName: TREE_EVENTS.nodeDeactivate, node }); // For IE11
}
}
setSelectedNode(node, value) {
this.selectedLeafNodeIds = Object.assign({}, this.selectedLeafNodeIds, { [node.id]: value });
if (value) {
node.focus();
this.fireEvent({ eventName: TREE_EVENTS.select, node });
}
else {
this.fireEvent({ eventName: TREE_EVENTS.deselect, node });
}
}
setExpandedNode(node, value) {
this.expandedNodeIds = Object.assign({}, this.expandedNodeIds, { [node.id]: value });
this.fireEvent({ eventName: TREE_EVENTS.toggleExpanded, node, isExpanded: value });
}
expandAll() {
this.roots.forEach((root) => root.expandAll());
}
collapseAll() {
this.roots.forEach((root) => root.collapseAll());
}
setIsHidden(node, value) {
this.hiddenNodeIds = Object.assign({}, this.hiddenNodeIds, { [node.id]: value });
}
setHiddenNodeIds(nodeIds) {
this.hiddenNodeIds = nodeIds.reduce((hiddenNodeIds, id) => Object.assign(hiddenNodeIds, {
[id]: true
}), {});
}
performKeyAction(node, $event) {
const keyAction = this.options.actionMapping.keys[$event.keyCode];
if (keyAction) {
$event.preventDefault();
keyAction(this, node, $event);
return true;
}
else {
return false;
}
}
filterNodes(filter, autoShow = true) {
let filterFn;
if (!filter) {
return this.clearFilter();
}
// support function and string filter
if (filter && typeof filter.valueOf() === 'string') {
filterFn = (node) => node.displayField.toLowerCase().indexOf(filter.toLowerCase()) !== -1;
}
else if (filter && typeof filter === 'function') {
filterFn = filter;
}
else {
console.error('Don\'t know what to do with filter', filter);
console.error('Should be either a string or function');
return;
}
const ids = {};
this.roots.forEach((node) => this._filterNode(ids, node, filterFn, autoShow));
this.hiddenNodeIds = ids;
this.fireEvent({ eventName: TREE_EVENTS.changeFilter });
}
clearFilter() {
this.hiddenNodeIds = {};
this.fireEvent({ eventName: TREE_EVENTS.changeFilter });
}
moveNode(node, to) {
const fromIndex = node.getIndexInParent();
const fromParent = node.parent;
if (!this.canMoveNode(node, to, fromIndex))
return;
const fromChildren = fromParent.getField('children');
// If node doesn't have children - create children array
if (!to.parent.getField('children')) {
to.parent.setField('children', []);
}
const toChildren = to.parent.getField('children');
const originalNode = fromChildren.splice(fromIndex, 1)[0];
// Compensate for index if already removed from parent:
let toIndex = (fromParent === to.parent && to.index > fromIndex) ? to.index - 1 : to.index;
toChildren.splice(toIndex, 0, originalNode);
fromParent.treeModel.update();
if (to.parent.treeModel !== fromParent.treeModel) {
to.parent.treeModel.update();
}
this.fireEvent({
eventName: TREE_EVENTS.moveNode,
node: originalNode,
to: { parent: to.parent.data, index: toIndex },
from: { parent: fromParent.data, index: fromIndex }
});
}
copyNode(node, to) {
const fromIndex = node.getIndexInParent();
if (!this.canMoveNode(node, to, fromIndex))
return;
// If node doesn't have children - create children array
if (!to.parent.getField('children')) {
to.parent.setField('children', []);
}
const toChildren = to.parent.getField('children');
const nodeCopy = this.options.getNodeClone(node);
toChildren.splice(to.index, 0, nodeCopy);
node.treeModel.update();
if (to.parent.treeModel !== node.treeModel) {
to.parent.treeModel.update();
}
this.fireEvent({ eventName: TREE_EVENTS.copyNode, node: nodeCopy, to: { parent: to.parent.data, index: to.index } });
}
getState() {
return {
expandedNodeIds: this.expandedNodeIds,
selectedLeafNodeIds: this.selectedLeafNodeIds,
activeNodeIds: this.activeNodeIds,
hiddenNodeIds: this.hiddenNodeIds,
focusedNodeId: this.focusedNodeId
};
}
setState(state) {
if (!state)
return;
Object.assign(this, {
expandedNodeIds: state.expandedNodeIds || {},
selectedLeafNodeIds: state.selectedLeafNodeIds || {},
activeNodeIds: state.activeNodeIds || {},
hiddenNodeIds: state.hiddenNodeIds || {},
focusedNodeId: state.focusedNodeId
});
}
subscribeToState(fn) {
autorun(() => fn(this.getState()));
}
canMoveNode(node, to, fromIndex = undefined) {
const fromNodeIndex = fromIndex || node.getIndexInParent();
// same node:
if (node.parent === to.parent && fromIndex === to.index) {
return false;
}
return !to.parent.isDescendantOf(node);
}
calculateExpandedNodes() {
this._calculateExpandedNodes();
}
// private methods
_filterNode(ids, node, filterFn, autoShow) {
// if node passes function then it's visible
let isVisible = filterFn(node);
if (node.children) {
// if one of node's children passes filter then this node is also visible
node.children.forEach((child) => {
if (this._filterNode(ids, child, filterFn, autoShow)) {
isVisible = true;
}
});
}
// mark node as hidden
if (!isVisible) {
ids[node.id] = true;
}
// auto expand parents to make sure the filtered nodes are visible
if (autoShow && isVisible) {
node.ensureVisible();
}
return isVisible;
}
_calculateExpandedNodes(startNode = null) {
startNode = startNode || this.virtualRoot;
if (startNode.data[this.options.isExpandedField]) {
this.expandedNodeIds = Object.assign({}, this.expandedNodeIds, { [startNode.id]: true });
}
if (startNode.children) {
startNode.children.forEach((child) => this._calculateExpandedNodes(child));
}
}
_setActiveNodeSingle(node, value) {
// Deactivate all other nodes:
this.activeNodes
.filter((activeNode) => activeNode !== node)
.forEach((activeNode) => {
this.fireEvent({ eventName: TREE_EVENTS.deactivate, node: activeNode });
this.fireEvent({ eventName: TREE_EVENTS.nodeDeactivate, node: activeNode }); // For IE11
});
if (value) {
this.activeNodeIds = { [node.id]: true };
}
else {
this.activeNodeIds = {};
}
}
_setActiveNodeMulti(node, value) {
this.activeNodeIds = Object.assign({}, this.activeNodeIds, { [node.id]: value });
}
/** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: TreeModel, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
/** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: TreeModel });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: TreeModel, decorators: [{
type: Injectable
}], ctorParameters: function () { return []; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS5tb2RlbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItdHJlZS1jb21wb25lbnQvc3JjL2xpYi9tb2RlbHMvdHJlZS5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFhLE1BQU0sZUFBZSxDQUFDO0FBQ3RELE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRTdFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM3QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFHbkQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHFCQUFxQixDQUFDOztBQUdsRCxNQUFNLE9BQU8sU0FBUztJQUNwQixNQUFNLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztJQUUxQixPQUFPLEdBQWdCLElBQUksV0FBVyxFQUFFLENBQUM7SUFDekMsS0FBSyxDQUFRO0lBQ2IsVUFBVSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDdEMsYUFBYSxDQUFvQjtJQUVqQyxLQUFLLENBQWE7SUFDbEIsZUFBZSxHQUFxQixFQUFFLENBQUM7SUFDdkMsbUJBQW1CLEdBQXFCLEVBQUUsQ0FBQztJQUMzQyxhQUFhLEdBQXFCLEVBQUUsQ0FBQztJQUNyQyxhQUFhLEdBQXFCLEVBQUUsQ0FBQztJQUNyQyxhQUFhLEdBQVcsSUFBSSxDQUFDO0lBQzdCLFdBQVcsQ0FBVztJQUVkLFdBQVcsR0FBRyxJQUFJLENBQUM7SUFDbkIsTUFBTSxDQUFNO0lBQ1osYUFBYSxHQUFtQixFQUFFLENBQUM7SUFFM0M7UUFDRSxjQUFjLENBQUMsSUFBSSxFQUFFO1lBQ25CLEtBQUssRUFBRSxVQUFVO1lBQ2pCLGVBQWUsRUFBRSxVQUFV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QUksQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFDO0lBQ2pGLENBQUM7MEhBN2lCVSxTQUFTOzhIQUFULFNBQVM7OzJGQUFULFNBQVM7a0JBRHJCLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgb2JzZXJ2YWJsZSwgY29tcHV0ZWQsIGFjdGlvbiwgYXV0b3J1biwgbWFrZU9ic2VydmFibGUgfSBmcm9tICdtb2J4JztcclxuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IFRyZWVOb2RlIH0gZnJvbSAnLi90cmVlLW5vZGUubW9kZWwnO1xyXG5pbXBvcnQgeyBUcmVlT3B0aW9ucyB9IGZyb20gJy4vdHJlZS1vcHRpb25zLm1vZGVsJztcclxuaW1wb3J0IHsgVHJlZVZpcnR1YWxTY3JvbGwgfSBmcm9tICcuL3RyZWUtdmlydHVhbC1zY3JvbGwubW9kZWwnO1xyXG5pbXBvcnQgeyBJVHJlZU1vZGVsLCBJRFR5cGUsIElEVHlwZURpY3Rpb25hcnkgfSBmcm9tICcuLi9kZWZzL2FwaSc7XHJcbmltcG9ydCB7IFRSRUVfRVZFTlRTIH0gZnJvbSAnLi4vY29uc3RhbnRzL2V2ZW50cyc7XHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBUcmVlTW9kZWwgaW1wbGVtZW50cyBJVHJlZU1vZGVsLCBPbkRlc3Ryb3kge1xyXG4gIHN0YXRpYyBmb2N1c2VkVHJlZSA9IG51bGw7XHJcblxyXG4gIG9wdGlvbnM6IFRyZWVPcHRpb25zID0gbmV3IFRyZWVPcHRpb25zKCk7XHJcbiAgbm9kZXM6IGFueVtdO1xyXG4gIGV2ZW50TmFtZXMgPSBPYmplY3Qua2V5cyhUUkVFX0VWRU5UUyk7XHJcbiAgdmlydHVhbFNjcm9sbDogVHJlZVZpcnR1YWxTY3JvbGw7XHJcblxyXG4gIHJvb3RzOiBUcmVlTm9kZVtdO1xyXG4gIGV4cGFuZGVkTm9kZUlkczogSURUeXBlRGljdGlvbmFyeSA9IHt9O1xyXG4gIHNlbGVjdGVkTGVhZk5vZGVJZHM6IElEVHlwZURpY3Rpb25hcnkgPSB7fTtcclxuICBhY3RpdmVOb2RlSWRzOiBJRFR5cGVEaWN0aW9uYXJ5ID0ge307XHJcbiAgaGlkZGVuTm9kZUlkczogSURUeXBlRGljdGlvbmFyeSA9IHt9O1xyXG4gIGZvY3VzZWROb2RlSWQ6IElEVHlwZSA9IG51bGw7XHJcbiAgdmlydHVhbFJvb3Q6IFRyZWVOb2RlO1xyXG5cclxuICBwcml2YXRlIGZpcnN0VXBkYXRlID0gdHJ1ZTtcclxuICBwcml2YXRlIGV2ZW50czogYW55O1xyXG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uW10gPSBbXTtcclxuXHJcbiAgY29uc3RydWN0b3IoKSB7XHJcbiAgICBtYWtlT2JzZXJ2YWJsZSh0aGlzLCB7XHJcbiAgICAgIHJvb3RzOiBvYnNlcnZhYmxlLFxyXG4gICAgICBleHBhbmRlZE5vZGVJZHM6IG9ic2VydmFibGUsXHJcbiAgICAgIHNlbGVjdGVkTGVhZk5vZGVJZHM6IG9ic2VydmFibGUsXHJcbiAgICAgIGFjdGl2ZU5vZGVJZHM6IG9ic2VydmFibGUsXHJcbiAgICAgIGhpZGRlbk5vZGVJZHM6IG9ic2VydmFibGUsXHJcbiAgICAgIGZvY3VzZWROb2RlSWQ6IG9ic2VydmFibGUsXHJcbiAgICAgIHZpcnR1YWxSb290OiBvYnNlcnZhYmxlLFxyXG5cclxuICAgICAgZm9jdXNlZE5vZGU6IGNvbXB1dGVkLFxyXG4gICAgICBleHBhbmRlZE5vZGVzOiBjb21wdXRlZCxcclxuICAgICAgYWN0aXZlTm9kZXM6IGNvbXB1dGVkLFxyXG4gICAgICBoaWRkZW5Ob2RlczogY29tcHV0ZWQsXHJcbiAgICAgIHNlbGVjdGVkTGVhZk5vZGVzOiBjb21wdXRlZCxcclxuICAgICAgc2V0RGF0YTogYWN0aW9uLFxyXG4gICAgICB1cGRhdGU6IGFjdGlvbixcclxuICAgICAgc2V0Rm9jdXNlZE5vZGU6IGFjdGlvbixcclxuICAgICAgc2V0Rm9jdXM6IGFjdGlvbixcclxuICAgICAgZG9Gb3JBbGw6IGFjdGlvbixcclxuICAgICAgZm9jdXNOZXh0Tm9kZTogYWN0aW9uLFxyXG4gICAgICBmb2N1c1ByZXZpb3VzTm9kZTogYWN0aW9uLFxyXG4gICAgICBmb2N1c0RyaWxsRG93bjogYWN0aW9uLFxyXG4gICAgICBmb2N1c0RyaWxsVXA6IGFjdGlvbixcclxuICAgICAgc2V0QWN0aXZlTm9kZTogYWN0aW9uLFxyXG4gICAgICBzZXRTZWxlY3RlZE5vZGU6IGFjdGlvbixcclxuICAgICAgc2V0RXhwYW5kZWROb2RlOmFjdGlvbixcclxuICAgICAgZXhwYW5kQWxsOiBhY3Rpb24sXHJcbiAgICAgIGNvbGxhcHNlQWxsOmFjdGlvbixcclxuICAgICAgc2V0SXNIaWRkZW46YWN0aW9uLFxyXG4gICAgICBzZXRIaWRkZW5Ob2RlSWRzOmFjdGlvbixcclxuICAgICAgZmlsdGVyTm9kZXM6IGFjdGlvbixcclxuICAgICAgY2xlYXJGaWx0ZXI6IGFjdGlvbixcclxuICAgICAgbW92ZU5vZGU6IGFjdGlvbixcclxuICAgICAgY29weU5vZGU6IGFjdGlvbixcclxuICAgICAgc2V0U3RhdGU6IGFjdGlvbixcclxuICAgICAgXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8vIGV2ZW50c1xyXG4gIGZpcmVFdmVudChldmVudCkge1xyXG4gICAgZXZlbnQudHJlZU1vZGVsID0gdGhpcztcclxuICAgIHRoaXMuZXZlbnRzW2V2ZW50LmV2ZW50TmFtZV0uZW1pdChldmVudCk7XHJcbiAgICB0aGlzLmV2ZW50cy5ldmVudC5lbWl0KGV2ZW50KTtcclxuICB9XHJcblxyXG4gIHN1YnNjcmliZShldmVudE5hbWUsIGZuKSB7XHJcbiAgICBjb25zdCBzdWJzY3JpcHRpb24gPSB0aGlzLmV2ZW50c1tldmVudE5hbWVdLnN1YnNjcmliZShmbik7XHJcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChzdWJzY3JpcHRpb24pO1xyXG4gIH1cclxuXHJcblxyXG4gIC8vIGdldHRlcnNcclxuICBnZXRGb2N1c2VkTm9kZSgpOiBUcmVlTm9kZSB7XHJcbiAgICByZXR1cm4gdGhpcy5mb2N1c2VkTm9kZTtcclxuICB9XHJcblxyXG5cclxuICBnZXRBY3RpdmVOb2RlKCk6IFRyZWVOb2RlIHtcclxuICAgIHJldHVybiB0aGlzLmFjdGl2ZU5vZGVzWzBdO1xyXG4gIH1cclxuXHJcbiAgZ2V0QWN0aXZlTm9kZXMoKTogVHJlZU5vZGVbXSB7XHJcbiAgICByZXR1cm4gdGhpcy5hY3RpdmVOb2RlcztcclxuICB9XHJcblxyXG4gIGdldFZpc2libGVSb290cygpIHtcclxuICAgIHJldHVybiB0aGlzLnZpcnR1YWxSb290LnZpc2libGVDaGlsZHJlbjtcclxuICB9XHJcblxyXG4gIGdldEZpcnN0Um9vdChza2lwSGlkZGVuID0gZmFsc2UpIHtcclxuICAgIGNvbnN0IHJvb3QgPSBza2lwSGlkZGVuID8gdGhpcy5nZXRWaXNpYmxlUm9vdHMoKSA6IHRoaXMucm9vdHM7XHJcbiAgICByZXR1cm4gcm9vdCAhPSBudWxsICYmIHJvb3QubGVuZ3RoID8gcm9vdFswXSA6IG51bGw7XHJcbiAgfVxyXG5cclxuICBnZXRMYXN0Um9vdChza2lwSGlkZGVuID0gZmFsc2UpIHtcclxuICAgIGNvbnN0IHJvb3QgPSBza2lwSGlkZGVuID8gdGhpcy5nZXRWaXNpYmxlUm9vdHMoKSA6IHRoaXMucm9vdHM7XHJcbiAgICByZXR1cm4gcm9vdCAhPSBudWxsICYmIHJvb3QubGVuZ3RoID8gcm9vdFtyb290Lmxlbmd0aCAtIDFdIDogbnVsbDtcclxuICB9XHJcblxyXG4gIGdldCBpc0ZvY3VzZWQoKSB7XHJcbiAgICByZXR1cm4gVHJlZU1vZGVsLmZvY3VzZWRUcmVlID09PSB0aGlzO1xyXG4gIH1cclxuXHJcbiAgaXNOb2RlRm9jdXNlZChub2RlKSB7XHJcbiAgICByZXR1cm4gdGhpcy5mb2N1c2VkTm9kZSA9PT0gbm9kZTtcclxuICB9XHJcblxyXG4gIGlzRW1wdHlUcmVlKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMucm9vdHMgJiYgdGhpcy5yb290cy5sZW5ndGggPT09IDA7XHJcbiAgfVxyXG5cclxuICBnZXQgZm9jdXNlZE5vZGUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5mb2N1c2VkTm9kZUlkID8gdGhpcy5nZXROb2RlQnlJZCh0aGlzLmZvY3VzZWROb2RlSWQpIDogbnVsbDtcclxuICB9XHJcblxyXG4gIGdldCBleHBhbmRlZE5vZGVzKCkge1xyXG4gICAgY29uc3Qgbm9kZXMgPSBPYmplY3Qua2V5cyh0aGlzLmV4cGFuZGVkTm9kZUlkcylcclxuICAgICAgLmZpbHRlcigoaWQpID0+IHRoaXMuZXhwYW5kZWROb2RlSWRzW2lkXSlcclxuICAgICAgLm1hcCgoaWQpID0+IHRoaXMuZ2V0Tm9kZUJ5SWQoaWQpKTtcclxuXHJcbiAgICByZXR1cm4gbm9kZXMuZmlsdGVyKEJvb2xlYW4pO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGFjdGl2ZU5vZGVzKCkge1xyXG4gICAgY29uc3Qgbm9kZXMgPSBPYmplY3Qua2V5cyh0aGlzLmFjdGl2ZU5vZGVJZHMpXHJcbiAgICAgIC5maWx0ZXIoKGlkKSA9PiB0aGlzLmFjdGl2ZU5vZGVJZHNbaWRdKVxyXG4gICAgICAubWFwKChpZCkgPT4gdGhpcy5nZXROb2RlQnlJZChpZCkpO1xyXG5cclxuICAgIHJldHVybiBub2Rlcy5maWx0ZXIoQm9vbGVhbik7XHJcbiAgfVxyXG5cclxuICBnZXQgaGlkZGVuTm9kZXMoKSB7XHJcbiAgICBjb25zdCBub2RlcyA9IE9iamVjdC5rZXlzKHRoaXMuaGlkZGVuTm9kZUlkcylcclxuICAgICAgICAuZmlsdGVyKChpZCkgPT4gdGhpcy5oaWRkZW5Ob2RlSWRzW2lkXSlcclxuICAgICAgICAubWFwKChpZCkgPT4gdGhpcy5nZXROb2RlQnlJZChpZCkpO1xyXG5cclxuICAgIHJldHVybiBub2Rlcy5maWx0ZXIoQm9vbGVhbik7XHJcbiAgfVxyXG5cclxuICBnZXQgc2VsZWN0ZWRMZWFmTm9kZXMoKSB7XHJcbiAgICBjb25zdCBub2RlcyA9IE9iamVjdC5rZXlzKHRoaXMuc2VsZWN0ZWRMZWFmTm9kZUlkcylcclxuICAgICAgICAuZmlsdGVyKChpZCkgPT4gdGhpcy5zZWxlY3RlZExlYWZOb2RlSWRzW2lkXSlcclxuICAgICAgICAubWFwKChpZCkgPT4gdGhpcy5nZXROb2RlQnlJZChpZCkpO1xyXG5cclxuICAgIHJldHVybiBub2Rlcy5maWx0ZXIoQm9vbGVhbik7XHJcbiAgfVxyXG5cclxuICAvLyBsb2NhdGluZyBub2Rlc1xyXG4gIGdldE5vZGVCeVBhdGgocGF0aDogYW55W10sIHN0YXJ0Tm9kZT0gbnVsbCk6IFRyZWVOb2RlIHtcclxuICAgIGlmICghcGF0aCkgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgc3RhcnROb2RlID0gc3RhcnROb2RlIHx8IHRoaXMudmlydHVhbFJvb3Q7XHJcbiAgICBpZiAocGF0aC5sZW5ndGggPT09IDApIHJldHVybiBzdGFydE5vZGU7XHJcblxyXG4gICAgaWYgKCFzdGFydE5vZGUuY2hpbGRyZW4pIHJldHVybiBudWxsO1xyXG5cclxuICAgIGNvbnN0IGNoaWxkSWQgPSBwYXRoLnNoaWZ0KCk7XHJcbiAgICBjb25zdCBjaGlsZE5vZGUgPSBzdGFydE5vZGUuY2hpbGRyZW4uZmluZChjID0+IGMuaWQgPT09IGNoaWxkSWQpO1xyXG5cclxuICAgIGlmICghY2hpbGROb2RlKSByZXR1cm4gbnVsbDtcclxuXHJcbiAgICByZXR1cm4gdGhpcy5nZXROb2RlQnlQYXRoKHBhdGgsIGNoaWxkTm9kZSk7XHJcbiAgfVxyXG5cclxuICBnZXROb2RlQnlJZChpZCkge1xyXG4gICAgY29uc3QgaWRTdHIgPSBpZC50b1N0cmluZygpO1xyXG5cclxuICAgIHJldHVybiB0aGlzLmdldE5vZGVCeSgobm9kZSkgPT4gbm9kZS5pZC50b1N0cmluZygpID09PSBpZFN0cik7XHJcbiAgfVxyXG5cclxuICBnZXROb2RlQnkocHJlZGljYXRlLCBzdGFydE5vZGUgPSBudWxsKSB7XHJcbiAgICBzdGFydE5vZGUgPSBzdGFydE5vZGUgfHwgdGhpcy52aXJ0dWFsUm9vdDtcclxuXHJcbiAgICBpZiAoIXN0YXJ0Tm9kZS5jaGlsZHJlbikgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgY29uc3QgZm91bmQgPSBzdGFydE5vZGUuY2hpbGRyZW4uZmluZChwcmVkaWNhdGUpO1xyXG5cclxuICAgIGlmIChmb3VuZCkgeyAvLyBmb3VuZCBpbiBjaGlsZHJlblxyXG4gICAgICByZXR1cm4gZm91bmQ7XHJcbiAgICB9IGVsc2UgeyAvLyBsb29rIGluIGNoaWxkcmVuJ3MgY2hpbGRyZW5cclxuICAgICAgZm9yIChsZXQgY2hpbGQgb2Ygc3RhcnROb2RlLmNoaWxkcmVuKSB7XHJcbiAgICAgICAgY29uc3QgZm91bmRJbkNoaWxkcmVuID0gdGhpcy5nZXROb2RlQnkocHJlZGljYXRlLCBjaGlsZCk7XHJcbiAgICAgICAgaWYgKGZvdW5kSW5DaGlsZHJlbikgcmV0dXJuIGZvdW5kSW5DaGlsZHJlbjtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaXNFeHBhbmRlZChub2RlKSB7XHJcbiAgICByZXR1cm4gdGhpcy5leHBhbmRlZE5vZGVJZHNbbm9kZS5pZF07XHJcbiAgfVxyXG5cclxuICBpc0hpZGRlbihub2RlKSB7XHJcbiAgICByZXR1cm4gdGhpcy5oaWRkZW5Ob2RlSWRzW25vZGUuaWRdO1xyXG4gIH1cclxuXHJcbiAgaXNBY3RpdmUobm9kZSkge1xyXG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlTm9kZUlkc1tub2RlLmlkXTtcclxuICB9XHJcblxyXG4gIGlzU2VsZWN0ZWQobm9kZSkge1xyXG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRMZWFmTm9kZUlkc1tub2RlLmlkXTtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCkge1xyXG4gICAgdGhpcy5kaXNwb3NlKCk7XHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlQWxsKCk7XHJcbiAgfVxyXG5cclxuICBkaXNwb3NlKCkge1xyXG4gICAgLy8gRGlzcG9zZSByZWFjdGlvbnMgb2YgdGhlIHJlcGxhY2VkIG5vZGVzXHJcbiAgICBpZiAodGhpcy52aXJ0dWFsUm9vdCkge1xyXG4gICAgICB0aGlzLnZpcnR1YWxSb290LmRpc3Bvc2UoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHVuc3Vic2NyaWJlQWxsKCkge1xyXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmZvckVhY2goc3Vic2NyaXB0aW9uID0+IHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpKTtcclxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucyA9IFtdO1xyXG4gIH1cclxuXHJcbiAgLy8gYWN0aW9uc1xyXG4gIHNldERhdGEoeyBub2Rlcywgb3B0aW9ucyA9IG51bGwsIGV2ZW50cyA9IG51bGwgfToge25vZGVzOiBhbnksIG9wdGlvbnM6IGFueSwgZXZlbnRzOiBhbnl9KSB7XHJcbiAgICBpZiAob3B0aW9ucykge1xyXG4gICAgICB0aGlzLm9wdGlvbnMgPSBuZXcgVHJlZU9wdGlvbnMob3B0aW9ucyk7XHJcbiAgICB9XHJcbiAgICBpZiAoZXZlbnRzKSB7XHJcbiAgICAgIHRoaXMuZXZlbnRzID0gZXZlbnRzO1xyXG4gICAgfVxyXG4gICAgaWYgKG5vZGVzKSB7XHJcbiAgICAgIHRoaXMubm9kZXMgPSBub2RlcztcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnVwZGF0ZSgpO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlKCkge1xyXG4gICAgLy8gUmVidWlsZCB0cmVlOlxyXG4gICAgbGV0IHZpcnR1YWxSb290Q29uZmlnID0ge1xyXG4gICAgICBpZDogdGhpcy5vcHRpb25zLnJvb3RJZCxcclxuICAgICAgdmlydHVhbDogdHJ1ZSxcclxuICAgICAgW3RoaXMub3B0aW9ucy5jaGlsZHJlbkZpZWxkXTogdGhpcy5ub2Rlc1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLmRpc3Bvc2UoKTtcclxuXHJcbiAgICB0aGlzLnZpcnR1YWxSb290ID0gbmV3IFRyZWVOb2RlKHZpcnR1YWxSb290Q29uZmlnLCBudWxsLCB0aGlzLCAwKTtcclxuXHJcbiAgICB0aGlzLnJvb3RzID0gdGhpcy52aXJ0dWFsUm9vdC5jaGlsZHJlbjtcclxuXHJcbiAgICAvLyBGaXJlIGV2ZW50OlxyXG4gICAgaWYgKHRoaXMuZmlyc3RVcGRhdGUpIHtcclxuICAgICAgaWYgKHRoaXMucm9vdHMpIHtcclxuICAgICAgICB0aGlzLmZpcnN0VXBkYXRlID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5fY2FsY3VsYXRlRXhwYW5kZWROb2RlcygpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmZpcmVFdmVudCh7IGV2ZW50TmFtZTogVFJFRV9FVkVOVFMudXBkYXRlRGF0YSB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuICBzZXRGb2N1c2VkTm9kZShub2RlKSB7XHJcbiAgICB0aGlzLmZvY3VzZWROb2RlSWQgPSBub2RlID8gbm9kZS5pZCA6IG51bGw7XHJcbiAgfVxyXG5cclxuICBzZXRGb2N1cyh2YWx1ZSkge1xyXG4gICAgVHJlZU1vZGVsLmZvY3VzZWRUcmVlID0gdmFsdWUgPyB0aGlzIDogbnVsbDtcclxuICB9XHJcblxyXG4gIGRvRm9yQWxsKGZuKSB7XHJcbiAgICB0aGlzLnJvb3RzLmZvckVhY2goKHJvb3QpID0+IHJvb3QuZG9Gb3JBbGwoZm4pKTtcclxuICB9XHJcblxyXG4gIGZvY3VzTmV4dE5vZGUoKSB7XHJcbiAgICBsZXQgcHJldmlvdXNOb2RlID0gdGhpcy5nZXRGb2N1c2VkTm9kZSgpO1xyXG4gICAgbGV0IG5leHROb2RlID0gcHJldmlvdXNOb2RlID8gcHJldmlvdXNOb2RlLmZpbmROZXh0Tm9kZSh0cnVlLCB0cnVlKSA6IHRoaXMuZ2V0Rmlyc3RSb290KHRydWUpO1xyXG4gICAgaWYgKG5leHROb2RlKSBuZXh0Tm9kZS5mb2N1cygpO1xyXG4gIH1cclxuXHJcbiAgZm9jdXNQcmV2aW91c05vZGUoKSB7XHJcbiAgICBsZXQgcHJldmlvdXNOb2RlID0gdGhpcy5nZXRGb2N1c2VkTm9kZSgpO1xyXG4gICAgbGV0IG5leHROb2RlID0gcHJldmlvdXNOb2RlID8gcHJldmlvdXNOb2RlLmZpbmRQcmV2aW91c05vZGUodHJ1ZSkgOiB0aGlzLmdldExhc3RSb290KHRydWUpO1xyXG4gICAgaWYgKG5leHROb2Rl