/*
  Default comparison function to be used
   */

/*
  Fast version of a heappush followed by a heappop.
   */

/*
  Find the n largest elements in a dataset.
   */

/*
  Find the n smallest elements in a dataset.
   */

/*
  Insert item x in list a, and keep it sorted assuming a is sorted.
  
  If x is already in a, insert it to the right of the rightmost x.
  
  Optional args lo (default 0) and hi (default a.length) bound the slice
  of a to be searched.
   */

/*
  Pop and return the current smallest value, and add the new item.
  
  This is more efficient than heappop() followed by heappush(), and can be
  more appropriate when using a fixed size heap. Note that the value
  returned may be larger than item! That constrains reasonable use of
  this routine unless written as part of a conditional replacement:
      if item > array[0]
        item = heapreplace(array, item)
   */

/*
  Pop the smallest item off the heap, maintaining the heap invariant.
   */

/*
  Push item onto heap, maintaining the heap invariant.
   */

/*
  Transform list into a heap, in-place, in O(array.length) time.
   */

/*
  Update the position of the given item in the heap.
  This function should be called every time the item is being modified.
   */

/*
 * A function that takes a layering (an array of layers, each with an array of
 * ordererd nodes) and a graph and returns a weighted crossing count.
 *
 * Pre-conditions:
 *
 *    1. Input graph must be simple (not a multigraph), directed, and include
 *       only simple edges.
 *    2. Edges in the input graph must have assigned weights.
 *
 * Post-conditions:
 *
 *    1. The graph and layering matrix are left unchanged.
 *
 * This algorithm is derived from Barth, et al., "Bilayer Cross Counting."
 */

/*
 * A greedy heuristic for finding a feedback arc set for a graph. A feedback
 * arc set is a set of edges that can be removed to make a graph acyclic.
 * The algorithm comes from: P. Eades, X. Lin, and W. F. Smyth, "A fast and
 * effective heuristic for the feedback arc set problem." This implementation
 * adjusts that from the paper to allow for weighted edges.
 */

/*
 * A helper that preforms a pre- or post-order traversal on the input graph
 * and returns the nodes in the order they were visited. If the graph is
 * undirected then this algorithm will navigate using neighbors. If the graph
 * is directed then this algorithm will navigate using successors.
 *
 * Order must be one of "pre" or "post".
 */

/*
 * A nesting graph creates dummy nodes for the tops and bottoms of subgraphs,
 * adds appropriate edges to ensure that all cluster nodes are placed between
 * these boundries, and ensures that the graph is connected.
 *
 * In addition we ensure, through the use of the minlen property, that nodes
 * and subgraph border nodes to not end up on the same rank.
 *
 * Preconditions:
 *
 *    1. Input graph is a DAG
 *    2. Nodes in the input graph has a minlen attribute
 *
 * Postconditions:
 *
 *    1. Input graph is connected.
 *    2. Dummy nodes are added for the tops and bottoms of subgraphs.
 *    3. The minlen attribute for nodes is adjusted to ensure nodes do not
 *       get placed on the same rank as subgraph border nodes.
 *
 * The nesting graph idea comes from Sander, "Layout of Compound Directed
 * Graphs."
 */

/*
 * Adds a dummy node to the graph and return v.
 */

/*
 * Adjusts the ranks for all nodes in the graph such that all nodes v have
 * rank(v) >= 0 and at least one node w has rank(w) = 0.
 */

/*
 * Align the coordinates of each of the layout alignments such that
 * left-biased alignments have their minimum coordinate at the same point as
 * the minimum coordinate of the smallest width alignment and right-biased
 * alignments have their maximum coordinate at the same point as the maximum
 * coordinate of the smallest width alignment.
 */

/*
 * Applies heuristics to minimize edge crossings in the graph and sets the best
 * order solution as an order attribute on each node.
 *
 * Pre-conditions:
 *
 *    1. Graph must be DAG
 *    2. Graph nodes must be objects with a "rank" attribute
 *    3. Graph edges must have the "weight" attribute
 *
 * Post-conditions:
 *
 *    1. Graph nodes will have an "order" attribute based on the results of the
 *       algorithm.
 */

/*
 * Assigns a rank to each node in the input graph that respects the "minlen"
 * constraint specified on edges between nodes.
 *
 * This basic structure is derived from Gansner, et al., "A Technique for
 * Drawing Directed Graphs."
 *
 * Pre-conditions:
 *
 *    1. Graph must be a connected DAG
 *    2. Graph nodes must be objects
 *    3. Graph edges must have "weight" and "minlen" attributes
 *
 * Post-conditions:
 *
 *    1. Graph nodes will have a "rank" attribute based on the results of the
 *       algorithm. Ranks can start at any index (including negative), we'll
 *       fix them up later.
 */

/*
 * Assigns an initial order value for each node by performing a DFS search
 * starting from nodes in the first rank. Nodes are assigned an order in their
 * rank as they are first visited.
 *
 * This approach comes from Gansner, et al., "A Technique for Drawing Directed
 * Graphs."
 *
 * Returns a layering matrix with an array per layer and each layer sorted by
 * the order of its nodes.
 */

/*
 * Breaks any long edges in the graph into short segments that span 1 layer
 * each. This operation is undoable with the denormalize function.
 *
 * Pre-conditions:
 *
 *    1. The input graph is a DAG.
 *    2. Each node in the graph has a "rank" property.
 *
 * Post-condition:
 *
 *    1. All edges in the graph have a length of 1.
 *    2. Dummy nodes are added where edges have been split into segments.
 *    3. The graph is augmented with a "dummyChains" attribute which contains
 *       the first dummy in each chain of dummy nodes produced.
 */

/*
 * Constructs a graph that can be used to sort a layer of nodes. The graph will
 * contain all base and subgraph nodes from the request layer in their original
 * hierarchy and any edges that are incident on these nodes and are of the type
 * requested by the "relationship" parameter.
 *
 * Nodes from the requested rank that do not have parents are assigned a root
 * node in the output graph, which is set in the root graph attribute. This
 * makes it easy to walk the hierarchy of movable nodes during ordering.
 *
 * Pre-conditions:
 *
 *    1. Input graph is a DAG
 *    2. Base nodes in the input graph have a rank attribute
 *    3. Subgraph nodes in the input graph has minRank and maxRank attributes
 *    4. Edges have an assigned weight
 *
 * Post-conditions:
 *
 *    1. Output graph has all nodes in the movable rank with preserved
 *       hierarchy.
 *    2. Root nodes in the movable layer are made children of the node
 *       indicated by the root attribute of the graph.
 *    3. Non-movable nodes incident on movable nodes, selected by the
 *       relationship parameter, are included in the graph (without hierarchy).
 *    4. Edges incident on movable nodes, selected by the relationship
 *       parameter, are added to the output graph.
 *    5. The weights for copied edges are aggregated as need, since the output
 *       graph is not a multi-graph.
 */

/*
 * Constructs a new graph from the input graph, which can be used for layout.
 * This process copies only whitelisted attributes from the input graph to the
 * layout graph. Thus this function serves as a good place to determine what
 * attributes can influence layout.
 */

/*
 * Constructs a spanning tree with tight edges and adjusted the input node's
 * ranks to achieve this. A tight edge is one that is has a length that matches
 * its "minlen" attribute.
 *
 * The basic structure for this function is derived from Gansner, et al., "A
 * Technique for Drawing Directed Graphs."
 *
 * Pre-conditions:
 *
 *    1. Graph must be a DAG.
 *    2. Graph must be connected.
 *    3. Graph must have at least one node.
 *    5. Graph nodes must have been previously assigned a "rank" property that
 *       respects the "minlen" property of incident edges.
 *    6. Graph edges must have a "minlen" property.
 *
 * Post-conditions:
 *
 *    - Graph nodes will have their rank adjusted to ensure that all edges are
 *      tight.
 *
 * Returns a tree (undirected graph) that is constructed using only "tight"
 * edges.
 */

/*
 * Copies final layout information from the layout graph back to the input
 * graph. This process only copies whitelisted attributes from the layout graph
 * to the input graph, so it serves as a good place to determine what
 * attributes can influence layout.
 */

/*
 * Creates temporary dummy nodes that capture the rank in which each edge's
 * label is going to, if it has one of non-zero width and height. We do this
 * so that we can safely remove empty ranks while preserving balance for the
 * label's position.
 */

/*
 * Finds a maximal tree of tight edges and returns the number of nodes in the
 * tree.
 */

/*
 * Finds the edge with the smallest slack that is incident on tree and returns
 * it.
 */

/*
 * Finds where a line starting at point ({x, y}) would intersect a rectangle
 * ({x, y, width, height}) if it were pointing at the rectangle's center.
 */

/*
 * Given a DAG with each node assigned "rank" and "order" properties, this
 * function will produce a matrix with the ids of each node.
 */

/*
 * Given a list of entries of the form {v, barycenter, weight} and a
 * constraint graph this function will resolve any conflicts between the
 * constraint graph and the barycenters for the entries. If the barycenters for
 * an entry would violate a constraint in the constraint graph then we coalesce
 * the nodes in the conflict into a new node that respects the contraint and
 * aggregates barycenter and weight information.
 *
 * This implementation is based on the description in Forster, "A Fast and
 * Simple Hueristic for Constrained Two-Level Crossing Reduction," thought it
 * differs in some specific details.
 *
 * Pre-conditions:
 *
 *    1. Each entry has the form {v, barycenter, weight}, or if the node has
 *       no barycenter, then {v}.
 *
 * Returns:
 *
 *    A new list of entries of the form {vs, i, barycenter, weight}. The list
 *    `vs` may either be a singleton or it may be an aggregation of nodes
 *    ordered such that they do not violate constraints from the constraint
 *    graph. The property `i` is the lowest original index of any of the
 *    elements in `vs`.
 */

/*
 * Given the tight tree, its graph, and a child in the graph calculate and
 * return the cut value for the edge between the child and its parent.
 */

/*
 * Initializes cut values for all edges in the tree.
 */

/*
 * Initializes ranks for the input graph using the longest path algorithm. This
 * algorithm scales well and is fast in practice, it yields rather poor
 * solutions. Nodes are pushed to the lowest layer possible, leaving the bottom
 * ranks wide and leaving edges longer than necessary. However, due to its
 * speed, this algorithm is good for getting an initial ranking that can be fed
 * into other algorithms.
 *
 * This algorithm does not normalize layers because it will be used by other
 * algorithms in most cases. If using this algorithm directly, be sure to
 * run normalize at the end.
 *
 * Pre-conditions:
 *
 *    1. Input graph is a DAG.
 *    2. Input graph node labels can be assigned properties.
 *
 * Post-conditions:
 *
 *    1. Each node will be assign an (unnormalized) "rank" property.
 */

/*
 * Marks all edges in the graph with a type-1 conflict with the "type1Conflict"
 * property. A type-1 conflict is one where a non-inner segment crosses an
 * inner segment. An inner segment is an edge with both incident nodes marked
 * with the "dummy" property.
 *
 * This algorithm scans layer by layer, starting with the second, for type-1
 * conflicts between the current layer and the previous layer. For each layer
 * it scans the nodes from left to right until it reaches one that is incident
 * on an inner segment. It then scans predecessors to determine if they have
 * edges that cross that inner segment. At the end a final scan is done for all
 * nodes on the current rank to see if they cross the last visited inner
 * segment.
 *
 * This algorithm (safely) assumes that a dummy node will only be incident on a
 * single node in the layers being scanned.
 */

/*
 * Partition a collection into two groups: `lhs` and `rhs`. If the supplied
 * function returns true for an entry it goes into `lhs`. Otherwise it goes
 * into `rhs.
 */

/*
 * Returns a new function that wraps `fn` with a timer. The wrapper logs the
 * time it takes to execute the function.
 */

/*
 * Returns a new graph with only simple edges. Handles aggregation of data
 * associated with multi-edges.
 */

/*
 * Returns the alignment that has the smallest width of the given alignments.
 */

/*
 * Returns the amount of slack for the given edge. The slack is defined as the
 * difference between the length of the edge and its minimum length.
 */

/*
 * Returns true if the edge is in the tree.
 */

/*
 * Returns true if the specified node is descendant of the root node per the
 * assigned low and lim attributes in the tree.
 */

/*
 * Simple doubly linked list implementation derived from Cormen, et al.,
 * "Introduction to Algorithms".
 */

/*
 * The network simplex algorithm assigns ranks to each node in the input graph
 * and iteratively improves the ranking to reduce the length of edges.
 *
 * Preconditions:
 *
 *    1. The input graph must be a DAG.
 *    2. All nodes in the graph must have an object value.
 *    3. All edges in the graph must have "minlen" and "weight" attributes.
 *
 * Postconditions:
 *
 *    1. All nodes in the graph will have an assigned "rank" attribute that has
 *       been optimized by the network simplex algorithm. Ranks start at 0.
 *
 *
 * A rough sketch of the algorithm is as follows:
 *
 *    1. Assign initial ranks to each node. We use the longest path algorithm,
 *       which assigns ranks to the lowest position possible. In general this
 *       leads to very wide bottom ranks and unnecessarily long edges.
 *    2. Construct a feasible tight tree. A tight tree is one such that all
 *       edges in the tree have no slack (difference between length of edge
 *       and minlen for the edge). This by itself greatly improves the assigned
 *       rankings by shorting edges.
 *    3. Iteratively find edges that have negative cut values. Generally a
 *       negative cut value indicates that the edge could be removed and a new
 *       tree edge could be added to produce a more compact graph.
 *
 * Much of the algorithms here are derived from Gansner, et al., "A Technique
 * for Drawing Directed Graphs." The structure of the file roughly follows the
 * structure of the overall algorithm.
 */

/*
 * This idea comes from the Gansner paper: to account for edge labels in our
 * layout we split each rank in half by doubling minlen and halving ranksep.
 * Then we can place labels at these mid-points between nodes.
 *
 * We also add some minimal padding to the width to push the label for the edge
 * away from the edge itself a bit.
 */

/*
 * This module provides coordinate assignment based on Brandes and Köpf, "Fast
 * and Simple Horizontal Coordinate Assignment."
 */

/*
 * Try to align nodes into vertical "blocks" where possible. This algorithm
 * attempts to align a node with one of its median neighbors. If the edge
 * connecting a neighbor is a type-1 conflict then we ignore that possibility.
 * If a previous node has already formed a block with a node after the node
 * we're trying to form a block with, we also ignore that possibility - our
 * blocks would be split in that scenario.
 */

/*
 * setEdge(v, w, [value, [name]])
 * setEdge({ v, w, [name] }, [value])
 */

/*
Copyright (c) 2012-2014 Chris Pettitt

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

/*  "The then Method" [Promises/A+ 1.1, 1.2, 2.2]  */

/*  [Promises/A+ 1.3, 2.1.2.2]  */

/*  [Promises/A+ 1.5, 2.1.3.2]  */

/*  [Promises/A+ 2.1.1]  */

/*  [Promises/A+ 2.1.2.1, 2.1.3.1]  */

/*  [Promises/A+ 2.1.2.2, 2.1.3.2]  */

/*  [Promises/A+ 2.2.1, 2.2.7.3, 2.2.7.4]  */

/*  [Promises/A+ 2.2.2.1, 2.2.3.1, 2.2.5, 3.2]  */

/*  [Promises/A+ 2.2.2.3, 2.2.3.3]  */

/*  [Promises/A+ 2.2.2/2.2.6]  */

/*  [Promises/A+ 2.2.3/2.2.6]  */

/*  [Promises/A+ 2.2.4, 3.1]  */

/*  [Promises/A+ 2.2.5]  */

/*  [Promises/A+ 2.2.7, 3.3]  */

/*  [Promises/A+ 2.2.7.2]  */

/*  [Promises/A+ 2.2.7.3, 2.2.7.4]  */

/*  [Promises/A+ 2.2.7]  */

/*  [Promises/A+ 2.3.1]  */

/*  [Promises/A+ 2.3.3.1, 3.5]  */

/*  [Promises/A+ 2.3.3.2]  */

/*  [Promises/A+ 2.3.3.3.1]  */

/*  [Promises/A+ 2.3.3.3.2]  */

/*  [Promises/A+ 2.3.3.3.3]  */

/*  [Promises/A+ 2.3.3.3.4]  */

/*  [Promises/A+ 2.3.3.3]  */

/*  [Promises/A+ 2.3.4, 2.3.3.4]  */

/*  [Promises/A+ 3.6]  */

/*  call retrieved "then" method */

/*  deliver an action  */

/*  execute all handlers  */

/*  execute procedure asynchronously  */

/*  handle other values  */

/*  handle own Thenables    [Promises/A+ 2.3.2]
    and similar "thenables" [Promises/A+ 2.3.3]  */

/*  initial handlers  */

/*  initial reason */

/*  initial state  */

/*  initial value  */

/*  initialize object  */

/*  iterate over all handlers, exactly once  */

/*  optionally support non-constructor/plain-function call  */

/*  promise API methods  */

/*  promise resolving methods  */

/*  promise states [Promises/A+ 2.1]  */

/*  provide optional information-hiding proxy  */

/*  rejectPromise  */

/*  resolvePromise  */

/*  sanity check arguments  */

/*  short-circuit processing  */

/*  support optional executor function  */

/*  surgically check for a "then" method
    (mainly to just call the "getter" of "then" only once)  */

/* . */

/* 0 */

/* 1 */

/* 2 */

/* 3 */

/* 4 */

/* === Edge functions ========== */

/* === Graph functions ========= */

/* === Node functions ========== */

/* Arguments must be numbers. */

/* Built-in method references for those with the same name as other `lodash` methods. */

/* Built-in method references that are verified to be native. */

/* Calculate the actual time it takes for this animation to complete with the provided conditions. */

/* Compute the adjusted time delta. */

/* Given a tension, friction, and duration, a simulation at 60FPS will first run without a defined duration in order to calculate the full path. A second pass
   then adjusts the time delta -- using the relation between actual time and duration -- to calculate the path for the duration-constrained animation. */

/* If duration is not defined, return the actual time required for completing this animation. Otherwise, return a closure that holds the
       computed path and returns a snapshot of the position according to a given percentComplete. */

/* Must contain four arguments. */

/* Next/step function .*/

/* Node.js helper references. */

/* Number of edges in the graph. Should only be changed by the implementation. */

/* Number of nodes in the graph. Should only be changed by the implementation. */

/* Run the simulation without a duration. */

/* Store the position. */

/* X values must be in the [0, 1] range. */

/* eslint "no-console": off */

/* eslint-disable no-console */

/* eslint-disable no-unused-vars */

/* eslint-enable */

/* global Float32Array */

/* global Path2D */

/* global atob, ArrayBuffer, Uint8Array, Blob */

/* global document */

/* global document, window, ResizeObserver, MutationObserver */

/* global setImmediate: true */

/* global setTimeout: true */

/* global window */

/* istanbul ignore next */

/* module decorator */

/* placeholders */

/*!
Embeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable
Copyright (c) 2013-2014 Ralf S. Engelschall (http://engelschall.com)
Licensed under The MIT License (http://opensource.org/licenses/MIT)
*/

/*! Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License */

/*! Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */

/*#__PURE__*/

/**
 *
 * Creates an array cache object to store unique values.
 *
 * @private
 * @constructor
 * @param {Array} [values] The values to cache.
 */

/**
 *  Elements are drawn in a specific order based on compound depth (low to high), the element type (nodes above edges),
 *  and z-index (low to high).  These styles affect how this applies:
 *
 *  z-compound-depth: May be `bottom | orphan | auto | top`.  The first drawn is `bottom`, then `orphan` which is the
 *      same depth as the root of the compound graph, followed by the default value `auto` which draws in order from
 *      root to leaves of the compound graph.  The last drawn is `top`.
 *  z-index-compare: May be `auto | manual`.  The default value is `auto` which always draws edges under nodes.
 *      `manual` ignores this convention and draws based on the `z-index` value setting.
 *  z-index: An integer value that affects the relative draw order of elements.  In general, an element with a higher
 *      `z-index` will be drawn on top of an element with a lower `z-index`.
 */

/**
 * @brief       : constructor
 * @arg options : object containing layout options
 */

/**
 * @brief     : Creates an object which is contains all the data
 *              used in the layout process
 * @arg cy    : cytoscape.js object
 * @return    : layoutInfo object initialized
 */

/**
 * @brief :  default layout options
 */

/**
 * @brief : This function finds the index of the lowest common
 *          graph ancestor between 2 nodes in the subtree
 *          (from the graph hierarchy induced tree) whose
 *          root is graphIx
 *
 * @arg node1: node1's ID
 * @arg node2: node2's ID
 * @arg layoutInfo: layoutInfo object
 *
 */

/**
 * @brief : called on continuous layouts to stop them before they finish
 */

/**
 * @brief : runs the layout
 */

/**
 * A check type enum-like object.  Uses integer values for fast match() lookup.
 * The ordering does not matter as long as the ints are unique.
 */

/**
 * A faster alternative to `Function#apply`, this function invokes `func`
 * with the `this` binding of `thisArg` and the arguments of `args`.
 *
 * @private
 * @param {Function} func The function to invoke.
 * @param {*} thisArg The `this` binding of `func`.
 * @param {Array} args The arguments to invoke `func` with.
 * @returns {*} Returns the result of `func`.
 */

/**
 * A min-priority queue data structure. This algorithm is derived from Cormen,
 * et al., "Introduction to Algorithms". The basic idea of a min-priority
 * queue is that you can efficiently (in O(1) time) get the smallest key in
 * the queue. Adding and removing elements takes O(log n) time. A key can
 * have its priority decreased in O(log n) time.
 */

/**
 * A specialized version of `_.filter` for arrays without support for
 * iteratee shorthands.
 *
 * @private
 * @param {Array} [array] The array to iterate over.
 * @param {Function} predicate The function invoked per iteration.
 * @returns {Array} Returns the new filtered array.
 */

/**
 * A specialized version of `_.forEach` for arrays without support for
 * iteratee shorthands.
 *
 * @private
 * @param {Array} [array] The array to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns `array`.
 */

/**
 * A specialized version of `_.includes` for arrays without support for
 * specifying an index to search from.
 *
 * @private
 * @param {Array} [array] The array to inspect.
 * @param {*} target The value to search for.
 * @returns {boolean} Returns `true` if `target` is found, else `false`.
 */

/**
 * A specialized version of `_.indexOf` which performs strict equality
 * comparisons of values, i.e. `===`.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {*} value The value to search for.
 * @param {number} fromIndex The index to search from.
 * @returns {number} Returns the index of the matched value, else `-1`.
 */

/**
 * A specialized version of `_.map` for arrays without support for iteratee
 * shorthands.
 *
 * @private
 * @param {Array} [array] The array to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns the new mapped array.
 */

/**
 * A specialized version of `_.memoize` which clears the memoized function's
 * cache when it exceeds `MAX_MEMOIZE_SIZE`.
 *
 * @private
 * @param {Function} func The function to have its output memoized.
 * @returns {Function} Returns the new memoized function.
 */

/**
 * A specialized version of `_.reduce` for arrays without support for
 * iteratee shorthands.
 *
 * @private
 * @param {Array} [array] The array to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @param {*} [accumulator] The initial value.
 * @param {boolean} [initAccum] Specify using the first element of `array` as
 *  the initial value.
 * @returns {*} Returns the accumulated value.
 */

/**
 * A specialized version of `_.some` for arrays without support for iteratee
 * shorthands.
 *
 * @private
 * @param {Array} [array] The array to iterate over.
 * @param {Function} predicate The function invoked per iteration.
 * @returns {boolean} Returns `true` if any element passes the predicate check,
 *  else `false`.
 */

/**
 * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
 *
 * @private
 * @param {*} value The value to query.
 * @returns {string} Returns the raw `toStringTag`.
 */

/**
 * A specialized version of `baseIsEqualDeep` for arrays with support for
 * partial deep comparisons.
 *
 * @private
 * @param {Array} array The array to compare.
 * @param {Array} other The other array to compare.
 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
 * @param {Function} customizer The function to customize comparisons.
 * @param {Function} equalFunc The function to determine equivalents of values.
 * @param {Object} stack Tracks traversed `array` and `other` objects.
 * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`.
 */

/**
 * A specialized version of `baseIsEqualDeep` for comparing objects of
 * the same `toStringTag`.
 *
 * **Note:** This function only supports comparing values with tags of
 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.
 *
 * @private
 * @param {Object} object The object to compare.
 * @param {Object} other The other object to compare.
 * @param {string} tag The `toStringTag` of the objects to compare.
 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
 * @param {Function} customizer The function to customize comparisons.
 * @param {Function} equalFunc The function to determine equivalents of values.
 * @param {Object} stack Tracks traversed `object` and `other` objects.
 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
 */

/**
 * A specialized version of `baseIsEqualDeep` for objects with support for
 * partial deep comparisons.
 *
 * @private
 * @param {Object} object The object to compare.
 * @param {Object} other The other object to compare.
 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
 * @param {Function} customizer The function to customize comparisons.
 * @param {Function} equalFunc The function to determine equivalents of values.
 * @param {Object} stack Tracks traversed `object` and `other` objects.
 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
 */

/**
 * A specialized version of `baseIsEqual` for arrays and objects which performs
 * deep comparisons and tracks traversed objects enabling objects with circular
 * references to be compared.
 *
 * @private
 * @param {Object} object The object to compare.
 * @param {Object} other The other object to compare.
 * @param {number} bitmask The bitmask flags. See `baseIsEqual` for more details.
 * @param {Function} customizer The function to customize comparisons.
 * @param {Function} equalFunc The function to determine equivalents of values.
 * @param {Object} [stack] Tracks traversed `object` and `other` objects.
 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`.
 */

/**
 * A specialized version of `baseMerge` for arrays and objects which performs
 * deep merges and tracks traversed objects enabling objects with circular
 * references to be merged.
 *
 * @private
 * @param {Object} object The destination object.
 * @param {Object} source The source object.
 * @param {string} key The key of the value to merge.
 * @param {number} srcIndex The index of `source`.
 * @param {Function} mergeFunc The function to merge values.
 * @param {Function} [customizer] The function to customize assigned values.
 * @param {Object} [stack] Tracks traversed source values and their merged
 *  counterparts.
 */

/**
 * A specialized version of `baseProperty` which supports deep paths.
 *
 * @private
 * @param {Array|string} path The path of the property to get.
 * @returns {Function} Returns the new accessor function.
 */

/**
 * A specialized version of `baseRest` which flattens the rest array.
 *
 * @private
 * @param {Function} func The function to apply a rest parameter to.
 * @returns {Function} Returns the new function.
 */

/**
 * A specialized version of `baseRest` which transforms the rest array.
 *
 * @private
 * @param {Function} func The function to apply a rest parameter to.
 * @param {number} [start=func.length-1] The start position of the rest parameter.
 * @param {Function} transform The rest array transform.
 * @returns {Function} Returns the new function.
 */

/**
 * A specialized version of `matchesProperty` for source values suitable
 * for strict equality comparisons, i.e. `===`.
 *
 * @private
 * @param {string} key The key of the property to get.
 * @param {*} srcValue The value to match.
 * @returns {Function} Returns the new spec function.
 */

/**
 * Adds `value` to the array cache.
 *
 * @private
 * @name add
 * @memberOf SetCache
 * @alias push
 * @param {*} value The value to cache.
 * @returns {Object} Returns the cache instance.
 */

/**
 * An alternative to `_.reduce`; this method transforms `object` to a new
 * `accumulator` object which is the result of running each of its own
 * enumerable string keyed properties thru `iteratee`, with each invocation
 * potentially mutating the `accumulator` object. If `accumulator` is not
 * provided, a new object with the same `[[Prototype]]` will be used. The
 * iteratee is invoked with four arguments: (accumulator, value, key, object).
 * Iteratee functions may exit iteration early by explicitly returning `false`.
 *
 * @static
 * @memberOf _
 * @since 1.3.0
 * @category Object
 * @param {Object} object The object to iterate over.
 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
 * @param {*} [accumulator] The custom accumulator value.
 * @returns {*} Returns the accumulated value.
 * @example
 *
 * _.transform([2, 3, 4], function(result, n) {
 *   result.push(n *= n);
 *   return n % 2 == 0;
 * }, []);
 * // => [4, 9]
 *
 * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
 *   (result[value] || (result[value] = [])).push(key);
 * }, {});
 * // => { '1': ['a', 'c'], '2': ['b'] }
 */

/**
 * Appends the elements of `values` to `array`.
 *
 * @private
 * @param {Array} array The array to modify.
 * @param {Array} values The values to append.
 * @returns {Array} Returns `array`.
 */

/**
 * Assigns `value` to `key` of `object` if the existing value is not equivalent
 * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
 * for equality comparisons.
 *
 * @private
 * @param {Object} object The object to modify.
 * @param {string} key The key of the property to assign.
 * @param {*} value The value to assign.
 */

/**
 * Casts `value` to `identity` if it's not a function.
 *
 * @private
 * @param {*} value The value to inspect.
 * @returns {Function} Returns cast function.
 */

/**
 * Casts `value` to a path array if it's not one.
 *
 * @private
 * @param {*} value The value to inspect.
 * @param {Object} [object] The object to query keys on.
 * @returns {Array} Returns the cast property path array.
 */

/**
 * Checks if `func` has its source masked.
 *
 * @private
 * @param {Function} func The function to check.
 * @returns {boolean} Returns `true` if `func` is masked, else `false`.
 */

/**
 * Checks if `path` exists on `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {Array|string} path The path to check.
 * @param {Function} hasFunc The function to check properties.
 * @returns {boolean} Returns `true` if `path` exists, else `false`.
 */

/**
 * Checks if `path` is a direct or inherited property of `object`.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Object
 * @param {Object} object The object to query.
 * @param {Array|string} path The path to check.
 * @returns {boolean} Returns `true` if `path` exists, else `false`.
 * @example
 *
 * var object = _.create({ 'a': _.create({ 'b': 2 }) });
 *
 * _.hasIn(object, 'a');
 * // => true
 *
 * _.hasIn(object, 'a.b');
 * // => true
 *
 * _.hasIn(object, ['a', 'b']);
 * // => true
 *
 * _.hasIn(object, 'b');
 * // => false
 */

/**
 * Checks if `path` is a direct property of `object`.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Object
 * @param {Object} object The object to query.
 * @param {Array|string} path The path to check.
 * @returns {boolean} Returns `true` if `path` exists, else `false`.
 * @example
 *
 * var object = { 'a': { 'b': 2 } };
 * var other = _.create({ 'a': _.create({ 'b': 2 }) });
 *
 * _.has(object, 'a');
 * // => true
 *
 * _.has(object, 'a.b');
 * // => true
 *
 * _.has(object, ['a', 'b']);
 * // => true
 *
 * _.has(other, 'a');
 * // => false
 */

/**
 * Checks if `string` contains Unicode symbols.
 *
 * @private
 * @param {string} string The string to inspect.
 * @returns {boolean} Returns `true` if a symbol is found, else `false`.
 */

/**
 * Checks if `value` is `undefined`.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`.
 * @example
 *
 * _.isUndefined(void 0);
 * // => true
 *
 * _.isUndefined(null);
 * // => false
 */

/**
 * Checks if `value` is a flattenable `arguments` object or array.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is flattenable, else `false`.
 */

/**
 * Checks if `value` is a plain object, that is, an object created by the
 * `Object` constructor or one with a `[[Prototype]]` of `null`.
 *
 * @static
 * @memberOf _
 * @since 0.8.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`.
 * @example
 *
 * function Foo() {
 *   this.a = 1;
 * }
 *
 * _.isPlainObject(new Foo);
 * // => false
 *
 * _.isPlainObject([1, 2, 3]);
 * // => false
 *
 * _.isPlainObject({ 'x': 0, 'y': 0 });
 * // => true
 *
 * _.isPlainObject(Object.create(null));
 * // => true
 */

/**
 * Checks if `value` is a property name and not a property path.
 *
 * @private
 * @param {*} value The value to check.
 * @param {Object} [object] The object to query keys on.
 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
 */

/**
 * Checks if `value` is a valid array-like index.
 *
 * @private
 * @param {*} value The value to check.
 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
 */

/**
 * Checks if `value` is a valid array-like length.
 *
 * **Note:** This method is loosely based on
 * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
 * @example
 *
 * _.isLength(3);
 * // => true
 *
 * _.isLength(Number.MIN_VALUE);
 * // => false
 *
 * _.isLength(Infinity);
 * // => false
 *
 * _.isLength('3');
 * // => false
 */

/**
 * Checks if `value` is an empty object, collection, map, or set.
 *
 * Objects are considered empty if they have no own enumerable string keyed
 * properties.
 *
 * Array-like values such as `arguments` objects, arrays, buffers, strings, or
 * jQuery-like collections are considered empty if they have a `length` of `0`.
 * Similarly, maps and sets are considered empty if they have a `size` of `0`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is empty, else `false`.
 * @example
 *
 * _.isEmpty(null);
 * // => true
 *
 * _.isEmpty(true);
 * // => true
 *
 * _.isEmpty(1);
 * // => true
 *
 * _.isEmpty([1, 2, 3]);
 * // => false
 *
 * _.isEmpty({ 'a': 1 });
 * // => false
 */

/**
 * Checks if `value` is array-like. A value is considered array-like if it's
 * not a function and has a `value.length` that's an integer greater than or
 * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
 * @example
 *
 * _.isArrayLike([1, 2, 3]);
 * // => true
 *
 * _.isArrayLike(document.body.children);
 * // => true
 *
 * _.isArrayLike('abc');
 * // => true
 *
 * _.isArrayLike(_.noop);
 * // => false
 */

/**
 * Checks if `value` is classified as a `Function` object.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a function, else `false`.
 * @example
 *
 * _.isFunction(_);
 * // => true
 *
 * _.isFunction(/abc/);
 * // => false
 */

/**
 * Checks if `value` is classified as a `String` primitive or object.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a string, else `false`.
 * @example
 *
 * _.isString('abc');
 * // => true
 *
 * _.isString(1);
 * // => false
 */

/**
 * Checks if `value` is classified as a `Symbol` primitive or object.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
 * @example
 *
 * _.isSymbol(Symbol.iterator);
 * // => true
 *
 * _.isSymbol('abc');
 * // => false
 */

/**
 * Checks if `value` is classified as an `Array` object.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an array, else `false`.
 * @example
 *
 * _.isArray([1, 2, 3]);
 * // => true
 *
 * _.isArray(document.body.children);
 * // => false
 *
 * _.isArray('abc');
 * // => false
 *
 * _.isArray(_.noop);
 * // => false
 */

/**
 * Checks if `value` is in the array cache.
 *
 * @private
 * @name has
 * @memberOf SetCache
 * @param {*} value The value to search for.
 * @returns {number} Returns `true` if `value` is found, else `false`.
 */

/**
 * Checks if `value` is likely a prototype object.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.
 */

/**
 * Checks if `value` is object-like. A value is object-like if it's not `null`
 * and has a `typeof` result of "object".
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
 * @example
 *
 * _.isObjectLike({});
 * // => true
 *
 * _.isObjectLike([1, 2, 3]);
 * // => true
 *
 * _.isObjectLike(_.noop);
 * // => false
 *
 * _.isObjectLike(null);
 * // => false
 */

/**
 * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` if suitable for strict
 *  equality comparisons, else `false`.
 */

/**
 * Checks if `value` is suitable for use as unique object key.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
 */

/**
 * Checks if `value` is the
 * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
 * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
 * @example
 *
 * _.isObject({});
 * // => true
 *
 * _.isObject([1, 2, 3]);
 * // => true
 *
 * _.isObject(_.noop);
 * // => true
 *
 * _.isObject(null);
 * // => false
 */

/**
 * Checks if a `cache` value for `key` exists.
 *
 * @private
 * @param {Object} cache The cache to query.
 * @param {string} key The key of the entry to check.
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
 */

/**
 * Checks if a hash value for `key` exists.
 *
 * @private
 * @name has
 * @memberOf Hash
 * @param {string} key The key of the entry to check.
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
 */

/**
 * Checks if a list cache value for `key` exists.
 *
 * @private
 * @name has
 * @memberOf ListCache
 * @param {string} key The key of the entry to check.
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
 */

/**
 * Checks if a map value for `key` exists.
 *
 * @private
 * @name has
 * @memberOf MapCache
 * @param {string} key The key of the entry to check.
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
 */

/**
 * Checks if a stack value for `key` exists.
 *
 * @private
 * @name has
 * @memberOf Stack
 * @param {string} key The key of the entry to check.
 * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
 */

/**
 * Checks if the given arguments are from an iteratee call.
 *
 * @private
 * @param {*} value The potential iteratee value argument.
 * @param {*} index The potential iteratee index or key argument.
 * @param {*} object The potential iteratee object argument.
 * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
 *  else `false`.
 */

/**
 * Compares values to sort them in ascending order.
 *
 * @private
 * @param {*} value The value to compare.
 * @param {*} other The other value to compare.
 * @returns {number} Returns the sort order indicator for `value`.
 */

/**
 * Computes the maximum value of `array`. If `array` is empty or falsey,
 * `undefined` is returned.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Math
 * @param {Array} array The array to iterate over.
 * @returns {*} Returns the maximum value.
 * @example
 *
 * _.max([4, 2, 8, 6]);
 * // => 8
 *
 * _.max([]);
 * // => undefined
 */

/**
 * Computes the minimum value of `array`. If `array` is empty or falsey,
 * `undefined` is returned.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Math
 * @param {Array} array The array to iterate over.
 * @returns {*} Returns the minimum value.
 * @example
 *
 * _.min([4, 2, 8, 6]);
 * // => 2
 *
 * _.min([]);
 * // => undefined
 */

/**
 * Consume all the leading whitespace
 * @param {string} remaining The text to consume
 * @returns The text with the leading whitespace removed
 */

/**
 * Converts `func` to its source code.
 *
 * @private
 * @param {Function} func The function to convert.
 * @returns {string} Returns the source code.
 */

/**
 * Converts `map` to its key-value pairs.
 *
 * @private
 * @param {Object} map The map to convert.
 * @returns {Array} Returns the key-value pairs.
 */

/**
 * Converts `set` to an array of its values.
 *
 * @private
 * @param {Object} set The set to convert.
 * @returns {Array} Returns the values.
 */

/**
 * Converts `value` to a finite number.
 *
 * @static
 * @memberOf _
 * @since 4.12.0
 * @category Lang
 * @param {*} value The value to convert.
 * @returns {number} Returns the converted number.
 * @example
 *
 * _.toFinite(3.2);
 * // => 3.2
 *
 * _.toFinite(Number.MIN_VALUE);
 * // => 5e-324
 *
 * _.toFinite(Infinity);
 * // => 1.7976931348623157e+308
 *
 * _.toFinite('3.2');
 * // => 3.2
 */

/**
 * Converts `value` to a number.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to process.
 * @returns {number} Returns the number.
 * @example
 *
 * _.toNumber(3.2);
 * // => 3.2
 *
 * _.toNumber(Number.MIN_VALUE);
 * // => 5e-324
 *
 * _.toNumber(Infinity);
 * // => Infinity
 *
 * _.toNumber('3.2');
 * // => 3.2
 */

/**
 * Converts `value` to a plain object flattening inherited enumerable string
 * keyed properties of `value` to own properties of the plain object.
 *
 * @static
 * @memberOf _
 * @since 3.0.0
 * @category Lang
 * @param {*} value The value to convert.
 * @returns {Object} Returns the converted plain object.
 * @example
 *
 * function Foo() {
 *   this.b = 2;
 * }
 *
 * Foo.prototype.c = 3;
 *
 * _.assign({ 'a': 1 }, new Foo);
 * // => { 'a': 1, 'b': 2 }
 *
 * _.assign({ 'a': 1 }, _.toPlainObject(new Foo));
 * // => { 'a': 1, 'b': 2, 'c': 3 }
 */

/**
 * Converts `value` to a property path array.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Util
 * @param {*} value The value to convert.
 * @returns {Array} Returns the new property path array.
 * @example
 *
 * _.toPath('a.b.c');
 * // => ['a', 'b', 'c']
 *
 * _.toPath('a[0].b.c');
 * // => ['a', '0', 'b', 'c']
 */

/**
 * Converts `value` to a string key if it's not a string or symbol.
 *
 * @private
 * @param {*} value The value to inspect.
 * @returns {string|symbol} Returns the key.
 */

/**
 * Converts `value` to a string using `Object.prototype.toString`.
 *
 * @private
 * @param {*} value The value to convert.
 * @returns {string} Returns the converted string.
 */

/**
 * Converts `value` to a string. An empty string is returned for `null`
 * and `undefined` values. The sign of `-0` is preserved.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to convert.
 * @returns {string} Returns the converted string.
 * @example
 *
 * _.toString(null);
 * // => ''
 *
 * _.toString(-0);
 * // => '-0'
 *
 * _.toString([1, 2, 3]);
 * // => '1,2,3'
 */

/**
 * Converts `value` to an integer.
 *
 * **Note:** This method is loosely based on
 * [`ToInteger`](http://www.ecma-international.org/ecma-262/7.0/#sec-tointeger).
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to convert.
 * @returns {number} Returns the converted integer.
 * @example
 *
 * _.toInteger(3.2);
 * // => 3
 *
 * _.toInteger(Number.MIN_VALUE);
 * // => 0
 *
 * _.toInteger(Infinity);
 * // => 1.7976931348623157e+308
 *
 * _.toInteger('3.2');
 * // => 3
 */

/**
 * Copies own and inherited symbols of `source` to `object`.
 *
 * @private
 * @param {Object} source The object to copy symbols from.
 * @param {Object} [object={}] The object to copy symbols to.
 * @returns {Object} Returns `object`.
 */

/**
 * Copies own symbols of `source` to `object`.
 *
 * @private
 * @param {Object} source The object to copy symbols from.
 * @param {Object} [object={}] The object to copy symbols to.
 * @returns {Object} Returns `object`.
 */

/**
 * Copies properties of `source` to `object`.
 *
 * @private
 * @param {Object} source The object to copy properties from.
 * @param {Array} props The property identifiers to copy.
 * @param {Object} [object={}] The object to copy properties to.
 * @param {Function} [customizer] The function to customize copied values.
 * @returns {Object} Returns `object`.
 */

/**
 * Copies the values of `source` to `array`.
 *
 * @private
 * @param {Array} source The array to copy values from.
 * @param {Array} [array=[]] The array to copy values to.
 * @returns {Array} Returns `array`.
 */

/**
 * Copyright (c) 2014, Chris Pettitt
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * Copyright (c) 2016-2022, The Cytoscape Consortium.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the “Software”), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 * of the Software, and to permit persons to whom the Software is furnished to do
 * so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

/**
 * Creates a `_.find` or `_.findLast` function.
 *
 * @private
 * @param {Function} findIndexFunc The function to find the collection index.
 * @returns {Function} Returns the new find function.
 */

/**
 * Creates a `_.range` or `_.rangeRight` function.
 *
 * @private
 * @param {boolean} [fromRight] Specify iterating from right to left.
 * @returns {Function} Returns the new range function.
 */

/**
 * Creates a `baseEach` or `baseEachRight` function.
 *
 * @private
 * @param {Function} eachFunc The function to iterate over a collection.
 * @param {boolean} [fromRight] Specify iterating from right to left.
 * @returns {Function} Returns the new base function.
 */

/**
 * Creates a base function for methods like `_.forIn` and `_.forOwn`.
 *
 * @private
 * @param {boolean} [fromRight] Specify iterating from right to left.
 * @returns {Function} Returns the new base function.
 */

/**
 * Creates a clone of  `buffer`.
 *
 * @private
 * @param {Buffer} buffer The buffer to clone.
 * @param {boolean} [isDeep] Specify a deep clone.
 * @returns {Buffer} Returns the cloned buffer.
 */

/**
 * Creates a clone of `arrayBuffer`.
 *
 * @private
 * @param {ArrayBuffer} arrayBuffer The array buffer to clone.
 * @returns {ArrayBuffer} Returns the cloned array buffer.
 */

/**
 * Creates a clone of `dataView`.
 *
 * @private
 * @param {Object} dataView The data view to clone.
 * @param {boolean} [isDeep] Specify a deep clone.
 * @returns {Object} Returns the cloned data view.
 */

/**
 * Creates a clone of `regexp`.
 *
 * @private
 * @param {Object} regexp The regexp to clone.
 * @returns {Object} Returns the cloned regexp.
 */

/**
 * Creates a clone of `typedArray`.
 *
 * @private
 * @param {Object} typedArray The typed array to clone.
 * @param {boolean} [isDeep] Specify a deep clone.
 * @returns {Object} Returns the cloned typed array.
 */

/**
 * Creates a clone of the `symbol` object.
 *
 * @private
 * @param {Object} symbol The symbol object to clone.
 * @returns {Object} Returns the cloned symbol object.
 */

/**
 * Creates a debounced function that delays invoking `func` until after `wait`
 * milliseconds have elapsed since the last time the debounced function was
 * invoked. The debounced function comes with a `cancel` method to cancel
 * delayed `func` invocations and a `flush` method to immediately invoke them.
 * Provide `options` to indicate whether `func` should be invoked on the
 * leading and/or trailing edge of the `wait` timeout. The `func` is invoked
 * with the last arguments provided to the debounced function. Subsequent
 * calls to the debounced function return the result of the last `func`
 * invocation.
 *
 * **Note:** If `leading` and `trailing` options are `true`, `func` is
 * invoked on the trailing edge of the timeout only if the debounced function
 * is invoked more than once during the `wait` timeout.
 *
 * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred
 * until to the next tick, similar to `setTimeout` with a timeout of `0`.
 *
 * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)
 * for details over the differences between `_.debounce` and `_.throttle`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Function
 * @param {Function} func The function to debounce.
 * @param {number} [wait=0] The number of milliseconds to delay.
 * @param {Object} [options={}] The options object.
 * @param {boolean} [options.leading=false]
 *  Specify invoking on the leading edge of the timeout.
 * @param {number} [options.maxWait]
 *  The maximum time `func` is allowed to be delayed before it's invoked.
 * @param {boolean} [options.trailing=true]
 *  Specify invoking on the trailing edge of the timeout.
 * @returns {Function} Returns the new debounced function.
 * @example
 *
 * // Avoid costly calculations while the window size is in flux.
 * jQuery(window).on('resize', _.debounce(calculateLayout, 150));
 *
 * // Invoke `sendMail` when clicked, debouncing subsequent calls.
 * jQuery(element).on('click', _.debounce(sendMail, 300, {
 *   'leading': true,
 *   'trailing': false
 * }));
 *
 * // Ensure `batchLog` is invoked once after 1 second of debounced calls.
 * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
 * var source = new EventSource('/stream');
 * jQuery(source).on('message', debounced);
 *
 * // Cancel the trailing debounced invocation.
 * jQuery(window).on('popstate', debounced.cancel);
 */

/**
 * Creates a function like `_.assign`.
 *
 * @private
 * @param {Function} assigner The function to assign values.
 * @returns {Function} Returns the new assigner function.
 */

/**
 * Creates a function that memoizes the result of `func`. If `resolver` is
 * provided, it determines the cache key for storing the result based on the
 * arguments provided to the memoized function. By default, the first argument
 * provided to the memoized function is used as the map cache key. The `func`
 * is invoked with the `this` binding of the memoized function.
 *
 * **Note:** The cache is exposed as the `cache` property on the memoized
 * function. Its creation may be customized by replacing the `_.memoize.Cache`
 * constructor with one whose instances implement the
 * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
 * method interface of `clear`, `delete`, `get`, `has`, and `set`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Function
 * @param {Function} func The function to have its output memoized.
 * @param {Function} [resolver] The function to resolve the cache key.
 * @returns {Function} Returns the new memoized function.
 * @example
 *
 * var object = { 'a': 1, 'b': 2 };
 * var other = { 'c': 3, 'd': 4 };
 *
 * var values = _.memoize(_.values);
 * values(object);
 * // => [1, 2]
 *
 * values(other);
 * // => [3, 4]
 *
 * object.a = 2;
 * values(object);
 * // => [1, 2]
 *
 * // Modify the result cache.
 * values.cache.set(object, ['a', 'b']);
 * values(object);
 * // => ['a', 'b']
 *
 * // Replace `_.memoize.Cache`.
 * _.memoize.Cache = WeakMap;
 */

/**
 * Creates a function that returns `value`.
 *
 * @static
 * @memberOf _
 * @since 2.4.0
 * @category Util
 * @param {*} value The value to return from the new function.
 * @returns {Function} Returns the new constant function.
 * @example
 *
 * var objects = _.times(2, _.constant({ 'a': 1 }));
 *
 * console.log(objects);
 * // => [{ 'a': 1 }, { 'a': 1 }]
 *
 * console.log(objects[0] === objects[1]);
 * // => true
 */

/**
 * Creates a function that returns the value at `path` of a given object.
 *
 * @static
 * @memberOf _
 * @since 2.4.0
 * @category Util
 * @param {Array|string} path The path of the property to get.
 * @returns {Function} Returns the new accessor function.
 * @example
 *
 * var objects = [
 *   { 'a': { 'b': 2 } },
 *   { 'a': { 'b': 1 } }
 * ];
 *
 * _.map(objects, _.property('a.b'));
 * // => [2, 1]
 *
 * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b');
 * // => [1, 2]
 */

/**
 * Creates a function that'll short out and invoke `identity` instead
 * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN`
 * milliseconds.
 *
 * @private
 * @param {Function} func The function to restrict.
 * @returns {Function} Returns the new shortable function.
 */

/**
 * Creates a hash object.
 *
 * @private
 * @constructor
 * @param {Array} [entries] The key-value pairs to cache.
 */

/**
 * Creates a map cache object to store key-value pairs.
 *
 * @private
 * @constructor
 * @param {Array} [entries] The key-value pairs to cache.
 */

/**
 * Creates a shallow clone of `value`.
 *
 * **Note:** This method is loosely based on the
 * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm)
 * and supports cloning arrays, array buffers, booleans, date objects, maps,
 * numbers, `Object` objects, regexes, sets, strings, symbols, and typed
 * arrays. The own enumerable properties of `arguments` objects are cloned
 * as plain objects. An empty object is returned for uncloneable values such
 * as error objects, functions, DOM nodes, and WeakMaps.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to clone.
 * @returns {*} Returns the cloned value.
 * @see _.cloneDeep
 * @example
 *
 * var objects = [{ 'a': 1 }, { 'b': 2 }];
 *
 * var shallow = _.clone(objects);
 * console.log(shallow[0] === objects[0]);
 * // => true
 */

/**
 * Creates a stack cache object to store key-value pairs.
 *
 * @private
 * @constructor
 * @param {Array} [entries] The key-value pairs to cache.
 */

/**
 * Creates a unary function that invokes `func` with its argument transformed.
 *
 * @private
 * @param {Function} func The function to wrap.
 * @param {Function} transform The argument transform.
 * @returns {Function} Returns the new function.
 */

/**
 * Creates an array of elements, sorted in ascending order by the results of
 * running each element in a collection thru each iteratee. This method
 * performs a stable sort, that is, it preserves the original sort order of
 * equal elements. The iteratees are invoked with one argument: (value).
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Collection
 * @param {Array|Object} collection The collection to iterate over.
 * @param {...(Function|Function[])} [iteratees=[_.identity]]
 *  The iteratees to sort by.
 * @returns {Array} Returns the new sorted array.
 * @example
 *
 * var users = [
 *   { 'user': 'fred',   'age': 48 },
 *   { 'user': 'barney', 'age': 36 },
 *   { 'user': 'fred',   'age': 30 },
 *   { 'user': 'barney', 'age': 34 }
 * ];
 *
 * _.sortBy(users, [function(o) { return o.user; }]);
 * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]]
 *
 * _.sortBy(users, ['user', 'age']);
 * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]]
 */

/**
 * Creates an array of numbers (positive and/or negative) progressing from
 * `start` up to, but not including, `end`. A step of `-1` is used if a negative
 * `start` is specified without an `end` or `step`. If `end` is not specified,
 * it's set to `start` with `start` then set to `0`.
 *
 * **Note:** JavaScript follows the IEEE-754 standard for resolving
 * floating-point values which can produce unexpected results.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Util
 * @param {number} [start=0] The start of the range.
 * @param {number} end The end of the range.
 * @param {number} [step=1] The value to increment or decrement by.
 * @returns {Array} Returns the range of numbers.
 * @see _.inRange, _.rangeRight
 * @example
 *
 * _.range(4);
 * // => [0, 1, 2, 3]
 *
 * _.range(-4);
 * // => [0, -1, -2, -3]
 *
 * _.range(1, 5);
 * // => [1, 2, 3, 4]
 *
 * _.range(0, 20, 5);
 * // => [0, 5, 10, 15]
 *
 * _.range(0, -4, -1);
 * // => [0, -1, -2, -3]
 *
 * _.range(1, 4, 0);
 * // => [1, 1, 1]
 *
 * _.range(0);
 * // => []
 */

/**
 * Creates an array of own and inherited enumerable property names and
 * symbols of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names and symbols.
 */

/**
 * Creates an array of own enumerable property names and symbols of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names and symbols.
 */

/**
 * Creates an array of the enumerable property names of the array-like `value`.
 *
 * @private
 * @param {*} value The value to query.
 * @param {boolean} inherited Specify returning inherited property names.
 * @returns {Array} Returns the array of property names.
 */

/**
 * Creates an array of the own and inherited enumerable property names of `object`.
 *
 * **Note:** Non-object values are coerced to objects.
 *
 * @static
 * @memberOf _
 * @since 3.0.0
 * @category Object
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 * @example
 *
 * function Foo() {
 *   this.a = 1;
 *   this.b = 2;
 * }
 *
 * Foo.prototype.c = 3;
 *
 * _.keysIn(new Foo);
 * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
 */

/**
 * Creates an array of the own enumerable property names of `object`.
 *
 * **Note:** Non-object values are coerced to objects. See the
 * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
 * for more details.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Object
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 * @example
 *
 * function Foo() {
 *   this.a = 1;
 *   this.b = 2;
 * }
 *
 * Foo.prototype.c = 3;
 *
 * _.keys(new Foo);
 * // => ['a', 'b'] (iteration order is not guaranteed)
 *
 * _.keys('hi');
 * // => ['0', '1']
 */

/**
 * Creates an array of the own enumerable string keyed property values of `object`.
 *
 * **Note:** Non-object values are coerced to objects.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Object
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property values.
 * @example
 *
 * function Foo() {
 *   this.a = 1;
 *   this.b = 2;
 * }
 *
 * Foo.prototype.c = 3;
 *
 * _.values(new Foo);
 * // => [1, 2] (iteration order is not guaranteed)
 *
 * _.values('hi');
 * // => ['h', 'i']
 */

/**
 * Creates an array of unique values, in order, from all given arrays using
 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
 * for equality comparisons.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Array
 * @param {...Array} [arrays] The arrays to inspect.
 * @returns {Array} Returns the new array of combined values.
 * @example
 *
 * _.union([2], [1, 2]);
 * // => [2, 1]
 */

/**
 * Creates an array of values by running each element in `collection` thru
 * `iteratee`. The iteratee is invoked with three arguments:
 * (value, index|key, collection).
 *
 * Many lodash methods are guarded to work as iteratees for methods like
 * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`.
 *
 * The guarded methods are:
 * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`,
 * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`,
 * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`,
 * `template`, `trim`, `trimEnd`, `trimStart`, and `words`
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Collection
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
 * @returns {Array} Returns the new mapped array.
 * @example
 *
 * function square(n) {
 *   return n * n;
 * }
 *
 * _.map([4, 8], square);
 * // => [16, 64]
 *
 * _.map({ 'a': 4, 'b': 8 }, square);
 * // => [16, 64] (iteration order is not guaranteed)
 *
 * var users = [
 *   { 'user': 'barney' },
 *   { 'user': 'fred' }
 * ];
 *
 * // The `_.property` iteratee shorthand.
 * _.map(users, 'user');
 * // => ['barney', 'fred']
 */

/**
 * Creates an list cache object.
 *
 * @private
 * @constructor
 * @param {Array} [entries] The key-value pairs to cache.
 */

/**
 * Creates an object composed of the picked `object` properties.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Object
 * @param {Object} object The source object.
 * @param {...(string|string[])} [paths] The property paths to pick.
 * @returns {Object} Returns the new object.
 * @example
 *
 * var object = { 'a': 1, 'b': '2', 'c': 3 };
 *
 * _.pick(object, ['a', 'c']);
 * // => { 'a': 1, 'c': 3 }
 */

/**
 * Creates an object with the same keys as `object` and values generated
 * by running each own enumerable string keyed property of `object` thru
 * `iteratee`. The iteratee is invoked with three arguments:
 * (value, key, object).
 *
 * @static
 * @memberOf _
 * @since 2.4.0
 * @category Object
 * @param {Object} object The object to iterate over.
 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
 * @returns {Object} Returns the new mapped object.
 * @see _.mapKeys
 * @example
 *
 * var users = {
 *   'fred':    { 'user': 'fred',    'age': 40 },
 *   'pebbles': { 'user': 'pebbles', 'age': 1 }
 * };
 *
 * _.mapValues(users, function(o) { return o.age; });
 * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
 *
 * // The `_.property` iteratee shorthand.
 * _.mapValues(users, 'age');
 * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
 */

/**
 * Decreases the priority for **key** to **priority**. If the new priority is
 * greater than the previous priority, this function will throw an Error.
 *
 * @param {Object} key the key for which to raise priority
 * @param {Number} priority the new priority for the key
 */

/**
 * Flattens `array` a single level deep.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Array
 * @param {Array} array The array to flatten.
 * @returns {Array} Returns the new flattened array.
 * @example
 *
 * _.flatten([1, [2, [3, [4]], 5]]);
 * // => [1, 2, [3, [4]], 5]
 */

/**
 * Generates a unique ID. If `prefix` is given, the ID is appended to it.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Util
 * @param {string} [prefix=''] The value to prefix the ID with.
 * @returns {string} Returns the unique ID.
 * @example
 *
 * _.uniqueId('contact_');
 * // => 'contact_104'
 *
 * _.uniqueId();
 * // => '105'
 */

/**
 * Gets the data for `map`.
 *
 * @private
 * @param {Object} map The map to query.
 * @param {string} key The reference key.
 * @returns {*} Returns the map data.
 */

/**
 * Gets the hash value for `key`.
 *
 * @private
 * @name get
 * @memberOf Hash
 * @param {string} key The key of the value to get.
 * @returns {*} Returns the entry value.
 */

/**
 * Gets the index at which the `key` is found in `array` of key-value pairs.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {*} key The key to search for.
 * @returns {number} Returns the index of the matched value, else `-1`.
 */

/**
 * Gets the last element of `array`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Array
 * @param {Array} array The array to query.
 * @returns {*} Returns the last element of `array`.
 * @example
 *
 * _.last([1, 2, 3]);
 * // => 3
 */

/**
 * Gets the list cache value for `key`.
 *
 * @private
 * @name get
 * @memberOf ListCache
 * @param {string} key The key of the value to get.
 * @returns {*} Returns the entry value.
 */

/**
 * Gets the map value for `key`.
 *
 * @private
 * @name get
 * @memberOf MapCache
 * @param {string} key The key of the value to get.
 * @returns {*} Returns the entry value.
 */

/**
 * Gets the native function at `key` of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {string} key The key of the method to get.
 * @returns {*} Returns the function if it's native, else `undefined`.
 */

/**
 * Gets the number of symbols in `string`.
 *
 * @private
 * @param {string} string The string to inspect.
 * @returns {number} Returns the string size.
 */

/**
 * Gets the property names, values, and compare flags of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the match data of `object`.
 */

/**
 * Gets the size of `collection` by returning its length for array-like
 * values or the number of own enumerable string keyed properties for objects.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Collection
 * @param {Array|Object|string} collection The collection to inspect.
 * @returns {number} Returns the collection size.
 * @example
 *
 * _.size([1, 2, 3]);
 * // => 3
 *
 * _.size({ 'a': 1, 'b': 2 });
 * // => 2
 *
 * _.size('pebbles');
 * // => 7
 */

/**
 * Gets the size of a Unicode `string`.
 *
 * @private
 * @param {string} string The string inspect.
 * @returns {number} Returns the string size.
 */

/**
 * Gets the size of an ASCII `string`.
 *
 * @private
 * @param {string} string The string inspect.
 * @returns {number} Returns the string size.
 */

/**
 * Gets the stack value for `key`.
 *
 * @private
 * @name get
 * @memberOf Stack
 * @param {string} key The key of the value to get.
 * @returns {*} Returns the entry value.
 */

/**
 * Gets the timestamp of the number of milliseconds that have elapsed since
 * the Unix epoch (1 January 1970 00:00:00 UTC).
 *
 * @static
 * @memberOf _
 * @since 2.4.0
 * @category Date
 * @returns {number} Returns the timestamp.
 * @example
 *
 * _.defer(function(stamp) {
 *   console.log(_.now() - stamp);
 * }, _.now());
 * // => Logs the number of milliseconds it took for the deferred invocation.
 */

/**
 * Gets the value at `key` of `object`.
 *
 * @private
 * @param {Object} [object] The object to query.
 * @param {string} key The key of the property to get.
 * @returns {*} Returns the property value.
 */

/**
 * Gets the value at `key`, unless `key` is "__proto__" or "constructor".
 *
 * @private
 * @param {Object} object The object to query.
 * @param {string} key The key of the property to get.
 * @returns {*} Returns the property value.
 */

/**
 * Gets the value at `path` of `object`. If the resolved value is
 * `undefined`, the `defaultValue` is returned in its place.
 *
 * @static
 * @memberOf _
 * @since 3.7.0
 * @category Object
 * @param {Object} object The object to query.
 * @param {Array|string} path The path of the property to get.
 * @param {*} [defaultValue] The value returned for `undefined` resolved values.
 * @returns {*} Returns the resolved value.
 * @example
 *
 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
 *
 * _.get(object, 'a[0].b.c');
 * // => 3
 *
 * _.get(object, ['a', '0', 'b', 'c']);
 * // => 3
 *
 * _.get(object, 'a.b.c', 'default');
 * // => 'default'
 */

/**
 * Initializes an array clone.
 *
 * @private
 * @param {Array} array The array to clone.
 * @returns {Array} Returns the initialized clone.
 */

/**
 * Initializes an object clone based on its `toStringTag`.
 *
 * **Note:** This function only supports cloning values with tags of
 * `Boolean`, `Date`, `Error`, `Map`, `Number`, `RegExp`, `Set`, or `String`.
 *
 * @private
 * @param {Object} object The object to clone.
 * @param {string} tag The `toStringTag` of the object to clone.
 * @param {boolean} [isDeep] Specify a deep clone.
 * @returns {Object} Returns the initialized clone.
 */

/**
 * Initializes an object clone.
 *
 * @private
 * @param {Object} object The object to clone.
 * @returns {Object} Returns the initialized clone.
 */

/**
 * Inserts a new key into the priority queue. If the key already exists in
 * the queue this function returns `false`; otherwise it will return `true`.
 * Takes `O(n)` time.
 *
 * @param {Object} key the key to add
 * @param {Number} priority the initial priority for the key
 */

/**
 * Iterates over elements of `collection` and invokes `iteratee` for each element.
 * The iteratee is invoked with three arguments: (value, index|key, collection).
 * Iteratee functions may exit iteration early by explicitly returning `false`.
 *
 * **Note:** As with other "Collections" methods, objects with a "length"
 * property are iterated like arrays. To avoid this behavior use `_.forIn`
 * or `_.forOwn` for object iteration.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @alias each
 * @category Collection
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
 * @returns {Array|Object} Returns `collection`.
 * @see _.forEachRight
 * @example
 *
 * _.forEach([1, 2], function(value) {
 *   console.log(value);
 * });
 * // => Logs `1` then `2`.
 *
 * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) {
 *   console.log(key);
 * });
 * // => Logs 'a' then 'b' (iteration order is not guaranteed).
 */

/**
 * Iterates over elements of `collection`, returning an array of all elements
 * `predicate` returns truthy for. The predicate is invoked with three
 * arguments: (value, index|key, collection).
 *
 * **Note:** Unlike `_.remove`, this method returns a new array.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Collection
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} [predicate=_.identity] The function invoked per iteration.
 * @returns {Array} Returns the new filtered array.
 * @see _.reject
 * @example
 *
 * var users = [
 *   { 'user': 'barney', 'age': 36, 'active': true },
 *   { 'user': 'fred',   'age': 40, 'active': false }
 * ];
 *
 * _.filter(users, function(o) { return !o.active; });
 * // => objects for ['fred']
 *
 * // The `_.matches` iteratee shorthand.
 * _.filter(users, { 'age': 36, 'active': true });
 * // => objects for ['barney']
 *
 * // The `_.matchesProperty` iteratee shorthand.
 * _.filter(users, ['active', false]);
 * // => objects for ['fred']
 *
 * // The `_.property` iteratee shorthand.
 * _.filter(users, 'active');
 * // => objects for ['barney']
 *
 * // Combining several predicates using `_.overEvery` or `_.overSome`.
 * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]]));
 * // => objects for ['fred', 'barney']
 */

/**
 * Iterates over elements of `collection`, returning the first element
 * `predicate` returns truthy for. The predicate is invoked with three
 * arguments: (value, index|key, collection).
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Collection
 * @param {Array|Object} collection The collection to inspect.
 * @param {Function} [predicate=_.identity] The function invoked per iteration.
 * @param {number} [fromIndex=0] The index to search from.
 * @returns {*} Returns the matched element, else `undefined`.
 * @example
 *
 * var users = [
 *   { 'user': 'barney',  'age': 36, 'active': true },
 *   { 'user': 'fred',    'age': 40, 'active': false },
 *   { 'user': 'pebbles', 'age': 1,  'active': true }
 * ];
 *
 * _.find(users, function(o) { return o.age < 40; });
 * // => object for 'barney'
 *
 * // The `_.matches` iteratee shorthand.
 * _.find(users, { 'age': 1, 'active': true });
 * // => object for 'pebbles'
 *
 * // The `_.matchesProperty` iteratee shorthand.
 * _.find(users, ['active', false]);
 * // => object for 'fred'
 *
 * // The `_.property` iteratee shorthand.
 * _.find(users, 'active');
 * // => object for 'barney'
 */

/**
 * Iterates over own and inherited enumerable string keyed properties of an
 * object and invokes `iteratee` for each property. The iteratee is invoked
 * with three arguments: (value, key, object). Iteratee functions may exit
 * iteration early by explicitly returning `false`.
 *
 * @static
 * @memberOf _
 * @since 0.3.0
 * @category Object
 * @param {Object} object The object to iterate over.
 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
 * @returns {Object} Returns `object`.
 * @see _.forInRight
 * @example
 *
 * function Foo() {
 *   this.a = 1;
 *   this.b = 2;
 * }
 *
 * Foo.prototype.c = 3;
 *
 * _.forIn(new Foo, function(value, key) {
 *   console.log(key);
 * });
 * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed).
 */

/**
 * Make a new query object
 *
 * @prop type {Type} The type enum (int) of the query
 * @prop checks List of checks to make against an ele to test for a match
 */

/**
 * Of all the expressions, find the first match in the remaining text.
 * @param {string} remaining The remaining text to parse
 * @returns The matched expression and the newly remaining text `{ expr, match, name, remaining }`
 */

/**
 * Performs a
 * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
 * comparison between two values to determine if they are equivalent.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to compare.
 * @param {*} other The other value to compare.
 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
 * @example
 *
 * var object = { 'a': 1 };
 * var other = { 'a': 1 };
 *
 * _.eq(object, object);
 * // => true
 *
 * _.eq(object, other);
 * // => false
 *
 * _.eq('a', 'a');
 * // => true
 *
 * _.eq('a', Object('a'));
 * // => false
 *
 * _.eq(NaN, NaN);
 * // => true
 */

/**
 * Reduces `collection` to a value which is the accumulated result of running
 * each element in `collection` thru `iteratee`, where each successive
 * invocation is supplied the return value of the previous. If `accumulator`
 * is not given, the first element of `collection` is used as the initial
 * value. The iteratee is invoked with four arguments:
 * (accumulator, value, index|key, collection).
 *
 * Many lodash methods are guarded to work as iteratees for methods like
 * `_.reduce`, `_.reduceRight`, and `_.transform`.
 *
 * The guarded methods are:
 * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`,
 * and `sortBy`
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Collection
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} [iteratee=_.identity] The function invoked per iteration.
 * @param {*} [accumulator] The initial value.
 * @returns {*} Returns the accumulated value.
 * @see _.reduceRight
 * @example
 *
 * _.reduce([1, 2], function(sum, n) {
 *   return sum + n;
 * }, 0);
 * // => 3
 *
 * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
 *   (result[value] || (result[value] = [])).push(key);
 *   return result;
 * }, {});
 * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed)
 */

/**
 * Removes `key` and its value from the hash.
 *
 * @private
 * @name delete
 * @memberOf Hash
 * @param {Object} hash The hash to modify.
 * @param {string} key The key of the value to remove.
 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
 */

/**
 * Removes `key` and its value from the list cache.
 *
 * @private
 * @name delete
 * @memberOf ListCache
 * @param {string} key The key of the value to remove.
 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
 */

/**
 * Removes `key` and its value from the map.
 *
 * @private
 * @name delete
 * @memberOf MapCache
 * @param {string} key The key of the value to remove.
 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
 */

/**
 * Removes `key` and its value from the stack.
 *
 * @private
 * @name delete
 * @memberOf Stack
 * @param {string} key The key of the value to remove.
 * @returns {boolean} Returns `true` if the entry was removed, else `false`.
 */

/**
 * Removes all key-value entries from the hash.
 *
 * @private
 * @name clear
 * @memberOf Hash
 */

/**
 * Removes all key-value entries from the list cache.
 *
 * @private
 * @name clear
 * @memberOf ListCache
 */

/**
 * Removes all key-value entries from the map.
 *
 * @private
 * @name clear
 * @memberOf MapCache
 */

/**
 * Removes all key-value entries from the stack.
 *
 * @private
 * @name clear
 * @memberOf Stack
 */

/**
 * Removes and returns the smallest key in the queue. Takes `O(log n)` time.
 */

/**
 * Returns `true` if **key** is in the queue and `false` if not.
 */

/**
 * Returns the key for the minimum element in this queue. If the queue is
 * empty this function throws an Error. Takes `O(1)` time.
 */

/**
 * Returns the keys that are in the queue. Takes `O(n)` time.
 */

/**
 * Returns the number of elements in the queue. Takes `O(1)` time.
 */

/**
 * Returns the priority for **key**. If **key** is not present in the queue
 * then this function returns `undefined`. Takes `O(1)` time.
 *
 * @param {Object} key
 */

/**
 * Sets the `toString` method of `func` to return `string`.
 *
 * @private
 * @param {Function} func The function to modify.
 * @param {Function} string The `toString` result.
 * @returns {Function} Returns `func`.
 */

/**
 * Sets the hash `key` to `value`.
 *
 * @private
 * @name set
 * @memberOf Hash
 * @param {string} key The key of the value to set.
 * @param {*} value The value to set.
 * @returns {Object} Returns the hash instance.
 */

/**
 * Sets the list cache `key` to `value`.
 *
 * @private
 * @name set
 * @memberOf ListCache
 * @param {string} key The key of the value to set.
 * @param {*} value The value to set.
 * @returns {Object} Returns the list cache instance.
 */

/**
 * Sets the map `key` to `value`.
 *
 * @private
 * @name set
 * @memberOf MapCache
 * @param {string} key The key of the value to set.
 * @param {*} value The value to set.
 * @returns {Object} Returns the map cache instance.
 */

/**
 * Sets the stack `key` to `value`.
 *
 * @private
 * @name set
 * @memberOf Stack
 * @param {string} key The key of the value to set.
 * @param {*} value The value to set.
 * @returns {Object} Returns the stack cache instance.
 */

/**
 * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,
 * it's created. Arrays are created for missing index properties while objects
 * are created for all other missing properties. Use `_.setWith` to customize
 * `path` creation.
 *
 * **Note:** This method mutates `object`.
 *
 * @static
 * @memberOf _
 * @since 3.7.0
 * @category Object
 * @param {Object} object The object to modify.
 * @param {Array|string} path The path of the property to set.
 * @param {*} value The value to set.
 * @returns {Object} Returns `object`.
 * @example
 *
 * var object = { 'a': [{ 'b': { 'c': 3 } }] };
 *
 * _.set(object, 'a[0].b.c', 4);
 * console.log(object.a[0].b.c);
 * // => 4
 *
 * _.set(object, ['x', '0', 'y', 'z'], 5);
 * console.log(object.x[0].y.z);
 * // => 5
 */

/**
 * The base implementation of  `_.pickBy` without support for iteratee shorthands.
 *
 * @private
 * @param {Object} object The source object.
 * @param {string[]} paths The property paths to pick.
 * @param {Function} predicate The function invoked per property.
 * @returns {Object} Returns the new object.
 */

/**
 * The base implementation of `_.assignIn` without support for multiple sources
 * or `customizer` functions.
 *
 * @private
 * @param {Object} object The destination object.
 * @param {Object} source The source object.
 * @returns {Object} Returns `object`.
 */

/**
 * The base implementation of `_.assign` without support for multiple sources
 * or `customizer` functions.
 *
 * @private
 * @param {Object} object The destination object.
 * @param {Object} source The source object.
 * @returns {Object} Returns `object`.
 */

/**
 * The base implementation of `_.clone` and `_.cloneDeep` which tracks
 * traversed objects.
 *
 * @private
 * @param {*} value The value to clone.
 * @param {boolean} bitmask The bitmask flags.
 *  1 - Deep clone
 *  2 - Flatten inherited properties
 *  4 - Clone symbols
 * @param {Function} [customizer] The function to customize cloning.
 * @param {string} [key] The key of `value`.
 * @param {Object} [object] The parent object of `value`.
 * @param {Object} [stack] Tracks traversed objects and their clone counterparts.
 * @returns {*} Returns the cloned value.
 */

/**
 * The base implementation of `_.filter` without support for iteratee shorthands.
 *
 * @private
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} predicate The function invoked per iteration.
 * @returns {Array} Returns the new filtered array.
 */

/**
 * The base implementation of `_.findIndex` and `_.findLastIndex` without
 * support for iteratee shorthands.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {Function} predicate The function invoked per iteration.
 * @param {number} fromIndex The index to search from.
 * @param {boolean} [fromRight] Specify iterating from right to left.
 * @returns {number} Returns the index of the matched value, else `-1`.
 */

/**
 * The base implementation of `_.flatten` with support for restricting flattening.
 *
 * @private
 * @param {Array} array The array to flatten.
 * @param {number} depth The maximum recursion depth.
 * @param {boolean} [predicate=isFlattenable] The function invoked per iteration.
 * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks.
 * @param {Array} [result=[]] The initial result value.
 * @returns {Array} Returns the new flattened array.
 */

/**
 * The base implementation of `_.forEach` without support for iteratee shorthands.
 *
 * @private
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array|Object} Returns `collection`.
 */

/**
 * The base implementation of `_.forOwn` without support for iteratee shorthands.
 *
 * @private
 * @param {Object} object The object to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Object} Returns `object`.
 */

/**
 * The base implementation of `_.get` without support for default values.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {Array|string} path The path of the property to get.
 * @returns {*} Returns the resolved value.
 */

/**
 * The base implementation of `_.gt` which doesn't coerce arguments.
 *
 * @private
 * @param {*} value The value to compare.
 * @param {*} other The other value to compare.
 * @returns {boolean} Returns `true` if `value` is greater than `other`,
 *  else `false`.
 */

/**
 * The base implementation of `_.hasIn` without support for deep paths.
 *
 * @private
 * @param {Object} [object] The object to query.
 * @param {Array|string} key The key to check.
 * @returns {boolean} Returns `true` if `key` exists, else `false`.
 */

/**
 * The base implementation of `_.has` without support for deep paths.
 *
 * @private
 * @param {Object} [object] The object to query.
 * @param {Array|string} key The key to check.
 * @returns {boolean} Returns `true` if `key` exists, else `false`.
 */

/**
 * The base implementation of `_.indexOf` without `fromIndex` bounds checks.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {*} value The value to search for.
 * @param {number} fromIndex The index to search from.
 * @returns {number} Returns the index of the matched value, else `-1`.
 */

/**
 * The base implementation of `_.isArguments`.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an `arguments` object,
 */

/**
 * The base implementation of `_.isEqual` which supports partial comparisons
 * and tracks traversed objects.
 *
 * @private
 * @param {*} value The value to compare.
 * @param {*} other The other value to compare.
 * @param {boolean} bitmask The bitmask flags.
 *  1 - Unordered comparison
 *  2 - Partial comparison
 * @param {Function} [customizer] The function to customize comparisons.
 * @param {Object} [stack] Tracks traversed `value` and `other` objects.
 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
 */

/**
 * The base implementation of `_.isMap` without Node.js optimizations.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a map, else `false`.
 */

/**
 * The base implementation of `_.isMatch` without support for iteratee shorthands.
 *
 * @private
 * @param {Object} object The object to inspect.
 * @param {Object} source The object of property values to match.
 * @param {Array} matchData The property names, values, and compare flags to match.
 * @param {Function} [customizer] The function to customize comparisons.
 * @returns {boolean} Returns `true` if `object` is a match, else `false`.
 */

/**
 * The base implementation of `_.isNaN` without support for number objects.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`.
 */

/**
 * The base implementation of `_.isNative` without bad shim checks.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a native function,
 *  else `false`.
 */

/**
 * The base implementation of `_.isSet` without Node.js optimizations.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a set, else `false`.
 */

/**
 * The base implementation of `_.isTypedArray` without Node.js optimizations.
 *
 * @private
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is a typed array, else `false`.
 */

/**
 * The base implementation of `_.iteratee`.
 *
 * @private
 * @param {*} [value=_.identity] The value to convert to an iteratee.
 * @returns {Function} Returns the iteratee.
 */

/**
 * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 */

/**
 * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 */

/**
 * The base implementation of `_.lt` which doesn't coerce arguments.
 *
 * @private
 * @param {*} value The value to compare.
 * @param {*} other The other value to compare.
 * @returns {boolean} Returns `true` if `value` is less than `other`,
 *  else `false`.
 */

/**
 * The base implementation of `_.map` without support for iteratee shorthands.
 *
 * @private
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns the new mapped array.
 */

/**
 * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
 *
 * @private
 * @param {string} path The path of the property to get.
 * @param {*} srcValue The value to match.
 * @returns {Function} Returns the new spec function.
 */

/**
 * The base implementation of `_.matches` which doesn't clone `source`.
 *
 * @private
 * @param {Object} source The object of property values to match.
 * @returns {Function} Returns the new spec function.
 */

/**
 * The base implementation of `_.merge` without support for multiple sources.
 *
 * @private
 * @param {Object} object The destination object.
 * @param {Object} source The source object.
 * @param {number} srcIndex The index of `source`.
 * @param {Function} [customizer] The function to customize merged values.
 * @param {Object} [stack] Tracks traversed source values and their merged
 *  counterparts.
 */

/**
 * The base implementation of `_.orderBy` without param guards.
 *
 * @private
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by.
 * @param {string[]} orders The sort orders of `iteratees`.
 * @returns {Array} Returns the new sorted array.
 */

/**
 * The base implementation of `_.pick` without support for individual
 * property identifiers.
 *
 * @private
 * @param {Object} object The source object.
 * @param {string[]} paths The property paths to pick.
 * @returns {Object} Returns the new object.
 */

/**
 * The base implementation of `_.property` without support for deep paths.
 *
 * @private
 * @param {string} key The key of the property to get.
 * @returns {Function} Returns the new accessor function.
 */

/**
 * The base implementation of `_.range` and `_.rangeRight` which doesn't
 * coerce arguments.
 *
 * @private
 * @param {number} start The start of the range.
 * @param {number} end The end of the range.
 * @param {number} step The value to increment or decrement by.
 * @param {boolean} [fromRight] Specify iterating from right to left.
 * @returns {Array} Returns the range of numbers.
 */

/**
 * The base implementation of `_.reduce` and `_.reduceRight`, without support
 * for iteratee shorthands, which iterates over `collection` using `eachFunc`.
 *
 * @private
 * @param {Array|Object} collection The collection to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @param {*} accumulator The initial value.
 * @param {boolean} initAccum Specify using the first or last element of
 *  `collection` as the initial value.
 * @param {Function} eachFunc The function to iterate over `collection`.
 * @returns {*} Returns the accumulated value.
 */

/**
 * The base implementation of `_.rest` which doesn't validate or coerce arguments.
 *
 * @private
 * @param {Function} func The function to apply a rest parameter to.
 * @param {number} [start=func.length-1] The start position of the rest parameter.
 * @returns {Function} Returns the new function.
 */

/**
 * The base implementation of `_.set`.
 *
 * @private
 * @param {Object} object The object to modify.
 * @param {Array|string} path The path of the property to set.
 * @param {*} value The value to set.
 * @param {Function} [customizer] The function to customize path creation.
 * @returns {Object} Returns `object`.
 */

/**
 * The base implementation of `_.sortBy` which uses `comparer` to define the
 * sort order of `array` and replaces criteria objects with their corresponding
 * values.
 *
 * @private
 * @param {Array} array The array to sort.
 * @param {Function} comparer The function to define sort order.
 * @returns {Array} Returns `array`.
 */

/**
 * The base implementation of `_.times` without support for iteratee shorthands
 * or max array length checks.
 *
 * @private
 * @param {number} n The number of times to invoke `iteratee`.
 * @param {Function} iteratee The function invoked per iteration.
 * @returns {Array} Returns the array of results.
 */

/**
 * The base implementation of `_.toString` which doesn't convert nullish
 * values to empty strings.
 *
 * @private
 * @param {*} value The value to process.
 * @returns {string} Returns the string.
 */

/**
 * The base implementation of `_.trim`.
 *
 * @private
 * @param {string} string The string to trim.
 * @returns {string} Returns the trimmed string.
 */

/**
 * The base implementation of `_.unary` without support for storing metadata.
 *
 * @private
 * @param {Function} func The function to cap arguments for.
 * @returns {Function} Returns the new capped function.
 */

/**
 * The base implementation of `_.uniqBy` without support for iteratee shorthands.
 *
 * @private
 * @param {Array} array The array to inspect.
 * @param {Function} [iteratee] The iteratee invoked per element.
 * @param {Function} [comparator] The comparator invoked per element.
 * @returns {Array} Returns the new duplicate free array.
 */

/**
 * The base implementation of `_.values` and `_.valuesIn` which creates an
 * array of `object` property values corresponding to the property names
 * of `props`.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {Array} props The property names to get values for.
 * @returns {Object} Returns the array of property values.
 */

/**
 * The base implementation of `assignValue` and `assignMergeValue` without
 * value checks.
 *
 * @private
 * @param {Object} object The object to modify.
 * @param {string} key The key of the property to assign.
 * @param {*} value The value to assign.
 */

/**
 * The base implementation of `baseForOwn` which iterates over `object`
 * properties returned by `keysFunc` and invokes `iteratee` for each property.
 * Iteratee functions may exit iteration early by explicitly returning `false`.
 *
 * @private
 * @param {Object} object The object to iterate over.
 * @param {Function} iteratee The function invoked per iteration.
 * @param {Function} keysFunc The function to get the keys of `object`.
 * @returns {Object} Returns `object`.
 */

/**
 * The base implementation of `getAllKeys` and `getAllKeysIn` which uses
 * `keysFunc` and `symbolsFunc` to get the enumerable property names and
 * symbols of `object`.
 *
 * @private
 * @param {Object} object The object to query.
 * @param {Function} keysFunc The function to get the keys of `object`.
 * @param {Function} symbolsFunc The function to get the symbols of `object`.
 * @returns {Array} Returns the array of property names and symbols.
 */

/**
 * The base implementation of `getTag` without fallbacks for buggy environments.
 *
 * @private
 * @param {*} value The value to query.
 * @returns {string} Returns the `toStringTag`.
 */

/**
 * The base implementation of `setToString` without support for hot loop shorting.
 *
 * @private
 * @param {Function} func The function to modify.
 * @param {Function} string The `toString` result.
 * @returns {Function} Returns `func`.
 */

/**
 * The base implementation of methods like `_.max` and `_.min` which accepts a
 * `comparator` to determine the extremum value.
 *
 * @private
 * @param {Array} array The array to iterate over.
 * @param {Function} iteratee The iteratee invoked per iteration.
 * @param {Function} comparator The comparator used to compare values.
 * @returns {*} Returns the extremum value.
 */

/**
 * This base implementation of `_.zipObject` which assigns values using `assignFunc`.
 *
 * @private
 * @param {Array} props The property identifiers.
 * @param {Array} values The property values.
 * @param {Function} assignFunc The function to assign values.
 * @returns {Object} Returns the new object.
 */

/**
 * This function is like
 * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)
 * except that it includes inherited enumerable properties.
 *
 * @private
 * @param {Object} object The object to query.
 * @returns {Array} Returns the array of property names.
 */

/**
 * This function is like `arrayIncludes` except that it accepts a comparator.
 *
 * @private
 * @param {Array} [array] The array to inspect.
 * @param {*} target The value to search for.
 * @param {Function} comparator The comparator invoked per element.
 * @returns {boolean} Returns `true` if `target` is found, else `false`.
 */

/**
 * This function is like `assignValue` except that it doesn't assign
 * `undefined` values.
 *
 * @private
 * @param {Object} object The object to modify.
 * @param {string} key The key of the property to assign.
 * @param {*} value The value to assign.
 */

/**
 * This method is like `_.assign` except that it recursively merges own and
 * inherited enumerable string keyed properties of source objects into the
 * destination object. Source properties that resolve to `undefined` are
 * skipped if a destination value exists. Array and plain object properties
 * are merged recursively. Other objects and value types are overridden by
 * assignment. Source objects are applied from left to right. Subsequent
 * sources overwrite property assignments of previous sources.
 *
 * **Note:** This method mutates `object`.
 *
 * @static
 * @memberOf _
 * @since 0.5.0
 * @category Object
 * @param {Object} object The destination object.
 * @param {...Object} [sources] The source objects.
 * @returns {Object} Returns `object`.
 * @example
 *
 * var object = {
 *   'a': [{ 'b': 2 }, { 'd': 4 }]
 * };
 *
 * var other = {
 *   'a': [{ 'c': 3 }, { 'e': 5 }]
 * };
 *
 * _.merge(object, other);
 * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] }
 */

/**
 * This method is like `_.clone` except that it recursively clones `value`.
 *
 * @static
 * @memberOf _
 * @since 1.0.0
 * @category Lang
 * @param {*} value The value to recursively clone.
 * @returns {*} Returns the deep cloned value.
 * @see _.clone
 * @example
 *
 * var objects = [{ 'a': 1 }, { 'b': 2 }];
 *
 * var deep = _.cloneDeep(objects);
 * console.log(deep[0] === objects[0]);
 * // => false
 */

/**
 * This method is like `_.find` except that it returns the index of the first
 * element `predicate` returns truthy for instead of the element itself.
 *
 * @static
 * @memberOf _
 * @since 1.1.0
 * @category Array
 * @param {Array} array The array to inspect.
 * @param {Function} [predicate=_.identity] The function invoked per iteration.
 * @param {number} [fromIndex=0] The index to search from.
 * @returns {number} Returns the index of the found element, else `-1`.
 * @example
 *
 * var users = [
 *   { 'user': 'barney',  'active': false },
 *   { 'user': 'fred',    'active': false },
 *   { 'user': 'pebbles', 'active': true }
 * ];
 *
 * _.findIndex(users, function(o) { return o.user == 'barney'; });
 * // => 0
 *
 * // The `_.matches` iteratee shorthand.
 * _.findIndex(users, { 'user': 'fred', 'active': false });
 * // => 1
 *
 * // The `_.matchesProperty` iteratee shorthand.
 * _.findIndex(users, ['active', false]);
 * // => 0
 *
 * // The `_.property` iteratee shorthand.
 * _.findIndex(users, 'active');
 * // => 2
 */

/**
 * This method is like `_.fromPairs` except that it accepts two arrays,
 * one of property identifiers and one of corresponding values.
 *
 * @static
 * @memberOf _
 * @since 0.4.0
 * @category Array
 * @param {Array} [props=[]] The property identifiers.
 * @param {Array} [values=[]] The property values.
 * @returns {Object} Returns the new object.
 * @example
 *
 * _.zipObject(['a', 'b'], [1, 2]);
 * // => { 'a': 1, 'b': 2 }
 */

/**
 * This method is like `_.isArrayLike` except that it also checks if `value`
 * is an object.
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is an array-like object,
 *  else `false`.
 * @example
 *
 * _.isArrayLikeObject([1, 2, 3]);
 * // => true
 *
 * _.isArrayLikeObject(document.body.children);
 * // => true
 *
 * _.isArrayLikeObject('abc');
 * // => false
 *
 * _.isArrayLikeObject(_.noop);
 * // => false
 */

/**
 * This method is like `_.min` except that it accepts `iteratee` which is
 * invoked for each element in `array` to generate the criterion by which
 * the value is ranked. The iteratee is invoked with one argument: (value).
 *
 * @static
 * @memberOf _
 * @since 4.0.0
 * @category Math
 * @param {Array} array The array to iterate over.
 * @param {Function} [iteratee=_.identity] The iteratee invoked per element.
 * @returns {*} Returns the minimum value.
 * @example
 *
 * var objects = [{ 'n': 1 }, { 'n': 2 }];
 *
 * _.minBy(objects, function(o) { return o.n; });
 * // => { 'n': 1 }
 *
 * // The `_.property` iteratee shorthand.
 * _.minBy(objects, 'n');
 * // => { 'n': 1 }
 */

/**
 * This method returns `false`.
 *
 * @static
 * @memberOf _
 * @since 4.13.0
 * @category Util
 * @returns {boolean} Returns `false`.
 * @example
 *
 * _.times(2, _.stubFalse);
 * // => [false, false]
 */

/**
 * This method returns `undefined`.
 *
 * @static
 * @memberOf _
 * @since 2.3.0
 * @category Util
 * @example
 *
 * _.times(2, _.noop);
 * // => [undefined, undefined]
 */

/**
 * This method returns a new empty array.
 *
 * @static
 * @memberOf _
 * @since 4.13.0
 * @category Util
 * @returns {Array} Returns the new empty array.
 * @example
 *
 * var arrays = _.times(2, _.stubArray);
 *
 * console.log(arrays);
 * // => [[], []]
 *
 * console.log(arrays[0] === arrays[1]);
 * // => false
 */

/**
 * This method returns the first argument it receives.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Util
 * @param {*} value Any value.
 * @returns {*} Returns `value`.
 * @example
 *
 * var object = { 'a': 1 };
 *
 * console.log(_.identity(object) === object);
 * // => true
 */

/**
 * Used by `_.orderBy` to compare multiple properties of a value to another
 * and stable sort them.
 *
 * If `orders` is unspecified, all values are sorted in ascending order. Otherwise,
 * specify an order of "desc" for descending or "asc" for ascending sort order
 * of corresponding values.
 *
 * @private
 * @param {Object} object The object to compare.
 * @param {Object} other The other object to compare.
 * @param {boolean[]|string[]} orders The order to sort by for each property.
 * @returns {number} Returns the sort order indicator for `object`.
 */

/**
 * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
 * character of `string`.
 *
 * @private
 * @param {string} string The string to inspect.
 * @returns {number} Returns the index of the last non-whitespace character.
 */

/**
 * Used to match `RegExp`
 * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
 */

/**
 * Used to resolve the
 * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
 * of values.
 */

/** Built-in value references. */

/** Detect free variable `exports`. */

/** Detect free variable `global` from Node.js. */

/** Detect free variable `self`. */

/** Error message constants. */

/** Used as references for various `Number` constants. */

/** Used as the maximum memoize cache size. */

/** Used as the size to enable large array optimizations. */

/** Used for built-in method references. */

/** Used to check objects for own properties. */

/** Used to compose bitmasks for cloning. */

/** Used to compose bitmasks for value comparisons. */

/** Used to compose unicode capture groups. */

/** Used to compose unicode character classes. */

/** Used to convert symbols to primitives and strings. */

/** Used to detect hot functions by number of calls within a span of milliseconds. */

/** Used to detect methods masquerading as native. */

/** Used to detect overreaching core-js shims. */

/** Used to detect unsigned integer values. */

/** Used to generate unique IDs. */

/** Used to match `RegExp` flags from their coerced string values. */

/** Used to match a single whitespace character. */

/** Used to match leading whitespace. */

/** Used to match property names within property paths. */

/** Used to resolve the decompiled source of functions. */

/** Used to stand-in for `undefined` hash values. */

/** `Object#toString` result references. */

/** power **/

/** r **/

/************************************************************************/

/******/

/***/

/*, conf*/

/*, eventObj*/

/*, extent*/

/*, listener, eventObj*/

//

//    composed of enough information to uniquely identify an edge: {v, w, name}.

//    console.log("base: " + basePoints);

//    edges up and, object properties, which have string keys, are the closest

//    reference edges. This is because we need a performant way to look these

//    we're going to get to a performant hashtable in JavaScript.

//   ". OffsetX: " + offX + ". OffsetY: " + offY;

//   context.fillStyle = cache.fillStyle = fillStyle;

//   context.strokeStyle = cache.strokeStyle = strokeStyle;

//   tentative gScore is less than previous value

//   w not present in openSet

//  ". Depth: " + depth);

//  ". Index: " + lca + " Contents: " + lcaGraph.toString() +

//  * Edge id query functions should return an "edgeObj", edge object, that is

//  * Internally we use an "edgeId", a stringified form of the edgeObj, to

//  * Node id query functions should return string ids for the nodes

//  return a random number or 4

// "Node centrality in weighted networks: Generalizing degree and shortest paths"

// #1582 safari doesn't load data uris with crossOrigin properly

// 'Give me everything from this box'

// 'TB' for top to bottom flow, 'LR' for left to right,

// 'core' is a special case and does not need a selector

// 'end' : Animate with the end result, from the initial positions to the end positions

// 'manual'

// 'orphan'

// (Coefficients are divided by 4)

// (and a request for recalc may come in between frames)

// (could be removed in a future major version)

// (disable eslint for next line as this serves as example layout code to external developers)

// (i.e. `left`, `auto`, etc)

// (i.e. there is an ele in between the eles in the layer)

// (may be removing more than specified due to connected edges etc)

// (otherwise intersection will yield nothing)

// (potentially expensive calculation)

// (prevents flashing on fast runs)

// (useful for init)

// (x, y) position pair

// (x2, y2) for fingers 1 and 2

// *2 b/c the stroke is drawn centred on the middle

// *2 radius guarantees outside shape

// - adding new props to an existing group gets handled automatically

// - adding the current slice would go beyond the full circle

// - bypass : true iff the property is a bypass property

// - bypasses can't be shared b/c the value can be changed by animations or otherwise overridden

// - collection of elements in the graph on selector arg

// - empty collection on no args

// - good for perf in certain cases but currently requires dirtying the rendered style

// - guarantee a returned collection when elements or collection specified

// - its bypass

// - mappings can't be shared b/c mappings are per-element

// - n.b. adding a new group of props may require updates to updateStyleHints()

// - name : the name of the property

// - strValue : a string value that represents the property value in valid css

// - try to use for only things like discrete layouts where the node position would change anyway

// - value : the parsed, native-typed value of the property

// - we're already beyond the full circle

// - what selectors match it

// - would be better to not modify the nodes but the nodes are read directly everywhere in the renderer...

// - zero size

// --

// -----

// .data('foo')

// .data('foo', 'bar')

// .data('foo', ...)

// .data({ 'foo': 'bar' })

// .pan('x')

// .pan('x', 100)

// .pan()

// .pan({ x: 0, y: 100 })

// .panBy('x', 100)

// .panBy({ x: 0, y: 100 })

// .removeData('foo bar')

// .removeData()

// 1 hash op vs n hash ops (for length n string)

// 1..N

// 50% reserved for white between the two borders

// @O Polygon drawing

// A contains the neighborhoods of every node

// A fast and simple ranker, but results are far from optimal.

// A feedback arc set is a set of edges that can be removed to make a graph acyclic.

// A function that determines whether the node should be animated

// A random force has already been applied as node repulsion

// Add additional probability based on damping factor

// Add cMin to processed nodes

// Add children nodes as a new graph to graph set

// Add children to que queue to be visited

// Add children to queue to be visited

// Add entry to id-index map

// Add methods to `Hash`.

// Add methods to `ListCache`.

// Add methods to `MapCache`.

// Add methods to `SetCache`.

// Add methods to `Stack`.

// Add new node

// Add node Id to parent's list of children

// Add properties assigned by `RegExp#exec`.

// Add root graph to graphSet

// Add this force to target and source nodes

// Aggregate weights on nodes, but also sum the weights across multi-edges

// All edges pointing to partition2 should now point to partition1

// All nodes animated by default on animate enabled

// Also, initialize a null vector which will be used as shorthand

// Also, take into account columns that have sum = 0

// An implementation of the Cardano method from the year 1545

// Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up

// Apply force

// Apply force to all nodes in graph

// Arc from bottom to left side

// Arc from left side to topBorder

// Arc from middle top to right side

// Arc from right side to bottom

// Assign nodes to clusters

// Assign nodes to clusters with highest probability.

// Assign x coordinates to all nodes

// Assume CCW polygon winding

// Assume cyclic values are equal.

// Assuming percentage is number from 0 to 1

// Begin Markov cluster algorithm

// Begin affinity propagation algorithm

// Both nodes are present in this subgraph

// Browser Event object

// Build clusters from matrix

// Build k centroids, each represented as an n-dim feature vector

// Calculate a weight that is sufficient to keep subgraphs vertically compact

// Calculate d, direction vector of line

// Calculate edge forces

// Calculate gravity forces

// Calculate node repulsions

// Calculate the distance between each pair of clusters

// Calculate the weighted crossings

// Calculates and returns node dimensions { x, y } based on options given

// Called on `layoutready`

// Called on `layoutstop`

// Cancel drag pan

// Case: Intersects the bottom border

// Case: Intersects the left border

// Case: Intersects the right border

// Case: Intersects the top border

// Case: Vertical direction (down)

// Case: Vertical direction (up)

// Check bottom right quarter circle

// Check endpoint of second line

// Check for circular references and return its corresponding clone.

// Check for convergence

// Check for negative weight cycles

// Check hBox

// Check if already process another edge between same 2 nodes

// Check if module is in cache

// Check if node n has a parent node

// Check if we are drag panning the entire graph

// Check source

// Check start point of second line

// Check target

// Check that both matrices have the same elements (i,j)

// Check that cyclic values are equal.

// Check to see if algorithm has converged, i.e. when centroids no longer change

// Check top left quarter circle

// Check top right quarter circle

// Check vBox

// Choose an edge randomly

// Choose arbitrary node from which to start our tree

// Clean up meta data used for clustering

// Coerce booleans to `1` or `0` and dates to milliseconds.

// Coerce parent to string

// Coerce regexes to strings and treat strings, primitives and objects,

// Collapse graph based on edge

// Compound edge

// Compute closeness for every node and find the maximum closeness

// Compute difference (squared module) of both vectors

// Compute dominant eigenvector using power method

// Compute graph center

// Compute ideal length

// Compute sum of node depths, relative to lca graph

// Compute the module and components of the force vector

// Computes the minimum cut of an undirected graph

// Constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }

// Construct result

// Contract until stop point (stopSize nodes)

// Cooling factor (how the temperature is reduced between consecutive iterations

// Coordinates for selection box, plus enabled flag

// Counter

// Create a copy of the colapsed nodes state

// Create a new module (and put it into the cache)

// Create a timestamp if incoming event doesn't have one

// Create border nodes and link them up

// Create indexToGraph map

// Create null matrix

// Current line: [currentPointX, currentPointY] to [nextPointX, nextPointY]

// DAG functions

// Defaults to be set when creating a new edge

// Defaults to be set when creating a new node

// Delete all edges between partition1 and partition2

// Dendrogram mode builds the hierarchy and adds intermediary nodes + edges

// Deselect all elements if nothing is currently under the mouse cursor and we aren't dragging something

// Determine which cluster the node is most likely to belong in

// Determine which cluster this node belongs to: node id => cluster #

// Direction vector of line

// Divisor to compute edge forces

// Do one step in the phisical simulation

// Don't include loops in the matrix

// Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.

// Easing of the animation for animate:'end'

// Edge functions

// Edges relaxation

// Either this is the first call, activity has stopped and we're at the

// End of main loop

// End of neighbors update

// Endpoint of first line

// Ensure the intersection is on the desired quarter of the circle

// Ensure the sign of `-0` is preserved.

// Ensure we add undirected edges in a consistent way.

// Event string

// Events bubbling up the document may have been marked as prevented

// Excludes the label when calculating node bounding boxes for the layout algorithm

// Execute the module function

// Exit early for strings to avoid a performance hit in some environments.

// Expand multi-edges

// Expose `MapCache`.

// Expose some internals for testing purposes

// Extra spacing between components in non-compound graphs

// Fallback for data views, maps, sets, and weak maps in IE 11 and promises in Node.js < 6.

// Finally, return layoutInfo object

// Find a path from v to w through the lowest common ancestor (LCA). Return the

// Find lowest common graph ancestor

// Find min, max values for each attribute dimension

// Find minimum distance by using the minimum of the distance

// Find the closest pair of clusters and merge them into a single cluster.

// Find their common ancester, starting from the root graph

// Find two closest clusters from cached mins

// First ensure the nodes exist.

// First pass, assign smallest coordinates

// First, get sum of all elements

// Fit the graph if necessary

// Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications

// Flag the module as loaded

// Font style

// For simplicity the layout will be:

// For small data sets, the probability of medoid conflict is greater,

// For the rest of this function we assume that v is the tail and w is the

// Format for each edge (edge index, source node index, target node index)

// Functions

// Functions to help with handling mouseout/mouseover on the Cytoscape container

// Functions to help with whether mouse wheel should trigger zooming

// G should be symmetric and undirected

// Generate stochastic matrix M from input graph G (should be symmetric/undirected)

// Generated by CoffeeScript 1.8.0

// Get Parent Node

// Get Parent node for this graph, and use its position as center

// Get all nodes that belong to this cluster

// Get all nodes that belong to this medoid

// Get clipping points for both nodes

// Get direction of line connecting both node centers

// Get edge, source & target nodes

// Get the node to visit and remove it from queue

// Gives negative angle

// Go through each of the graphs in graphSet

// Gravity force (constant)

// Handle invocations in a tight loop.

// Handle mouseout on Cytoscape container

// Ideal edge (non nested) length

// Identify exemplars (cluster centers)

// If a node doesn't have a parent, then it's in the root graph

// If both centers are the same, apply a random force

// If both centers are the same, do nothing.

// If both nodes belongs to graphIx

// If difference is less than the desired threshold, stop iterating

// If nodes overlap, repulsion force is proportional

// If required, randomize node positions

// If set to 'greedy', uses a greedy heuristic for finding a feedback arc set for a graph.

// If something is under the cursor and it is draggable, prepare to grab it

// If the node has no child, skip it

// If the root is in the tail of the edge then we need to flip the logic that

// If there's no overlap, force is inversely proportional

// If undirected graph, process 'reversed' edge

// If undirected graph, we need to take into account the 'reverse' edge

// If updated boundaries, propagate changes upward

// If we've already chosen this node to be a medoid, don't choose it again (for small data sets).

// If we've found our goal, then we are done

// If we've reached here, then we've not reached our goal

// Ignore non-index properties.

// Implementation notes:

// Implemented by Zoe Xi @zoexi for GSOC 2016

// Implemented from pseudocode from wikipedia

// Implemented from the algorithm in Opsahl's paper

// Implemented from the algorithm in the paper "On Variants of Shortest-Path Betweenness Centrality and their Generic Computation" by Ulrik Brandes

// In agglomerative (bottom-up) clustering, each node starts as its own cluster

// Includes only the "core" of graphlib

// Initial temperature (maximum node displacement)

// Initializations { dist, pred, edge }

// Initialize A availability matrix

// Initialize R responsibility matrix

// Initialize and build S similarity matrix

// Initialize distance matrix

// Initialize layout info

// Initialize matrix used for path reconstruction

// Initialize selection box coordinates

// Inline implementation of a queue, used for traversing the graph in BFS order

// Instead choose a different random node.

// Instead of their algorithm we construct a new block graph and do two

// Intersection is left or right of rect.

// Intersection is top or bottom of rect.

// Invalid dates are coerced to `NaN`.

// Invoke the leading edge.

// Is any of the 2 results the best cut so far?

// It didn't exist, so we need to create it.

// Iterate over all edges

// Iterate over all edges, creating Layout Edges

// Iterate over all nodes, creating layout nodes

// Join line

// L-shape (turn distance not respected, but works well for tree siblings)

// L-shape fallback (turn distance not respected, but works well with tree siblings)

// Label for the graph itself

// Layout has finished

// Legacy `process.binding('util')` for Node.js < 10.

// Limit displacement in order to improve stability

// Load entry module and return exports

// Lower temperature threshold (below this point the layout will end)

// M(i,j) ^ inflatePower

// Main loop

// Make recursive calls for all subgraphs

// MaxX

// MaxY

// Maximum number of iterations to perform

// Merge two closest clusters

// MinX

// MinY

// Misc functions

// Move all nodes from partition2 to partition1

// Multiply matrix with previous result

// Multiply minlen by nodeSep to align nodes on non-border ranks.

// N x C matrix

// NB alpha === 0

// NB don't write to cxtProp, as it's shared among eles (stored in stylesheet)

// NB no restore

// NB the animation loop will exec in headless environments if style enabled

// NB: context.selector may be null for 'core'

// NOTE: when something is added here, add also to ele.json()

// Needs reproject due to pan changing viewport

// Neighbourhood functions

// Nested for loop is OK; total number of iterations for both loops = edgeCount

// Nesting factor (multiplier) to compute ideal edge length for nested edges

// New tentative score for node w

// No 'links' out from node jth, assume equal probability for each possible node

// No need to randomize compound nodes or locked nodes

// No operation performed.

// Node jth has outgoing link, compute normalized probabilities

// Node repulsion (non overlapping) multiplier

// Node repulsion (overlapping) multiplier

// Node.js 0.10 has enumerable non-index properties on buffers.

// Nodes only repel each other if they belong to the same graph

// Non `Object` object instances with different constructors are not equal.

// Non-animated nodes are positioned immediately when the layout starts

// Now get all the pairs of nodes

// Now store edge destination as indexes

// Now, divide each by the sum of all elements

// Now, process edges

// Now, sum edge weights

// Now, sum incoming edge weights

// Now, sum outgoing edge weights

// Number of iterations between consecutive screen positions update

// OR

// Object.prototype.hasOwnProperty.call

// One of (node1, node2) is present in this subgraph

// Only get each pair once, (A, B) = (B, A)

// Only invoke if we have `lastArgs` which means `func` has been

// Padding on fit

// Parallel, coincident lines. Check if overlap

// PhantomJS 2 has enumerable non-index properties on typed arrays.

// Place preferences on the diagonal of S

// Plain object containing all event details

// Points to the end of the queue

// Possible values: network-simplex, tight-tree or longest-path

// Pre-compute control points

// Prepare to select the currently touched node, only if it hasn't been dragged past a certain distance

// Primary key

// Process edges

// Project mouse

// Propagate forces from parent to child

// Propagate offset

// Put explicitly provided properties onto the event object

// Randomize the initial positions of the nodes (true) or use existing positions (false)

// Randomly select k medoids from the n nodes

// Ranks may not start at 0, so we need to offset them

// Rasterize the layers, but only if container has nonzero size

// Re-project

// Recursively compare arrays (susceptible to call stack limits).

// Recursively compare objects (susceptible to call stack limits).

// Recursively convert values (susceptible to call stack limits).

// Recursively flatten arrays (susceptible to call stack limits).

// Recursively merge objects and arrays (susceptible to call stack limits).

// Recursively populate clone (susceptible to call stack limits).

// Regular mode simply returns the clusters

// Relatively large data set, so pretty safe to not check and just select random nodes

// Remove duplicate clusters due to symmetry of graph and M matrix

// Reset any `maxWait` timer.

// Reset boundaries for compound nodes

// Reset meta node partition

// Reset parent offsets

// Resize canvas

// Restart the timer.

// Return the exports of the module

// Returns the correct answer with high probability

// Right click button

// Round rectangle drawing

// Row-wise attractors and elements that they attract belong in same cluster

// Run 2 iterations starting in the stop state

// Safari 9 has enumerable `arguments.length` in strict mode.

// Save previous step

// Save the multiplier for node layers for later removal of empty border

// Second pass to add child information and

// Second pass, assign greatest coordinates

// See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details.

// See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.

// Segments (multiple straight lines)

// Select different medoid if its configuration has the lowest cost

// Self-edge

// Set DEBUG - Global variable

// Shorcuts

// Shortcut

// Shorthand

// Show LayoutInfo contents if debugging

// Simple, internal Object.assign() polyfill for options objects etc.

// Since these points depend on the radius length (which in turns depend on the width/height of the node) we will only pre-compute

// Single selection

// Skip index properties.

// Solves a cubic function, returns root in form [r1, i1, r2, i2, r3, i3], where

// Sort all of the edges between the north and south layers by their position

// Start at top middle

// Start by visiting the nodes in the root graph

// Start from an arbitrary node

// Start the timer for the trailing edge.

// Start with a vector of all 1's

// Step 1: Add self loops to each node, ie. add multFactor to matrix diagonal

// Step 1: Initialize centroid positions

// Step 1: Initialize k medoids

// Step 1: Initialize letiables.

// Step 2: Assign nodes to the nearest centroid

// Step 2: Assign nodes to the nearest medoid

// Step 2: Calculate the centroids for each step.

// Step 2: M = normalize( M );

// Step 3:

// Step 3: For each medoid m, and for each node assciated with mediod m,

// Step 3: For each of the k clusters, update its centroid

// Step 3: Update the partition matrix U.

// Step 4:

// Step 4: Check for convergence.

// Step 5: check to see if ~steady state has been reached

// Straight edge within bundle

// TODO ensure re-used

// TODO should be able to remove this when we incrementally update low lim

// TODO: implement a seeded random number generator.

// Take into account if graph is directed or not

// Tap event, roughly same as mouse click event for touch

// Tap, taphold

// Target depth

// Taxicab geometry with two turns maximum

// Temp array with all 0's

// The duration of the animation for animate:'end'

// The layout animates only after this many milliseconds for animate:true

// The module cache

// The require function

// The use of `Object#toString` avoids issues with the `typeof` operator

// These 3 fields related to tap, taphold events

// This also ensures a stable sort in V8 and other engines.

// This assumes we have only short edges!

// This gives the coefficients of the resulting cubic equation

// This portion of the algorithm differs from BK due to a number of problems.

// Tracks the last node in this layer scanned for crossings with a type-1

// Traverse from w to LCA

// Traverse matrix, column by column

// Traverse the graph, level by level,

// Traverse up from v to find the LCA

// Trigger layoutReady only on first call

// Turn every array into a collection of nodes

// Type of algorithm to assigns a rank to each node in the input graph.

// Update A availability matrix

// Update R responsibility matrix

// Update ancestry boudaries

// Update cached mins

// Update centroids by calculating avg of all nodes within the cluster.

// Update column sum

// Update distances between new cluster and each of the old clusters, and loop until threshold reached.

// Update distances with new merged cluster

// Update gScore for node w if:

// Update idealLength

// Update matrix

// Update positions based on calculated forces

// Update scores for neighbors of cMin

// Update size, position of compund nodes

// Update temperature

// Use `util.types` for Node.js 10+.

// Use the cubic solving algorithm

// We cache the position here based on the layering because the graph and

// We only need to process the node if it's compound

// We will store the best cut found here

// We've already found both nodes, no need to keep searching

// Whether to animate while running the layout

// Whether to fit the network view after when done

// [ p0, UnitVectorP0P1, p1, UniVectorP1P2, ..., pn, UnitVectorPnP0 ]

// [0] in case elements is an array of collections, rather than array of elements

// __webpack_public_path__

// `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247

// a caching layer for property parsing

// a class name has the same rules as a variable except it can't have a '.' in the name

// a function that applies a transform to the final node position

// a function that determines whether the node should be animated.  All nodes animated by default on animate enabled.  Non-animated nodes are positioned immediately when the layout starts

// a grabbable compound node below the ele => no passthrough panning

// a layer may want to use an ele cache of a higher level to avoid blurriness

// a restriction on whether to match this emitter

// a sorting function to order nodes at equal depth. e.g. function(a, b){ return a.data('weight') - b.data('weight') }

// a sorting function to order the nodes and edges; e.g. function(a, b){ return a.data('weight') - b.data('weight') }

// a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') }

// a value literal, either a string or number

// a variable name can have letters, numbers, dashes, and periods

// access data field

// accessible cy.style() function

// achromatic

// add ! variants to comparatorOp

// add @ variants to comparatorOp

// add a single css rule to the current context

// add alias prop for parsing

// add center point to style so bounding box calculations can use it

// add connected edge

// add connected edges

// add current node to the current options object and call degreeCentrality

// add descendant nodes

// add edges to dagre

// add nodes to dagre

// add one or many css rules to the current context

// add padding around text dims, as the measurement isn't that accurate

// add property to current context if valid

// add the elements

// add to target's animation queue

// add to the animation loop pool

// adding an edge invalidates the traversal cache for the connected nodes

// adding an edge invalidates the traversal caches for the parallel edges

// affects cluster granularity (the greater the value, the more clusters): M(i,j) / E(j)

// affects time of computation and cluster granularity to some extent: M * M

// against all other centroids

// aka DAG ancestors

// aka DAG descendants

// alias

// aliases

// aliases:

// alignment for rank nodes. Can be 'UL', 'UR', 'DL', or 'DR', where U = up, D = down, L = left, and R = right

// all non finite (e.g. Infinity, NaN) elements must be -Infinity so they go to the start

// allow access by name as well

// allow access of properties by name ( e.g. style.properties.height )

// allow custom renderer name to be re-used, otherwise use canvas

// allow exiting early

// allow for passing a wrapped jquery object

// allow rendering hints in top level options

// allowed metadata fields (i.e. allowed functions to use from Collection)

// allows a core instance to access extensions internally

// allows negative

// also add nodes and edges related to the topmost ancestor

// always add to drag

// always need redraw in case eles unselectable

// always override as haystack in case set to different type previously

// always store the body bounds separately from the labels

// always store the individual arrow bounds

// always store the unrotated label bounds separately

// an apply() while playing shouldn't do anything

// an edge may be implicitly dirty b/c of one of its connected nodes

// an element id (follows variable conventions)

// ancestor implicitly refs the subject

// ancestor query

// and explicit cy.destroy() is necessary to stop the loop

// and later queue the current layerset so we can get the proper quality level soon

// and use elefn and elesfn as shorthands to the prototypes

// animate

// animated

// any change invalidates the layers

// append a dummy stylesheet object on a real style object

// applied style contexts from the styler

// apply a property to the style (for internal use)

// apply pixel ratio

// apply selector

// apply the not op, but null vals for inequalities should always stay non-matching

// apply the style to the element based on

// apply to all property names

// approximate curve pts based on the two t values

// args to pass to ext

// array of bound listeners

// array of children

// array of connected edges

// as equal. See http://www.ecma-international.org/ecma-262/7.0/#sec-regexp.prototype.tostring

// assign orphan nodes to a new top-level depth

// assign the nodes a depth and index

// assume 60 frames per second

// assume bb

// attributes/features used to group nodes, ie. similarity values between nodes

// auto justfication : center

// auto justification : left

// auto justification : right

// auto resize

// autorewind

// availability matrix (1D array)

// avoid division by zero while keeping the overall expression close in value

// avoid duplicate style updates

// avoiding the overhead of the rest of the function

// b - result , a - numeric letiable

// b/c drawToContext() may be async w.r.t. redraw(), keep track of last texture frame

// b/c have to half width/height

// backwards compatibility

// because a rogue async texture frame would clear needDraw

// because cytoscape dagre creates a directed graph, and directed graphs use the node order as a tie breaker when

// because the bypassed property was already applied (and therefore parsed), we can just replace it (no reapplying necessary)

// because the pie properties are numbered, give access to a constant N (for renderer use)

// because we need to have up-to-date style (e.g. stylesheet mappers)

// before calculating rendered style (and pstyle might not be called yet)

// bellmanFord

// betweennessCentrality

// bezier-like or segment-like edge

// binary comparison op (used in data selectors)

// bind all the ready handlers registered before creating this instance

// bind to event

// boolean (unary) operators (used in data selectors)

// bounds cache of edge arrows

// bounds cache of element body, including overlay

// bounds cache of element body, w/o overlay

// bounds cache of labels

// box selection

// bring to front of queue

// build up the style to animate towards

// builds a style object for the 'core' selector

// but lazily -- only use non-default prop values to reduce the number of hashes

// but only if more than one node (can't overlap)

// but only if over threshold

// by a handler lower down the tree; reflect the correct value.

// bypass was overriding)

// bypasses are applied to an existing style on an element, and just tacked on temporarily

// cMin must be the source of edge if directed

// cache cycle (i.e. before fired events)

// cache of output of traversal functions

// cache of the current bounding box

// cached options

// caching large elements is not efficient

// calculate max size now based on potentially updated mappers

// calculate the node positions

// calculate the node value

// calculate the radius

// call onSet callback

// callback on layoutready

// callback on layoutstop

// callback to run

// callbacks on dequeue

// called on continuous layouts to stop them before they finish

// can be % or px only

// can be enum, deg, or rad only

// can only correct beziers for now...

// can only map to colours and numbers

// can replace only if same z-index

// can write to mapping, as it's a per-ele copy

// can't assign undefined

// can't be invalid or mapped

// can't centre pan to nothing

// can't create edge if one of its nodes doesn't exist

// can't create element if it has empty string as id or non-string id

// can't create element if one already has that id

// can't create element if prior id already exists

// can't create if source or target is not defined properly

// can't create this

// can't do anything without well defined properties

// can't fit to nothing

// can't get a spring w/ duration 0

// can't get from no eles

// can't make a mapper without a range

// can't make much of a mapper without a range

// can't override unless the context is active

// can't register if cytoscape unspecified

// can't replace node

// can't set to no eles

// can't set undefined imperatively, so use null

// can't transition if there's nothing previous to transition from

// can't zoom with invalid params

// cancel ctx gestures if the distance b/t the fingers increases

// case: one bb above other

// case: one bb below other

// case: one bb to left of other

// case: one bb to right of other

// chainability

// chaining

// chaining and exit early when batching

// change of state => possible change of style

// change to neighbor check

// change to target node check

// chars we need to escape in let names, etc

// cheap collection ref check

// cheap element ref check

// cheap length check

// check and update each ele

// check for cached value before calling function

// check for nodes not found by bfs

// check if bypass is null or empty string (i.e. indication to delete bypass property)

// check if ele has all of the passed classes

// check if ele has classes outside of those passed

// check if it's path and a field with the same name doesn't exist

// check if this number type also accepts special keywords in place of numbers

// check if value is a function used as a mapper

// check if value is mapped

// check if value must be an integer

// check if valueMin and valueMax are the same

// check if we need to delete the current bypass

// check non-rounded top side

// check the heading 2 "Degree"

// check the type and return the appropriate object

// check this first b/c it's the most common/performant case

// check to cancel taphold

// check to see if we have a compound graph or not

// check value is within range

// checks for the head and tail nodes in the candidates function below.

// checks under left refs the subject implicitly

// circ

// clean up refs etc.

// clean up shift

// clean up unused fields for new type

// clear b/c we've bound them all and don't want to keep it around in case a new core uses the same div etc

// clear holes

// clear mapping for current key

// clear out the key to req lookup

// clear the cache since we don't need it

// clear the cached points state

// clear the queue of future animations

// clearQueue

// closenessCentrality

// code from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript

// collect udpated elements (cascaded from the layers) and update each

// colours are simple, so just create the flat property instead of expensive string parsing

// combine forests for u and v

// common node/edge props

// common to all eles

// compare indices in the core (order added to graph w/ last on top)

// compound props

// compound split query

// connect with children

// connectedEdges() usually cached

// consider px values

// constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }

// construct components corresponding to each disjoint subset of nodes

// constructor

// context swipe

// context swipe cancelling

// continue regardless of error

// coordinates. The second sweep removes unused space by moving blocks to the

// copy

// core props

// create a fake namespace object

// create a new context from the specified selector string and switch to that context

// create a rendered position based on the passed position

// create a table of edge (src, tgt) => list of edges between them

// create and cache new shape

// create instance

// create mock ids / indexes maps for element so it can be used like collections

// create positions from levels

// create the renderer

// create with args

// crop zoom

// ctrl pt itself

// ctrpt

// cubic

// cut at root

// cy is automatically populated for us in the constructor

// cytoscape is first arg to ext

// dagre algo options, uses default value on undefined

// dagre can't handle edges on compound nodes

// damping factor between [0.5, 1)

// data

// data for the core

// data object

// debounced at least once.

// debug('distance for param ' + params[i] + ": " + Math.sqrt(distSquared));

// default easings

// default midpt for labels etc

// default number of layers to use

// default: child query

// default: descendant query

// define

// define __esModule on exports

// define aliases

// define getter function for harmony exports

// define visual style properties

// defining the topology of a graph, this sort function can help ensure the correct order of the nodes/edges.

// degreeCentrality

// degreeCentralityNormalized

// delay

// delete bypassed

// delete each non-empty key

// delete the property and use the default value on falsey value

// delete the property that the

// delta

// delta finger1

// delta time % value for initVal (allows animating out of init zero opacity)

// depth at which dendrogram branches are merged into the returned clusters

// depth of deepest parent

// dequeueing isn't necessary with an existing cache

// desktop safari pinch to zoom start

// destroy the renderer

// detect problematic cases for old browsers with bad images (cheaper than try-catch)

// didn't match any

// diffProps : { name => { prev, next } }

// direct draw fallback

// direct mapping

// directed edge with subject on the target

// disable nonstandard wheel events

// displayed suffices, since we will find zero area eles anyway

// distance metric to compare attributes between two nodes

// distance metric to compare nodes

// distance to s

// djb2/string-hash

// do a cheaper bb check

// do compound node sanity checks

// do nothing if args are invalid

// do the transform on creation to save cycles (it's the same for all eles)

// does selector match a single element?

// does the node have at least one pie piece?

// don't affect touch devices like iphone

// don't cut tree, simply return all nodes as 1 single cluster

// don't update with null dim

// don't update with zero area boxes

// done if none left

// done if touched all outgoers already

// down++;

// drag node

// dragging nodes

// draw the current view

// draw the full bounds of the graph

// duration 0 => jump to end so impl doesn't matter

// duration of animation in ms if enabled

// during all of the remaining frame time

// e -> edgeObj

// e -> label

// e.g. 'c-0-2' => true

// e.g. (private) cy.nodes().select(['tapselect'])

// e.g. 2 => [ layer1, layer2, ..., layerN ]

// e.g. already registered some info (e.g. readies) via jquery

// e.g. center

// e.g. cy.data() changed => recalc ele mappers

// e.g. cy.nodes().select( data, handler )

// e.g. cy.nodes().select( handler )

// e.g. cy.nodes().select()

// e.g. cytoscape({ container: $('#cy') })

// e.g. cytoscape.use( require('cytoscape-foo'), bar )

// e.g. extension('renderer', 'svg')

// e.g. middle

// each cache should check for sub-key diff to see that the update affects that cache particularly

// each element

// each iteration yields a component

// each node

// each visual style property has a type and needs to be validated according to it

// easing of animation if enabled

// easing of animation if enabled,

// edge arrows

// edge must be in set of calling eles

// edge props

// edge sanity checks to prevent the client from making serious mistakes

// edges

// edges connected to compound nodes can not be haystacks

// either .start() or .run() is defined, so autogen the other

// element's style is replaced by what's pointed to by the `bypassed`

// elements being animated

// elements in the graph

// elements is optional

// elements: []

// elements: { nodes: [], edges: [] }

// eles who had classes changed

// elesfn

// else

// else not right mouse

// empty => remove bypass

// empty collection => can't get any value

// empty collections don't need to notify anything

// end if props allow ani

// end init FCM

// end of main loop

// endpt

// enqueue v

// ensure edge is within calling collection and edge is not in cut

// ensure ele ref

// error

// eslint-disable-line no-constant-condition

// eslint-disable-line no-undef

// eslint-disable-line no-unused-vars

// eslint-disable-next-line no-unused-vars

// even if we're comparing numbers

// exclude any node that is a descendant of the calling collection

// exclude loops

// existing element should be updated

// exit each early on return false

// exit if destroy() called on core or renderer in between frames #1499 #1528

// exit if population failed

// exit on disabled

// exit on failure

// exit or we loop forever

// expand bounds by 1 because antialiasing can increase the visual/effective size by 1 on all sides

// expand to work around browser dimension inaccuracies

// expo

// expose public apis (mostly for extensions)

// expose the module cache

// expose the modules object (__webpack_modules__)

// expose to global cytoscape (i.e. window.cytoscape)

// extend

// extend the map if necessary

// extra checks for edges

// extra checks for nodes

// extra spacing around nodes when avoidOverlap: true

// extract classes from string

// fall back on plain caching if no layers

// fall back on step size

// fallback compatibility layer for ms pointer events

// fallback if no container (not 0 b/c can be used for dividing etc)

// fallback on source and target positions

// false : Just show the end result

// field in the bypass property (i.e. restoring the property the

// fields :

// fill in missing layout functions in the prototype

// filter

// final node

// find min distance we need to leave between nodes

// find the depths of the nodes

// find the metrics for each level

// find the offset

// find the segment we're on

// find top-level parent

// find unused col

// find unused row

// first

// first check enums

// first half of the rectangle

// first try the second last one in case it has space at the end

// fit padding

// fixes slow wheel events on ff/linux and ff/windows

// flatten the field (e.g. data.foo.bar)

// flatten the property if mapped

// floydWarshall

// for

// for 1 id #foo queries, just get the element

// for all nodes

// for backwards compatibility

// for bb

// for cases where two data points shouldn't be linked together

// for compound graphs, hitting edge may actually want a connected node instead (b/c edge may have greater z-index precedence)

// for context

// for contexts

// for each connected edge, add the edge and the other node

// for each ele

// for each element

// for each node

// for each node (U is N x C matrix)

// for each pair (src, tgt), create the ctrl pts

// for each pair id, the edges should be sorted by index

// for each prop

// for elements

// for eles

// for empty collection case

// for empty text, skip all processing

// for future timeline/animations impl

// for i eles

// for initial kick off

// for internal use

// for internal use only

// for j classes

// for listener

// for more details.

// for pair edges

// for pair ids

// for parsedProp:{ bypass: true }

// for parsedProp:{ bypass: true, deleteBypass: true }

// for parsedProp:{ mapped: truthy }

// for props

// for style mapping

// for the directed case, try to make the edges all go down (i.e. depth i => depth i + 1)

// for very outofdate browsers

// force num of columns in the grid

// force num of rows in the grid

// forces

// from https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection

// from is a selector string

// from pseudocode on wikipedia

// from val

// full event string

// full path and the LCA.

// fully updates (recalculates) the style for the elements

// function

// function between the given point and the curve

// function values can't be cached in all cases, and there isn't much benefit of caching them anyway

// general layout options

// generate a random number from 0 to 15

// generate a real style object from the dummy stylesheet

// generate different extreme alignments.

// get

// get a collection

// get ele or empty collection

// get elements if a selector is specified

// get hue

// get image, and if not loaded then ask to redraw when later loaded

// get json from cy.style() api

// get rid of leading whitespace

// get the cxt key

// get the internal parsed style object for the specified property

// get the leaf nodes in the DAG

// get the root nodes in the DAG

// get the specified css property as a rendered value (i.e. on-screen value)

// get the style key hashes per prop group

// get the weighted percent for an element based on its connectivity to other levels

// get whole object

// get/set the position relative to the parent

// get/set the rendered (i.e. on screen) positon of the element

// getDefaultExport function for compatibility with non-harmony modules

// gets a computed ele style object based on matched contexts

// gets css property from the core container

// gets the raw style for an element

// gets the rendered style for an element

// gets what an em size corresponds to in pixels relative to a dom element

// getting

// getting for an element may need to add to the id list b/c eles can share keys

// ghost

// ghost props

// go over each prop

// go to lower quality blurry frames when several m/b frames have been rendered (avoids flashing)

// greatest coordinates without violating separation.

// handle all eles

// handle edge arrow size

// handle edge dimensions (rough box estimate)

// handle label dimensions

// handle node dimensions

// has() is cheap

// hash of all clusters by key

// haystacks avoid the expense of pairInfo stuff (intersections etc.)

// head, so if we don't have this edge in the graph we should flip it to

// headless or style disabled

// height of layout area (overrides container height)

// higher priority callbacks executed first

// higher priority execs before lower one

// higher weight edges are generally made shorter and straighter than lower weight edges

// horizontal

// horizontal Z-shape (direction not respected)

// horizontal Z-shape (turn distance not respected)

// horizontal fallbacks

// how many radians should be between the first and last node (defaults to full circle)

// html dom ele container

// http://en.wikipedia.org/wiki/Cubic_function#The_nature_of_the_roots

// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html

// https://bugs.webkit.org/show_bug.cgi?id=123978

// id => position

// id is finalised, now let's keep a ref

// id must be string

// ideal routing

// ie10 issue #1014

// if

// if a layer has been or will be replaced, then don't waste time with it

// if a layer is going to be replaced, queuing is a waste of time

// if a ready callback is specified as an option, the bind it

// if a selector is specified, then filter by it instead

// if already computed style, returned cached copy

// if bezier ctrl pts can not be calculated, then die

// if children take up zero area then keep position and fall back on stylesheet w/h

// if displayed

// if ellipsize

// if in a layer the eles are not in the same order, then the layer is invalid

// if is edge

// if listener matches

// if no options specified, use default

// if node is in closedSet, ignore it

// if node shapes overlap, then no ctrl pts to draw

// if not a number and enums not allowed, then the value is invalid

// if not handled by above, give 'em an empty collection

// if nothing currently animating, get something from the queue

// if outside the rough bounding box for the bezier, then it can't be a hit

// if pan dragging or cxt dragging, wheel movements make no zoom

// if preventDefault exists run it on the original event

// if rounding was too low, add rows or columns

// if rows or columns were set in options, use those values

// if specified parent

// if stopPropagation exists run it on the original event

// if target is outisde cy container, then this event is not for us

// if texture has been mostly filled and passed over several times, remove

// if the current level is incomplete, then use the closest, best quality layerset temporarily

// if the last one doesn't exist, we need a first one

// if the layer has all its eles done, then remove from the queue

// if the layer is invalid, the level is not complete

// if the prop change makes the bb of pll bezier edges invalid,

// if the property is a bypass property, then link the resultant property to the original one

// if the replaced layer is not in the active list for the level, then replacing

// if there are any eles needed to be drawn yet, the level is not complete

// if there's no room in the current texture, we need a new one

// if there's remaining text, put it in a wrapped line

// if this get was on an unused/invalidated cache, then restore the texture usage metric

// if this is a replacement layer that has been superceded, then forget it

// if update is a request from the ele cache, then it affects only

// if we aren't in a tick that causes a draw, then the rendered style

// if we can't flatten the property, then don't apply and fall back on the existing style

// if we can't flatten the property, then don't apply the property and fall back on the existing style

// if we're close to the edge but didn't hit it, maybe we hit its arrows

// if we're doing a case insensitive comparison, then we're using a STRING comparison

// if we're rendering faster than the ideal fps, then do dequeueing

// if( !isBypass ){

// if( cache.fillStyle !== fillStyle ){

// if( cache.strokeStyle !== strokeStyle ){

// if( tmpLayers ){

// if( y3 < y ){

// ignore

// ignore edges who are not to be displayed

// ignore group -- immutable

// ignore if

// ignore zero size case

// img

// implemented from pseudocode from wikipedia

// impossible to map to num

// in Safari 9 which returns 'object' for typed arrays and other constructors.

// in addition to returning the clusters.

// in case selector passed

// in case the user accidentally doesn't use camel case

// in case we used the `concentric` in style

// in future, this could potentially be allowed if there were operator precedence and detection of invalid combinations

// in place merge on calling collection

// in the north layer and then the south. Map these edges to the position of

// included extensions

// indicate that we actually did drag the node

// indicates this is an element

// info for parent query

// init dictionaries

// init style

// init zoom bounds

// initial load

// initialize queue for hierarchical traversal

// insure it's an element

// intermediate parents may be moved by prior line, so make sure we remove by fresh refs

// internal helper to get nodes and edges as separate collections with single iteration over elements

// into a single edge for the fasGraph.

// invalid

// invalid alpha value

// invalid channel value

// invalid gradient style

// invalidate all entries in the cache if the cache size is small

// it as the trailing edge, or we've hit the `maxWait` limit.

// it from the queue so we don't need to waste time looking at it to put new things

// it's done

// just go over all elements rather than doing a bunch of (possibly expensive) traversals

// just remove it if we don't want to consider holes

// just send to all eles

// just set the property

// just set the zoom

// just store the property to be parsed later

// just store the selector to be parsed later

// just to have some nice spacing

// just used for identifying when debugging

// keep a reference to the mapping

// keep nodes first in the array and edges after

// keep the prototypes in sync (an element has the same functions as a collection)

// key => true if immutable

// keys for style blocks, e.g. ttfftt

// kruskal's algorithm (finds min spanning tree, assuming undirected graph)

// label dims

// labels

// larger preference = greater # of clusters

// last visited node in the previous layer that is incident on an inner

// layer itself along the way

// layer.eles = [];

// layering may be out of sync. The layering matrix is manipulated to

// layers.

// left

// let changedEles = style.apply( updatedEles );

// let cy = ele.cy();

// let down = 0;

// let the core know we have a compound graph

// let the renderer know we've updated style

// let the renderer schedule animations

// let the token populate the selector object in currentQuery

// lightness is [0, 100]

// line is already short enough

// line is too long

// linkage criterion : how to determine the distance between clusters of nodes

// list of listeners

// list of property names

// load all data asynchronously, then exec rest of init

// load bg image

// log('--');

// log('--\nget layers with %s eles', eles.length);

// log('apply replacement layer %s over %s', layer.id, replaced.id);

// log('dequeue layer %s', layer.id);

// log('dequeue of layer %s complete', layer.id);

// log('do layers');

// log('draw ele %s in layer %s', ele.id(), layer.id);

// log('invalidate based on ordering', layer.id);

// log('invalidate layer', layer.id );

// log('layer %s in queue skipped b/c it already has a replacement', layer.id);

// log('layer is no longer the most uptodate replacement; dequeued', layer.id)

// log('level complete, using existing layers\n--');

// log('make new layer for ele %s', ele.id());

// log('queue ele %s in layer %s', ele.id(), layer.id);

// log('queue replacement layer refinement', rLyr.id);

// log('refine', eles.length);

// log('replacement layer %s is invalid; dequeued', layer.id);

// log('reuse layer for', ele.id());

// log('skip layers');

// log('update invalidate layer time from eles');

// log('update invalidate layer time');

// logDebug("Resetting boundaries of compound node: " + n.id);

// logDebug('LCA of nodes ' + tempEdge.sourceId + ' and ' + tempEdge.targetId +

// logDebug('propagateForces');

// logDebug(s);

// look at all the edges in the collection

// look at edges connected to the src node of this edge

// loop :)

// loops must be bundled beziers

// main algorithmic loop

// maintain chainability

// maintain chaining

// make a regex from the type string

// make elements from json and restore all at once later

// make sure container assoc'd reg points to this cy

// make sure layout has _private for use w/ std apis like .on()

// make sure newly created elements have valid ids

// make sure src/tgt distinction is consistent w.r.t. pairId

// make sure the nodes have a defined position

// make sure the property name is in dash form (e.g. 'property-name' not 'propertyName')

// make sure to bound percent value

// make the element array-like, just like a collection

// make the list of elements to remove

// manage the animation loop ourselves

// manually hook and run the animation

// map ( className => true )

// map aliases

// map integer range [0, 100] to [0, 1]

// map of (node id) => (position obj); or function(node){ return somPos; }

// mappers not allowed in bypass

// mark as removed

// mark self as parent and remove from data

// mark the cache as invalidated

// match the correct orientation.

// max number of iterations to run

// maximum number of iterations of the MCL algorithm in a single run

// maybe e.altKey

// memoized version of position function

// micro-optimisation vs Object.assign() -- reduces Element instantiation time

// micro-optimised for renderer

// mid source

// mid target

// middle

// might not be a number if it allows enums

// min & max are numeric

// min dist between nodes

// min number of iterations to run in order for clustering to stop

// min spacing between outside of nodes (used for radius adjustment)

// minimum cost configuration for each cluster

// mode & 1: value is a module id, require it

// mode & 2: merge all properties of value into the ns

// mode & 4: return value when already ns object

// mode & 8|1: behave like require

// mode:'dendrogram' => the nodes are organised as leaves in a tree (siblings are close), merging makes clusters

// mode:'threshold' => clusters must be threshold distance apart

// modes store cluster values differently

// more efficient to manually copy fields we use

// motionblur: blit rendered blurry frames

// mouse already handled

// move node to new parent

// multi or single unbundled

// must all be percent values if one is

// must be an instance of Error to pass testing

// must have an element and must be a node to return position

// must have at least row or col def'd

// must manually notify since trigger won't do this automatically once removed

// n.b. most layouts would use layoutPositions(), instead of positions() and manual events

// n.b. no spaces b/c of multiple support

// n.b. partitions are included to be compatible with the old api spec

// n.b. selectors that are starting substrings of others must have the longer ones first

// n.b. this flag should be set before apply() to avoid potential infinite recursion

// n.b. use cached key, not newly computed key

// n.b. use stored key rather than current (potential key)

// n.positionX + ", " + n.positionY + ").";

// name-value pair

// nb affects initial application on mapped values like control-point-distances

// nb negative because similarity should have an inverse relationship to distance

// need a bypass if one doesn't exist

// need a copy since props are mutated later in their lifecycles

// need check in case of loop

// need several frames before even high quality motionblur

// need to calc these after endpts

// need to fill bg at end like this in order to fill cleared transparent pixels in jpgs

// needs to be started by animation loop

// neighbourhood

// new context means new index

// next iteration of the animation loop, the animation

// nice, short mathematical alias

// no after specified => first layer made so put at start

// no context prop means delete

// no existing prop means nothing needs to be removed

// no more box selection if we don't have three fingers

// no need to remove

// no parent node: no nodes to add to the drag layer

// no property is generated, instead the bypass property in the

// no type, no luck

// node

// node gradient

// node must be in set of calling eles

// node pie bg

// node props

// nodes are removed last

// non-existant parent; just remove it

// non-ideal routing

// nonzero is truthy

// normalise on [0, 1]

// normalise value in ms

// normalise value in pixels

// normalise value in rad

// normalised delta

// normalize value in %

// normally called children in graph theory

// normally called parents in graph theory

// not a valid mapping

// not active bg now

// not possible to do on non-compound graphs or with the style disabled

// not set => px

// not supported

// not using def opts => need to build up bb from combination of sub bbs

// not valid if immutable

// nothing to animate

// nothing to do

// nothing to do really

// notify renderer

// notify the renderer of queued eles and event types

// now it's a string

// now pan to middle

// now populating the neighbor with following expressions

// now populating the right side's child

// now populating the right side's descendant

// now populating the target with the following expressions

// now, add the elements to the drag layer if not done already

// now, apply the bypass properties on the elements

// now, convert to rgb

// now, restore each element

// now, this function flattens the property, and here's how:

// number literal (used in data selectors) --- e.g. 0.1234, 1234, 12e123

// number of ranks to keep between the source and target of the edge

// numbers are cheaper to hash than strings

// object for currently-running animations

// object in which the renderer can store information

// offset from non-finite values

// on by default

// on layoutready

// on layoutstop

// only allow explicit units if so set

// only for beziers -- so performance of other edges isn't affected

// only get influenced by elements above

// only one edge in node if loop

// only update if dirty and in graph

// only update if not display: none

// only useful in specific cases like animation

// onready

// optimisation for single ele call

// optional alpha

// optional self loops for each node. Use a neutral value to improve cluster computations.

// options : object containing layout options

// or get the whole rendered style if no property specified (NB doesn't allow setting)

// original cost

// otherise keep track of drag delta for later

// otherwise just remove ele from req

// otherwise save drag delta for when we actually start dragging so the relative grab pos is constant

// otherwise set automatically

// otherwise should be added

// otherwise, copy from json

// otherwise, the opaque arrow clears it for free :)

// overall style key

// overlay

// override pan & zoom w/ fit if set

// override pan w/ center if set

// override pan w/ panBy if set

// override zoom (& potentially pan) w/ zoom obj if set

// padding on fit

// padding used on fit

// pageRank

// panning

// panning disabled

// parent implicitly refs the subject

// parent is immutable via data()

// parent query

// parent ref

// parse a property; return null on invalid; return parsed property otherwise

// parse the block of properties and values

// parse the selector

// parse to validate

// pc query takes over

// per-group keys of style property values

// percent can't push beyond 1

// point to intersect with source shape

// points are in clockwise order, inner (imaginary) triangle pt on [4, 5]

// populate the subject and replace the q at the old spot (within left) with TRUE

// position but no notification to renderer

// position the nodes

// positive spacing factor, larger => more space between nodes (N.B. n/a if causes overlap)

// precise edges

// prepend a stylesheet in the head such that

// prevent the dragging from triggering text selection on the page

// prevents node overlap, may overflow boundingBox and radius if not enough space

// prevents node overlap, may overflow boundingBox if not enough space

// private helper to get bounding box for custom node positions

// private: clears dirty flag and recalculates style

// project control point along line from src centre to outside the src shape

// project control point along line from tgt centre to outside the tgt shape

// prop is not bypass

// properties as set by the style

// properties for style sent from the renderer to the core

// pt outside src shape to calc distance/displacement from src to tgt

// pull in animation functions

// put all the properties (can specify one or many) in an array after parsing them

// put depths in concentric circles if true, put depths top down if false

// put in array if not array-like

// put lone nodes at the start

// put the grab target nodes last so it's on top of its neighbourhood

// put the parsed block in the style

// put the property in the style objects

// put the values into levels

// put to end of array if edge

// put to front of array if node

// puts all nodes at (0, 0)

// quad

// quart

// queries are separated by commas, e.g. edge[foo = 'bar'], node.someClass

// queue

// queue of element draw requests at different scale levels

// queue of element draw requests at different scale levels (element id lookup)

// queue won't automatically be flushed before dequeueing starts

// quint

// r is the real component, i is the imaginary component

// r.registerBinding(r.container, 'DOMMouseScroll', wheelHandler, true);

// r.registerBinding(r.container, 'MozMousePixelScroll', wheelHandler, true); // older firefox

// r.registerBinding(r.container, 'mousewheel', wheelHandler, true);

// random initial value

// re-use array

// read the calculated css style of the element or override the style (via a bypass)

// recalc endpts

// record starting points for pinch-to-zoom

// redraw/restore path if steps after pie need it

// reducing the small side takes away the most cells, so try it first

// refs would be a mistake (i.e. overwriting the true active layer)

// regex for matching event strings (e.g. "click.namespace")

// regex matches

// registers the extension on a cytoscape lib ref

// regular colours

// remove all contexts

// remove child => parent ref

// remove comments from the style string

// remove data field

// remove dragged eles

// remove ele

// remove elements from list of currently animating if its queues are empty

// remove eles in place on calling collection

// remove from queue

// remove from queue since the old req was for the old state

// remove if last ele in the req

// remove old elements

// remove parent => child ref

// remove parent reference

// remove reference to parent

// remove references to this edge in its connected nodes

// remove single ele in place in calling collection

// remove space from the texture it belongs to

// remove the invalid layers; they will be replaced as needed later in this function

// remove the parsed property and value from the remaining block text to parse

// remove the parsed selector and block from the remaining text to parse

// remove the refs from the eles to the caches:

// removeData

// removing an edge invalidates the traversal caches for the parallel edges

// removing an edges invalidates the traversal cache for its nodes

// renderedPosition overrides if specified

// replace empty spot with last ele in collection

// replace level ref

// replace refs in eles

// replace useCapture w/ opts obj

// replaced by build system

// reset any line dashes

// reset drag elements, since near will be added again

// reset ele area in texture

// reset for next touchstart

// reset in case we changed the border style

// reset transform by applying inverse

// resizing resets the style

// restore the elements if we created them from json

// retire the texture from the active / searchable queue:

// retire the texture if its utility is low

// return null on property of unknown name

// return true if at least one succesful bypass applied

// return value of _.map([]) for Lodash 3

// return value of _.map([null])

// returns numeric value for each node, placing higher nodes in levels towards the centre

// returns transformed text string

// returns true if no other eles reference the invalidated cache (n.b. other eles may need the cache with the same key)

// returns true iff application was successful for at least 1 specified property

// returns whether application was successful

// returns { row, col } for element

// reuse layer for later eles

// reverse order for precedence

// root may contain only edges

// runs the layout

// s += " New Position: (" + n.positionX + ", " + n.positionY + ").";

// s += ". No changes in boundaries/position of parent node " + p.id;

// s += ".\nResult: (" + res.x + ", " + res.y + ")";

// s += "\n Children: " + children.toString();

// s += "\n###############################\n";

// s += "\nNodes DO overlap.";

// s += "\nNodes do NOT overlap.";

// s += "\nOverlap: " + overlap;

// s += "\nSTEP: " + step;

// s += "\nUp direction";

// s += "\ndirectionX: " + directionX + ", directionY: " + directionY;

// s = "Center found at: " + centerX + ", " + centerY;

// s = "Node: " + n.id + " Previous position: (" +

// s = "Node: " + node.id;

// s = "Set: " + graph.toString();

// s = 'Triggering layoutready';

// s.t. no nodes overlapping

// safari on ios pans the page otherwise (normally you should be able to preventdefault on touchmove...)

// safety check -- not strictly necessary as no props of zero range should be passed here

// same instance => just restore

// sanitise the dimensions for external layouts (avoid division by zero)

// saturation is [0, 100]

// save cycles

// save cycles if mouse events aren't to be captured

// save cycles when a mapped context prop doesn't need to be applied

// save cycles when batching -- but bounds will be stale (or not exist yet)

// save cycles when no style used

// save cycles when the context prop doesn't need to be applied

// save recalc if the label is the same as before

// scratch object for core

// scratch objects

// sdbm/string-hash

// search the graph like jQuery

// second half of the rectangle

// second node is subject

// see if we have a manual position set

// segment.

// select the node with the lowest configuration cost as new medoid.

// set

// set compound parents

// set id and validate

// set one dimension

// set or get property

// set selection type

// set the value

// set transform to arrow position/orientation

// set up canvas context with font

// set up the right q

// set up the root compound q

// set whole position

// set zoom about position

// setup styles

// several types also allow enums

// shift applied to cached bb to be applied on next get

// shift by margin and expand by outline and border

// shift points so that the distance between the cross points matches edge width

// short alias

// sigma

// sine

// skip = b/c != is explicitly defined

// skip ops that explicitly contain !

// skip this property in the block

// skip this selector and block

// so borders are square with the node shape

// so text outlines aren't jagged

// so that children are not removed w/parent

// so the layer level might not equal the ele level

// so we always have Promise.all()

// so we need to check to see if we've already seen or chose this node before.

// sort each level to make connected nodes closer

// sort node values in descreasing order

// source

// source and target are immutable via data()

// source/target

// special colour names

// specified s.t. the cache is used, so check for this case to make it faster by

// specify an array of options

// specify options for one element

// specify via opts.nodes and opts.edges

// start at 12 o'clock

// start at 12 o'clock and go clockwise

// start with one forest per node

// start with the default stylesheet so we have something before loading an external stylesheet

// startpt

// static function

// static impl by name

// step and remove if done

// stepAll

// stepElement

// stop

// stop right click menu from appearing on cy

// store each ctrlpt info init

// store in the path cache with values easily manipulated later

// stretch factors

// string literals (used in data selectors) -- doublequotes | singlequotes

// string; 'nodes' or 'edges'

// success

// suitability of a data point to serve as an exemplar

// sw, sh

// swap styles

// sweeps. The first sweep places blocks with the smallest possible

// sx, sy

// take impl from registrant

// take into account edge width

// take the checks from the left

// target

// target to source index

// temporarily cache the value in case of a miss

// that causes it, under certain circumstances, to provide the same value for

// the active bg indicator should be removed when making a swipe that is neither for dragging nodes or panning

// the animation loop will apply the animation at this progress

// the animation loop will start the animation...

// the collection is now 1 ele smaller

// the distance threshold

// the effective texture level

// the eles in the layer must be in the same continuous order, else the layer is invalid

// the event namespace (e.g. ".foo")

// the event type (e.g. 'click')

// the flattened (mapped) property is the one we want

// the generated flattenedProp:{ bypassed: parsedProp }

// the generated flattenedProp:{ mapping: prop }

// the label already fits

// the list of textures in which new subtextures for elements can be placed

// the list of usused textures which can be recycled (in use in texture queue)

// the main usecase is ele.boundingBox() for a single element with no/def options

// the matching level

// the midpt between ctrlpts as intermediate destination pts

// the nearest cache with a higher level

// the nearest cache with a lower level

// the node may have not been assigned a cluster if no valid attributes were specified

// the old start global pos'n may not be the same finger that remains

// the padding on fit

// the pan level to set (prob want fit = false if set)

// the parent-child query takes the place of the query previously being populated

// the parents who were modified by the removal need their style updated

// the previous query contains the checks for the parent

// the previous value is good for an animation only if it's different

// the property may be an alias

// the query in the selector should be the '>' itself

// the query in the selector should be the edge rather than the source

// the query in the selector should be the neighbourhood rather than the node

// the radius of the circle

// the renderer can't add tick callbacks when destroyed

// the renderer can't be notified after it's destroyed

// the renderer can't be used for calcs when destroyed, e.g. ele.boundingBox()

// the roots of the trees

// the separation between adjacent edges in the same rank

// the separation between adjacent nodes in the same rank

// the traversal cache should start fresh when ele is added

// the unit vectors.

// the variation of concentric values in each level

// the zoom level to set (prob want fit = false if set)

// their head in the south layer.

// then add everything up and down for compound selector checks

// then add extra bounding box constraint

// then assume preparsed array

// then automake string

// then define w/ name

// then delete all keys

// then dirty the pll edge bb cache as well

// then don't apply and fall back on the existing style

// then dragging can happen

// then edge

// then extend the bypass

// then extra clear is needed

// then get the list of keys, and delete them

// then get the property from the style

// then just replace the old prop with the new one

// then keep the orig prop (since it's a bypass) and link to the new prop

// then make a prop of it

// then parse each property

// then parse the single property

// then replace existing edge

// then replace the bypass property with the original

// then selection overrides

// then set the bypass with the property value

// then set the zoom

// then strictly constrain to bb

// then the layer has nonexistant elements and is invalid

// then this bypass overrides the existing one

// then this property is just here to indicate we need to delete

// then update

// then use the higher cache for now and queue the next level down

// then use the lower quality cache for now and queue the better one for later

// then we can relatively cheaply rescale the existing image w/o rerendering

// then we can take action

// then we have convergence

// then zoom about a point

// there might be a normal field with a dot 

// these nodes <=edges= incoming nodes

// these nodes =edges=> outgoing nodes

// they shouldn't take up space

// this feature is most useful when adding and removing the same nodes and edges multiple times in a graph.

// this is just a wrapper alias of .on()

// this is the new query to be filled by the following exprs

// to avoid potential prototype pollution

// to be extra safe, remove the ref

// to be removed from animation queues

// to cheaply scale towards the smaller level

// to squared distance

// to the overlap

// to val

// top

// touchmove

// trailing edge, the system time has gone backwards and we're treating

// transform a given node position. Useful for changing flow direction in discrete layouts

// transform a given node position. Useful for changing flow direction in discrete layouts 

// trigger context drag if rmouse down

// trigger layoutready when each node has had its position set at least once

// trigger layoutstop when the layout stops (e.g. finishes)

// trigger update style on those eles that had class changes

// trim the value to make parsing easier

// true : Animate continuously as the layout is running

// try camel case name too

// try the last one if there is no second last one

// try to add to larger side first (adds less in multiplication)

// try to automatically infer the group if unspecified

// turn off for now, seems context does its own caching

// two fingers => pinch to zoom

// type is swapped on right side queries

// type[.namespace]

// u -> v -> Number

// unassigned neighbours shouldn't affect the ordering

// undirected edge

// undirected edge with subject on the second node

// update bb1 with bb2 bounds

// update each ctrlpt with segment info

// update edge data from projections

// update mappers if asked

// update node data from projections

// update position if w is in Q

// update rstyle positions

// update style b/c :backgrounding state changed

// update style for dirty eles

// update the old bg timestamp so diffs can be done in the ele txr caches

// update the ref since we moved things around for `query`

// updates the visual style for all elements (useful for manual style modification after init)

// updating the compound bounds happens outside of the regular

// use 'main' as an alias for the main label (i.e. null prefix)

// use a weighted average with a bias from the previous average so we don't spike so easily

// use cache by default for perf

// use cache so only 1x per edge

// use cached value from ctrlpt calc

// use caching on user-specified polygons so they are as fast as native shapes

// use default

// use line stroke style for triangle fill style

// use specified units if set

// use the max lvl b/c in between lvls are cheap to make

// use two fixed t values for the bezier curve approximation

// user param easings...

// user registered renderers inherit from base

// uses all available space on false, uses minimal space on true

// using standard layout options, apply position function (w/ or w/o animation)

// v -> children

// v -> edgeObj

// v -> label

// v -> parent

// v -> w -> Number

// validate group

// var cache = this.paintCache(context);

// var fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';

// var isFirefox = typeof InstallTrigger !== 'undefined';

// var s = "Limiting force: (" + forceX + ", " + forceY + "). Max: " + max;

// var s = "Propagating new position/size of node " + node.id;

// var s = "Propagating offset from parent node : " + node.id +

// var s = "\n\n###############################";

// var s = 'Refreshing positions';

// var s = 'Updating positions';

// var s = 'calculateGravityForces';

// var s = 'calculateNodeForces';

// var strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';

// vertical Z-shape (direction not respected)

// vertical Z-shape (distance not respected)

// vertical fallbacks

// very efficient version of eles.add( eles.descendants() ).forEach()

// w already in openSet, but with greater gScore

// w not in openSet

// watch for when the cy container is removed from the dom

// we can map only if the type is a colour or a number

// we have to notify (the animation loop doesn't do it for us on `stop`)

// we missed this event by turning notifications off, so pass it on

// we need distance from this node to every other node

// we need only one entry in deqd to queue redrawing etc

// we should have exactly the number of eles passed in to be complete

// we want the low quality motionblur only when the viewport is being manipulated etc (where it's not noticed)

// we're a bypass if the mapping property is a bypass

// we're done when there's nothing left to parse

// we're now populating the child

// we're now populating the child query with expressions that follow

// we're now populating the descendant query with expressions that follow

// we're now populating the target query with expressions that follow

// we've consumed one expr, so we can return now

// we've failed if there are no valid properties

// webpackBootstrap

// when a replacement layer is dequeued, it replaces the old layer in the level

// where nodes start in radians

// whether background images are loading

// whether destroy was called

// whether it's inside the vis; true if removed (set true here since we call restore)

// whether it's selectable

// whether it's selected

// whether labels should be included in determining the space used by a node

// whether levels have an equal radial distance betwen them, may cause bounding box overflow

// whether notifications are sent to the renderer

// whether ready has been triggered

// whether the compound dimensions need to be recalculated the next time dimensions are read

// whether the element can be grabbed

// whether the element has passthrough panning enabled

// whether the element is active from user interaction

// whether the element is grabbed by the mouse; renderer sets this privately

// whether the element is locked (cannot be moved)

// whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false)

// whether the tree is directed downwards (or edges can point in any direction if false)

// whether to add the dendrogram to the graph for viz

// whether to animate specific nodes when animation is on; non-animated nodes immediately go to their final positions

// whether to create an even grid into which the DAG is placed (circle:false only)

// whether to fit the viewport to the graph

// whether to fit to viewport

// whether to shift nodes down their natural BFS depths in order to avoid upwards edges (DAGS only)

// whether to transition the node positions

// whether to use Path2D caching for drawing

// which texture height this ele belongs to

// while

// while scrolling, ignore wheel-to-zoom

// whose roots tell us where a possible minimum is

// width and height of nodes calculated by the renderer when set to special 'auto' value

// width of layout area (overrides container width)

// width/height * splits^2 = cells where splits is number of times to split width

// will go straight to the end and be removed

// with the margin added after the rotation is applied

// word fits on current line

// word starts new line

// workaround for broken browsers like ie

// x

// x, y

// you probably wouldn't want to append a Style, since you'd duplicate the default parts

// zooming disabled

// }

//--Pointer-related data

////////

//////////

////////////////

/////////////////

/////////////////////////

//////////////////////////

//////////////////////////////////////////

//////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////

//0.8;

//console.log("Node " + node.id() + " is associated with medoid #: " + m);

//if any parent node in event hierarchy isn't pannable, reject passthrough

//if w is not in Q

//log eles.map(function(ele){ return ele.id() }) );

//r.fullQualityMb = false;

//self.queueLayer( layer );
