{"version":3,"sources":["jsdelivr-header.js","/npm/symbol-tree@3.2.4/lib/SymbolTree.js"],"names":[],"mappings":"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","file":"/npm/symbol-tree@3.2.4/lib/SymbolTree.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.37.0.\n * Original file: /npm/symbol-tree@3.2.4/lib/SymbolTree.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","'use strict';\n\n/**\n * @module symbol-tree\n * @author Joris van der Wel <joris@jorisvanderwel.com>\n */\n\nconst SymbolTreeNode = require('./SymbolTreeNode');\nconst TreePosition = require('./TreePosition');\nconst TreeIterator = require('./TreeIterator');\n\nfunction returnTrue() {\n        return true;\n}\n\nfunction reverseArrayIndex(array, reverseIndex) {\n        return array[array.length - 1 - reverseIndex]; // no need to check `index >= 0`\n}\n\nclass SymbolTree {\n\n        /**\n         * @constructor\n         * @alias module:symbol-tree\n         * @param {string} [description='SymbolTree data'] Description used for the Symbol\n         */\n        constructor(description) {\n                this.symbol = Symbol(description || 'SymbolTree data');\n        }\n\n        /**\n         * You can use this function to (optionally) initialize an object right after its creation,\n         * to take advantage of V8's fast properties. Also useful if you would like to\n         * freeze your object.\n         *\n         * `O(1)`\n         *\n         * @method\n         * @alias module:symbol-tree#initialize\n         * @param {Object} object\n         * @return {Object} object\n         */\n        initialize(object) {\n                this._node(object);\n\n                return object;\n        }\n\n        _node(object) {\n                if (!object) {\n                        return null;\n                }\n\n                const node = object[this.symbol];\n\n                if (node) {\n                        return node;\n                }\n\n                return (object[this.symbol] = new SymbolTreeNode());\n        }\n\n        /**\n         * Returns `true` if the object has any children. Otherwise it returns `false`.\n         *\n         * * `O(1)`\n         *\n         * @method hasChildren\n         * @memberOf module:symbol-tree#\n         * @param {Object} object\n         * @return {Boolean}\n         */\n        hasChildren(object) {\n                return this._node(object).hasChildren;\n        }\n\n        /**\n         * Returns the first child of the given object.\n         *\n         * * `O(1)`\n         *\n         * @method firstChild\n         * @memberOf module:symbol-tree#\n         * @param {Object} object\n         * @return {Object}\n         */\n        firstChild(object) {\n                return this._node(object).firstChild;\n        }\n\n        /**\n         * Returns the last child of the given object.\n         *\n         * * `O(1)`\n         *\n         * @method lastChild\n         * @memberOf module:symbol-tree#\n         * @param {Object} object\n         * @return {Object}\n         */\n        lastChild(object) {\n                return this._node(object).lastChild;\n        }\n\n        /**\n         * Returns the previous sibling of the given object.\n         *\n         * * `O(1)`\n         *\n         * @method previousSibling\n         * @memberOf module:symbol-tree#\n         * @param {Object} object\n         * @return {Object}\n         */\n        previousSibling(object) {\n                return this._node(object).previousSibling;\n        }\n\n        /**\n         * Returns the next sibling of the given object.\n         *\n         * * `O(1)`\n         *\n         * @method nextSibling\n         * @memberOf module:symbol-tree#\n         * @param {Object} object\n         * @return {Object}\n         */\n        nextSibling(object) {\n                return this._node(object).nextSibling;\n        }\n\n        /**\n         * Return the parent of the given object.\n         *\n         * * `O(1)`\n         *\n         * @method parent\n         * @memberOf module:symbol-tree#\n         * @param {Object} object\n         * @return {Object}\n         */\n        parent(object) {\n                return this._node(object).parent;\n        }\n\n        /**\n         * Find the inclusive descendant that is last in tree order of the given object.\n         *\n         * * `O(n)` (worst case) where `n` is the depth of the subtree of `object`\n         *\n         * @method lastInclusiveDescendant\n         * @memberOf module:symbol-tree#\n         * @param {Object} object\n         * @return {Object}\n         */\n        lastInclusiveDescendant(object) {\n                let lastChild;\n                let current = object;\n\n                while ((lastChild = this._node(current).lastChild)) {\n                        current = lastChild;\n                }\n\n                return current;\n        }\n\n        /**\n         * Find the preceding object (A) of the given object (B).\n         * An object A is preceding an object B if A and B are in the same tree\n         * and A comes before B in tree order.\n         *\n         * * `O(n)` (worst case)\n         * * `O(1)` (amortized when walking the entire tree)\n         *\n         * @method preceding\n         * @memberOf module:symbol-tree#\n         * @param {Object} object\n         * @param {Object} [options]\n         * @param {Object} [options.root] If set, `root` must be an inclusive ancestor\n         *        of the return value (or else null is returned). This check _assumes_\n         *        that `root` is also an inclusive ancestor of the given `object`\n         * @return {?Object}\n         */\n        preceding(object, options) {\n                const treeRoot = options && options.root;\n\n                if (object === treeRoot) {\n                        return null;\n                }\n\n                const previousSibling = this._node(object).previousSibling;\n\n                if (previousSibling) {\n                        return this.lastInclusiveDescendant(previousSibling);\n                }\n\n                // if there is no previous sibling return the parent (might be null)\n                return this._node(object).parent;\n        }\n\n        /**\n         * Find the following object (A) of the given object (B).\n         * An object A is following an object B if A and B are in the same tree\n         * and A comes after B in tree order.\n         *\n         * * `O(n)` (worst case) where `n` is the amount of objects in the entire tree\n         * * `O(1)` (amortized when walking the entire tree)\n         *\n         * @method following\n         * @memberOf module:symbol-tree#\n         * @param {!Object} object\n         * @param {Object} [options]\n         * @param {Object} [options.root] If set, `root` must be an inclusive ancestor\n         *        of the return value (or else null is returned). This check _assumes_\n         *        that `root` is also an inclusive ancestor of the given `object`\n         * @param {Boolean} [options.skipChildren=false] If set, ignore the children of `object`\n         * @return {?Object}\n         */\n        following(object, options) {\n                const treeRoot = options && options.root;\n                const skipChildren = options && options.skipChildren;\n\n                const firstChild = !skipChildren && this._node(object).firstChild;\n\n                if (firstChild) {\n                        return firstChild;\n                }\n\n                let current = object;\n\n                do {\n                        if (current === treeRoot) {\n                                return null;\n                        }\n\n                        const nextSibling = this._node(current).nextSibling;\n\n                        if (nextSibling) {\n                                return nextSibling;\n                        }\n\n                        current = this._node(current).parent;\n                } while (current);\n\n                return null;\n        }\n\n        /**\n         * Append all children of the given object to an array.\n         *\n         * * `O(n)` where `n` is the amount of children of the given `parent`\n         *\n         * @method childrenToArray\n         * @memberOf module:symbol-tree#\n         * @param {Object} parent\n         * @param {Object} [options]\n         * @param {Object[]} [options.array=[]]\n         * @param {Function} [options.filter] Function to test each object before it is added to the array.\n         *                            Invoked with arguments (object). Should return `true` if an object\n         *                            is to be included.\n         * @param {*} [options.thisArg] Value to use as `this` when executing `filter`.\n         * @return {Object[]}\n         */\n        childrenToArray(parent, options) {\n                const array   = (options && options.array) || [];\n                const filter  = (options && options.filter) || returnTrue;\n                const thisArg = (options && options.thisArg) || undefined;\n\n                const parentNode = this._node(parent);\n                let object = parentNode.firstChild;\n                let index = 0;\n\n                while (object) {\n                        const node = this._node(object);\n                        node.setCachedIndex(parentNode, index);\n\n                        if (filter.call(thisArg, object)) {\n                                array.push(object);\n                        }\n\n                        object = node.nextSibling;\n                        ++index;\n                }\n\n                return array;\n        }\n\n        /**\n         * Append all inclusive ancestors of the given object to an array.\n         *\n         * * `O(n)` where `n` is the amount of ancestors of the given `object`\n         *\n         * @method ancestorsToArray\n         * @memberOf module:symbol-tree#\n         * @param {Object} object\n         * @param {Object} [options]\n         * @param {Object[]} [options.array=[]]\n         * @param {Function} [options.filter] Function to test each object before it is added to the array.\n         *                            Invoked with arguments (object). Should return `true` if an object\n         *                            is to be included.\n         * @param {*} [options.thisArg] Value to use as `this` when executing `filter`.\n         * @return {Object[]}\n         */\n        ancestorsToArray(object, options) {\n                const array   = (options && options.array) || [];\n                const filter  = (options && options.filter) || returnTrue;\n                const thisArg = (options && options.thisArg) || undefined;\n\n                let ancestor = object;\n\n                while (ancestor) {\n                        if (filter.call(thisArg, ancestor)) {\n                                array.push(ancestor);\n                        }\n                        ancestor = this._node(ancestor).parent;\n                }\n\n                return array;\n        }\n\n        /**\n         * Append all descendants of the given object to an array (in tree order).\n         *\n         * * `O(n)` where `n` is the amount of objects in the sub-tree of the given `object`\n         *\n         * @method treeToArray\n         * @memberOf module:symbol-tree#\n         * @param {Object} root\n         * @param {Object} [options]\n         * @param {Object[]} [options.array=[]]\n         * @param {Function} [options.filter] Function to test each object before it is added to the array.\n         *                            Invoked with arguments (object). Should return `true` if an object\n         *                            is to be included.\n         * @param {*} [options.thisArg] Value to use as `this` when executing `filter`.\n         * @return {Object[]}\n         */\n        treeToArray(root, options) {\n                const array   = (options && options.array) || [];\n                const filter  = (options && options.filter) || returnTrue;\n                const thisArg = (options && options.thisArg) || undefined;\n\n                let object = root;\n\n                while (object) {\n                        if (filter.call(thisArg, object)) {\n                                array.push(object);\n                        }\n                        object = this.following(object, {root: root});\n                }\n\n                return array;\n        }\n\n        /**\n         * Iterate over all children of the given object\n         *\n         * * `O(1)` for a single iteration\n         *\n         * @method childrenIterator\n         * @memberOf module:symbol-tree#\n         * @param {Object} parent\n         * @param {Object} [options]\n         * @param {Boolean} [options.reverse=false]\n         * @return {Object} An iterable iterator (ES6)\n         */\n        childrenIterator(parent, options) {\n                const reverse = options && options.reverse;\n                const parentNode = this._node(parent);\n\n                return new TreeIterator(\n                        this,\n                        parent,\n                        reverse ? parentNode.lastChild : parentNode.firstChild,\n                        reverse ? TreeIterator.PREV : TreeIterator.NEXT\n                );\n        }\n\n        /**\n         * Iterate over all the previous siblings of the given object. (in reverse tree order)\n         *\n         * * `O(1)` for a single iteration\n         *\n         * @method previousSiblingsIterator\n         * @memberOf module:symbol-tree#\n         * @param {Object} object\n         * @return {Object} An iterable iterator (ES6)\n         */\n        previousSiblingsIterator(object) {\n                return new TreeIterator(\n                        this,\n                        object,\n                        this._node(object).previousSibling,\n                        TreeIterator.PREV\n                );\n        }\n\n        /**\n         * Iterate over all the next siblings of the given object. (in tree order)\n         *\n         * * `O(1)` for a single iteration\n         *\n         * @method nextSiblingsIterator\n         * @memberOf module:symbol-tree#\n         * @param {Object} object\n         * @return {Object} An iterable iterator (ES6)\n         */\n        nextSiblingsIterator(object) {\n                return new TreeIterator(\n                        this,\n                        object,\n                        this._node(object).nextSibling,\n                        TreeIterator.NEXT\n                );\n        }\n\n        /**\n         * Iterate over all inclusive ancestors of the given object\n         *\n         * * `O(1)` for a single iteration\n         *\n         * @method ancestorsIterator\n         * @memberOf module:symbol-tree#\n         * @param {Object} object\n         * @return {Object} An iterable iterator (ES6)\n         */\n        ancestorsIterator(object) {\n                return new TreeIterator(\n                        this,\n                        object,\n                        object,\n                        TreeIterator.PARENT\n                );\n        }\n\n        /**\n         * Iterate over all descendants of the given object (in tree order).\n         *\n         * Where `n` is the amount of objects in the sub-tree of the given `root`:\n         *\n         * * `O(n)` (worst case for a single iteration)\n         * * `O(n)` (amortized, when completing the iterator)\n         *\n         * @method treeIterator\n         * @memberOf module:symbol-tree#\n         * @param {Object} root\n         * @param {Object} options\n         * @param {Boolean} [options.reverse=false]\n         * @return {Object} An iterable iterator (ES6)\n         */\n        treeIterator(root, options) {\n                const reverse = options && options.reverse;\n\n                return new TreeIterator(\n                        this,\n                        root,\n                        reverse ? this.lastInclusiveDescendant(root) : root,\n                        reverse ? TreeIterator.PRECEDING : TreeIterator.FOLLOWING\n                );\n        }\n\n        /**\n         * Find the index of the given object (the number of preceding siblings).\n         *\n         * * `O(n)` where `n` is the amount of preceding siblings\n         * * `O(1)` (amortized, if the tree is not modified)\n         *\n         * @method index\n         * @memberOf module:symbol-tree#\n         * @param {Object} child\n         * @return {Number} The number of preceding siblings, or -1 if the object has no parent\n         */\n        index(child) {\n                const childNode = this._node(child);\n                const parentNode = this._node(childNode.parent);\n\n                if (!parentNode) {\n                        // In principal, you could also find out the number of preceding siblings\n                        // for objects that do not have a parent. This method limits itself only to\n                        // objects that have a parent because that lets us optimize more.\n                        return -1;\n                }\n\n                let currentIndex = childNode.getCachedIndex(parentNode);\n\n                if (currentIndex >= 0) {\n                        return currentIndex;\n                }\n\n                currentIndex = 0;\n                let object = parentNode.firstChild;\n\n                if (parentNode.childIndexCachedUpTo) {\n                        const cachedUpToNode = this._node(parentNode.childIndexCachedUpTo);\n                        object = cachedUpToNode.nextSibling;\n                        currentIndex = cachedUpToNode.getCachedIndex(parentNode) + 1;\n                }\n\n                while (object) {\n                        const node = this._node(object);\n                        node.setCachedIndex(parentNode, currentIndex);\n\n                        if (object === child) {\n                                break;\n                        }\n\n                        ++currentIndex;\n                        object = node.nextSibling;\n                }\n\n                parentNode.childIndexCachedUpTo = child;\n\n                return currentIndex;\n        }\n\n        /**\n         * Calculate the number of children.\n         *\n         * * `O(n)` where `n` is the amount of children\n         * * `O(1)` (amortized, if the tree is not modified)\n         *\n         * @method childrenCount\n         * @memberOf module:symbol-tree#\n         * @param {Object} parent\n         * @return {Number}\n         */\n        childrenCount(parent) {\n                const parentNode = this._node(parent);\n\n                if (!parentNode.lastChild) {\n                        return 0;\n                }\n\n                return this.index(parentNode.lastChild) + 1;\n        }\n\n        /**\n         * Compare the position of an object relative to another object. A bit set is returned:\n         *\n         * <ul>\n         *     <li>DISCONNECTED : 1</li>\n         *     <li>PRECEDING : 2</li>\n         *     <li>FOLLOWING : 4</li>\n         *     <li>CONTAINS : 8</li>\n         *     <li>CONTAINED_BY : 16</li>\n         * </ul>\n         *\n         * The semantics are the same as compareDocumentPosition in DOM, with the exception that\n         * DISCONNECTED never occurs with any other bit.\n         *\n         * where `n` and `m` are the amount of ancestors of `left` and `right`;\n         * where `o` is the amount of children of the lowest common ancestor of `left` and `right`:\n         *\n         * * `O(n + m + o)` (worst case)\n         * * `O(n + m)` (amortized, if the tree is not modified)\n         *\n         * @method compareTreePosition\n         * @memberOf module:symbol-tree#\n         * @param {Object} left\n         * @param {Object} right\n         * @return {Number}\n         */\n        compareTreePosition(left, right) {\n                // In DOM terms:\n                // left = reference / context object\n                // right = other\n\n                if (left === right) {\n                        return 0;\n                }\n\n                /* jshint -W016 */\n\n                const leftAncestors = []; { // inclusive\n                        let leftAncestor = left;\n\n                        while (leftAncestor) {\n                                if (leftAncestor === right) {\n                                        return TreePosition.CONTAINS | TreePosition.PRECEDING;\n                                        // other is ancestor of reference\n                                }\n\n                                leftAncestors.push(leftAncestor);\n                                leftAncestor = this.parent(leftAncestor);\n                        }\n                }\n\n\n                const rightAncestors = []; {\n                        let rightAncestor = right;\n\n                        while (rightAncestor) {\n                                if (rightAncestor === left) {\n                                        return TreePosition.CONTAINED_BY | TreePosition.FOLLOWING;\n                                }\n\n                                rightAncestors.push(rightAncestor);\n                                rightAncestor = this.parent(rightAncestor);\n                        }\n                }\n\n\n                const root = reverseArrayIndex(leftAncestors, 0);\n\n                if (!root || root !== reverseArrayIndex(rightAncestors, 0)) {\n                        // note: unlike DOM, preceding / following is not set here\n                        return TreePosition.DISCONNECTED;\n                }\n\n                // find the lowest common ancestor\n                let commonAncestorIndex = 0;\n                const ancestorsMinLength = Math.min(leftAncestors.length, rightAncestors.length);\n\n                for (let i = 0; i < ancestorsMinLength; ++i) {\n                        const leftAncestor  = reverseArrayIndex(leftAncestors, i);\n                        const rightAncestor = reverseArrayIndex(rightAncestors, i);\n\n                        if (leftAncestor !== rightAncestor) {\n                                break;\n                        }\n\n                        commonAncestorIndex = i;\n                }\n\n                // indexes within the common ancestor\n                const leftIndex  = this.index(reverseArrayIndex(leftAncestors, commonAncestorIndex + 1));\n                const rightIndex = this.index(reverseArrayIndex(rightAncestors, commonAncestorIndex + 1));\n\n                return rightIndex < leftIndex\n                        ? TreePosition.PRECEDING\n                        : TreePosition.FOLLOWING;\n        }\n\n        /**\n         * Remove the object from this tree.\n         * Has no effect if already removed.\n         *\n         * * `O(1)`\n         *\n         * @method remove\n         * @memberOf module:symbol-tree#\n         * @param {Object} removeObject\n         * @return {Object} removeObject\n         */\n        remove(removeObject) {\n                const removeNode = this._node(removeObject);\n                const parentNode = this._node(removeNode.parent);\n                const prevNode = this._node(removeNode.previousSibling);\n                const nextNode = this._node(removeNode.nextSibling);\n\n                if (parentNode) {\n                        if (parentNode.firstChild === removeObject) {\n                                parentNode.firstChild = removeNode.nextSibling;\n                        }\n\n                        if (parentNode.lastChild === removeObject) {\n                                parentNode.lastChild = removeNode.previousSibling;\n                        }\n                }\n\n                if (prevNode) {\n                        prevNode.nextSibling = removeNode.nextSibling;\n                }\n\n                if (nextNode) {\n                        nextNode.previousSibling = removeNode.previousSibling;\n                }\n\n                removeNode.parent = null;\n                removeNode.previousSibling = null;\n                removeNode.nextSibling = null;\n                removeNode.cachedIndex = -1;\n                removeNode.cachedIndexVersion = NaN;\n\n                if (parentNode) {\n                        parentNode.childrenChanged();\n                }\n\n                return removeObject;\n        }\n\n        /**\n         * Insert the given object before the reference object.\n         * `newObject` is now the previous sibling of `referenceObject`.\n         *\n         * * `O(1)`\n         *\n         * @method insertBefore\n         * @memberOf module:symbol-tree#\n         * @param {Object} referenceObject\n         * @param {Object} newObject\n         * @throws {Error} If the newObject is already present in this SymbolTree\n         * @return {Object} newObject\n         */\n        insertBefore(referenceObject, newObject) {\n                const referenceNode = this._node(referenceObject);\n                const prevNode = this._node(referenceNode.previousSibling);\n                const newNode = this._node(newObject);\n                const parentNode = this._node(referenceNode.parent);\n\n                if (newNode.isAttached) {\n                        throw Error('Given object is already present in this SymbolTree, remove it first');\n                }\n\n                newNode.parent = referenceNode.parent;\n                newNode.previousSibling = referenceNode.previousSibling;\n                newNode.nextSibling = referenceObject;\n                referenceNode.previousSibling = newObject;\n\n                if (prevNode) {\n                        prevNode.nextSibling = newObject;\n                }\n\n                if (parentNode && parentNode.firstChild === referenceObject) {\n                        parentNode.firstChild = newObject;\n                }\n\n                if (parentNode) {\n                        parentNode.childrenChanged();\n                }\n\n                return newObject;\n        }\n\n        /**\n         * Insert the given object after the reference object.\n         * `newObject` is now the next sibling of `referenceObject`.\n         *\n         * * `O(1)`\n         *\n         * @method insertAfter\n         * @memberOf module:symbol-tree#\n         * @param {Object} referenceObject\n         * @param {Object} newObject\n         * @throws {Error} If the newObject is already present in this SymbolTree\n         * @return {Object} newObject\n         */\n        insertAfter(referenceObject, newObject) {\n                const referenceNode = this._node(referenceObject);\n                const nextNode = this._node(referenceNode.nextSibling);\n                const newNode = this._node(newObject);\n                const parentNode = this._node(referenceNode.parent);\n\n                if (newNode.isAttached) {\n                        throw Error('Given object is already present in this SymbolTree, remove it first');\n                }\n\n                newNode.parent = referenceNode.parent;\n                newNode.previousSibling = referenceObject;\n                newNode.nextSibling = referenceNode.nextSibling;\n                referenceNode.nextSibling = newObject;\n\n                if (nextNode) {\n                        nextNode.previousSibling = newObject;\n                }\n\n                if (parentNode && parentNode.lastChild === referenceObject) {\n                        parentNode.lastChild = newObject;\n                }\n\n                if (parentNode) {\n                        parentNode.childrenChanged();\n                }\n\n                return newObject;\n        }\n\n        /**\n         * Insert the given object as the first child of the given reference object.\n         * `newObject` is now the first child of `referenceObject`.\n         *\n         * * `O(1)`\n         *\n         * @method prependChild\n         * @memberOf module:symbol-tree#\n         * @param {Object} referenceObject\n         * @param {Object} newObject\n         * @throws {Error} If the newObject is already present in this SymbolTree\n         * @return {Object} newObject\n         */\n        prependChild(referenceObject, newObject) {\n                const referenceNode = this._node(referenceObject);\n                const newNode = this._node(newObject);\n\n                if (newNode.isAttached) {\n                        throw Error('Given object is already present in this SymbolTree, remove it first');\n                }\n\n                if (referenceNode.hasChildren) {\n                        this.insertBefore(referenceNode.firstChild, newObject);\n                }\n                else {\n                        newNode.parent = referenceObject;\n                        referenceNode.firstChild = newObject;\n                        referenceNode.lastChild = newObject;\n                        referenceNode.childrenChanged();\n                }\n\n                return newObject;\n        }\n\n        /**\n         * Insert the given object as the last child of the given reference object.\n         * `newObject` is now the last child of `referenceObject`.\n         *\n         * * `O(1)`\n         *\n         * @method appendChild\n         * @memberOf module:symbol-tree#\n         * @param {Object} referenceObject\n         * @param {Object} newObject\n         * @throws {Error} If the newObject is already present in this SymbolTree\n         * @return {Object} newObject\n         */\n        appendChild(referenceObject, newObject) {\n                const referenceNode = this._node(referenceObject);\n                const newNode = this._node(newObject);\n\n                if (newNode.isAttached) {\n                        throw Error('Given object is already present in this SymbolTree, remove it first');\n                }\n\n                if (referenceNode.hasChildren) {\n                        this.insertAfter(referenceNode.lastChild, newObject);\n                }\n                else {\n                        newNode.parent = referenceObject;\n                        referenceNode.firstChild = newObject;\n                        referenceNode.lastChild = newObject;\n                        referenceNode.childrenChanged();\n                }\n\n                return newObject;\n        }\n}\n\nmodule.exports = SymbolTree;\nSymbolTree.TreePosition = TreePosition;\n"]}