exports.id = 55;
exports.ids = [55];
exports.modules = {

/***/ 87799:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

(function webpackUniversalModuleDefinition(root, factory) {
	if(true)
		module.exports = factory(__webpack_require__(23143));
	else {}
})(this, function(__WEBPACK_EXTERNAL_MODULE_0__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __nested_webpack_require_643__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_643__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__nested_webpack_require_643__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__nested_webpack_require_643__.c = installedModules;
/******/
/******/ 	// identity function for calling harmony imports with the correct context
/******/ 	__nested_webpack_require_643__.i = function(value) { return value; };
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__nested_webpack_require_643__.d = function(exports, name, getter) {
/******/ 		if(!__nested_webpack_require_643__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__nested_webpack_require_643__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__nested_webpack_require_643__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__nested_webpack_require_643__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__nested_webpack_require_643__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __nested_webpack_require_643__(__nested_webpack_require_643__.s = 7);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {

module.exports = __WEBPACK_EXTERNAL_MODULE_0__;

/***/ }),
/* 1 */
/***/ (function(module, exports, __nested_webpack_require_3185__) {

"use strict";


var FDLayoutConstants = __nested_webpack_require_3185__(0).FDLayoutConstants;

function CoSEConstants() {}

//CoSEConstants inherits static props in FDLayoutConstants
for (var prop in FDLayoutConstants) {
  CoSEConstants[prop] = FDLayoutConstants[prop];
}

CoSEConstants.DEFAULT_USE_MULTI_LEVEL_SCALING = false;
CoSEConstants.DEFAULT_RADIAL_SEPARATION = FDLayoutConstants.DEFAULT_EDGE_LENGTH;
CoSEConstants.DEFAULT_COMPONENT_SEPERATION = 60;
CoSEConstants.TILE = true;
CoSEConstants.TILING_PADDING_VERTICAL = 10;
CoSEConstants.TILING_PADDING_HORIZONTAL = 10;
CoSEConstants.TREE_REDUCTION_ON_INCREMENTAL = false; // make this true when cose is used incrementally as a part of other non-incremental layout

module.exports = CoSEConstants;

/***/ }),
/* 2 */
/***/ (function(module, exports, __nested_webpack_require_4002__) {

"use strict";


var FDLayoutEdge = __nested_webpack_require_4002__(0).FDLayoutEdge;

function CoSEEdge(source, target, vEdge) {
  FDLayoutEdge.call(this, source, target, vEdge);
}

CoSEEdge.prototype = Object.create(FDLayoutEdge.prototype);
for (var prop in FDLayoutEdge) {
  CoSEEdge[prop] = FDLayoutEdge[prop];
}

module.exports = CoSEEdge;

/***/ }),
/* 3 */
/***/ (function(module, exports, __nested_webpack_require_4409__) {

"use strict";


var LGraph = __nested_webpack_require_4409__(0).LGraph;

function CoSEGraph(parent, graphMgr, vGraph) {
  LGraph.call(this, parent, graphMgr, vGraph);
}

CoSEGraph.prototype = Object.create(LGraph.prototype);
for (var prop in LGraph) {
  CoSEGraph[prop] = LGraph[prop];
}

module.exports = CoSEGraph;

/***/ }),
/* 4 */
/***/ (function(module, exports, __nested_webpack_require_4790__) {

"use strict";


var LGraphManager = __nested_webpack_require_4790__(0).LGraphManager;

function CoSEGraphManager(layout) {
  LGraphManager.call(this, layout);
}

CoSEGraphManager.prototype = Object.create(LGraphManager.prototype);
for (var prop in LGraphManager) {
  CoSEGraphManager[prop] = LGraphManager[prop];
}

module.exports = CoSEGraphManager;

/***/ }),
/* 5 */
/***/ (function(module, exports, __nested_webpack_require_5205__) {

"use strict";


var FDLayoutNode = __nested_webpack_require_5205__(0).FDLayoutNode;
var IMath = __nested_webpack_require_5205__(0).IMath;

function CoSENode(gm, loc, size, vNode) {
  FDLayoutNode.call(this, gm, loc, size, vNode);
}

CoSENode.prototype = Object.create(FDLayoutNode.prototype);
for (var prop in FDLayoutNode) {
  CoSENode[prop] = FDLayoutNode[prop];
}

CoSENode.prototype.move = function () {
  var layout = this.graphManager.getLayout();
  this.displacementX = layout.coolingFactor * (this.springForceX + this.repulsionForceX + this.gravitationForceX) / this.noOfChildren;
  this.displacementY = layout.coolingFactor * (this.springForceY + this.repulsionForceY + this.gravitationForceY) / this.noOfChildren;

  if (Math.abs(this.displacementX) > layout.coolingFactor * layout.maxNodeDisplacement) {
    this.displacementX = layout.coolingFactor * layout.maxNodeDisplacement * IMath.sign(this.displacementX);
  }

  if (Math.abs(this.displacementY) > layout.coolingFactor * layout.maxNodeDisplacement) {
    this.displacementY = layout.coolingFactor * layout.maxNodeDisplacement * IMath.sign(this.displacementY);
  }

  // a simple node, just move it
  if (this.child == null) {
    this.moveBy(this.displacementX, this.displacementY);
  }
  // an empty compound node, again just move it
  else if (this.child.getNodes().length == 0) {
      this.moveBy(this.displacementX, this.displacementY);
    }
    // non-empty compound node, propogate movement to children as well
    else {
        this.propogateDisplacementToChildren(this.displacementX, this.displacementY);
      }

  layout.totalDisplacement += Math.abs(this.displacementX) + Math.abs(this.displacementY);

  this.springForceX = 0;
  this.springForceY = 0;
  this.repulsionForceX = 0;
  this.repulsionForceY = 0;
  this.gravitationForceX = 0;
  this.gravitationForceY = 0;
  this.displacementX = 0;
  this.displacementY = 0;
};

CoSENode.prototype.propogateDisplacementToChildren = function (dX, dY) {
  var nodes = this.getChild().getNodes();
  var node;
  for (var i = 0; i < nodes.length; i++) {
    node = nodes[i];
    if (node.getChild() == null) {
      node.moveBy(dX, dY);
      node.displacementX += dX;
      node.displacementY += dY;
    } else {
      node.propogateDisplacementToChildren(dX, dY);
    }
  }
};

CoSENode.prototype.setPred1 = function (pred1) {
  this.pred1 = pred1;
};

CoSENode.prototype.getPred1 = function () {
  return pred1;
};

CoSENode.prototype.getPred2 = function () {
  return pred2;
};

CoSENode.prototype.setNext = function (next) {
  this.next = next;
};

CoSENode.prototype.getNext = function () {
  return next;
};

CoSENode.prototype.setProcessed = function (processed) {
  this.processed = processed;
};

CoSENode.prototype.isProcessed = function () {
  return processed;
};

module.exports = CoSENode;

/***/ }),
/* 6 */
/***/ (function(module, exports, __nested_webpack_require_8085__) {

"use strict";


var FDLayout = __nested_webpack_require_8085__(0).FDLayout;
var CoSEGraphManager = __nested_webpack_require_8085__(4);
var CoSEGraph = __nested_webpack_require_8085__(3);
var CoSENode = __nested_webpack_require_8085__(5);
var CoSEEdge = __nested_webpack_require_8085__(2);
var CoSEConstants = __nested_webpack_require_8085__(1);
var FDLayoutConstants = __nested_webpack_require_8085__(0).FDLayoutConstants;
var LayoutConstants = __nested_webpack_require_8085__(0).LayoutConstants;
var Point = __nested_webpack_require_8085__(0).Point;
var PointD = __nested_webpack_require_8085__(0).PointD;
var Layout = __nested_webpack_require_8085__(0).Layout;
var Integer = __nested_webpack_require_8085__(0).Integer;
var IGeometry = __nested_webpack_require_8085__(0).IGeometry;
var LGraph = __nested_webpack_require_8085__(0).LGraph;
var Transform = __nested_webpack_require_8085__(0).Transform;

function CoSELayout() {
  FDLayout.call(this);

  this.toBeTiled = {}; // Memorize if a node is to be tiled or is tiled
}

CoSELayout.prototype = Object.create(FDLayout.prototype);

for (var prop in FDLayout) {
  CoSELayout[prop] = FDLayout[prop];
}

CoSELayout.prototype.newGraphManager = function () {
  var gm = new CoSEGraphManager(this);
  this.graphManager = gm;
  return gm;
};

CoSELayout.prototype.newGraph = function (vGraph) {
  return new CoSEGraph(null, this.graphManager, vGraph);
};

CoSELayout.prototype.newNode = function (vNode) {
  return new CoSENode(this.graphManager, vNode);
};

CoSELayout.prototype.newEdge = function (vEdge) {
  return new CoSEEdge(null, null, vEdge);
};

CoSELayout.prototype.initParameters = function () {
  FDLayout.prototype.initParameters.call(this, arguments);
  if (!this.isSubLayout) {
    if (CoSEConstants.DEFAULT_EDGE_LENGTH < 10) {
      this.idealEdgeLength = 10;
    } else {
      this.idealEdgeLength = CoSEConstants.DEFAULT_EDGE_LENGTH;
    }

    this.useSmartIdealEdgeLengthCalculation = CoSEConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION;
    this.springConstant = FDLayoutConstants.DEFAULT_SPRING_STRENGTH;
    this.repulsionConstant = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH;
    this.gravityConstant = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH;
    this.compoundGravityConstant = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH;
    this.gravityRangeFactor = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR;
    this.compoundGravityRangeFactor = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR;

    // variables for tree reduction support
    this.prunedNodesAll = [];
    this.growTreeIterations = 0;
    this.afterGrowthIterations = 0;
    this.isTreeGrowing = false;
    this.isGrowthFinished = false;

    // variables for cooling
    this.coolingCycle = 0;
    this.maxCoolingCycle = this.maxIterations / FDLayoutConstants.CONVERGENCE_CHECK_PERIOD;
    this.finalTemperature = FDLayoutConstants.CONVERGENCE_CHECK_PERIOD / this.maxIterations;
    this.coolingAdjuster = 1;
  }
};

CoSELayout.prototype.layout = function () {
  var createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED;
  if (createBendsAsNeeded) {
    this.createBendpoints();
    this.graphManager.resetAllEdges();
  }

  this.level = 0;
  return this.classicLayout();
};

CoSELayout.prototype.classicLayout = function () {
  this.nodesWithGravity = this.calculateNodesToApplyGravitationTo();
  this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity);
  this.calcNoOfChildrenForAllNodes();
  this.graphManager.calcLowestCommonAncestors();
  this.graphManager.calcInclusionTreeDepths();
  this.graphManager.getRoot().calcEstimatedSize();
  this.calcIdealEdgeLengths();

  if (!this.incremental) {
    var forest = this.getFlatForest();

    // The graph associated with this layout is flat and a forest
    if (forest.length > 0) {
      this.positionNodesRadially(forest);
    }
    // The graph associated with this layout is not flat or a forest
    else {
        // Reduce the trees when incremental mode is not enabled and graph is not a forest 
        this.reduceTrees();
        // Update nodes that gravity will be applied
        this.graphManager.resetAllNodesToApplyGravitation();
        var allNodes = new Set(this.getAllNodes());
        var intersection = this.nodesWithGravity.filter(function (x) {
          return allNodes.has(x);
        });
        this.graphManager.setAllNodesToApplyGravitation(intersection);

        this.positionNodesRandomly();
      }
  } else {
    if (CoSEConstants.TREE_REDUCTION_ON_INCREMENTAL) {
      // Reduce the trees in incremental mode if only this constant is set to true 
      this.reduceTrees();
      // Update nodes that gravity will be applied
      this.graphManager.resetAllNodesToApplyGravitation();
      var allNodes = new Set(this.getAllNodes());
      var intersection = this.nodesWithGravity.filter(function (x) {
        return allNodes.has(x);
      });
      this.graphManager.setAllNodesToApplyGravitation(intersection);
    }
  }

  this.initSpringEmbedder();
  this.runSpringEmbedder();

  return true;
};

CoSELayout.prototype.tick = function () {
  this.totalIterations++;

  if (this.totalIterations === this.maxIterations && !this.isTreeGrowing && !this.isGrowthFinished) {
    if (this.prunedNodesAll.length > 0) {
      this.isTreeGrowing = true;
    } else {
      return true;
    }
  }

  if (this.totalIterations % FDLayoutConstants.CONVERGENCE_CHECK_PERIOD == 0 && !this.isTreeGrowing && !this.isGrowthFinished) {
    if (this.isConverged()) {
      if (this.prunedNodesAll.length > 0) {
        this.isTreeGrowing = true;
      } else {
        return true;
      }
    }

    this.coolingCycle++;

    if (this.layoutQuality == 0) {
      // quality - "draft"
      this.coolingAdjuster = this.coolingCycle;
    } else if (this.layoutQuality == 1) {
      // quality - "default"
      this.coolingAdjuster = this.coolingCycle / 3;
    }

    // cooling schedule is based on http://www.btluke.com/simanf1.html -> cooling schedule 3
    this.coolingFactor = Math.max(this.initialCoolingFactor - Math.pow(this.coolingCycle, Math.log(100 * (this.initialCoolingFactor - this.finalTemperature)) / Math.log(this.maxCoolingCycle)) / 100 * this.coolingAdjuster, this.finalTemperature);
    this.animationPeriod = Math.ceil(this.initialAnimationPeriod * Math.sqrt(this.coolingFactor));
  }
  // Operations while tree is growing again 
  if (this.isTreeGrowing) {
    if (this.growTreeIterations % 10 == 0) {
      if (this.prunedNodesAll.length > 0) {
        this.graphManager.updateBounds();
        this.updateGrid();
        this.growTree(this.prunedNodesAll);
        // Update nodes that gravity will be applied
        this.graphManager.resetAllNodesToApplyGravitation();
        var allNodes = new Set(this.getAllNodes());
        var intersection = this.nodesWithGravity.filter(function (x) {
          return allNodes.has(x);
        });
        this.graphManager.setAllNodesToApplyGravitation(intersection);

        this.graphManager.updateBounds();
        this.updateGrid();
        this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL;
      } else {
        this.isTreeGrowing = false;
        this.isGrowthFinished = true;
      }
    }
    this.growTreeIterations++;
  }
  // Operations after growth is finished
  if (this.isGrowthFinished) {
    if (this.isConverged()) {
      return true;
    }
    if (this.afterGrowthIterations % 10 == 0) {
      this.graphManager.updateBounds();
      this.updateGrid();
    }
    this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL * ((100 - this.afterGrowthIterations) / 100);
    this.afterGrowthIterations++;
  }

  var gridUpdateAllowed = !this.isTreeGrowing && !this.isGrowthFinished;
  var forceToNodeSurroundingUpdate = this.growTreeIterations % 10 == 1 && this.isTreeGrowing || this.afterGrowthIterations % 10 == 1 && this.isGrowthFinished;

  this.totalDisplacement = 0;
  this.graphManager.updateBounds();
  this.calcSpringForces();
  this.calcRepulsionForces(gridUpdateAllowed, forceToNodeSurroundingUpdate);
  this.calcGravitationalForces();
  this.moveNodes();
  this.animate();

  return false; // Layout is not ended yet return false
};

CoSELayout.prototype.getPositionsData = function () {
  var allNodes = this.graphManager.getAllNodes();
  var pData = {};
  for (var i = 0; i < allNodes.length; i++) {
    var rect = allNodes[i].rect;
    var id = allNodes[i].id;
    pData[id] = {
      id: id,
      x: rect.getCenterX(),
      y: rect.getCenterY(),
      w: rect.width,
      h: rect.height
    };
  }

  return pData;
};

CoSELayout.prototype.runSpringEmbedder = function () {
  this.initialAnimationPeriod = 25;
  this.animationPeriod = this.initialAnimationPeriod;
  var layoutEnded = false;

  // If aminate option is 'during' signal that layout is supposed to start iterating
  if (FDLayoutConstants.ANIMATE === 'during') {
    this.emit('layoutstarted');
  } else {
    // If aminate option is 'during' tick() function will be called on index.js
    while (!layoutEnded) {
      layoutEnded = this.tick();
    }

    this.graphManager.updateBounds();
  }
};

CoSELayout.prototype.calculateNodesToApplyGravitationTo = function () {
  var nodeList = [];
  var graph;

  var graphs = this.graphManager.getGraphs();
  var size = graphs.length;
  var i;
  for (i = 0; i < size; i++) {
    graph = graphs[i];

    graph.updateConnected();

    if (!graph.isConnected) {
      nodeList = nodeList.concat(graph.getNodes());
    }
  }

  return nodeList;
};

CoSELayout.prototype.createBendpoints = function () {
  var edges = [];
  edges = edges.concat(this.graphManager.getAllEdges());
  var visited = new Set();
  var i;
  for (i = 0; i < edges.length; i++) {
    var edge = edges[i];

    if (!visited.has(edge)) {
      var source = edge.getSource();
      var target = edge.getTarget();

      if (source == target) {
        edge.getBendpoints().push(new PointD());
        edge.getBendpoints().push(new PointD());
        this.createDummyNodesForBendpoints(edge);
        visited.add(edge);
      } else {
        var edgeList = [];

        edgeList = edgeList.concat(source.getEdgeListToNode(target));
        edgeList = edgeList.concat(target.getEdgeListToNode(source));

        if (!visited.has(edgeList[0])) {
          if (edgeList.length > 1) {
            var k;
            for (k = 0; k < edgeList.length; k++) {
              var multiEdge = edgeList[k];
              multiEdge.getBendpoints().push(new PointD());
              this.createDummyNodesForBendpoints(multiEdge);
            }
          }
          edgeList.forEach(function (edge) {
            visited.add(edge);
          });
        }
      }
    }

    if (visited.size == edges.length) {
      break;
    }
  }
};

CoSELayout.prototype.positionNodesRadially = function (forest) {
  // We tile the trees to a grid row by row; first tree starts at (0,0)
  var currentStartingPoint = new Point(0, 0);
  var numberOfColumns = Math.ceil(Math.sqrt(forest.length));
  var height = 0;
  var currentY = 0;
  var currentX = 0;
  var point = new PointD(0, 0);

  for (var i = 0; i < forest.length; i++) {
    if (i % numberOfColumns == 0) {
      // Start of a new row, make the x coordinate 0, increment the
      // y coordinate with the max height of the previous row
      currentX = 0;
      currentY = height;

      if (i != 0) {
        currentY += CoSEConstants.DEFAULT_COMPONENT_SEPERATION;
      }

      height = 0;
    }

    var tree = forest[i];

    // Find the center of the tree
    var centerNode = Layout.findCenterOfTree(tree);

    // Set the staring point of the next tree
    currentStartingPoint.x = currentX;
    currentStartingPoint.y = currentY;

    // Do a radial layout starting with the center
    point = CoSELayout.radialLayout(tree, centerNode, currentStartingPoint);

    if (point.y > height) {
      height = Math.floor(point.y);
    }

    currentX = Math.floor(point.x + CoSEConstants.DEFAULT_COMPONENT_SEPERATION);
  }

  this.transform(new PointD(LayoutConstants.WORLD_CENTER_X - point.x / 2, LayoutConstants.WORLD_CENTER_Y - point.y / 2));
};

CoSELayout.radialLayout = function (tree, centerNode, startingPoint) {
  var radialSep = Math.max(this.maxDiagonalInTree(tree), CoSEConstants.DEFAULT_RADIAL_SEPARATION);
  CoSELayout.branchRadialLayout(centerNode, null, 0, 359, 0, radialSep);
  var bounds = LGraph.calculateBounds(tree);

  var transform = new Transform();
  transform.setDeviceOrgX(bounds.getMinX());
  transform.setDeviceOrgY(bounds.getMinY());
  transform.setWorldOrgX(startingPoint.x);
  transform.setWorldOrgY(startingPoint.y);

  for (var i = 0; i < tree.length; i++) {
    var node = tree[i];
    node.transform(transform);
  }

  var bottomRight = new PointD(bounds.getMaxX(), bounds.getMaxY());

  return transform.inverseTransformPoint(bottomRight);
};

CoSELayout.branchRadialLayout = function (node, parentOfNode, startAngle, endAngle, distance, radialSeparation) {
  // First, position this node by finding its angle.
  var halfInterval = (endAngle - startAngle + 1) / 2;

  if (halfInterval < 0) {
    halfInterval += 180;
  }

  var nodeAngle = (halfInterval + startAngle) % 360;
  var teta = nodeAngle * IGeometry.TWO_PI / 360;

  // Make polar to java cordinate conversion.
  var cos_teta = Math.cos(teta);
  var x_ = distance * Math.cos(teta);
  var y_ = distance * Math.sin(teta);

  node.setCenter(x_, y_);

  // Traverse all neighbors of this node and recursively call this
  // function.
  var neighborEdges = [];
  neighborEdges = neighborEdges.concat(node.getEdges());
  var childCount = neighborEdges.length;

  if (parentOfNode != null) {
    childCount--;
  }

  var branchCount = 0;

  var incEdgesCount = neighborEdges.length;
  var startIndex;

  var edges = node.getEdgesBetween(parentOfNode);

  // If there are multiple edges, prune them until there remains only one
  // edge.
  while (edges.length > 1) {
    //neighborEdges.remove(edges.remove(0));
    var temp = edges[0];
    edges.splice(0, 1);
    var index = neighborEdges.indexOf(temp);
    if (index >= 0) {
      neighborEdges.splice(index, 1);
    }
    incEdgesCount--;
    childCount--;
  }

  if (parentOfNode != null) {
    //assert edges.length == 1;
    startIndex = (neighborEdges.indexOf(edges[0]) + 1) % incEdgesCount;
  } else {
    startIndex = 0;
  }

  var stepAngle = Math.abs(endAngle - startAngle) / childCount;

  for (var i = startIndex; branchCount != childCount; i = ++i % incEdgesCount) {
    var currentNeighbor = neighborEdges[i].getOtherEnd(node);

    // Don't back traverse to root node in current tree.
    if (currentNeighbor == parentOfNode) {
      continue;
    }

    var childStartAngle = (startAngle + branchCount * stepAngle) % 360;
    var childEndAngle = (childStartAngle + stepAngle) % 360;

    CoSELayout.branchRadialLayout(currentNeighbor, node, childStartAngle, childEndAngle, distance + radialSeparation, radialSeparation);

    branchCount++;
  }
};

CoSELayout.maxDiagonalInTree = function (tree) {
  var maxDiagonal = Integer.MIN_VALUE;

  for (var i = 0; i < tree.length; i++) {
    var node = tree[i];
    var diagonal = node.getDiagonal();

    if (diagonal > maxDiagonal) {
      maxDiagonal = diagonal;
    }
  }

  return maxDiagonal;
};

CoSELayout.prototype.calcRepulsionRange = function () {
  // formula is 2 x (level + 1) x idealEdgeLength
  return 2 * (this.level + 1) * this.idealEdgeLength;
};

// Tiling methods

// Group zero degree members whose parents are not to be tiled, create dummy parents where needed and fill memberGroups by their dummp parent id's
CoSELayout.prototype.groupZeroDegreeMembers = function () {
  var self = this;
  // array of [parent_id x oneDegreeNode_id]
  var tempMemberGroups = {}; // A temporary map of parent node and its zero degree members
  this.memberGroups = {}; // A map of dummy parent node and its zero degree members whose parents are not to be tiled
  this.idToDummyNode = {}; // A map of id to dummy node 

  var zeroDegree = []; // List of zero degree nodes whose parents are not to be tiled
  var allNodes = this.graphManager.getAllNodes();

  // Fill zero degree list
  for (var i = 0; i < allNodes.length; i++) {
    var node = allNodes[i];
    var parent = node.getParent();
    // If a node has zero degree and its parent is not to be tiled if exists add that node to zeroDegres list
    if (this.getNodeDegreeWithChildren(node) === 0 && (parent.id == undefined || !this.getToBeTiled(parent))) {
      zeroDegree.push(node);
    }
  }

  // Create a map of parent node and its zero degree members
  for (var i = 0; i < zeroDegree.length; i++) {
    var node = zeroDegree[i]; // Zero degree node itself
    var p_id = node.getParent().id; // Parent id

    if (typeof tempMemberGroups[p_id] === "undefined") tempMemberGroups[p_id] = [];

    tempMemberGroups[p_id] = tempMemberGroups[p_id].concat(node); // Push node to the list belongs to its parent in tempMemberGroups
  }

  // If there are at least two nodes at a level, create a dummy compound for them
  Object.keys(tempMemberGroups).forEach(function (p_id) {
    if (tempMemberGroups[p_id].length > 1) {
      var dummyCompoundId = "DummyCompound_" + p_id; // The id of dummy compound which will be created soon
      self.memberGroups[dummyCompoundId] = tempMemberGroups[p_id]; // Add dummy compound to memberGroups

      var parent = tempMemberGroups[p_id][0].getParent(); // The parent of zero degree nodes will be the parent of new dummy compound

      // Create a dummy compound with calculated id
      var dummyCompound = new CoSENode(self.graphManager);
      dummyCompound.id = dummyCompoundId;
      dummyCompound.paddingLeft = parent.paddingLeft || 0;
      dummyCompound.paddingRight = parent.paddingRight || 0;
      dummyCompound.paddingBottom = parent.paddingBottom || 0;
      dummyCompound.paddingTop = parent.paddingTop || 0;

      self.idToDummyNode[dummyCompoundId] = dummyCompound;

      var dummyParentGraph = self.getGraphManager().add(self.newGraph(), dummyCompound);
      var parentGraph = parent.getChild();

      // Add dummy compound to parent the graph
      parentGraph.add(dummyCompound);

      // For each zero degree node in this level remove it from its parent graph and add it to the graph of dummy parent
      for (var i = 0; i < tempMemberGroups[p_id].length; i++) {
        var node = tempMemberGroups[p_id][i];

        parentGraph.remove(node);
        dummyParentGraph.add(node);
      }
    }
  });
};

CoSELayout.prototype.clearCompounds = function () {
  var childGraphMap = {};
  var idToNode = {};

  // Get compound ordering by finding the inner one first
  this.performDFSOnCompounds();

  for (var i = 0; i < this.compoundOrder.length; i++) {

    idToNode[this.compoundOrder[i].id] = this.compoundOrder[i];
    childGraphMap[this.compoundOrder[i].id] = [].concat(this.compoundOrder[i].getChild().getNodes());

    // Remove children of compounds
    this.graphManager.remove(this.compoundOrder[i].getChild());
    this.compoundOrder[i].child = null;
  }

  this.graphManager.resetAllNodes();

  // Tile the removed children
  this.tileCompoundMembers(childGraphMap, idToNode);
};

CoSELayout.prototype.clearZeroDegreeMembers = function () {
  var self = this;
  var tiledZeroDegreePack = this.tiledZeroDegreePack = [];

  Object.keys(this.memberGroups).forEach(function (id) {
    var compoundNode = self.idToDummyNode[id]; // Get the dummy compound

    tiledZeroDegreePack[id] = self.tileNodes(self.memberGroups[id], compoundNode.paddingLeft + compoundNode.paddingRight);

    // Set the width and height of the dummy compound as calculated
    compoundNode.rect.width = tiledZeroDegreePack[id].width;
    compoundNode.rect.height = tiledZeroDegreePack[id].height;
  });
};

CoSELayout.prototype.repopulateCompounds = function () {
  for (var i = this.compoundOrder.length - 1; i >= 0; i--) {
    var lCompoundNode = this.compoundOrder[i];
    var id = lCompoundNode.id;
    var horizontalMargin = lCompoundNode.paddingLeft;
    var verticalMargin = lCompoundNode.paddingTop;

    this.adjustLocations(this.tiledMemberPack[id], lCompoundNode.rect.x, lCompoundNode.rect.y, horizontalMargin, verticalMargin);
  }
};

CoSELayout.prototype.repopulateZeroDegreeMembers = function () {
  var self = this;
  var tiledPack = this.tiledZeroDegreePack;

  Object.keys(tiledPack).forEach(function (id) {
    var compoundNode = self.idToDummyNode[id]; // Get the dummy compound by its id
    var horizontalMargin = compoundNode.paddingLeft;
    var verticalMargin = compoundNode.paddingTop;

    // Adjust the positions of nodes wrt its compound
    self.adjustLocations(tiledPack[id], compoundNode.rect.x, compoundNode.rect.y, horizontalMargin, verticalMargin);
  });
};

CoSELayout.prototype.getToBeTiled = function (node) {
  var id = node.id;
  //firstly check the previous results
  if (this.toBeTiled[id] != null) {
    return this.toBeTiled[id];
  }

  //only compound nodes are to be tiled
  var childGraph = node.getChild();
  if (childGraph == null) {
    this.toBeTiled[id] = false;
    return false;
  }

  var children = childGraph.getNodes(); // Get the children nodes

  //a compound node is not to be tiled if all of its compound children are not to be tiled
  for (var i = 0; i < children.length; i++) {
    var theChild = children[i];

    if (this.getNodeDegree(theChild) > 0) {
      this.toBeTiled[id] = false;
      return false;
    }

    //pass the children not having the compound structure
    if (theChild.getChild() == null) {
      this.toBeTiled[theChild.id] = false;
      continue;
    }

    if (!this.getToBeTiled(theChild)) {
      this.toBeTiled[id] = false;
      return false;
    }
  }
  this.toBeTiled[id] = true;
  return true;
};

// Get degree of a node depending of its edges and independent of its children
CoSELayout.prototype.getNodeDegree = function (node) {
  var id = node.id;
  var edges = node.getEdges();
  var degree = 0;

  // For the edges connected
  for (var i = 0; i < edges.length; i++) {
    var edge = edges[i];
    if (edge.getSource().id !== edge.getTarget().id) {
      degree = degree + 1;
    }
  }
  return degree;
};

// Get degree of a node with its children
CoSELayout.prototype.getNodeDegreeWithChildren = function (node) {
  var degree = this.getNodeDegree(node);
  if (node.getChild() == null) {
    return degree;
  }
  var children = node.getChild().getNodes();
  for (var i = 0; i < children.length; i++) {
    var child = children[i];
    degree += this.getNodeDegreeWithChildren(child);
  }
  return degree;
};

CoSELayout.prototype.performDFSOnCompounds = function () {
  this.compoundOrder = [];
  this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes());
};

CoSELayout.prototype.fillCompexOrderByDFS = function (children) {
  for (var i = 0; i < children.length; i++) {
    var child = children[i];
    if (child.getChild() != null) {
      this.fillCompexOrderByDFS(child.getChild().getNodes());
    }
    if (this.getToBeTiled(child)) {
      this.compoundOrder.push(child);
    }
  }
};

/**
* This method places each zero degree member wrt given (x,y) coordinates (top left).
*/
CoSELayout.prototype.adjustLocations = function (organization, x, y, compoundHorizontalMargin, compoundVerticalMargin) {
  x += compoundHorizontalMargin;
  y += compoundVerticalMargin;

  var left = x;

  for (var i = 0; i < organization.rows.length; i++) {
    var row = organization.rows[i];
    x = left;
    var maxHeight = 0;

    for (var j = 0; j < row.length; j++) {
      var lnode = row[j];

      lnode.rect.x = x; // + lnode.rect.width / 2;
      lnode.rect.y = y; // + lnode.rect.height / 2;

      x += lnode.rect.width + organization.horizontalPadding;

      if (lnode.rect.height > maxHeight) maxHeight = lnode.rect.height;
    }

    y += maxHeight + organization.verticalPadding;
  }
};

CoSELayout.prototype.tileCompoundMembers = function (childGraphMap, idToNode) {
  var self = this;
  this.tiledMemberPack = [];

  Object.keys(childGraphMap).forEach(function (id) {
    // Get the compound node
    var compoundNode = idToNode[id];

    self.tiledMemberPack[id] = self.tileNodes(childGraphMap[id], compoundNode.paddingLeft + compoundNode.paddingRight);

    compoundNode.rect.width = self.tiledMemberPack[id].width;
    compoundNode.rect.height = self.tiledMemberPack[id].height;
  });
};

CoSELayout.prototype.tileNodes = function (nodes, minWidth) {
  var verticalPadding = CoSEConstants.TILING_PADDING_VERTICAL;
  var horizontalPadding = CoSEConstants.TILING_PADDING_HORIZONTAL;
  var organization = {
    rows: [],
    rowWidth: [],
    rowHeight: [],
    width: 0,
    height: minWidth, // assume minHeight equals to minWidth
    verticalPadding: verticalPadding,
    horizontalPadding: horizontalPadding
  };

  // Sort the nodes in ascending order of their areas
  nodes.sort(function (n1, n2) {
    if (n1.rect.width * n1.rect.height > n2.rect.width * n2.rect.height) return -1;
    if (n1.rect.width * n1.rect.height < n2.rect.width * n2.rect.height) return 1;
    return 0;
  });

  // Create the organization -> tile members
  for (var i = 0; i < nodes.length; i++) {
    var lNode = nodes[i];

    if (organization.rows.length == 0) {
      this.insertNodeToRow(organization, lNode, 0, minWidth);
    } else if (this.canAddHorizontal(organization, lNode.rect.width, lNode.rect.height)) {
      this.insertNodeToRow(organization, lNode, this.getShortestRowIndex(organization), minWidth);
    } else {
      this.insertNodeToRow(organization, lNode, organization.rows.length, minWidth);
    }

    this.shiftToLastRow(organization);
  }

  return organization;
};

CoSELayout.prototype.insertNodeToRow = function (organization, node, rowIndex, minWidth) {
  var minCompoundSize = minWidth;

  // Add new row if needed
  if (rowIndex == organization.rows.length) {
    var secondDimension = [];

    organization.rows.push(secondDimension);
    organization.rowWidth.push(minCompoundSize);
    organization.rowHeight.push(0);
  }

  // Update row width
  var w = organization.rowWidth[rowIndex] + node.rect.width;

  if (organization.rows[rowIndex].length > 0) {
    w += organization.horizontalPadding;
  }

  organization.rowWidth[rowIndex] = w;
  // Update compound width
  if (organization.width < w) {
    organization.width = w;
  }

  // Update height
  var h = node.rect.height;
  if (rowIndex > 0) h += organization.verticalPadding;

  var extraHeight = 0;
  if (h > organization.rowHeight[rowIndex]) {
    extraHeight = organization.rowHeight[rowIndex];
    organization.rowHeight[rowIndex] = h;
    extraHeight = organization.rowHeight[rowIndex] - extraHeight;
  }

  organization.height += extraHeight;

  // Insert node
  organization.rows[rowIndex].push(node);
};

//Scans the rows of an organization and returns the one with the min width
CoSELayout.prototype.getShortestRowIndex = function (organization) {
  var r = -1;
  var min = Number.MAX_VALUE;

  for (var i = 0; i < organization.rows.length; i++) {
    if (organization.rowWidth[i] < min) {
      r = i;
      min = organization.rowWidth[i];
    }
  }
  return r;
};

//Scans the rows of an organization and returns the one with the max width
CoSELayout.prototype.getLongestRowIndex = function (organization) {
  var r = -1;
  var max = Number.MIN_VALUE;

  for (var i = 0; i < organization.rows.length; i++) {

    if (organization.rowWidth[i] > max) {
      r = i;
      max = organization.rowWidth[i];
    }
  }

  return r;
};

/**
* This method checks whether adding extra width to the organization violates
* the aspect ratio(1) or not.
*/
CoSELayout.prototype.canAddHorizontal = function (organization, extraWidth, extraHeight) {

  var sri = this.getShortestRowIndex(organization);

  if (sri < 0) {
    return true;
  }

  var min = organization.rowWidth[sri];

  if (min + organization.horizontalPadding + extraWidth <= organization.width) return true;

  var hDiff = 0;

  // Adding to an existing row
  if (organization.rowHeight[sri] < extraHeight) {
    if (sri > 0) hDiff = extraHeight + organization.verticalPadding - organization.rowHeight[sri];
  }

  var add_to_row_ratio;
  if (organization.width - min >= extraWidth + organization.horizontalPadding) {
    add_to_row_ratio = (organization.height + hDiff) / (min + extraWidth + organization.horizontalPadding);
  } else {
    add_to_row_ratio = (organization.height + hDiff) / organization.width;
  }

  // Adding a new row for this node
  hDiff = extraHeight + organization.verticalPadding;
  var add_new_row_ratio;
  if (organization.width < extraWidth) {
    add_new_row_ratio = (organization.height + hDiff) / extraWidth;
  } else {
    add_new_row_ratio = (organization.height + hDiff) / organization.width;
  }

  if (add_new_row_ratio < 1) add_new_row_ratio = 1 / add_new_row_ratio;

  if (add_to_row_ratio < 1) add_to_row_ratio = 1 / add_to_row_ratio;

  return add_to_row_ratio < add_new_row_ratio;
};

//If moving the last node from the longest row and adding it to the last
//row makes the bounding box smaller, do it.
CoSELayout.prototype.shiftToLastRow = function (organization) {
  var longest = this.getLongestRowIndex(organization);
  var last = organization.rowWidth.length - 1;
  var row = organization.rows[longest];
  var node = row[row.length - 1];

  var diff = node.width + organization.horizontalPadding;

  // Check if there is enough space on the last row
  if (organization.width - organization.rowWidth[last] > diff && longest != last) {
    // Remove the last element of the longest row
    row.splice(-1, 1);

    // Push it to the last row
    organization.rows[last].push(node);

    organization.rowWidth[longest] = organization.rowWidth[longest] - diff;
    organization.rowWidth[last] = organization.rowWidth[last] + diff;
    organization.width = organization.rowWidth[instance.getLongestRowIndex(organization)];

    // Update heights of the organization
    var maxHeight = Number.MIN_VALUE;
    for (var i = 0; i < row.length; i++) {
      if (row[i].height > maxHeight) maxHeight = row[i].height;
    }
    if (longest > 0) maxHeight += organization.verticalPadding;

    var prevTotal = organization.rowHeight[longest] + organization.rowHeight[last];

    organization.rowHeight[longest] = maxHeight;
    if (organization.rowHeight[last] < node.height + organization.verticalPadding) organization.rowHeight[last] = node.height + organization.verticalPadding;

    var finalTotal = organization.rowHeight[longest] + organization.rowHeight[last];
    organization.height += finalTotal - prevTotal;

    this.shiftToLastRow(organization);
  }
};

CoSELayout.prototype.tilingPreLayout = function () {
  if (CoSEConstants.TILE) {
    // Find zero degree nodes and create a compound for each level
    this.groupZeroDegreeMembers();
    // Tile and clear children of each compound
    this.clearCompounds();
    // Separately tile and clear zero degree nodes for each level
    this.clearZeroDegreeMembers();
  }
};

CoSELayout.prototype.tilingPostLayout = function () {
  if (CoSEConstants.TILE) {
    this.repopulateZeroDegreeMembers();
    this.repopulateCompounds();
  }
};

// -----------------------------------------------------------------------------
// Section: Tree Reduction methods
// -----------------------------------------------------------------------------
// Reduce trees 
CoSELayout.prototype.reduceTrees = function () {
  var prunedNodesAll = [];
  var containsLeaf = true;
  var node;

  while (containsLeaf) {
    var allNodes = this.graphManager.getAllNodes();
    var prunedNodesInStepTemp = [];
    containsLeaf = false;

    for (var i = 0; i < allNodes.length; i++) {
      node = allNodes[i];
      if (node.getEdges().length == 1 && !node.getEdges()[0].isInterGraph && node.getChild() == null) {
        prunedNodesInStepTemp.push([node, node.getEdges()[0], node.getOwner()]);
        containsLeaf = true;
      }
    }
    if (containsLeaf == true) {
      var prunedNodesInStep = [];
      for (var j = 0; j < prunedNodesInStepTemp.length; j++) {
        if (prunedNodesInStepTemp[j][0].getEdges().length == 1) {
          prunedNodesInStep.push(prunedNodesInStepTemp[j]);
          prunedNodesInStepTemp[j][0].getOwner().remove(prunedNodesInStepTemp[j][0]);
        }
      }
      prunedNodesAll.push(prunedNodesInStep);
      this.graphManager.resetAllNodes();
      this.graphManager.resetAllEdges();
    }
  }
  this.prunedNodesAll = prunedNodesAll;
};

// Grow tree one step 
CoSELayout.prototype.growTree = function (prunedNodesAll) {
  var lengthOfPrunedNodesInStep = prunedNodesAll.length;
  var prunedNodesInStep = prunedNodesAll[lengthOfPrunedNodesInStep - 1];

  var nodeData;
  for (var i = 0; i < prunedNodesInStep.length; i++) {
    nodeData = prunedNodesInStep[i];

    this.findPlaceforPrunedNode(nodeData);

    nodeData[2].add(nodeData[0]);
    nodeData[2].add(nodeData[1], nodeData[1].source, nodeData[1].target);
  }

  prunedNodesAll.splice(prunedNodesAll.length - 1, 1);
  this.graphManager.resetAllNodes();
  this.graphManager.resetAllEdges();
};

// Find an appropriate position to replace pruned node, this method can be improved
CoSELayout.prototype.findPlaceforPrunedNode = function (nodeData) {

  var gridForPrunedNode;
  var nodeToConnect;
  var prunedNode = nodeData[0];
  if (prunedNode == nodeData[1].source) {
    nodeToConnect = nodeData[1].target;
  } else {
    nodeToConnect = nodeData[1].source;
  }
  var startGridX = nodeToConnect.startX;
  var finishGridX = nodeToConnect.finishX;
  var startGridY = nodeToConnect.startY;
  var finishGridY = nodeToConnect.finishY;

  var upNodeCount = 0;
  var downNodeCount = 0;
  var rightNodeCount = 0;
  var leftNodeCount = 0;
  var controlRegions = [upNodeCount, rightNodeCount, downNodeCount, leftNodeCount];

  if (startGridY > 0) {
    for (var i = startGridX; i <= finishGridX; i++) {
      controlRegions[0] += this.grid[i][startGridY - 1].length + this.grid[i][startGridY].length - 1;
    }
  }
  if (finishGridX < this.grid.length - 1) {
    for (var i = startGridY; i <= finishGridY; i++) {
      controlRegions[1] += this.grid[finishGridX + 1][i].length + this.grid[finishGridX][i].length - 1;
    }
  }
  if (finishGridY < this.grid[0].length - 1) {
    for (var i = startGridX; i <= finishGridX; i++) {
      controlRegions[2] += this.grid[i][finishGridY + 1].length + this.grid[i][finishGridY].length - 1;
    }
  }
  if (startGridX > 0) {
    for (var i = startGridY; i <= finishGridY; i++) {
      controlRegions[3] += this.grid[startGridX - 1][i].length + this.grid[startGridX][i].length - 1;
    }
  }
  var min = Integer.MAX_VALUE;
  var minCount;
  var minIndex;
  for (var j = 0; j < controlRegions.length; j++) {
    if (controlRegions[j] < min) {
      min = controlRegions[j];
      minCount = 1;
      minIndex = j;
    } else if (controlRegions[j] == min) {
      minCount++;
    }
  }

  if (minCount == 3 && min == 0) {
    if (controlRegions[0] == 0 && controlRegions[1] == 0 && controlRegions[2] == 0) {
      gridForPrunedNode = 1;
    } else if (controlRegions[0] == 0 && controlRegions[1] == 0 && controlRegions[3] == 0) {
      gridForPrunedNode = 0;
    } else if (controlRegions[0] == 0 && controlRegions[2] == 0 && controlRegions[3] == 0) {
      gridForPrunedNode = 3;
    } else if (controlRegions[1] == 0 && controlRegions[2] == 0 && controlRegions[3] == 0) {
      gridForPrunedNode = 2;
    }
  } else if (minCount == 2 && min == 0) {
    var random = Math.floor(Math.random() * 2);
    if (controlRegions[0] == 0 && controlRegions[1] == 0) {
      ;
      if (random == 0) {
        gridForPrunedNode = 0;
      } else {
        gridForPrunedNode = 1;
      }
    } else if (controlRegions[0] == 0 && controlRegions[2] == 0) {
      if (random == 0) {
        gridForPrunedNode = 0;
      } else {
        gridForPrunedNode = 2;
      }
    } else if (controlRegions[0] == 0 && controlRegions[3] == 0) {
      if (random == 0) {
        gridForPrunedNode = 0;
      } else {
        gridForPrunedNode = 3;
      }
    } else if (controlRegions[1] == 0 && controlRegions[2] == 0) {
      if (random == 0) {
        gridForPrunedNode = 1;
      } else {
        gridForPrunedNode = 2;
      }
    } else if (controlRegions[1] == 0 && controlRegions[3] == 0) {
      if (random == 0) {
        gridForPrunedNode = 1;
      } else {
        gridForPrunedNode = 3;
      }
    } else {
      if (random == 0) {
        gridForPrunedNode = 2;
      } else {
        gridForPrunedNode = 3;
      }
    }
  } else if (minCount == 4 && min == 0) {
    var random = Math.floor(Math.random() * 4);
    gridForPrunedNode = random;
  } else {
    gridForPrunedNode = minIndex;
  }

  if (gridForPrunedNode == 0) {
    prunedNode.setCenter(nodeToConnect.getCenterX(), nodeToConnect.getCenterY() - nodeToConnect.getHeight() / 2 - FDLayoutConstants.DEFAULT_EDGE_LENGTH - prunedNode.getHeight() / 2);
  } else if (gridForPrunedNode == 1) {
    prunedNode.setCenter(nodeToConnect.getCenterX() + nodeToConnect.getWidth() / 2 + FDLayoutConstants.DEFAULT_EDGE_LENGTH + prunedNode.getWidth() / 2, nodeToConnect.getCenterY());
  } else if (gridForPrunedNode == 2) {
    prunedNode.setCenter(nodeToConnect.getCenterX(), nodeToConnect.getCenterY() + nodeToConnect.getHeight() / 2 + FDLayoutConstants.DEFAULT_EDGE_LENGTH + prunedNode.getHeight() / 2);
  } else {
    prunedNode.setCenter(nodeToConnect.getCenterX() - nodeToConnect.getWidth() / 2 - FDLayoutConstants.DEFAULT_EDGE_LENGTH - prunedNode.getWidth() / 2, nodeToConnect.getCenterY());
  }
};

module.exports = CoSELayout;

/***/ }),
/* 7 */
/***/ (function(module, exports, __nested_webpack_require_45620__) {

"use strict";


var coseBase = {};

coseBase.layoutBase = __nested_webpack_require_45620__(0);
coseBase.CoSEConstants = __nested_webpack_require_45620__(1);
coseBase.CoSEEdge = __nested_webpack_require_45620__(2);
coseBase.CoSEGraph = __nested_webpack_require_45620__(3);
coseBase.CoSEGraphManager = __nested_webpack_require_45620__(4);
coseBase.CoSELayout = __nested_webpack_require_45620__(6);
coseBase.CoSENode = __nested_webpack_require_45620__(5);

module.exports = coseBase;

/***/ })
/******/ ]);
});

/***/ }),

/***/ 43457:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

(function webpackUniversalModuleDefinition(root, factory) {
	if(true)
		module.exports = factory(__webpack_require__(87799));
	else {}
})(this, function(__WEBPACK_EXTERNAL_MODULE_0__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __nested_webpack_require_659__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_659__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__nested_webpack_require_659__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__nested_webpack_require_659__.c = installedModules;
/******/
/******/ 	// identity function for calling harmony imports with the correct context
/******/ 	__nested_webpack_require_659__.i = function(value) { return value; };
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__nested_webpack_require_659__.d = function(exports, name, getter) {
/******/ 		if(!__nested_webpack_require_659__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__nested_webpack_require_659__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__nested_webpack_require_659__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__nested_webpack_require_659__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__nested_webpack_require_659__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __nested_webpack_require_659__(__nested_webpack_require_659__.s = 1);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {

module.exports = __WEBPACK_EXTERNAL_MODULE_0__;

/***/ }),
/* 1 */
/***/ (function(module, exports, __nested_webpack_require_3201__) {

"use strict";


var LayoutConstants = __nested_webpack_require_3201__(0).layoutBase.LayoutConstants;
var FDLayoutConstants = __nested_webpack_require_3201__(0).layoutBase.FDLayoutConstants;
var CoSEConstants = __nested_webpack_require_3201__(0).CoSEConstants;
var CoSELayout = __nested_webpack_require_3201__(0).CoSELayout;
var CoSENode = __nested_webpack_require_3201__(0).CoSENode;
var PointD = __nested_webpack_require_3201__(0).layoutBase.PointD;
var DimensionD = __nested_webpack_require_3201__(0).layoutBase.DimensionD;

var defaults = {
  // Called on `layoutready`
  ready: function ready() {},
  // Called on `layoutstop`
  stop: function stop() {},
  // 'draft', 'default' or 'proof" 
  // - 'draft' fast cooling rate 
  // - 'default' moderate cooling rate 
  // - "proof" slow cooling rate
  quality: 'default',
  // include labels in node dimensions
  nodeDimensionsIncludeLabels: false,
  // number of ticks per frame; higher is faster but more jerky
  refresh: 30,
  // Whether to fit the network view after when done
  fit: true,
  // Padding on fit
  padding: 10,
  // Whether to enable incremental mode
  randomize: true,
  // Node repulsion (non overlapping) multiplier
  nodeRepulsion: 4500,
  // Ideal edge (non nested) length
  idealEdgeLength: 50,
  // Divisor to compute edge forces
  edgeElasticity: 0.45,
  // Nesting factor (multiplier) to compute ideal edge length for nested edges
  nestingFactor: 0.1,
  // Gravity force (constant)
  gravity: 0.25,
  // Maximum number of iterations to perform
  numIter: 2500,
  // For enabling tiling
  tile: true,
  // Type of layout animation. The option set is {'during', 'end', false}
  animate: 'end',
  // Duration for animate:end
  animationDuration: 500,
  // Represents the amount of the vertical space to put between the zero degree members during the tiling operation(can also be a function)
  tilingPaddingVertical: 10,
  // Represents the amount of the horizontal space to put between the zero degree members during the tiling operation(can also be a function)
  tilingPaddingHorizontal: 10,
  // Gravity range (constant) for compounds
  gravityRangeCompound: 1.5,
  // Gravity force (constant) for compounds
  gravityCompound: 1.0,
  // Gravity range (constant)
  gravityRange: 3.8,
  // Initial cooling factor for incremental layout
  initialEnergyOnIncremental: 0.5
};

function extend(defaults, options) {
  var obj = {};

  for (var i in defaults) {
    obj[i] = defaults[i];
  }

  for (var i in options) {
    obj[i] = options[i];
  }

  return obj;
};

function _CoSELayout(_options) {
  this.options = extend(defaults, _options);
  getUserOptions(this.options);
}

var getUserOptions = function getUserOptions(options) {
  if (options.nodeRepulsion != null) CoSEConstants.DEFAULT_REPULSION_STRENGTH = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH = options.nodeRepulsion;
  if (options.idealEdgeLength != null) CoSEConstants.DEFAULT_EDGE_LENGTH = FDLayoutConstants.DEFAULT_EDGE_LENGTH = options.idealEdgeLength;
  if (options.edgeElasticity != null) CoSEConstants.DEFAULT_SPRING_STRENGTH = FDLayoutConstants.DEFAULT_SPRING_STRENGTH = options.edgeElasticity;
  if (options.nestingFactor != null) CoSEConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = options.nestingFactor;
  if (options.gravity != null) CoSEConstants.DEFAULT_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH = options.gravity;
  if (options.numIter != null) CoSEConstants.MAX_ITERATIONS = FDLayoutConstants.MAX_ITERATIONS = options.numIter;
  if (options.gravityRange != null) CoSEConstants.DEFAULT_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR = options.gravityRange;
  if (options.gravityCompound != null) CoSEConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = options.gravityCompound;
  if (options.gravityRangeCompound != null) CoSEConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = options.gravityRangeCompound;
  if (options.initialEnergyOnIncremental != null) CoSEConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = options.initialEnergyOnIncremental;

  if (options.quality == 'draft') LayoutConstants.QUALITY = 0;else if (options.quality == 'proof') LayoutConstants.QUALITY = 2;else LayoutConstants.QUALITY = 1;

  CoSEConstants.NODE_DIMENSIONS_INCLUDE_LABELS = FDLayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = options.nodeDimensionsIncludeLabels;
  CoSEConstants.DEFAULT_INCREMENTAL = FDLayoutConstants.DEFAULT_INCREMENTAL = LayoutConstants.DEFAULT_INCREMENTAL = !options.randomize;
  CoSEConstants.ANIMATE = FDLayoutConstants.ANIMATE = LayoutConstants.ANIMATE = options.animate;
  CoSEConstants.TILE = options.tile;
  CoSEConstants.TILING_PADDING_VERTICAL = typeof options.tilingPaddingVertical === 'function' ? options.tilingPaddingVertical.call() : options.tilingPaddingVertical;
  CoSEConstants.TILING_PADDING_HORIZONTAL = typeof options.tilingPaddingHorizontal === 'function' ? options.tilingPaddingHorizontal.call() : options.tilingPaddingHorizontal;
};

_CoSELayout.prototype.run = function () {
  var ready;
  var frameId;
  var options = this.options;
  var idToLNode = this.idToLNode = {};
  var layout = this.layout = new CoSELayout();
  var self = this;

  self.stopped = false;

  this.cy = this.options.cy;

  this.cy.trigger({ type: 'layoutstart', layout: this });

  var gm = layout.newGraphManager();
  this.gm = gm;

  var nodes = this.options.eles.nodes();
  var edges = this.options.eles.edges();

  this.root = gm.addRoot();
  this.processChildrenList(this.root, this.getTopMostNodes(nodes), layout);

  for (var i = 0; i < edges.length; i++) {
    var edge = edges[i];
    var sourceNode = this.idToLNode[edge.data("source")];
    var targetNode = this.idToLNode[edge.data("target")];
    if (sourceNode !== targetNode && sourceNode.getEdgesBetween(targetNode).length == 0) {
      var e1 = gm.add(layout.newEdge(), sourceNode, targetNode);
      e1.id = edge.id();
    }
  }

  var getPositions = function getPositions(ele, i) {
    if (typeof ele === "number") {
      ele = i;
    }
    var theId = ele.data('id');
    var lNode = self.idToLNode[theId];

    return {
      x: lNode.getRect().getCenterX(),
      y: lNode.getRect().getCenterY()
    };
  };

  /*
   * Reposition nodes in iterations animatedly
   */
  var iterateAnimated = function iterateAnimated() {
    // Thigs to perform after nodes are repositioned on screen
    var afterReposition = function afterReposition() {
      if (options.fit) {
        options.cy.fit(options.eles, options.padding);
      }

      if (!ready) {
        ready = true;
        self.cy.one('layoutready', options.ready);
        self.cy.trigger({ type: 'layoutready', layout: self });
      }
    };

    var ticksPerFrame = self.options.refresh;
    var isDone;

    for (var i = 0; i < ticksPerFrame && !isDone; i++) {
      isDone = self.stopped || self.layout.tick();
    }

    // If layout is done
    if (isDone) {
      // If the layout is not a sublayout and it is successful perform post layout.
      if (layout.checkLayoutSuccess() && !layout.isSubLayout) {
        layout.doPostLayout();
      }

      // If layout has a tilingPostLayout function property call it.
      if (layout.tilingPostLayout) {
        layout.tilingPostLayout();
      }

      layout.isLayoutFinished = true;

      self.options.eles.nodes().positions(getPositions);

      afterReposition();

      // trigger layoutstop when the layout stops (e.g. finishes)
      self.cy.one('layoutstop', self.options.stop);
      self.cy.trigger({ type: 'layoutstop', layout: self });

      if (frameId) {
        cancelAnimationFrame(frameId);
      }

      ready = false;
      return;
    }

    var animationData = self.layout.getPositionsData(); // Get positions of layout nodes note that all nodes may not be layout nodes because of tiling

    // Position nodes, for the nodes whose id does not included in data (because they are removed from their parents and included in dummy compounds)
    // use position of their ancestors or dummy ancestors
    options.eles.nodes().positions(function (ele, i) {
      if (typeof ele === "number") {
        ele = i;
      }
      // If ele is a compound node, then its position will be defined by its children
      if (!ele.isParent()) {
        var theId = ele.id();
        var pNode = animationData[theId];
        var temp = ele;
        // If pNode is undefined search until finding position data of its first ancestor (It may be dummy as well)
        while (pNode == null) {
          pNode = animationData[temp.data('parent')] || animationData['DummyCompound_' + temp.data('parent')];
          animationData[theId] = pNode;
          temp = temp.parent()[0];
          if (temp == undefined) {
            break;
          }
        }
        if (pNode != null) {
          return {
            x: pNode.x,
            y: pNode.y
          };
        } else {
          return {
            x: ele.position('x'),
            y: ele.position('y')
          };
        }
      }
    });

    afterReposition();

    frameId = requestAnimationFrame(iterateAnimated);
  };

  /*
  * Listen 'layoutstarted' event and start animated iteration if animate option is 'during'
  */
  layout.addListener('layoutstarted', function () {
    if (self.options.animate === 'during') {
      frameId = requestAnimationFrame(iterateAnimated);
    }
  });

  layout.runLayout(); // Run cose layout

  /*
   * If animate option is not 'during' ('end' or false) perform these here (If it is 'during' similar things are already performed)
   */
  if (this.options.animate !== "during") {
    self.options.eles.nodes().not(":parent").layoutPositions(self, self.options, getPositions); // Use layout positions to reposition the nodes it considers the options parameter
    ready = false;
  }

  return this; // chaining
};

//Get the top most ones of a list of nodes
_CoSELayout.prototype.getTopMostNodes = function (nodes) {
  var nodesMap = {};
  for (var i = 0; i < nodes.length; i++) {
    nodesMap[nodes[i].id()] = true;
  }
  var roots = nodes.filter(function (ele, i) {
    if (typeof ele === "number") {
      ele = i;
    }
    var parent = ele.parent()[0];
    while (parent != null) {
      if (nodesMap[parent.id()]) {
        return false;
      }
      parent = parent.parent()[0];
    }
    return true;
  });

  return roots;
};

_CoSELayout.prototype.processChildrenList = function (parent, children, layout) {
  var size = children.length;
  for (var i = 0; i < size; i++) {
    var theChild = children[i];
    var children_of_children = theChild.children();
    var theNode;

    var dimensions = theChild.layoutDimensions({
      nodeDimensionsIncludeLabels: this.options.nodeDimensionsIncludeLabels
    });

    if (theChild.outerWidth() != null && theChild.outerHeight() != null) {
      theNode = parent.add(new CoSENode(layout.graphManager, new PointD(theChild.position('x') - dimensions.w / 2, theChild.position('y') - dimensions.h / 2), new DimensionD(parseFloat(dimensions.w), parseFloat(dimensions.h))));
    } else {
      theNode = parent.add(new CoSENode(this.graphManager));
    }
    // Attach id to the layout node
    theNode.id = theChild.data("id");
    // Attach the paddings of cy node to layout node
    theNode.paddingLeft = parseInt(theChild.css('padding'));
    theNode.paddingTop = parseInt(theChild.css('padding'));
    theNode.paddingRight = parseInt(theChild.css('padding'));
    theNode.paddingBottom = parseInt(theChild.css('padding'));

    //Attach the label properties to compound if labels will be included in node dimensions  
    if (this.options.nodeDimensionsIncludeLabels) {
      if (theChild.isParent()) {
        var labelWidth = theChild.boundingBox({ includeLabels: true, includeNodes: false }).w;
        var labelHeight = theChild.boundingBox({ includeLabels: true, includeNodes: false }).h;
        var labelPos = theChild.css("text-halign");
        theNode.labelWidth = labelWidth;
        theNode.labelHeight = labelHeight;
        theNode.labelPos = labelPos;
      }
    }

    // Map the layout node
    this.idToLNode[theChild.data("id")] = theNode;

    if (isNaN(theNode.rect.x)) {
      theNode.rect.x = 0;
    }

    if (isNaN(theNode.rect.y)) {
      theNode.rect.y = 0;
    }

    if (children_of_children != null && children_of_children.length > 0) {
      var theNewGraph;
      theNewGraph = layout.getGraphManager().add(layout.newGraph(), theNode);
      this.processChildrenList(theNewGraph, children_of_children, layout);
    }
  }
};

/**
 * @brief : called on continuous layouts to stop them before they finish
 */
_CoSELayout.prototype.stop = function () {
  this.stopped = true;

  return this; // chaining
};

var register = function register(cytoscape) {
  //  var Layout = getLayout( cytoscape );

  cytoscape('layout', 'cose-bilkent', _CoSELayout);
};

// auto reg for globals
if (typeof cytoscape !== 'undefined') {
  register(cytoscape);
}

module.exports = register;

/***/ })
/******/ ]);
});

/***/ }),

/***/ 15790:
/***/ (function(module) {

/**
 * Copyright (c) 2016-2023, 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.
 */

(function (global, factory) {
   true ? module.exports = factory() :
  0;
})(this, (function () { 'use strict';

  function _typeof(obj) {
    "@babel/helpers - typeof";

    return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
      return typeof obj;
    } : function (obj) {
      return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
    }, _typeof(obj);
  }
  function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
      throw new TypeError("Cannot call a class as a function");
    }
  }
  function _defineProperties(target, props) {
    for (var i = 0; i < props.length; i++) {
      var descriptor = props[i];
      descriptor.enumerable = descriptor.enumerable || false;
      descriptor.configurable = true;
      if ("value" in descriptor) descriptor.writable = true;
      Object.defineProperty(target, descriptor.key, descriptor);
    }
  }
  function _createClass(Constructor, protoProps, staticProps) {
    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
    if (staticProps) _defineProperties(Constructor, staticProps);
    Object.defineProperty(Constructor, "prototype", {
      writable: false
    });
    return Constructor;
  }
  function _defineProperty$1(obj, key, value) {
    if (key in obj) {
      Object.defineProperty(obj, key, {
        value: value,
        enumerable: true,
        configurable: true,
        writable: true
      });
    } else {
      obj[key] = value;
    }
    return obj;
  }
  function _slicedToArray(arr, i) {
    return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
  }
  function _arrayWithHoles(arr) {
    if (Array.isArray(arr)) return arr;
  }
  function _iterableToArrayLimit(arr, i) {
    var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
    if (_i == null) return;
    var _arr = [];
    var _n = true;
    var _d = false;
    var _s, _e;
    try {
      for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
        _arr.push(_s.value);
        if (i && _arr.length === i) break;
      }
    } catch (err) {
      _d = true;
      _e = err;
    } finally {
      try {
        if (!_n && _i["return"] != null) _i["return"]();
      } finally {
        if (_d) throw _e;
      }
    }
    return _arr;
  }
  function _unsupportedIterableToArray(o, minLen) {
    if (!o) return;
    if (typeof o === "string") return _arrayLikeToArray(o, minLen);
    var n = Object.prototype.toString.call(o).slice(8, -1);
    if (n === "Object" && o.constructor) n = o.constructor.name;
    if (n === "Map" || n === "Set") return Array.from(o);
    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
  }
  function _arrayLikeToArray(arr, len) {
    if (len == null || len > arr.length) len = arr.length;
    for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
    return arr2;
  }
  function _nonIterableRest() {
    throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  }

  var _window = typeof window === 'undefined' ? null : window; // eslint-disable-line no-undef

  var navigator = _window ? _window.navigator : null;
  _window ? _window.document : null;
  var typeofstr = _typeof('');
  var typeofobj = _typeof({});
  var typeoffn = _typeof(function () {});
  var typeofhtmlele = typeof HTMLElement === "undefined" ? "undefined" : _typeof(HTMLElement);
  var instanceStr = function instanceStr(obj) {
    return obj && obj.instanceString && fn$6(obj.instanceString) ? obj.instanceString() : null;
  };

  var string = function string(obj) {
    return obj != null && _typeof(obj) == typeofstr;
  };
  var fn$6 = function fn(obj) {
    return obj != null && _typeof(obj) === typeoffn;
  };
  var array = function array(obj) {
    return !elementOrCollection(obj) && (Array.isArray ? Array.isArray(obj) : obj != null && obj instanceof Array);
  };
  var plainObject = function plainObject(obj) {
    return obj != null && _typeof(obj) === typeofobj && !array(obj) && obj.constructor === Object;
  };
  var object = function object(obj) {
    return obj != null && _typeof(obj) === typeofobj;
  };
  var number$1 = function number(obj) {
    return obj != null && _typeof(obj) === _typeof(1) && !isNaN(obj);
  };
  var integer = function integer(obj) {
    return number$1(obj) && Math.floor(obj) === obj;
  };
  var htmlElement = function htmlElement(obj) {
    if ('undefined' === typeofhtmlele) {
      return undefined;
    } else {
      return null != obj && obj instanceof HTMLElement;
    }
  };
  var elementOrCollection = function elementOrCollection(obj) {
    return element(obj) || collection(obj);
  };
  var element = function element(obj) {
    return instanceStr(obj) === 'collection' && obj._private.single;
  };
  var collection = function collection(obj) {
    return instanceStr(obj) === 'collection' && !obj._private.single;
  };
  var core = function core(obj) {
    return instanceStr(obj) === 'core';
  };
  var stylesheet = function stylesheet(obj) {
    return instanceStr(obj) === 'stylesheet';
  };
  var event = function event(obj) {
    return instanceStr(obj) === 'event';
  };
  var emptyString = function emptyString(obj) {
    if (obj === undefined || obj === null) {
      // null is empty
      return true;
    } else if (obj === '' || obj.match(/^\s+$/)) {
      return true; // empty string is empty
    }

    return false; // otherwise, we don't know what we've got
  };
  var domElement = function domElement(obj) {
    if (typeof HTMLElement === 'undefined') {
      return false; // we're not in a browser so it doesn't matter
    } else {
      return obj instanceof HTMLElement;
    }
  };
  var boundingBox = function boundingBox(obj) {
    return plainObject(obj) && number$1(obj.x1) && number$1(obj.x2) && number$1(obj.y1) && number$1(obj.y2);
  };
  var promise = function promise(obj) {
    return object(obj) && fn$6(obj.then);
  };
  var ms = function ms() {
    return navigator && navigator.userAgent.match(/msie|trident|edge/i);
  }; // probably a better way to detect this...

  var memoize$1 = function memoize(fn, keyFn) {
    if (!keyFn) {
      keyFn = function keyFn() {
        if (arguments.length === 1) {
          return arguments[0];
        } else if (arguments.length === 0) {
          return 'undefined';
        }
        var args = [];
        for (var i = 0; i < arguments.length; i++) {
          args.push(arguments[i]);
        }
        return args.join('$');
      };
    }
    var memoizedFn = function memoizedFn() {
      var self = this;
      var args = arguments;
      var ret;
      var k = keyFn.apply(self, args);
      var cache = memoizedFn.cache;
      if (!(ret = cache[k])) {
        ret = cache[k] = fn.apply(self, args);
      }
      return ret;
    };
    memoizedFn.cache = {};
    return memoizedFn;
  };

  var camel2dash = memoize$1(function (str) {
    return str.replace(/([A-Z])/g, function (v) {
      return '-' + v.toLowerCase();
    });
  });
  var dash2camel = memoize$1(function (str) {
    return str.replace(/(-\w)/g, function (v) {
      return v[1].toUpperCase();
    });
  });
  var prependCamel = memoize$1(function (prefix, str) {
    return prefix + str[0].toUpperCase() + str.substring(1);
  }, function (prefix, str) {
    return prefix + '$' + str;
  });
  var capitalize = function capitalize(str) {
    if (emptyString(str)) {
      return str;
    }
    return str.charAt(0).toUpperCase() + str.substring(1);
  };

  var number = '(?:[-+]?(?:(?:\\d+|\\d*\\.\\d+)(?:[Ee][+-]?\\d+)?))';
  var rgba = 'rgb[a]?\\((' + number + '[%]?)\\s*,\\s*(' + number + '[%]?)\\s*,\\s*(' + number + '[%]?)(?:\\s*,\\s*(' + number + '))?\\)';
  var rgbaNoBackRefs = 'rgb[a]?\\((?:' + number + '[%]?)\\s*,\\s*(?:' + number + '[%]?)\\s*,\\s*(?:' + number + '[%]?)(?:\\s*,\\s*(?:' + number + '))?\\)';
  var hsla = 'hsl[a]?\\((' + number + ')\\s*,\\s*(' + number + '[%])\\s*,\\s*(' + number + '[%])(?:\\s*,\\s*(' + number + '))?\\)';
  var hslaNoBackRefs = 'hsl[a]?\\((?:' + number + ')\\s*,\\s*(?:' + number + '[%])\\s*,\\s*(?:' + number + '[%])(?:\\s*,\\s*(?:' + number + '))?\\)';
  var hex3 = '\\#[0-9a-fA-F]{3}';
  var hex6 = '\\#[0-9a-fA-F]{6}';

  var ascending = function ascending(a, b) {
    if (a < b) {
      return -1;
    } else if (a > b) {
      return 1;
    } else {
      return 0;
    }
  };
  var descending = function descending(a, b) {
    return -1 * ascending(a, b);
  };

  var extend = Object.assign != null ? Object.assign.bind(Object) : function (tgt) {
    var args = arguments;
    for (var i = 1; i < args.length; i++) {
      var obj = args[i];
      if (obj == null) {
        continue;
      }
      var keys = Object.keys(obj);
      for (var j = 0; j < keys.length; j++) {
        var k = keys[j];
        tgt[k] = obj[k];
      }
    }
    return tgt;
  };

  // get [r, g, b] from #abc or #aabbcc
  var hex2tuple = function hex2tuple(hex) {
    if (!(hex.length === 4 || hex.length === 7) || hex[0] !== '#') {
      return;
    }
    var shortHex = hex.length === 4;
    var r, g, b;
    var base = 16;
    if (shortHex) {
      r = parseInt(hex[1] + hex[1], base);
      g = parseInt(hex[2] + hex[2], base);
      b = parseInt(hex[3] + hex[3], base);
    } else {
      r = parseInt(hex[1] + hex[2], base);
      g = parseInt(hex[3] + hex[4], base);
      b = parseInt(hex[5] + hex[6], base);
    }
    return [r, g, b];
  };

  // get [r, g, b, a] from hsl(0, 0, 0) or hsla(0, 0, 0, 0)
  var hsl2tuple = function hsl2tuple(hsl) {
    var ret;
    var h, s, l, a, r, g, b;
    function hue2rgb(p, q, t) {
      if (t < 0) t += 1;
      if (t > 1) t -= 1;
      if (t < 1 / 6) return p + (q - p) * 6 * t;
      if (t < 1 / 2) return q;
      if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
      return p;
    }
    var m = new RegExp('^' + hsla + '$').exec(hsl);
    if (m) {
      // get hue
      h = parseInt(m[1]);
      if (h < 0) {
        h = (360 - -1 * h % 360) % 360;
      } else if (h > 360) {
        h = h % 360;
      }
      h /= 360; // normalise on [0, 1]

      s = parseFloat(m[2]);
      if (s < 0 || s > 100) {
        return;
      } // saturation is [0, 100]
      s = s / 100; // normalise on [0, 1]

      l = parseFloat(m[3]);
      if (l < 0 || l > 100) {
        return;
      } // lightness is [0, 100]
      l = l / 100; // normalise on [0, 1]

      a = m[4];
      if (a !== undefined) {
        a = parseFloat(a);
        if (a < 0 || a > 1) {
          return;
        } // alpha is [0, 1]
      }

      // now, convert to rgb
      // code from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
      if (s === 0) {
        r = g = b = Math.round(l * 255); // achromatic
      } else {
        var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
        var p = 2 * l - q;
        r = Math.round(255 * hue2rgb(p, q, h + 1 / 3));
        g = Math.round(255 * hue2rgb(p, q, h));
        b = Math.round(255 * hue2rgb(p, q, h - 1 / 3));
      }
      ret = [r, g, b, a];
    }
    return ret;
  };

  // get [r, g, b, a] from rgb(0, 0, 0) or rgba(0, 0, 0, 0)
  var rgb2tuple = function rgb2tuple(rgb) {
    var ret;
    var m = new RegExp('^' + rgba + '$').exec(rgb);
    if (m) {
      ret = [];
      var isPct = [];
      for (var i = 1; i <= 3; i++) {
        var channel = m[i];
        if (channel[channel.length - 1] === '%') {
          isPct[i] = true;
        }
        channel = parseFloat(channel);
        if (isPct[i]) {
          channel = channel / 100 * 255; // normalise to [0, 255]
        }

        if (channel < 0 || channel > 255) {
          return;
        } // invalid channel value

        ret.push(Math.floor(channel));
      }
      var atLeastOneIsPct = isPct[1] || isPct[2] || isPct[3];
      var allArePct = isPct[1] && isPct[2] && isPct[3];
      if (atLeastOneIsPct && !allArePct) {
        return;
      } // must all be percent values if one is

      var alpha = m[4];
      if (alpha !== undefined) {
        alpha = parseFloat(alpha);
        if (alpha < 0 || alpha > 1) {
          return;
        } // invalid alpha value

        ret.push(alpha);
      }
    }
    return ret;
  };
  var colorname2tuple = function colorname2tuple(color) {
    return colors[color.toLowerCase()];
  };
  var color2tuple = function color2tuple(color) {
    return (array(color) ? color : null) || colorname2tuple(color) || hex2tuple(color) || rgb2tuple(color) || hsl2tuple(color);
  };
  var colors = {
    // special colour names
    transparent: [0, 0, 0, 0],
    // NB alpha === 0

    // regular colours
    aliceblue: [240, 248, 255],
    antiquewhite: [250, 235, 215],
    aqua: [0, 255, 255],
    aquamarine: [127, 255, 212],
    azure: [240, 255, 255],
    beige: [245, 245, 220],
    bisque: [255, 228, 196],
    black: [0, 0, 0],
    blanchedalmond: [255, 235, 205],
    blue: [0, 0, 255],
    blueviolet: [138, 43, 226],
    brown: [165, 42, 42],
    burlywood: [222, 184, 135],
    cadetblue: [95, 158, 160],
    chartreuse: [127, 255, 0],
    chocolate: [210, 105, 30],
    coral: [255, 127, 80],
    cornflowerblue: [100, 149, 237],
    cornsilk: [255, 248, 220],
    crimson: [220, 20, 60],
    cyan: [0, 255, 255],
    darkblue: [0, 0, 139],
    darkcyan: [0, 139, 139],
    darkgoldenrod: [184, 134, 11],
    darkgray: [169, 169, 169],
    darkgreen: [0, 100, 0],
    darkgrey: [169, 169, 169],
    darkkhaki: [189, 183, 107],
    darkmagenta: [139, 0, 139],
    darkolivegreen: [85, 107, 47],
    darkorange: [255, 140, 0],
    darkorchid: [153, 50, 204],
    darkred: [139, 0, 0],
    darksalmon: [233, 150, 122],
    darkseagreen: [143, 188, 143],
    darkslateblue: [72, 61, 139],
    darkslategray: [47, 79, 79],
    darkslategrey: [47, 79, 79],
    darkturquoise: [0, 206, 209],
    darkviolet: [148, 0, 211],
    deeppink: [255, 20, 147],
    deepskyblue: [0, 191, 255],
    dimgray: [105, 105, 105],
    dimgrey: [105, 105, 105],
    dodgerblue: [30, 144, 255],
    firebrick: [178, 34, 34],
    floralwhite: [255, 250, 240],
    forestgreen: [34, 139, 34],
    fuchsia: [255, 0, 255],
    gainsboro: [220, 220, 220],
    ghostwhite: [248, 248, 255],
    gold: [255, 215, 0],
    goldenrod: [218, 165, 32],
    gray: [128, 128, 128],
    grey: [128, 128, 128],
    green: [0, 128, 0],
    greenyellow: [173, 255, 47],
    honeydew: [240, 255, 240],
    hotpink: [255, 105, 180],
    indianred: [205, 92, 92],
    indigo: [75, 0, 130],
    ivory: [255, 255, 240],
    khaki: [240, 230, 140],
    lavender: [230, 230, 250],
    lavenderblush: [255, 240, 245],
    lawngreen: [124, 252, 0],
    lemonchiffon: [255, 250, 205],
    lightblue: [173, 216, 230],
    lightcoral: [240, 128, 128],
    lightcyan: [224, 255, 255],
    lightgoldenrodyellow: [250, 250, 210],
    lightgray: [211, 211, 211],
    lightgreen: [144, 238, 144],
    lightgrey: [211, 211, 211],
    lightpink: [255, 182, 193],
    lightsalmon: [255, 160, 122],
    lightseagreen: [32, 178, 170],
    lightskyblue: [135, 206, 250],
    lightslategray: [119, 136, 153],
    lightslategrey: [119, 136, 153],
    lightsteelblue: [176, 196, 222],
    lightyellow: [255, 255, 224],
    lime: [0, 255, 0],
    limegreen: [50, 205, 50],
    linen: [250, 240, 230],
    magenta: [255, 0, 255],
    maroon: [128, 0, 0],
    mediumaquamarine: [102, 205, 170],
    mediumblue: [0, 0, 205],
    mediumorchid: [186, 85, 211],
    mediumpurple: [147, 112, 219],
    mediumseagreen: [60, 179, 113],
    mediumslateblue: [123, 104, 238],
    mediumspringgreen: [0, 250, 154],
    mediumturquoise: [72, 209, 204],
    mediumvioletred: [199, 21, 133],
    midnightblue: [25, 25, 112],
    mintcream: [245, 255, 250],
    mistyrose: [255, 228, 225],
    moccasin: [255, 228, 181],
    navajowhite: [255, 222, 173],
    navy: [0, 0, 128],
    oldlace: [253, 245, 230],
    olive: [128, 128, 0],
    olivedrab: [107, 142, 35],
    orange: [255, 165, 0],
    orangered: [255, 69, 0],
    orchid: [218, 112, 214],
    palegoldenrod: [238, 232, 170],
    palegreen: [152, 251, 152],
    paleturquoise: [175, 238, 238],
    palevioletred: [219, 112, 147],
    papayawhip: [255, 239, 213],
    peachpuff: [255, 218, 185],
    peru: [205, 133, 63],
    pink: [255, 192, 203],
    plum: [221, 160, 221],
    powderblue: [176, 224, 230],
    purple: [128, 0, 128],
    red: [255, 0, 0],
    rosybrown: [188, 143, 143],
    royalblue: [65, 105, 225],
    saddlebrown: [139, 69, 19],
    salmon: [250, 128, 114],
    sandybrown: [244, 164, 96],
    seagreen: [46, 139, 87],
    seashell: [255, 245, 238],
    sienna: [160, 82, 45],
    silver: [192, 192, 192],
    skyblue: [135, 206, 235],
    slateblue: [106, 90, 205],
    slategray: [112, 128, 144],
    slategrey: [112, 128, 144],
    snow: [255, 250, 250],
    springgreen: [0, 255, 127],
    steelblue: [70, 130, 180],
    tan: [210, 180, 140],
    teal: [0, 128, 128],
    thistle: [216, 191, 216],
    tomato: [255, 99, 71],
    turquoise: [64, 224, 208],
    violet: [238, 130, 238],
    wheat: [245, 222, 179],
    white: [255, 255, 255],
    whitesmoke: [245, 245, 245],
    yellow: [255, 255, 0],
    yellowgreen: [154, 205, 50]
  };

  // sets the value in a map (map may not be built)
  var setMap = function setMap(options) {
    var obj = options.map;
    var keys = options.keys;
    var l = keys.length;
    for (var i = 0; i < l; i++) {
      var key = keys[i];
      if (plainObject(key)) {
        throw Error('Tried to set map with object key');
      }
      if (i < keys.length - 1) {
        // extend the map if necessary
        if (obj[key] == null) {
          obj[key] = {};
        }
        obj = obj[key];
      } else {
        // set the value
        obj[key] = options.value;
      }
    }
  };

  // gets the value in a map even if it's not built in places
  var getMap = function getMap(options) {
    var obj = options.map;
    var keys = options.keys;
    var l = keys.length;
    for (var i = 0; i < l; i++) {
      var key = keys[i];
      if (plainObject(key)) {
        throw Error('Tried to get map with object key');
      }
      obj = obj[key];
      if (obj == null) {
        return obj;
      }
    }
    return obj;
  };

  /**
   * 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
   */
  function isObject(value) {
    var type = typeof value;
    return value != null && (type == 'object' || type == 'function');
  }

  var isObject_1 = isObject;

  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};

  function createCommonjsModule(fn, module) {
  	return module = { exports: {} }, fn(module, module.exports), module.exports;
  }

  /** Detect free variable `global` from Node.js. */
  var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;

  var _freeGlobal = freeGlobal;

  /** Detect free variable `self`. */
  var freeSelf = typeof self == 'object' && self && self.Object === Object && self;

  /** Used as a reference to the global object. */
  var root = _freeGlobal || freeSelf || Function('return this')();

  var _root = root;

  /**
   * 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.
   */
  var now = function() {
    return _root.Date.now();
  };

  var now_1 = now;

  /** Used to match a single whitespace character. */
  var reWhitespace = /\s/;

  /**
   * 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.
   */
  function trimmedEndIndex(string) {
    var index = string.length;

    while (index-- && reWhitespace.test(string.charAt(index))) {}
    return index;
  }

  var _trimmedEndIndex = trimmedEndIndex;

  /** Used to match leading whitespace. */
  var reTrimStart = /^\s+/;

  /**
   * The base implementation of `_.trim`.
   *
   * @private
   * @param {string} string The string to trim.
   * @returns {string} Returns the trimmed string.
   */
  function baseTrim(string) {
    return string
      ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '')
      : string;
  }

  var _baseTrim = baseTrim;

  /** Built-in value references. */
  var Symbol$1 = _root.Symbol;

  var _Symbol = Symbol$1;

  /** Used for built-in method references. */
  var objectProto$5 = Object.prototype;

  /** Used to check objects for own properties. */
  var hasOwnProperty$4 = objectProto$5.hasOwnProperty;

  /**
   * Used to resolve the
   * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
   * of values.
   */
  var nativeObjectToString$1 = objectProto$5.toString;

  /** Built-in value references. */
  var symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined;

  /**
   * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
   *
   * @private
   * @param {*} value The value to query.
   * @returns {string} Returns the raw `toStringTag`.
   */
  function getRawTag(value) {
    var isOwn = hasOwnProperty$4.call(value, symToStringTag$1),
        tag = value[symToStringTag$1];

    try {
      value[symToStringTag$1] = undefined;
      var unmasked = true;
    } catch (e) {}

    var result = nativeObjectToString$1.call(value);
    if (unmasked) {
      if (isOwn) {
        value[symToStringTag$1] = tag;
      } else {
        delete value[symToStringTag$1];
      }
    }
    return result;
  }

  var _getRawTag = getRawTag;

  /** Used for built-in method references. */
  var objectProto$4 = Object.prototype;

  /**
   * Used to resolve the
   * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
   * of values.
   */
  var nativeObjectToString = objectProto$4.toString;

  /**
   * Converts `value` to a string using `Object.prototype.toString`.
   *
   * @private
   * @param {*} value The value to convert.
   * @returns {string} Returns the converted string.
   */
  function objectToString(value) {
    return nativeObjectToString.call(value);
  }

  var _objectToString = objectToString;

  /** `Object#toString` result references. */
  var nullTag = '[object Null]',
      undefinedTag = '[object Undefined]';

  /** Built-in value references. */
  var symToStringTag = _Symbol ? _Symbol.toStringTag : undefined;

  /**
   * The base implementation of `getTag` without fallbacks for buggy environments.
   *
   * @private
   * @param {*} value The value to query.
   * @returns {string} Returns the `toStringTag`.
   */
  function baseGetTag(value) {
    if (value == null) {
      return value === undefined ? undefinedTag : nullTag;
    }
    return (symToStringTag && symToStringTag in Object(value))
      ? _getRawTag(value)
      : _objectToString(value);
  }

  var _baseGetTag = baseGetTag;

  /**
   * 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
   */
  function isObjectLike(value) {
    return value != null && typeof value == 'object';
  }

  var isObjectLike_1 = isObjectLike;

  /** `Object#toString` result references. */
  var symbolTag = '[object Symbol]';

  /**
   * 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
   */
  function isSymbol(value) {
    return typeof value == 'symbol' ||
      (isObjectLike_1(value) && _baseGetTag(value) == symbolTag);
  }

  var isSymbol_1 = isSymbol;

  /** Used as references for various `Number` constants. */
  var NAN = 0 / 0;

  /** Used to detect bad signed hexadecimal string values. */
  var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;

  /** Used to detect binary string values. */
  var reIsBinary = /^0b[01]+$/i;

  /** Used to detect octal string values. */
  var reIsOctal = /^0o[0-7]+$/i;

  /** Built-in method references without a dependency on `root`. */
  var freeParseInt = parseInt;

  /**
   * 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
   */
  function toNumber(value) {
    if (typeof value == 'number') {
      return value;
    }
    if (isSymbol_1(value)) {
      return NAN;
    }
    if (isObject_1(value)) {
      var other = typeof value.valueOf == 'function' ? value.valueOf() : value;
      value = isObject_1(other) ? (other + '') : other;
    }
    if (typeof value != 'string') {
      return value === 0 ? value : +value;
    }
    value = _baseTrim(value);
    var isBinary = reIsBinary.test(value);
    return (isBinary || reIsOctal.test(value))
      ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
      : (reIsBadHex.test(value) ? NAN : +value);
  }

  var toNumber_1 = toNumber;

  /** Error message constants. */
  var FUNC_ERROR_TEXT$1 = 'Expected a function';

  /* Built-in method references for those with the same name as other `lodash` methods. */
  var nativeMax = Math.max,
      nativeMin = Math.min;

  /**
   * 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);
   */
  function debounce(func, wait, options) {
    var lastArgs,
        lastThis,
        maxWait,
        result,
        timerId,
        lastCallTime,
        lastInvokeTime = 0,
        leading = false,
        maxing = false,
        trailing = true;

    if (typeof func != 'function') {
      throw new TypeError(FUNC_ERROR_TEXT$1);
    }
    wait = toNumber_1(wait) || 0;
    if (isObject_1(options)) {
      leading = !!options.leading;
      maxing = 'maxWait' in options;
      maxWait = maxing ? nativeMax(toNumber_1(options.maxWait) || 0, wait) : maxWait;
      trailing = 'trailing' in options ? !!options.trailing : trailing;
    }

    function invokeFunc(time) {
      var args = lastArgs,
          thisArg = lastThis;

      lastArgs = lastThis = undefined;
      lastInvokeTime = time;
      result = func.apply(thisArg, args);
      return result;
    }

    function leadingEdge(time) {
      // Reset any `maxWait` timer.
      lastInvokeTime = time;
      // Start the timer for the trailing edge.
      timerId = setTimeout(timerExpired, wait);
      // Invoke the leading edge.
      return leading ? invokeFunc(time) : result;
    }

    function remainingWait(time) {
      var timeSinceLastCall = time - lastCallTime,
          timeSinceLastInvoke = time - lastInvokeTime,
          timeWaiting = wait - timeSinceLastCall;

      return maxing
        ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
        : timeWaiting;
    }

    function shouldInvoke(time) {
      var timeSinceLastCall = time - lastCallTime,
          timeSinceLastInvoke = time - lastInvokeTime;

      // Either this is the first call, activity has stopped and we're at the
      // trailing edge, the system time has gone backwards and we're treating
      // it as the trailing edge, or we've hit the `maxWait` limit.
      return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
        (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));
    }

    function timerExpired() {
      var time = now_1();
      if (shouldInvoke(time)) {
        return trailingEdge(time);
      }
      // Restart the timer.
      timerId = setTimeout(timerExpired, remainingWait(time));
    }

    function trailingEdge(time) {
      timerId = undefined;

      // Only invoke if we have `lastArgs` which means `func` has been
      // debounced at least once.
      if (trailing && lastArgs) {
        return invokeFunc(time);
      }
      lastArgs = lastThis = undefined;
      return result;
    }

    function cancel() {
      if (timerId !== undefined) {
        clearTimeout(timerId);
      }
      lastInvokeTime = 0;
      lastArgs = lastCallTime = lastThis = timerId = undefined;
    }

    function flush() {
      return timerId === undefined ? result : trailingEdge(now_1());
    }

    function debounced() {
      var time = now_1(),
          isInvoking = shouldInvoke(time);

      lastArgs = arguments;
      lastThis = this;
      lastCallTime = time;

      if (isInvoking) {
        if (timerId === undefined) {
          return leadingEdge(lastCallTime);
        }
        if (maxing) {
          // Handle invocations in a tight loop.
          clearTimeout(timerId);
          timerId = setTimeout(timerExpired, wait);
          return invokeFunc(lastCallTime);
        }
      }
      if (timerId === undefined) {
        timerId = setTimeout(timerExpired, wait);
      }
      return result;
    }
    debounced.cancel = cancel;
    debounced.flush = flush;
    return debounced;
  }

  var debounce_1 = debounce;

  var performance = _window ? _window.performance : null;
  var pnow = performance && performance.now ? function () {
    return performance.now();
  } : function () {
    return Date.now();
  };
  var raf = function () {
    if (_window) {
      if (_window.requestAnimationFrame) {
        return function (fn) {
          _window.requestAnimationFrame(fn);
        };
      } else if (_window.mozRequestAnimationFrame) {
        return function (fn) {
          _window.mozRequestAnimationFrame(fn);
        };
      } else if (_window.webkitRequestAnimationFrame) {
        return function (fn) {
          _window.webkitRequestAnimationFrame(fn);
        };
      } else if (_window.msRequestAnimationFrame) {
        return function (fn) {
          _window.msRequestAnimationFrame(fn);
        };
      }
    }
    return function (fn) {
      if (fn) {
        setTimeout(function () {
          fn(pnow());
        }, 1000 / 60);
      }
    };
  }();
  var requestAnimationFrame = function requestAnimationFrame(fn) {
    return raf(fn);
  };
  var performanceNow = pnow;

  var DEFAULT_HASH_SEED = 9261;
  var K = 65599; // 37 also works pretty well
  var DEFAULT_HASH_SEED_ALT = 5381;
  var hashIterableInts = function hashIterableInts(iterator) {
    var seed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_HASH_SEED;
    // sdbm/string-hash
    var hash = seed;
    var entry;
    for (;;) {
      entry = iterator.next();
      if (entry.done) {
        break;
      }
      hash = hash * K + entry.value | 0;
    }
    return hash;
  };
  var hashInt = function hashInt(num) {
    var seed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_HASH_SEED;
    // sdbm/string-hash
    return seed * K + num | 0;
  };
  var hashIntAlt = function hashIntAlt(num) {
    var seed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_HASH_SEED_ALT;
    // djb2/string-hash
    return (seed << 5) + seed + num | 0;
  };
  var combineHashes = function combineHashes(hash1, hash2) {
    return hash1 * 0x200000 + hash2;
  };
  var combineHashesArray = function combineHashesArray(hashes) {
    return hashes[0] * 0x200000 + hashes[1];
  };
  var hashArrays = function hashArrays(hashes1, hashes2) {
    return [hashInt(hashes1[0], hashes2[0]), hashIntAlt(hashes1[1], hashes2[1])];
  };
  var hashIntsArray = function hashIntsArray(ints, seed) {
    var entry = {
      value: 0,
      done: false
    };
    var i = 0;
    var length = ints.length;
    var iterator = {
      next: function next() {
        if (i < length) {
          entry.value = ints[i++];
        } else {
          entry.done = true;
        }
        return entry;
      }
    };
    return hashIterableInts(iterator, seed);
  };
  var hashString = function hashString(str, seed) {
    var entry = {
      value: 0,
      done: false
    };
    var i = 0;
    var length = str.length;
    var iterator = {
      next: function next() {
        if (i < length) {
          entry.value = str.charCodeAt(i++);
        } else {
          entry.done = true;
        }
        return entry;
      }
    };
    return hashIterableInts(iterator, seed);
  };
  var hashStrings = function hashStrings() {
    return hashStringsArray(arguments);
  };
  var hashStringsArray = function hashStringsArray(strs) {
    var hash;
    for (var i = 0; i < strs.length; i++) {
      var str = strs[i];
      if (i === 0) {
        hash = hashString(str);
      } else {
        hash = hashString(str, hash);
      }
    }
    return hash;
  };

  /*global console */
  var warningsEnabled = true;
  var warnSupported = console.warn != null; // eslint-disable-line no-console
  var traceSupported = console.trace != null; // eslint-disable-line no-console

  var MAX_INT$1 = Number.MAX_SAFE_INTEGER || 9007199254740991;
  var trueify = function trueify() {
    return true;
  };
  var falsify = function falsify() {
    return false;
  };
  var zeroify = function zeroify() {
    return 0;
  };
  var noop$1 = function noop() {};
  var error = function error(msg) {
    throw new Error(msg);
  };
  var warnings = function warnings(enabled) {
    if (enabled !== undefined) {
      warningsEnabled = !!enabled;
    } else {
      return warningsEnabled;
    }
  };
  var warn = function warn(msg) {
    /* eslint-disable no-console */
    if (!warnings()) {
      return;
    }
    if (warnSupported) {
      console.warn(msg);
    } else {
      console.log(msg);
      if (traceSupported) {
        console.trace();
      }
    }
  }; /* eslint-enable */

  var clone = function clone(obj) {
    return extend({}, obj);
  };

  // gets a shallow copy of the argument
  var copy = function copy(obj) {
    if (obj == null) {
      return obj;
    }
    if (array(obj)) {
      return obj.slice();
    } else if (plainObject(obj)) {
      return clone(obj);
    } else {
      return obj;
    }
  };
  var copyArray$1 = function copyArray(arr) {
    return arr.slice();
  };
  var uuid = function uuid(a, b /* placeholders */) {
    for (
    // loop :)
    b = a = '';
    // b - result , a - numeric letiable
    a++ < 36;
    //
    b += a * 51 & 52 // if "a" is not 9 or 14 or 19 or 24
    ?
    //  return a random number or 4
    (a ^ 15 // if "a" is not 15
    ?
    // generate a random number from 0 to 15
    8 ^ Math.random() * (a ^ 20 ? 16 : 4) // unless "a" is 20, in which case a random number from 8 to 11
    : 4 //  otherwise 4
    ).toString(16) : '-' //  in other cases (if "a" is 9,14,19,24) insert "-"
    ) {
    }
    return b;
  };
  var _staticEmptyObject = {};
  var staticEmptyObject = function staticEmptyObject() {
    return _staticEmptyObject;
  };
  var defaults$g = function defaults(_defaults) {
    var keys = Object.keys(_defaults);
    return function (opts) {
      var filledOpts = {};
      for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        var optVal = opts == null ? undefined : opts[key];
        filledOpts[key] = optVal === undefined ? _defaults[key] : optVal;
      }
      return filledOpts;
    };
  };
  var removeFromArray = function removeFromArray(arr, ele, oneCopy) {
    for (var i = arr.length - 1; i >= 0; i--) {
      if (arr[i] === ele) {
        arr.splice(i, 1);
        if (oneCopy) {
          break;
        }
      }
    }
  };
  var clearArray = function clearArray(arr) {
    arr.splice(0, arr.length);
  };
  var push = function push(arr, otherArr) {
    for (var i = 0; i < otherArr.length; i++) {
      var el = otherArr[i];
      arr.push(el);
    }
  };
  var getPrefixedProperty = function getPrefixedProperty(obj, propName, prefix) {
    if (prefix) {
      propName = prependCamel(prefix, propName); // e.g. (labelWidth, source) => sourceLabelWidth
    }

    return obj[propName];
  };
  var setPrefixedProperty = function setPrefixedProperty(obj, propName, prefix, value) {
    if (prefix) {
      propName = prependCamel(prefix, propName); // e.g. (labelWidth, source) => sourceLabelWidth
    }

    obj[propName] = value;
  };

  /* global Map */
  var ObjectMap = /*#__PURE__*/function () {
    function ObjectMap() {
      _classCallCheck(this, ObjectMap);
      this._obj = {};
    }
    _createClass(ObjectMap, [{
      key: "set",
      value: function set(key, val) {
        this._obj[key] = val;
        return this;
      }
    }, {
      key: "delete",
      value: function _delete(key) {
        this._obj[key] = undefined;
        return this;
      }
    }, {
      key: "clear",
      value: function clear() {
        this._obj = {};
      }
    }, {
      key: "has",
      value: function has(key) {
        return this._obj[key] !== undefined;
      }
    }, {
      key: "get",
      value: function get(key) {
        return this._obj[key];
      }
    }]);
    return ObjectMap;
  }();
  var Map$2 = typeof Map !== 'undefined' ? Map : ObjectMap;

  /* global Set */

  var undef = "undefined" ;
  var ObjectSet = /*#__PURE__*/function () {
    function ObjectSet(arrayOrObjectSet) {
      _classCallCheck(this, ObjectSet);
      this._obj = Object.create(null);
      this.size = 0;
      if (arrayOrObjectSet != null) {
        var arr;
        if (arrayOrObjectSet.instanceString != null && arrayOrObjectSet.instanceString() === this.instanceString()) {
          arr = arrayOrObjectSet.toArray();
        } else {
          arr = arrayOrObjectSet;
        }
        for (var i = 0; i < arr.length; i++) {
          this.add(arr[i]);
        }
      }
    }
    _createClass(ObjectSet, [{
      key: "instanceString",
      value: function instanceString() {
        return 'set';
      }
    }, {
      key: "add",
      value: function add(val) {
        var o = this._obj;
        if (o[val] !== 1) {
          o[val] = 1;
          this.size++;
        }
      }
    }, {
      key: "delete",
      value: function _delete(val) {
        var o = this._obj;
        if (o[val] === 1) {
          o[val] = 0;
          this.size--;
        }
      }
    }, {
      key: "clear",
      value: function clear() {
        this._obj = Object.create(null);
      }
    }, {
      key: "has",
      value: function has(val) {
        return this._obj[val] === 1;
      }
    }, {
      key: "toArray",
      value: function toArray() {
        var _this = this;
        return Object.keys(this._obj).filter(function (key) {
          return _this.has(key);
        });
      }
    }, {
      key: "forEach",
      value: function forEach(callback, thisArg) {
        return this.toArray().forEach(callback, thisArg);
      }
    }]);
    return ObjectSet;
  }();
  var Set$1 = (typeof Set === "undefined" ? "undefined" : _typeof(Set)) !== undef ? Set : ObjectSet;

  // represents a node or an edge
  var Element = function Element(cy, params) {
    var restore = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
    if (cy === undefined || params === undefined || !core(cy)) {
      error('An element must have a core reference and parameters set');
      return;
    }
    var group = params.group;

    // try to automatically infer the group if unspecified
    if (group == null) {
      if (params.data && params.data.source != null && params.data.target != null) {
        group = 'edges';
      } else {
        group = 'nodes';
      }
    }

    // validate group
    if (group !== 'nodes' && group !== 'edges') {
      error('An element must be of type `nodes` or `edges`; you specified `' + group + '`');
      return;
    }

    // make the element array-like, just like a collection
    this.length = 1;
    this[0] = this;

    // NOTE: when something is added here, add also to ele.json()
    var _p = this._private = {
      cy: cy,
      single: true,
      // indicates this is an element
      data: params.data || {},
      // data object
      position: params.position || {
        x: 0,
        y: 0
      },
      // (x, y) position pair
      autoWidth: undefined,
      // width and height of nodes calculated by the renderer when set to special 'auto' value
      autoHeight: undefined,
      autoPadding: undefined,
      compoundBoundsClean: false,
      // whether the compound dimensions need to be recalculated the next time dimensions are read
      listeners: [],
      // array of bound listeners
      group: group,
      // string; 'nodes' or 'edges'
      style: {},
      // properties as set by the style
      rstyle: {},
      // properties for style sent from the renderer to the core
      styleCxts: [],
      // applied style contexts from the styler
      styleKeys: {},
      // per-group keys of style property values
      removed: true,
      // whether it's inside the vis; true if removed (set true here since we call restore)
      selected: params.selected ? true : false,
      // whether it's selected
      selectable: params.selectable === undefined ? true : params.selectable ? true : false,
      // whether it's selectable
      locked: params.locked ? true : false,
      // whether the element is locked (cannot be moved)
      grabbed: false,
      // whether the element is grabbed by the mouse; renderer sets this privately
      grabbable: params.grabbable === undefined ? true : params.grabbable ? true : false,
      // whether the element can be grabbed
      pannable: params.pannable === undefined ? group === 'edges' ? true : false : params.pannable ? true : false,
      // whether the element has passthrough panning enabled
      active: false,
      // whether the element is active from user interaction
      classes: new Set$1(),
      // map ( className => true )
      animation: {
        // object for currently-running animations
        current: [],
        queue: []
      },
      rscratch: {},
      // object in which the renderer can store information
      scratch: params.scratch || {},
      // scratch objects
      edges: [],
      // array of connected edges
      children: [],
      // array of children
      parent: params.parent && params.parent.isNode() ? params.parent : null,
      // parent ref
      traversalCache: {},
      // cache of output of traversal functions
      backgrounding: false,
      // whether background images are loading
      bbCache: null,
      // cache of the current bounding box
      bbCacheShift: {
        x: 0,
        y: 0
      },
      // shift applied to cached bb to be applied on next get
      bodyBounds: null,
      // bounds cache of element body, w/o overlay
      overlayBounds: null,
      // bounds cache of element body, including overlay
      labelBounds: {
        // bounds cache of labels
        all: null,
        source: null,
        target: null,
        main: null
      },
      arrowBounds: {
        // bounds cache of edge arrows
        source: null,
        target: null,
        'mid-source': null,
        'mid-target': null
      }
    };
    if (_p.position.x == null) {
      _p.position.x = 0;
    }
    if (_p.position.y == null) {
      _p.position.y = 0;
    }

    // renderedPosition overrides if specified
    if (params.renderedPosition) {
      var rpos = params.renderedPosition;
      var pan = cy.pan();
      var zoom = cy.zoom();
      _p.position = {
        x: (rpos.x - pan.x) / zoom,
        y: (rpos.y - pan.y) / zoom
      };
    }
    var classes = [];
    if (array(params.classes)) {
      classes = params.classes;
    } else if (string(params.classes)) {
      classes = params.classes.split(/\s+/);
    }
    for (var i = 0, l = classes.length; i < l; i++) {
      var cls = classes[i];
      if (!cls || cls === '') {
        continue;
      }
      _p.classes.add(cls);
    }
    this.createEmitter();
    var bypass = params.style || params.css;
    if (bypass) {
      warn('Setting a `style` bypass at element creation should be done only when absolutely necessary.  Try to use the stylesheet instead.');
      this.style(bypass);
    }
    if (restore === undefined || restore) {
      this.restore();
    }
  };

  var defineSearch = function defineSearch(params) {
    params = {
      bfs: params.bfs || !params.dfs,
      dfs: params.dfs || !params.bfs
    };

    // from pseudocode on wikipedia
    return function searchFn(roots, fn, directed) {
      var options;
      if (plainObject(roots) && !elementOrCollection(roots)) {
        options = roots;
        roots = options.roots || options.root;
        fn = options.visit;
        directed = options.directed;
      }
      directed = arguments.length === 2 && !fn$6(fn) ? fn : directed;
      fn = fn$6(fn) ? fn : function () {};
      var cy = this._private.cy;
      var v = roots = string(roots) ? this.filter(roots) : roots;
      var Q = [];
      var connectedNodes = [];
      var connectedBy = {};
      var id2depth = {};
      var V = {};
      var j = 0;
      var found;
      var _this$byGroup = this.byGroup(),
        nodes = _this$byGroup.nodes,
        edges = _this$byGroup.edges;

      // enqueue v
      for (var i = 0; i < v.length; i++) {
        var vi = v[i];
        var viId = vi.id();
        if (vi.isNode()) {
          Q.unshift(vi);
          if (params.bfs) {
            V[viId] = true;
            connectedNodes.push(vi);
          }
          id2depth[viId] = 0;
        }
      }
      var _loop = function _loop() {
        var v = params.bfs ? Q.shift() : Q.pop();
        var vId = v.id();
        if (params.dfs) {
          if (V[vId]) {
            return "continue";
          }
          V[vId] = true;
          connectedNodes.push(v);
        }
        var depth = id2depth[vId];
        var prevEdge = connectedBy[vId];
        var src = prevEdge != null ? prevEdge.source() : null;
        var tgt = prevEdge != null ? prevEdge.target() : null;
        var prevNode = prevEdge == null ? undefined : v.same(src) ? tgt[0] : src[0];
        var ret = void 0;
        ret = fn(v, prevEdge, prevNode, j++, depth);
        if (ret === true) {
          found = v;
          return "break";
        }
        if (ret === false) {
          return "break";
        }
        var vwEdges = v.connectedEdges().filter(function (e) {
          return (!directed || e.source().same(v)) && edges.has(e);
        });
        for (var _i2 = 0; _i2 < vwEdges.length; _i2++) {
          var e = vwEdges[_i2];
          var w = e.connectedNodes().filter(function (n) {
            return !n.same(v) && nodes.has(n);
          });
          var wId = w.id();
          if (w.length !== 0 && !V[wId]) {
            w = w[0];
            Q.push(w);
            if (params.bfs) {
              V[wId] = true;
              connectedNodes.push(w);
            }
            connectedBy[wId] = e;
            id2depth[wId] = id2depth[vId] + 1;
          }
        }
      };
      while (Q.length !== 0) {
        var _ret = _loop();
        if (_ret === "continue") continue;
        if (_ret === "break") break;
      }
      var connectedEles = cy.collection();
      for (var _i = 0; _i < connectedNodes.length; _i++) {
        var node = connectedNodes[_i];
        var edge = connectedBy[node.id()];
        if (edge != null) {
          connectedEles.push(edge);
        }
        connectedEles.push(node);
      }
      return {
        path: cy.collection(connectedEles),
        found: cy.collection(found)
      };
    };
  };

  // search, spanning trees, etc
  var elesfn$v = {
    breadthFirstSearch: defineSearch({
      bfs: true
    }),
    depthFirstSearch: defineSearch({
      dfs: true
    })
  };

  // nice, short mathematical alias
  elesfn$v.bfs = elesfn$v.breadthFirstSearch;
  elesfn$v.dfs = elesfn$v.depthFirstSearch;

  var heap$1 = createCommonjsModule(function (module, exports) {
  // Generated by CoffeeScript 1.8.0
  (function() {
    var Heap, defaultCmp, floor, heapify, heappop, heappush, heappushpop, heapreplace, insort, min, nlargest, nsmallest, updateItem, _siftdown, _siftup;

    floor = Math.floor, min = Math.min;


    /*
    Default comparison function to be used
     */

    defaultCmp = function(x, y) {
      if (x < y) {
        return -1;
      }
      if (x > y) {
        return 1;
      }
      return 0;
    };


    /*
    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.
     */

    insort = function(a, x, lo, hi, cmp) {
      var mid;
      if (lo == null) {
        lo = 0;
      }
      if (cmp == null) {
        cmp = defaultCmp;
      }
      if (lo < 0) {
        throw new Error('lo must be non-negative');
      }
      if (hi == null) {
        hi = a.length;
      }
      while (lo < hi) {
        mid = floor((lo + hi) / 2);
        if (cmp(x, a[mid]) < 0) {
          hi = mid;
        } else {
          lo = mid + 1;
        }
      }
      return ([].splice.apply(a, [lo, lo - lo].concat(x)), x);
    };


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

    heappush = function(array, item, cmp) {
      if (cmp == null) {
        cmp = defaultCmp;
      }
      array.push(item);
      return _siftdown(array, 0, array.length - 1, cmp);
    };


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

    heappop = function(array, cmp) {
      var lastelt, returnitem;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      lastelt = array.pop();
      if (array.length) {
        returnitem = array[0];
        array[0] = lastelt;
        _siftup(array, 0, cmp);
      } else {
        returnitem = lastelt;
      }
      return returnitem;
    };


    /*
    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)
     */

    heapreplace = function(array, item, cmp) {
      var returnitem;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      returnitem = array[0];
      array[0] = item;
      _siftup(array, 0, cmp);
      return returnitem;
    };


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

    heappushpop = function(array, item, cmp) {
      var _ref;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      if (array.length && cmp(array[0], item) < 0) {
        _ref = [array[0], item], item = _ref[0], array[0] = _ref[1];
        _siftup(array, 0, cmp);
      }
      return item;
    };


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

    heapify = function(array, cmp) {
      var i, _i, _len, _ref1, _results, _results1;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      _ref1 = (function() {
        _results1 = [];
        for (var _j = 0, _ref = floor(array.length / 2); 0 <= _ref ? _j < _ref : _j > _ref; 0 <= _ref ? _j++ : _j--){ _results1.push(_j); }
        return _results1;
      }).apply(this).reverse();
      _results = [];
      for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
        i = _ref1[_i];
        _results.push(_siftup(array, i, cmp));
      }
      return _results;
    };


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

    updateItem = function(array, item, cmp) {
      var pos;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      pos = array.indexOf(item);
      if (pos === -1) {
        return;
      }
      _siftdown(array, 0, pos, cmp);
      return _siftup(array, pos, cmp);
    };


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

    nlargest = function(array, n, cmp) {
      var elem, result, _i, _len, _ref;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      result = array.slice(0, n);
      if (!result.length) {
        return result;
      }
      heapify(result, cmp);
      _ref = array.slice(n);
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        elem = _ref[_i];
        heappushpop(result, elem, cmp);
      }
      return result.sort(cmp).reverse();
    };


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

    nsmallest = function(array, n, cmp) {
      var elem, los, result, _i, _j, _len, _ref, _ref1, _results;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      if (n * 10 <= array.length) {
        result = array.slice(0, n).sort(cmp);
        if (!result.length) {
          return result;
        }
        los = result[result.length - 1];
        _ref = array.slice(n);
        for (_i = 0, _len = _ref.length; _i < _len; _i++) {
          elem = _ref[_i];
          if (cmp(elem, los) < 0) {
            insort(result, elem, 0, null, cmp);
            result.pop();
            los = result[result.length - 1];
          }
        }
        return result;
      }
      heapify(array, cmp);
      _results = [];
      for (_j = 0, _ref1 = min(n, array.length); 0 <= _ref1 ? _j < _ref1 : _j > _ref1; 0 <= _ref1 ? ++_j : --_j) {
        _results.push(heappop(array, cmp));
      }
      return _results;
    };

    _siftdown = function(array, startpos, pos, cmp) {
      var newitem, parent, parentpos;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      newitem = array[pos];
      while (pos > startpos) {
        parentpos = (pos - 1) >> 1;
        parent = array[parentpos];
        if (cmp(newitem, parent) < 0) {
          array[pos] = parent;
          pos = parentpos;
          continue;
        }
        break;
      }
      return array[pos] = newitem;
    };

    _siftup = function(array, pos, cmp) {
      var childpos, endpos, newitem, rightpos, startpos;
      if (cmp == null) {
        cmp = defaultCmp;
      }
      endpos = array.length;
      startpos = pos;
      newitem = array[pos];
      childpos = 2 * pos + 1;
      while (childpos < endpos) {
        rightpos = childpos + 1;
        if (rightpos < endpos && !(cmp(array[childpos], array[rightpos]) < 0)) {
          childpos = rightpos;
        }
        array[pos] = array[childpos];
        pos = childpos;
        childpos = 2 * pos + 1;
      }
      array[pos] = newitem;
      return _siftdown(array, startpos, pos, cmp);
    };

    Heap = (function() {
      Heap.push = heappush;

      Heap.pop = heappop;

      Heap.replace = heapreplace;

      Heap.pushpop = heappushpop;

      Heap.heapify = heapify;

      Heap.updateItem = updateItem;

      Heap.nlargest = nlargest;

      Heap.nsmallest = nsmallest;

      function Heap(cmp) {
        this.cmp = cmp != null ? cmp : defaultCmp;
        this.nodes = [];
      }

      Heap.prototype.push = function(x) {
        return heappush(this.nodes, x, this.cmp);
      };

      Heap.prototype.pop = function() {
        return heappop(this.nodes, this.cmp);
      };

      Heap.prototype.peek = function() {
        return this.nodes[0];
      };

      Heap.prototype.contains = function(x) {
        return this.nodes.indexOf(x) !== -1;
      };

      Heap.prototype.replace = function(x) {
        return heapreplace(this.nodes, x, this.cmp);
      };

      Heap.prototype.pushpop = function(x) {
        return heappushpop(this.nodes, x, this.cmp);
      };

      Heap.prototype.heapify = function() {
        return heapify(this.nodes, this.cmp);
      };

      Heap.prototype.updateItem = function(x) {
        return updateItem(this.nodes, x, this.cmp);
      };

      Heap.prototype.clear = function() {
        return this.nodes = [];
      };

      Heap.prototype.empty = function() {
        return this.nodes.length === 0;
      };

      Heap.prototype.size = function() {
        return this.nodes.length;
      };

      Heap.prototype.clone = function() {
        var heap;
        heap = new Heap();
        heap.nodes = this.nodes.slice(0);
        return heap;
      };

      Heap.prototype.toArray = function() {
        return this.nodes.slice(0);
      };

      Heap.prototype.insert = Heap.prototype.push;

      Heap.prototype.top = Heap.prototype.peek;

      Heap.prototype.front = Heap.prototype.peek;

      Heap.prototype.has = Heap.prototype.contains;

      Heap.prototype.copy = Heap.prototype.clone;

      return Heap;

    })();

    (function(root, factory) {
      {
        return module.exports = factory();
      }
    })(this, function() {
      return Heap;
    });

  }).call(commonjsGlobal);
  });

  var heap = heap$1;

  var dijkstraDefaults = defaults$g({
    root: null,
    weight: function weight(edge) {
      return 1;
    },
    directed: false
  });
  var elesfn$u = {
    dijkstra: function dijkstra(options) {
      if (!plainObject(options)) {
        var args = arguments;
        options = {
          root: args[0],
          weight: args[1],
          directed: args[2]
        };
      }
      var _dijkstraDefaults = dijkstraDefaults(options),
        root = _dijkstraDefaults.root,
        weight = _dijkstraDefaults.weight,
        directed = _dijkstraDefaults.directed;
      var eles = this;
      var weightFn = weight;
      var source = string(root) ? this.filter(root)[0] : root[0];
      var dist = {};
      var prev = {};
      var knownDist = {};
      var _this$byGroup = this.byGroup(),
        nodes = _this$byGroup.nodes,
        edges = _this$byGroup.edges;
      edges.unmergeBy(function (ele) {
        return ele.isLoop();
      });
      var getDist = function getDist(node) {
        return dist[node.id()];
      };
      var setDist = function setDist(node, d) {
        dist[node.id()] = d;
        Q.updateItem(node);
      };
      var Q = new heap(function (a, b) {
        return getDist(a) - getDist(b);
      });
      for (var i = 0; i < nodes.length; i++) {
        var node = nodes[i];
        dist[node.id()] = node.same(source) ? 0 : Infinity;
        Q.push(node);
      }
      var distBetween = function distBetween(u, v) {
        var uvs = (directed ? u.edgesTo(v) : u.edgesWith(v)).intersect(edges);
        var smallestDistance = Infinity;
        var smallestEdge;
        for (var _i = 0; _i < uvs.length; _i++) {
          var edge = uvs[_i];
          var _weight = weightFn(edge);
          if (_weight < smallestDistance || !smallestEdge) {
            smallestDistance = _weight;
            smallestEdge = edge;
          }
        }
        return {
          edge: smallestEdge,
          dist: smallestDistance
        };
      };
      while (Q.size() > 0) {
        var u = Q.pop();
        var smalletsDist = getDist(u);
        var uid = u.id();
        knownDist[uid] = smalletsDist;
        if (smalletsDist === Infinity) {
          continue;
        }
        var neighbors = u.neighborhood().intersect(nodes);
        for (var _i2 = 0; _i2 < neighbors.length; _i2++) {
          var v = neighbors[_i2];
          var vid = v.id();
          var vDist = distBetween(u, v);
          var alt = smalletsDist + vDist.dist;
          if (alt < getDist(v)) {
            setDist(v, alt);
            prev[vid] = {
              node: u,
              edge: vDist.edge
            };
          }
        } // for
      } // while

      return {
        distanceTo: function distanceTo(node) {
          var target = string(node) ? nodes.filter(node)[0] : node[0];
          return knownDist[target.id()];
        },
        pathTo: function pathTo(node) {
          var target = string(node) ? nodes.filter(node)[0] : node[0];
          var S = [];
          var u = target;
          var uid = u.id();
          if (target.length > 0) {
            S.unshift(target);
            while (prev[uid]) {
              var p = prev[uid];
              S.unshift(p.edge);
              S.unshift(p.node);
              u = p.node;
              uid = u.id();
            }
          }
          return eles.spawn(S);
        }
      };
    }
  };

  var elesfn$t = {
    // kruskal's algorithm (finds min spanning tree, assuming undirected graph)
    // implemented from pseudocode from wikipedia
    kruskal: function kruskal(weightFn) {
      weightFn = weightFn || function (edge) {
        return 1;
      };
      var _this$byGroup = this.byGroup(),
        nodes = _this$byGroup.nodes,
        edges = _this$byGroup.edges;
      var numNodes = nodes.length;
      var forest = new Array(numNodes);
      var A = nodes; // assumes byGroup() creates new collections that can be safely mutated

      var findSetIndex = function findSetIndex(ele) {
        for (var i = 0; i < forest.length; i++) {
          var eles = forest[i];
          if (eles.has(ele)) {
            return i;
          }
        }
      };

      // start with one forest per node
      for (var i = 0; i < numNodes; i++) {
        forest[i] = this.spawn(nodes[i]);
      }
      var S = edges.sort(function (a, b) {
        return weightFn(a) - weightFn(b);
      });
      for (var _i = 0; _i < S.length; _i++) {
        var edge = S[_i];
        var u = edge.source()[0];
        var v = edge.target()[0];
        var setUIndex = findSetIndex(u);
        var setVIndex = findSetIndex(v);
        var setU = forest[setUIndex];
        var setV = forest[setVIndex];
        if (setUIndex !== setVIndex) {
          A.merge(edge);

          // combine forests for u and v
          setU.merge(setV);
          forest.splice(setVIndex, 1);
        }
      }
      return A;
    }
  };

  var aStarDefaults = defaults$g({
    root: null,
    goal: null,
    weight: function weight(edge) {
      return 1;
    },
    heuristic: function heuristic(edge) {
      return 0;
    },
    directed: false
  });
  var elesfn$s = {
    // Implemented from pseudocode from wikipedia
    aStar: function aStar(options) {
      var cy = this.cy();
      var _aStarDefaults = aStarDefaults(options),
        root = _aStarDefaults.root,
        goal = _aStarDefaults.goal,
        heuristic = _aStarDefaults.heuristic,
        directed = _aStarDefaults.directed,
        weight = _aStarDefaults.weight;
      root = cy.collection(root)[0];
      goal = cy.collection(goal)[0];
      var sid = root.id();
      var tid = goal.id();
      var gScore = {};
      var fScore = {};
      var closedSetIds = {};
      var openSet = new heap(function (a, b) {
        return fScore[a.id()] - fScore[b.id()];
      });
      var openSetIds = new Set$1();
      var cameFrom = {};
      var cameFromEdge = {};
      var addToOpenSet = function addToOpenSet(ele, id) {
        openSet.push(ele);
        openSetIds.add(id);
      };
      var cMin, cMinId;
      var popFromOpenSet = function popFromOpenSet() {
        cMin = openSet.pop();
        cMinId = cMin.id();
        openSetIds["delete"](cMinId);
      };
      var isInOpenSet = function isInOpenSet(id) {
        return openSetIds.has(id);
      };
      addToOpenSet(root, sid);
      gScore[sid] = 0;
      fScore[sid] = heuristic(root);

      // Counter
      var steps = 0;

      // Main loop
      while (openSet.size() > 0) {
        popFromOpenSet();
        steps++;

        // If we've found our goal, then we are done
        if (cMinId === tid) {
          var path = [];
          var pathNode = goal;
          var pathNodeId = tid;
          var pathEdge = cameFromEdge[pathNodeId];
          for (;;) {
            path.unshift(pathNode);
            if (pathEdge != null) {
              path.unshift(pathEdge);
            }
            pathNode = cameFrom[pathNodeId];
            if (pathNode == null) {
              break;
            }
            pathNodeId = pathNode.id();
            pathEdge = cameFromEdge[pathNodeId];
          }
          return {
            found: true,
            distance: gScore[cMinId],
            path: this.spawn(path),
            steps: steps
          };
        }

        // Add cMin to processed nodes
        closedSetIds[cMinId] = true;

        // Update scores for neighbors of cMin
        // Take into account if graph is directed or not
        var vwEdges = cMin._private.edges;
        for (var i = 0; i < vwEdges.length; i++) {
          var e = vwEdges[i];

          // edge must be in set of calling eles
          if (!this.hasElementWithId(e.id())) {
            continue;
          }

          // cMin must be the source of edge if directed
          if (directed && e.data('source') !== cMinId) {
            continue;
          }
          var wSrc = e.source();
          var wTgt = e.target();
          var w = wSrc.id() !== cMinId ? wSrc : wTgt;
          var wid = w.id();

          // node must be in set of calling eles
          if (!this.hasElementWithId(wid)) {
            continue;
          }

          // if node is in closedSet, ignore it
          if (closedSetIds[wid]) {
            continue;
          }

          // New tentative score for node w
          var tempScore = gScore[cMinId] + weight(e);

          // Update gScore for node w if:
          //   w not present in openSet
          // OR
          //   tentative gScore is less than previous value

          // w not in openSet
          if (!isInOpenSet(wid)) {
            gScore[wid] = tempScore;
            fScore[wid] = tempScore + heuristic(w);
            addToOpenSet(w, wid);
            cameFrom[wid] = cMin;
            cameFromEdge[wid] = e;
            continue;
          }

          // w already in openSet, but with greater gScore
          if (tempScore < gScore[wid]) {
            gScore[wid] = tempScore;
            fScore[wid] = tempScore + heuristic(w);
            cameFrom[wid] = cMin;
            cameFromEdge[wid] = e;
          }
        } // End of neighbors update
      } // End of main loop

      // If we've reached here, then we've not reached our goal
      return {
        found: false,
        distance: undefined,
        path: undefined,
        steps: steps
      };
    }
  }; // elesfn

  var floydWarshallDefaults = defaults$g({
    weight: function weight(edge) {
      return 1;
    },
    directed: false
  });
  var elesfn$r = {
    // Implemented from pseudocode from wikipedia
    floydWarshall: function floydWarshall(options) {
      var cy = this.cy();
      var _floydWarshallDefault = floydWarshallDefaults(options),
        weight = _floydWarshallDefault.weight,
        directed = _floydWarshallDefault.directed;
      var weightFn = weight;
      var _this$byGroup = this.byGroup(),
        nodes = _this$byGroup.nodes,
        edges = _this$byGroup.edges;
      var N = nodes.length;
      var Nsq = N * N;
      var indexOf = function indexOf(node) {
        return nodes.indexOf(node);
      };
      var atIndex = function atIndex(i) {
        return nodes[i];
      };

      // Initialize distance matrix
      var dist = new Array(Nsq);
      for (var n = 0; n < Nsq; n++) {
        var j = n % N;
        var i = (n - j) / N;
        if (i === j) {
          dist[n] = 0;
        } else {
          dist[n] = Infinity;
        }
      }

      // Initialize matrix used for path reconstruction
      // Initialize distance matrix
      var next = new Array(Nsq);
      var edgeNext = new Array(Nsq);

      // Process edges
      for (var _i = 0; _i < edges.length; _i++) {
        var edge = edges[_i];
        var src = edge.source()[0];
        var tgt = edge.target()[0];
        if (src === tgt) {
          continue;
        } // exclude loops

        var s = indexOf(src);
        var t = indexOf(tgt);
        var st = s * N + t; // source to target index
        var _weight = weightFn(edge);

        // Check if already process another edge between same 2 nodes
        if (dist[st] > _weight) {
          dist[st] = _weight;
          next[st] = t;
          edgeNext[st] = edge;
        }

        // If undirected graph, process 'reversed' edge
        if (!directed) {
          var ts = t * N + s; // target to source index

          if (!directed && dist[ts] > _weight) {
            dist[ts] = _weight;
            next[ts] = s;
            edgeNext[ts] = edge;
          }
        }
      }

      // Main loop
      for (var k = 0; k < N; k++) {
        for (var _i2 = 0; _i2 < N; _i2++) {
          var ik = _i2 * N + k;
          for (var _j = 0; _j < N; _j++) {
            var ij = _i2 * N + _j;
            var kj = k * N + _j;
            if (dist[ik] + dist[kj] < dist[ij]) {
              dist[ij] = dist[ik] + dist[kj];
              next[ij] = next[ik];
            }
          }
        }
      }
      var getArgEle = function getArgEle(ele) {
        return (string(ele) ? cy.filter(ele) : ele)[0];
      };
      var indexOfArgEle = function indexOfArgEle(ele) {
        return indexOf(getArgEle(ele));
      };
      var res = {
        distance: function distance(from, to) {
          var i = indexOfArgEle(from);
          var j = indexOfArgEle(to);
          return dist[i * N + j];
        },
        path: function path(from, to) {
          var i = indexOfArgEle(from);
          var j = indexOfArgEle(to);
          var fromNode = atIndex(i);
          if (i === j) {
            return fromNode.collection();
          }
          if (next[i * N + j] == null) {
            return cy.collection();
          }
          var path = cy.collection();
          var prev = i;
          var edge;
          path.merge(fromNode);
          while (i !== j) {
            prev = i;
            i = next[i * N + j];
            edge = edgeNext[prev * N + i];
            path.merge(edge);
            path.merge(atIndex(i));
          }
          return path;
        }
      };
      return res;
    } // floydWarshall
  }; // elesfn

  var bellmanFordDefaults = defaults$g({
    weight: function weight(edge) {
      return 1;
    },
    directed: false,
    root: null
  });
  var elesfn$q = {
    // Implemented from pseudocode from wikipedia
    bellmanFord: function bellmanFord(options) {
      var _this = this;
      var _bellmanFordDefaults = bellmanFordDefaults(options),
        weight = _bellmanFordDefaults.weight,
        directed = _bellmanFordDefaults.directed,
        root = _bellmanFordDefaults.root;
      var weightFn = weight;
      var eles = this;
      var cy = this.cy();
      var _this$byGroup = this.byGroup(),
        edges = _this$byGroup.edges,
        nodes = _this$byGroup.nodes;
      var numNodes = nodes.length;
      var infoMap = new Map$2();
      var hasNegativeWeightCycle = false;
      var negativeWeightCycles = [];
      root = cy.collection(root)[0]; // in case selector passed

      edges.unmergeBy(function (edge) {
        return edge.isLoop();
      });
      var numEdges = edges.length;
      var getInfo = function getInfo(node) {
        var obj = infoMap.get(node.id());
        if (!obj) {
          obj = {};
          infoMap.set(node.id(), obj);
        }
        return obj;
      };
      var getNodeFromTo = function getNodeFromTo(to) {
        return (string(to) ? cy.$(to) : to)[0];
      };
      var distanceTo = function distanceTo(to) {
        return getInfo(getNodeFromTo(to)).dist;
      };
      var pathTo = function pathTo(to) {
        var thisStart = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : root;
        var end = getNodeFromTo(to);
        var path = [];
        var node = end;
        for (;;) {
          if (node == null) {
            return _this.spawn();
          }
          var _getInfo = getInfo(node),
            edge = _getInfo.edge,
            pred = _getInfo.pred;
          path.unshift(node[0]);
          if (node.same(thisStart) && path.length > 0) {
            break;
          }
          if (edge != null) {
            path.unshift(edge);
          }
          node = pred;
        }
        return eles.spawn(path);
      };

      // Initializations { dist, pred, edge }
      for (var i = 0; i < numNodes; i++) {
        var node = nodes[i];
        var info = getInfo(node);
        if (node.same(root)) {
          info.dist = 0;
        } else {
          info.dist = Infinity;
        }
        info.pred = null;
        info.edge = null;
      }

      // Edges relaxation
      var replacedEdge = false;
      var checkForEdgeReplacement = function checkForEdgeReplacement(node1, node2, edge, info1, info2, weight) {
        var dist = info1.dist + weight;
        if (dist < info2.dist && !edge.same(info1.edge)) {
          info2.dist = dist;
          info2.pred = node1;
          info2.edge = edge;
          replacedEdge = true;
        }
      };
      for (var _i = 1; _i < numNodes; _i++) {
        replacedEdge = false;
        for (var e = 0; e < numEdges; e++) {
          var edge = edges[e];
          var src = edge.source();
          var tgt = edge.target();
          var _weight = weightFn(edge);
          var srcInfo = getInfo(src);
          var tgtInfo = getInfo(tgt);
          checkForEdgeReplacement(src, tgt, edge, srcInfo, tgtInfo, _weight);

          // If undirected graph, we need to take into account the 'reverse' edge
          if (!directed) {
            checkForEdgeReplacement(tgt, src, edge, tgtInfo, srcInfo, _weight);
          }
        }
        if (!replacedEdge) {
          break;
        }
      }
      if (replacedEdge) {
        // Check for negative weight cycles
        var negativeWeightCycleIds = [];
        for (var _e = 0; _e < numEdges; _e++) {
          var _edge = edges[_e];
          var _src = _edge.source();
          var _tgt = _edge.target();
          var _weight2 = weightFn(_edge);
          var srcDist = getInfo(_src).dist;
          var tgtDist = getInfo(_tgt).dist;
          if (srcDist + _weight2 < tgtDist || !directed && tgtDist + _weight2 < srcDist) {
            if (!hasNegativeWeightCycle) {
              warn('Graph contains a negative weight cycle for Bellman-Ford');
              hasNegativeWeightCycle = true;
            }
            if (options.findNegativeWeightCycles !== false) {
              var negativeNodes = [];
              if (srcDist + _weight2 < tgtDist) {
                negativeNodes.push(_src);
              }
              if (!directed && tgtDist + _weight2 < srcDist) {
                negativeNodes.push(_tgt);
              }
              var numNegativeNodes = negativeNodes.length;
              for (var n = 0; n < numNegativeNodes; n++) {
                var start = negativeNodes[n];
                var cycle = [start];
                cycle.push(getInfo(start).edge);
                var _node = getInfo(start).pred;
                while (cycle.indexOf(_node) === -1) {
                  cycle.push(_node);
                  cycle.push(getInfo(_node).edge);
                  _node = getInfo(_node).pred;
                }
                cycle = cycle.slice(cycle.indexOf(_node));
                var smallestId = cycle[0].id();
                var smallestIndex = 0;
                for (var c = 2; c < cycle.length; c += 2) {
                  if (cycle[c].id() < smallestId) {
                    smallestId = cycle[c].id();
                    smallestIndex = c;
                  }
                }
                cycle = cycle.slice(smallestIndex).concat(cycle.slice(0, smallestIndex));
                cycle.push(cycle[0]);
                var cycleId = cycle.map(function (el) {
                  return el.id();
                }).join(",");
                if (negativeWeightCycleIds.indexOf(cycleId) === -1) {
                  negativeWeightCycles.push(eles.spawn(cycle));
                  negativeWeightCycleIds.push(cycleId);
                }
              }
            } else {
              break;
            }
          }
        }
      }
      return {
        distanceTo: distanceTo,
        pathTo: pathTo,
        hasNegativeWeightCycle: hasNegativeWeightCycle,
        negativeWeightCycles: negativeWeightCycles
      };
    } // bellmanFord
  }; // elesfn

  var sqrt2 = Math.sqrt(2);

  // Function which colapses 2 (meta) nodes into one
  // Updates the remaining edge lists
  // Receives as a paramater the edge which causes the collapse
  var collapse = function collapse(edgeIndex, nodeMap, remainingEdges) {
    if (remainingEdges.length === 0) {
      error("Karger-Stein must be run on a connected (sub)graph");
    }
    var edgeInfo = remainingEdges[edgeIndex];
    var sourceIn = edgeInfo[1];
    var targetIn = edgeInfo[2];
    var partition1 = nodeMap[sourceIn];
    var partition2 = nodeMap[targetIn];
    var newEdges = remainingEdges; // re-use array

    // Delete all edges between partition1 and partition2
    for (var i = newEdges.length - 1; i >= 0; i--) {
      var edge = newEdges[i];
      var src = edge[1];
      var tgt = edge[2];
      if (nodeMap[src] === partition1 && nodeMap[tgt] === partition2 || nodeMap[src] === partition2 && nodeMap[tgt] === partition1) {
        newEdges.splice(i, 1);
      }
    }

    // All edges pointing to partition2 should now point to partition1
    for (var _i = 0; _i < newEdges.length; _i++) {
      var _edge = newEdges[_i];
      if (_edge[1] === partition2) {
        // Check source
        newEdges[_i] = _edge.slice(); // copy
        newEdges[_i][1] = partition1;
      } else if (_edge[2] === partition2) {
        // Check target
        newEdges[_i] = _edge.slice(); // copy
        newEdges[_i][2] = partition1;
      }
    }

    // Move all nodes from partition2 to partition1
    for (var _i2 = 0; _i2 < nodeMap.length; _i2++) {
      if (nodeMap[_i2] === partition2) {
        nodeMap[_i2] = partition1;
      }
    }
    return newEdges;
  };

  // Contracts a graph until we reach a certain number of meta nodes
  var contractUntil = function contractUntil(metaNodeMap, remainingEdges, size, sizeLimit) {
    while (size > sizeLimit) {
      // Choose an edge randomly
      var edgeIndex = Math.floor(Math.random() * remainingEdges.length);

      // Collapse graph based on edge
      remainingEdges = collapse(edgeIndex, metaNodeMap, remainingEdges);
      size--;
    }
    return remainingEdges;
  };
  var elesfn$p = {
    // Computes the minimum cut of an undirected graph
    // Returns the correct answer with high probability
    kargerStein: function kargerStein() {
      var _this = this;
      var _this$byGroup = this.byGroup(),
        nodes = _this$byGroup.nodes,
        edges = _this$byGroup.edges;
      edges.unmergeBy(function (edge) {
        return edge.isLoop();
      });
      var numNodes = nodes.length;
      var numEdges = edges.length;
      var numIter = Math.ceil(Math.pow(Math.log(numNodes) / Math.LN2, 2));
      var stopSize = Math.floor(numNodes / sqrt2);
      if (numNodes < 2) {
        error('At least 2 nodes are required for Karger-Stein algorithm');
        return undefined;
      }

      // Now store edge destination as indexes
      // Format for each edge (edge index, source node index, target node index)
      var edgeIndexes = [];
      for (var i = 0; i < numEdges; i++) {
        var e = edges[i];
        edgeIndexes.push([i, nodes.indexOf(e.source()), nodes.indexOf(e.target())]);
      }

      // We will store the best cut found here
      var minCutSize = Infinity;
      var minCutEdgeIndexes = [];
      var minCutNodeMap = new Array(numNodes);

      // Initial meta node partition
      var metaNodeMap = new Array(numNodes);
      var metaNodeMap2 = new Array(numNodes);
      var copyNodesMap = function copyNodesMap(from, to) {
        for (var _i3 = 0; _i3 < numNodes; _i3++) {
          to[_i3] = from[_i3];
        }
      };

      // Main loop
      for (var iter = 0; iter <= numIter; iter++) {
        // Reset meta node partition
        for (var _i4 = 0; _i4 < numNodes; _i4++) {
          metaNodeMap[_i4] = _i4;
        }

        // Contract until stop point (stopSize nodes)
        var edgesState = contractUntil(metaNodeMap, edgeIndexes.slice(), numNodes, stopSize);
        var edgesState2 = edgesState.slice(); // copy

        // Create a copy of the colapsed nodes state
        copyNodesMap(metaNodeMap, metaNodeMap2);

        // Run 2 iterations starting in the stop state
        var res1 = contractUntil(metaNodeMap, edgesState, stopSize, 2);
        var res2 = contractUntil(metaNodeMap2, edgesState2, stopSize, 2);

        // Is any of the 2 results the best cut so far?
        if (res1.length <= res2.length && res1.length < minCutSize) {
          minCutSize = res1.length;
          minCutEdgeIndexes = res1;
          copyNodesMap(metaNodeMap, minCutNodeMap);
        } else if (res2.length <= res1.length && res2.length < minCutSize) {
          minCutSize = res2.length;
          minCutEdgeIndexes = res2;
          copyNodesMap(metaNodeMap2, minCutNodeMap);
        }
      } // end of main loop

      // Construct result
      var cut = this.spawn(minCutEdgeIndexes.map(function (e) {
        return edges[e[0]];
      }));
      var partition1 = this.spawn();
      var partition2 = this.spawn();

      // traverse metaNodeMap for best cut
      var witnessNodePartition = minCutNodeMap[0];
      for (var _i5 = 0; _i5 < minCutNodeMap.length; _i5++) {
        var partitionId = minCutNodeMap[_i5];
        var node = nodes[_i5];
        if (partitionId === witnessNodePartition) {
          partition1.merge(node);
        } else {
          partition2.merge(node);
        }
      }

      // construct components corresponding to each disjoint subset of nodes
      var constructComponent = function constructComponent(subset) {
        var component = _this.spawn();
        subset.forEach(function (node) {
          component.merge(node);
          node.connectedEdges().forEach(function (edge) {
            // ensure edge is within calling collection and edge is not in cut
            if (_this.contains(edge) && !cut.contains(edge)) {
              component.merge(edge);
            }
          });
        });
        return component;
      };
      var components = [constructComponent(partition1), constructComponent(partition2)];
      var ret = {
        cut: cut,
        components: components,
        // n.b. partitions are included to be compatible with the old api spec
        // (could be removed in a future major version)
        partition1: partition1,
        partition2: partition2
      };
      return ret;
    }
  }; // elesfn

  var copyPosition = function copyPosition(p) {
    return {
      x: p.x,
      y: p.y
    };
  };
  var modelToRenderedPosition = function modelToRenderedPosition(p, zoom, pan) {
    return {
      x: p.x * zoom + pan.x,
      y: p.y * zoom + pan.y
    };
  };
  var renderedToModelPosition = function renderedToModelPosition(p, zoom, pan) {
    return {
      x: (p.x - pan.x) / zoom,
      y: (p.y - pan.y) / zoom
    };
  };
  var array2point = function array2point(arr) {
    return {
      x: arr[0],
      y: arr[1]
    };
  };
  var min = function min(arr) {
    var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length;
    var min = Infinity;
    for (var i = begin; i < end; i++) {
      var val = arr[i];
      if (isFinite(val)) {
        min = Math.min(val, min);
      }
    }
    return min;
  };
  var max = function max(arr) {
    var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length;
    var max = -Infinity;
    for (var i = begin; i < end; i++) {
      var val = arr[i];
      if (isFinite(val)) {
        max = Math.max(val, max);
      }
    }
    return max;
  };
  var mean = function mean(arr) {
    var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length;
    var total = 0;
    var n = 0;
    for (var i = begin; i < end; i++) {
      var val = arr[i];
      if (isFinite(val)) {
        total += val;
        n++;
      }
    }
    return total / n;
  };
  var median = function median(arr) {
    var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length;
    var copy = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
    var sort = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
    var includeHoles = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
    if (copy) {
      arr = arr.slice(begin, end);
    } else {
      if (end < arr.length) {
        arr.splice(end, arr.length - end);
      }
      if (begin > 0) {
        arr.splice(0, begin);
      }
    }

    // all non finite (e.g. Infinity, NaN) elements must be -Infinity so they go to the start
    var off = 0; // offset from non-finite values
    for (var i = arr.length - 1; i >= 0; i--) {
      var v = arr[i];
      if (includeHoles) {
        if (!isFinite(v)) {
          arr[i] = -Infinity;
          off++;
        }
      } else {
        // just remove it if we don't want to consider holes
        arr.splice(i, 1);
      }
    }
    if (sort) {
      arr.sort(function (a, b) {
        return a - b;
      }); // requires copy = true if you don't want to change the orig
    }

    var len = arr.length;
    var mid = Math.floor(len / 2);
    if (len % 2 !== 0) {
      return arr[mid + 1 + off];
    } else {
      return (arr[mid - 1 + off] + arr[mid + off]) / 2;
    }
  };
  var deg2rad = function deg2rad(deg) {
    return Math.PI * deg / 180;
  };
  var getAngleFromDisp = function getAngleFromDisp(dispX, dispY) {
    return Math.atan2(dispY, dispX) - Math.PI / 2;
  };
  var log2 = Math.log2 || function (n) {
    return Math.log(n) / Math.log(2);
  };
  var signum = function signum(x) {
    if (x > 0) {
      return 1;
    } else if (x < 0) {
      return -1;
    } else {
      return 0;
    }
  };
  var dist = function dist(p1, p2) {
    return Math.sqrt(sqdist(p1, p2));
  };
  var sqdist = function sqdist(p1, p2) {
    var dx = p2.x - p1.x;
    var dy = p2.y - p1.y;
    return dx * dx + dy * dy;
  };
  var inPlaceSumNormalize = function inPlaceSumNormalize(v) {
    var length = v.length;

    // First, get sum of all elements
    var total = 0;
    for (var i = 0; i < length; i++) {
      total += v[i];
    }

    // Now, divide each by the sum of all elements
    for (var _i = 0; _i < length; _i++) {
      v[_i] = v[_i] / total;
    }
    return v;
  };

  // from http://en.wikipedia.org/wiki/Bézier_curve#Quadratic_curves
  var qbezierAt = function qbezierAt(p0, p1, p2, t) {
    return (1 - t) * (1 - t) * p0 + 2 * (1 - t) * t * p1 + t * t * p2;
  };
  var qbezierPtAt = function qbezierPtAt(p0, p1, p2, t) {
    return {
      x: qbezierAt(p0.x, p1.x, p2.x, t),
      y: qbezierAt(p0.y, p1.y, p2.y, t)
    };
  };
  var lineAt = function lineAt(p0, p1, t, d) {
    var vec = {
      x: p1.x - p0.x,
      y: p1.y - p0.y
    };
    var vecDist = dist(p0, p1);
    var normVec = {
      x: vec.x / vecDist,
      y: vec.y / vecDist
    };
    t = t == null ? 0 : t;
    d = d != null ? d : t * vecDist;
    return {
      x: p0.x + normVec.x * d,
      y: p0.y + normVec.y * d
    };
  };
  var bound = function bound(min, val, max) {
    return Math.max(min, Math.min(max, val));
  };

  // makes a full bb (x1, y1, x2, y2, w, h) from implicit params
  var makeBoundingBox = function makeBoundingBox(bb) {
    if (bb == null) {
      return {
        x1: Infinity,
        y1: Infinity,
        x2: -Infinity,
        y2: -Infinity,
        w: 0,
        h: 0
      };
    } else if (bb.x1 != null && bb.y1 != null) {
      if (bb.x2 != null && bb.y2 != null && bb.x2 >= bb.x1 && bb.y2 >= bb.y1) {
        return {
          x1: bb.x1,
          y1: bb.y1,
          x2: bb.x2,
          y2: bb.y2,
          w: bb.x2 - bb.x1,
          h: bb.y2 - bb.y1
        };
      } else if (bb.w != null && bb.h != null && bb.w >= 0 && bb.h >= 0) {
        return {
          x1: bb.x1,
          y1: bb.y1,
          x2: bb.x1 + bb.w,
          y2: bb.y1 + bb.h,
          w: bb.w,
          h: bb.h
        };
      }
    }
  };
  var copyBoundingBox = function copyBoundingBox(bb) {
    return {
      x1: bb.x1,
      x2: bb.x2,
      w: bb.w,
      y1: bb.y1,
      y2: bb.y2,
      h: bb.h
    };
  };
  var clearBoundingBox = function clearBoundingBox(bb) {
    bb.x1 = Infinity;
    bb.y1 = Infinity;
    bb.x2 = -Infinity;
    bb.y2 = -Infinity;
    bb.w = 0;
    bb.h = 0;
  };
  var shiftBoundingBox = function shiftBoundingBox(bb, dx, dy) {
    return {
      x1: bb.x1 + dx,
      x2: bb.x2 + dx,
      y1: bb.y1 + dy,
      y2: bb.y2 + dy,
      w: bb.w,
      h: bb.h
    };
  };
  var updateBoundingBox = function updateBoundingBox(bb1, bb2) {
    // update bb1 with bb2 bounds

    bb1.x1 = Math.min(bb1.x1, bb2.x1);
    bb1.x2 = Math.max(bb1.x2, bb2.x2);
    bb1.w = bb1.x2 - bb1.x1;
    bb1.y1 = Math.min(bb1.y1, bb2.y1);
    bb1.y2 = Math.max(bb1.y2, bb2.y2);
    bb1.h = bb1.y2 - bb1.y1;
  };
  var expandBoundingBoxByPoint = function expandBoundingBoxByPoint(bb, x, y) {
    bb.x1 = Math.min(bb.x1, x);
    bb.x2 = Math.max(bb.x2, x);
    bb.w = bb.x2 - bb.x1;
    bb.y1 = Math.min(bb.y1, y);
    bb.y2 = Math.max(bb.y2, y);
    bb.h = bb.y2 - bb.y1;
  };
  var expandBoundingBox = function expandBoundingBox(bb) {
    var padding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
    bb.x1 -= padding;
    bb.x2 += padding;
    bb.y1 -= padding;
    bb.y2 += padding;
    bb.w = bb.x2 - bb.x1;
    bb.h = bb.y2 - bb.y1;
    return bb;
  };
  var expandBoundingBoxSides = function expandBoundingBoxSides(bb) {
    var padding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [0];
    var top, right, bottom, left;
    if (padding.length === 1) {
      top = right = bottom = left = padding[0];
    } else if (padding.length === 2) {
      top = bottom = padding[0];
      left = right = padding[1];
    } else if (padding.length === 4) {
      var _padding = _slicedToArray(padding, 4);
      top = _padding[0];
      right = _padding[1];
      bottom = _padding[2];
      left = _padding[3];
    }
    bb.x1 -= left;
    bb.x2 += right;
    bb.y1 -= top;
    bb.y2 += bottom;
    bb.w = bb.x2 - bb.x1;
    bb.h = bb.y2 - bb.y1;
    return bb;
  };

  // assign the values of bb2 into bb1
  var assignBoundingBox = function assignBoundingBox(bb1, bb2) {
    bb1.x1 = bb2.x1;
    bb1.y1 = bb2.y1;
    bb1.x2 = bb2.x2;
    bb1.y2 = bb2.y2;
    bb1.w = bb1.x2 - bb1.x1;
    bb1.h = bb1.y2 - bb1.y1;
  };
  var boundingBoxesIntersect = function boundingBoxesIntersect(bb1, bb2) {
    // case: one bb to right of other
    if (bb1.x1 > bb2.x2) {
      return false;
    }
    if (bb2.x1 > bb1.x2) {
      return false;
    }

    // case: one bb to left of other
    if (bb1.x2 < bb2.x1) {
      return false;
    }
    if (bb2.x2 < bb1.x1) {
      return false;
    }

    // case: one bb above other
    if (bb1.y2 < bb2.y1) {
      return false;
    }
    if (bb2.y2 < bb1.y1) {
      return false;
    }

    // case: one bb below other
    if (bb1.y1 > bb2.y2) {
      return false;
    }
    if (bb2.y1 > bb1.y2) {
      return false;
    }

    // otherwise, must have some overlap
    return true;
  };
  var inBoundingBox = function inBoundingBox(bb, x, y) {
    return bb.x1 <= x && x <= bb.x2 && bb.y1 <= y && y <= bb.y2;
  };
  var pointInBoundingBox = function pointInBoundingBox(bb, pt) {
    return inBoundingBox(bb, pt.x, pt.y);
  };
  var boundingBoxInBoundingBox = function boundingBoxInBoundingBox(bb1, bb2) {
    return inBoundingBox(bb1, bb2.x1, bb2.y1) && inBoundingBox(bb1, bb2.x2, bb2.y2);
  };
  var roundRectangleIntersectLine = function roundRectangleIntersectLine(x, y, nodeX, nodeY, width, height, padding) {
    var cornerRadius = getRoundRectangleRadius(width, height);
    var halfWidth = width / 2;
    var halfHeight = height / 2;

    // Check intersections with straight line segments
    var straightLineIntersections;

    // Top segment, left to right
    {
      var topStartX = nodeX - halfWidth + cornerRadius - padding;
      var topStartY = nodeY - halfHeight - padding;
      var topEndX = nodeX + halfWidth - cornerRadius + padding;
      var topEndY = topStartY;
      straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false);
      if (straightLineIntersections.length > 0) {
        return straightLineIntersections;
      }
    }

    // Right segment, top to bottom
    {
      var rightStartX = nodeX + halfWidth + padding;
      var rightStartY = nodeY - halfHeight + cornerRadius - padding;
      var rightEndX = rightStartX;
      var rightEndY = nodeY + halfHeight - cornerRadius + padding;
      straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, rightStartX, rightStartY, rightEndX, rightEndY, false);
      if (straightLineIntersections.length > 0) {
        return straightLineIntersections;
      }
    }

    // Bottom segment, left to right
    {
      var bottomStartX = nodeX - halfWidth + cornerRadius - padding;
      var bottomStartY = nodeY + halfHeight + padding;
      var bottomEndX = nodeX + halfWidth - cornerRadius + padding;
      var bottomEndY = bottomStartY;
      straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, bottomStartX, bottomStartY, bottomEndX, bottomEndY, false);
      if (straightLineIntersections.length > 0) {
        return straightLineIntersections;
      }
    }

    // Left segment, top to bottom
    {
      var leftStartX = nodeX - halfWidth - padding;
      var leftStartY = nodeY - halfHeight + cornerRadius - padding;
      var leftEndX = leftStartX;
      var leftEndY = nodeY + halfHeight - cornerRadius + padding;
      straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, leftStartX, leftStartY, leftEndX, leftEndY, false);
      if (straightLineIntersections.length > 0) {
        return straightLineIntersections;
      }
    }

    // Check intersections with arc segments
    var arcIntersections;

    // Top Left
    {
      var topLeftCenterX = nodeX - halfWidth + cornerRadius;
      var topLeftCenterY = nodeY - halfHeight + cornerRadius;
      arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, topLeftCenterX, topLeftCenterY, cornerRadius + padding);

      // Ensure the intersection is on the desired quarter of the circle
      if (arcIntersections.length > 0 && arcIntersections[0] <= topLeftCenterX && arcIntersections[1] <= topLeftCenterY) {
        return [arcIntersections[0], arcIntersections[1]];
      }
    }

    // Top Right
    {
      var topRightCenterX = nodeX + halfWidth - cornerRadius;
      var topRightCenterY = nodeY - halfHeight + cornerRadius;
      arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, topRightCenterX, topRightCenterY, cornerRadius + padding);

      // Ensure the intersection is on the desired quarter of the circle
      if (arcIntersections.length > 0 && arcIntersections[0] >= topRightCenterX && arcIntersections[1] <= topRightCenterY) {
        return [arcIntersections[0], arcIntersections[1]];
      }
    }

    // Bottom Right
    {
      var bottomRightCenterX = nodeX + halfWidth - cornerRadius;
      var bottomRightCenterY = nodeY + halfHeight - cornerRadius;
      arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, bottomRightCenterX, bottomRightCenterY, cornerRadius + padding);

      // Ensure the intersection is on the desired quarter of the circle
      if (arcIntersections.length > 0 && arcIntersections[0] >= bottomRightCenterX && arcIntersections[1] >= bottomRightCenterY) {
        return [arcIntersections[0], arcIntersections[1]];
      }
    }

    // Bottom Left
    {
      var bottomLeftCenterX = nodeX - halfWidth + cornerRadius;
      var bottomLeftCenterY = nodeY + halfHeight - cornerRadius;
      arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, bottomLeftCenterX, bottomLeftCenterY, cornerRadius + padding);

      // Ensure the intersection is on the desired quarter of the circle
      if (arcIntersections.length > 0 && arcIntersections[0] <= bottomLeftCenterX && arcIntersections[1] >= bottomLeftCenterY) {
        return [arcIntersections[0], arcIntersections[1]];
      }
    }
    return []; // if nothing
  };

  var inLineVicinity = function inLineVicinity(x, y, lx1, ly1, lx2, ly2, tolerance) {
    var t = tolerance;
    var x1 = Math.min(lx1, lx2);
    var x2 = Math.max(lx1, lx2);
    var y1 = Math.min(ly1, ly2);
    var y2 = Math.max(ly1, ly2);
    return x1 - t <= x && x <= x2 + t && y1 - t <= y && y <= y2 + t;
  };
  var inBezierVicinity = function inBezierVicinity(x, y, x1, y1, x2, y2, x3, y3, tolerance) {
    var bb = {
      x1: Math.min(x1, x3, x2) - tolerance,
      x2: Math.max(x1, x3, x2) + tolerance,
      y1: Math.min(y1, y3, y2) - tolerance,
      y2: Math.max(y1, y3, y2) + tolerance
    };

    // if outside the rough bounding box for the bezier, then it can't be a hit
    if (x < bb.x1 || x > bb.x2 || y < bb.y1 || y > bb.y2) {
      // console.log('bezier out of rough bb')
      return false;
    } else {
      // console.log('do more expensive check');
      return true;
    }
  };
  var solveQuadratic = function solveQuadratic(a, b, c, val) {
    c -= val;
    var r = b * b - 4 * a * c;
    if (r < 0) {
      return [];
    }
    var sqrtR = Math.sqrt(r);
    var denom = 2 * a;
    var root1 = (-b + sqrtR) / denom;
    var root2 = (-b - sqrtR) / denom;
    return [root1, root2];
  };
  var solveCubic = function solveCubic(a, b, c, d, result) {
    // Solves a cubic function, returns root in form [r1, i1, r2, i2, r3, i3], where
    // r is the real component, i is the imaginary component

    // An implementation of the Cardano method from the year 1545
    // http://en.wikipedia.org/wiki/Cubic_function#The_nature_of_the_roots

    var epsilon = 0.00001;

    // avoid division by zero while keeping the overall expression close in value
    if (a === 0) {
      a = epsilon;
    }
    b /= a;
    c /= a;
    d /= a;
    var discriminant, q, r, dum1, s, t, term1, r13;
    q = (3.0 * c - b * b) / 9.0;
    r = -(27.0 * d) + b * (9.0 * c - 2.0 * (b * b));
    r /= 54.0;
    discriminant = q * q * q + r * r;
    result[1] = 0;
    term1 = b / 3.0;
    if (discriminant > 0) {
      s = r + Math.sqrt(discriminant);
      s = s < 0 ? -Math.pow(-s, 1.0 / 3.0) : Math.pow(s, 1.0 / 3.0);
      t = r - Math.sqrt(discriminant);
      t = t < 0 ? -Math.pow(-t, 1.0 / 3.0) : Math.pow(t, 1.0 / 3.0);
      result[0] = -term1 + s + t;
      term1 += (s + t) / 2.0;
      result[4] = result[2] = -term1;
      term1 = Math.sqrt(3.0) * (-t + s) / 2;
      result[3] = term1;
      result[5] = -term1;
      return;
    }
    result[5] = result[3] = 0;
    if (discriminant === 0) {
      r13 = r < 0 ? -Math.pow(-r, 1.0 / 3.0) : Math.pow(r, 1.0 / 3.0);
      result[0] = -term1 + 2.0 * r13;
      result[4] = result[2] = -(r13 + term1);
      return;
    }
    q = -q;
    dum1 = q * q * q;
    dum1 = Math.acos(r / Math.sqrt(dum1));
    r13 = 2.0 * Math.sqrt(q);
    result[0] = -term1 + r13 * Math.cos(dum1 / 3.0);
    result[2] = -term1 + r13 * Math.cos((dum1 + 2.0 * Math.PI) / 3.0);
    result[4] = -term1 + r13 * Math.cos((dum1 + 4.0 * Math.PI) / 3.0);
    return;
  };
  var sqdistToQuadraticBezier = function sqdistToQuadraticBezier(x, y, x1, y1, x2, y2, x3, y3) {
    // Find minimum distance by using the minimum of the distance
    // function between the given point and the curve

    // This gives the coefficients of the resulting cubic equation
    // whose roots tell us where a possible minimum is
    // (Coefficients are divided by 4)

    var a = 1.0 * x1 * x1 - 4 * x1 * x2 + 2 * x1 * x3 + 4 * x2 * x2 - 4 * x2 * x3 + x3 * x3 + y1 * y1 - 4 * y1 * y2 + 2 * y1 * y3 + 4 * y2 * y2 - 4 * y2 * y3 + y3 * y3;
    var b = 1.0 * 9 * x1 * x2 - 3 * x1 * x1 - 3 * x1 * x3 - 6 * x2 * x2 + 3 * x2 * x3 + 9 * y1 * y2 - 3 * y1 * y1 - 3 * y1 * y3 - 6 * y2 * y2 + 3 * y2 * y3;
    var c = 1.0 * 3 * x1 * x1 - 6 * x1 * x2 + x1 * x3 - x1 * x + 2 * x2 * x2 + 2 * x2 * x - x3 * x + 3 * y1 * y1 - 6 * y1 * y2 + y1 * y3 - y1 * y + 2 * y2 * y2 + 2 * y2 * y - y3 * y;
    var d = 1.0 * x1 * x2 - x1 * x1 + x1 * x - x2 * x + y1 * y2 - y1 * y1 + y1 * y - y2 * y;

    // debug("coefficients: " + a / a + ", " + b / a + ", " + c / a + ", " + d / a);

    var roots = [];

    // Use the cubic solving algorithm
    solveCubic(a, b, c, d, roots);
    var zeroThreshold = 0.0000001;
    var params = [];
    for (var index = 0; index < 6; index += 2) {
      if (Math.abs(roots[index + 1]) < zeroThreshold && roots[index] >= 0 && roots[index] <= 1.0) {
        params.push(roots[index]);
      }
    }
    params.push(1.0);
    params.push(0.0);
    var minDistanceSquared = -1;
    var curX, curY, distSquared;
    for (var i = 0; i < params.length; i++) {
      curX = Math.pow(1.0 - params[i], 2.0) * x1 + 2.0 * (1 - params[i]) * params[i] * x2 + params[i] * params[i] * x3;
      curY = Math.pow(1 - params[i], 2.0) * y1 + 2 * (1.0 - params[i]) * params[i] * y2 + params[i] * params[i] * y3;
      distSquared = Math.pow(curX - x, 2) + Math.pow(curY - y, 2);
      // debug('distance for param ' + params[i] + ": " + Math.sqrt(distSquared));
      if (minDistanceSquared >= 0) {
        if (distSquared < minDistanceSquared) {
          minDistanceSquared = distSquared;
        }
      } else {
        minDistanceSquared = distSquared;
      }
    }
    return minDistanceSquared;
  };
  var sqdistToFiniteLine = function sqdistToFiniteLine(x, y, x1, y1, x2, y2) {
    var offset = [x - x1, y - y1];
    var line = [x2 - x1, y2 - y1];
    var lineSq = line[0] * line[0] + line[1] * line[1];
    var hypSq = offset[0] * offset[0] + offset[1] * offset[1];
    var dotProduct = offset[0] * line[0] + offset[1] * line[1];
    var adjSq = dotProduct * dotProduct / lineSq;
    if (dotProduct < 0) {
      return hypSq;
    }
    if (adjSq > lineSq) {
      return (x - x2) * (x - x2) + (y - y2) * (y - y2);
    }
    return hypSq - adjSq;
  };
  var pointInsidePolygonPoints = function pointInsidePolygonPoints(x, y, points) {
    var x1, y1, x2, y2;
    var y3;

    // Intersect with vertical line through (x, y)
    var up = 0;
    // let down = 0;
    for (var i = 0; i < points.length / 2; i++) {
      x1 = points[i * 2];
      y1 = points[i * 2 + 1];
      if (i + 1 < points.length / 2) {
        x2 = points[(i + 1) * 2];
        y2 = points[(i + 1) * 2 + 1];
      } else {
        x2 = points[(i + 1 - points.length / 2) * 2];
        y2 = points[(i + 1 - points.length / 2) * 2 + 1];
      }
      if (x1 == x && x2 == x) ; else if (x1 >= x && x >= x2 || x1 <= x && x <= x2) {
        y3 = (x - x1) / (x2 - x1) * (y2 - y1) + y1;
        if (y3 > y) {
          up++;
        }

        // if( y3 < y ){
        // down++;
        // }
      } else {
        continue;
      }
    }
    if (up % 2 === 0) {
      return false;
    } else {
      return true;
    }
  };
  var pointInsidePolygon = function pointInsidePolygon(x, y, basePoints, centerX, centerY, width, height, direction, padding) {
    var transformedPoints = new Array(basePoints.length);

    // Gives negative angle
    var angle;
    if (direction[0] != null) {
      angle = Math.atan(direction[1] / direction[0]);
      if (direction[0] < 0) {
        angle = angle + Math.PI / 2;
      } else {
        angle = -angle - Math.PI / 2;
      }
    } else {
      angle = direction;
    }
    var cos = Math.cos(-angle);
    var sin = Math.sin(-angle);

    //    console.log("base: " + basePoints);
    for (var i = 0; i < transformedPoints.length / 2; i++) {
      transformedPoints[i * 2] = width / 2 * (basePoints[i * 2] * cos - basePoints[i * 2 + 1] * sin);
      transformedPoints[i * 2 + 1] = height / 2 * (basePoints[i * 2 + 1] * cos + basePoints[i * 2] * sin);
      transformedPoints[i * 2] += centerX;
      transformedPoints[i * 2 + 1] += centerY;
    }
    var points;
    if (padding > 0) {
      var expandedLineSet = expandPolygon(transformedPoints, -padding);
      points = joinLines(expandedLineSet);
    } else {
      points = transformedPoints;
    }
    return pointInsidePolygonPoints(x, y, points);
  };
  var pointInsideRoundPolygon = function pointInsideRoundPolygon(x, y, basePoints, centerX, centerY, width, height) {
    var cutPolygonPoints = new Array(basePoints.length);
    var halfW = width / 2;
    var halfH = height / 2;
    var cornerRadius = getRoundPolygonRadius(width, height);
    var squaredCornerRadius = cornerRadius * cornerRadius;
    for (var i = 0; i < basePoints.length / 4; i++) {
      var sourceUv = void 0,
        destUv = void 0;
      if (i === 0) {
        sourceUv = basePoints.length - 2;
      } else {
        sourceUv = i * 4 - 2;
      }
      destUv = i * 4 + 2;
      var px = centerX + halfW * basePoints[i * 4];
      var py = centerY + halfH * basePoints[i * 4 + 1];
      var cosTheta = -basePoints[sourceUv] * basePoints[destUv] - basePoints[sourceUv + 1] * basePoints[destUv + 1];
      var offset = cornerRadius / Math.tan(Math.acos(cosTheta) / 2);
      var cp0x = px - offset * basePoints[sourceUv];
      var cp0y = py - offset * basePoints[sourceUv + 1];
      var cp1x = px + offset * basePoints[destUv];
      var cp1y = py + offset * basePoints[destUv + 1];
      cutPolygonPoints[i * 4] = cp0x;
      cutPolygonPoints[i * 4 + 1] = cp0y;
      cutPolygonPoints[i * 4 + 2] = cp1x;
      cutPolygonPoints[i * 4 + 3] = cp1y;
      var orthx = basePoints[sourceUv + 1];
      var orthy = -basePoints[sourceUv];
      var cosAlpha = orthx * basePoints[destUv] + orthy * basePoints[destUv + 1];
      if (cosAlpha < 0) {
        orthx *= -1;
        orthy *= -1;
      }
      var cx = cp0x + orthx * cornerRadius;
      var cy = cp0y + orthy * cornerRadius;
      var squaredDistance = Math.pow(cx - x, 2) + Math.pow(cy - y, 2);
      if (squaredDistance <= squaredCornerRadius) {
        return true;
      }
    }
    return pointInsidePolygonPoints(x, y, cutPolygonPoints);
  };
  var joinLines = function joinLines(lineSet) {
    var vertices = new Array(lineSet.length / 2);
    var currentLineStartX, currentLineStartY, currentLineEndX, currentLineEndY;
    var nextLineStartX, nextLineStartY, nextLineEndX, nextLineEndY;
    for (var i = 0; i < lineSet.length / 4; i++) {
      currentLineStartX = lineSet[i * 4];
      currentLineStartY = lineSet[i * 4 + 1];
      currentLineEndX = lineSet[i * 4 + 2];
      currentLineEndY = lineSet[i * 4 + 3];
      if (i < lineSet.length / 4 - 1) {
        nextLineStartX = lineSet[(i + 1) * 4];
        nextLineStartY = lineSet[(i + 1) * 4 + 1];
        nextLineEndX = lineSet[(i + 1) * 4 + 2];
        nextLineEndY = lineSet[(i + 1) * 4 + 3];
      } else {
        nextLineStartX = lineSet[0];
        nextLineStartY = lineSet[1];
        nextLineEndX = lineSet[2];
        nextLineEndY = lineSet[3];
      }
      var intersection = finiteLinesIntersect(currentLineStartX, currentLineStartY, currentLineEndX, currentLineEndY, nextLineStartX, nextLineStartY, nextLineEndX, nextLineEndY, true);
      vertices[i * 2] = intersection[0];
      vertices[i * 2 + 1] = intersection[1];
    }
    return vertices;
  };
  var expandPolygon = function expandPolygon(points, pad) {
    var expandedLineSet = new Array(points.length * 2);
    var currentPointX, currentPointY, nextPointX, nextPointY;
    for (var i = 0; i < points.length / 2; i++) {
      currentPointX = points[i * 2];
      currentPointY = points[i * 2 + 1];
      if (i < points.length / 2 - 1) {
        nextPointX = points[(i + 1) * 2];
        nextPointY = points[(i + 1) * 2 + 1];
      } else {
        nextPointX = points[0];
        nextPointY = points[1];
      }

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

      // Assume CCW polygon winding

      var offsetX = nextPointY - currentPointY;
      var offsetY = -(nextPointX - currentPointX);

      // Normalize
      var offsetLength = Math.sqrt(offsetX * offsetX + offsetY * offsetY);
      var normalizedOffsetX = offsetX / offsetLength;
      var normalizedOffsetY = offsetY / offsetLength;
      expandedLineSet[i * 4] = currentPointX + normalizedOffsetX * pad;
      expandedLineSet[i * 4 + 1] = currentPointY + normalizedOffsetY * pad;
      expandedLineSet[i * 4 + 2] = nextPointX + normalizedOffsetX * pad;
      expandedLineSet[i * 4 + 3] = nextPointY + normalizedOffsetY * pad;
    }
    return expandedLineSet;
  };
  var intersectLineEllipse = function intersectLineEllipse(x, y, centerX, centerY, ellipseWradius, ellipseHradius) {
    var dispX = centerX - x;
    var dispY = centerY - y;
    dispX /= ellipseWradius;
    dispY /= ellipseHradius;
    var len = Math.sqrt(dispX * dispX + dispY * dispY);
    var newLength = len - 1;
    if (newLength < 0) {
      return [];
    }
    var lenProportion = newLength / len;
    return [(centerX - x) * lenProportion + x, (centerY - y) * lenProportion + y];
  };
  var checkInEllipse = function checkInEllipse(x, y, width, height, centerX, centerY, padding) {
    x -= centerX;
    y -= centerY;
    x /= width / 2 + padding;
    y /= height / 2 + padding;
    return x * x + y * y <= 1;
  };

  // Returns intersections of increasing distance from line's start point
  var intersectLineCircle = function intersectLineCircle(x1, y1, x2, y2, centerX, centerY, radius) {
    // Calculate d, direction vector of line
    var d = [x2 - x1, y2 - y1]; // Direction vector of line
    var f = [x1 - centerX, y1 - centerY];
    var a = d[0] * d[0] + d[1] * d[1];
    var b = 2 * (f[0] * d[0] + f[1] * d[1]);
    var c = f[0] * f[0] + f[1] * f[1] - radius * radius;
    var discriminant = b * b - 4 * a * c;
    if (discriminant < 0) {
      return [];
    }
    var t1 = (-b + Math.sqrt(discriminant)) / (2 * a);
    var t2 = (-b - Math.sqrt(discriminant)) / (2 * a);
    var tMin = Math.min(t1, t2);
    var tMax = Math.max(t1, t2);
    var inRangeParams = [];
    if (tMin >= 0 && tMin <= 1) {
      inRangeParams.push(tMin);
    }
    if (tMax >= 0 && tMax <= 1) {
      inRangeParams.push(tMax);
    }
    if (inRangeParams.length === 0) {
      return [];
    }
    var nearIntersectionX = inRangeParams[0] * d[0] + x1;
    var nearIntersectionY = inRangeParams[0] * d[1] + y1;
    if (inRangeParams.length > 1) {
      if (inRangeParams[0] == inRangeParams[1]) {
        return [nearIntersectionX, nearIntersectionY];
      } else {
        var farIntersectionX = inRangeParams[1] * d[0] + x1;
        var farIntersectionY = inRangeParams[1] * d[1] + y1;
        return [nearIntersectionX, nearIntersectionY, farIntersectionX, farIntersectionY];
      }
    } else {
      return [nearIntersectionX, nearIntersectionY];
    }
  };
  var midOfThree = function midOfThree(a, b, c) {
    if (b <= a && a <= c || c <= a && a <= b) {
      return a;
    } else if (a <= b && b <= c || c <= b && b <= a) {
      return b;
    } else {
      return c;
    }
  };

  // (x1,y1)=>(x2,y2) intersect with (x3,y3)=>(x4,y4)
  var finiteLinesIntersect = function finiteLinesIntersect(x1, y1, x2, y2, x3, y3, x4, y4, infiniteLines) {
    var dx13 = x1 - x3;
    var dx21 = x2 - x1;
    var dx43 = x4 - x3;
    var dy13 = y1 - y3;
    var dy21 = y2 - y1;
    var dy43 = y4 - y3;
    var ua_t = dx43 * dy13 - dy43 * dx13;
    var ub_t = dx21 * dy13 - dy21 * dx13;
    var u_b = dy43 * dx21 - dx43 * dy21;
    if (u_b !== 0) {
      var ua = ua_t / u_b;
      var ub = ub_t / u_b;
      var flptThreshold = 0.001;
      var _min = 0 - flptThreshold;
      var _max = 1 + flptThreshold;
      if (_min <= ua && ua <= _max && _min <= ub && ub <= _max) {
        return [x1 + ua * dx21, y1 + ua * dy21];
      } else {
        if (!infiniteLines) {
          return [];
        } else {
          return [x1 + ua * dx21, y1 + ua * dy21];
        }
      }
    } else {
      if (ua_t === 0 || ub_t === 0) {
        // Parallel, coincident lines. Check if overlap

        // Check endpoint of second line
        if (midOfThree(x1, x2, x4) === x4) {
          return [x4, y4];
        }

        // Check start point of second line
        if (midOfThree(x1, x2, x3) === x3) {
          return [x3, y3];
        }

        // Endpoint of first line
        if (midOfThree(x3, x4, x2) === x2) {
          return [x2, y2];
        }
        return [];
      } else {
        // Parallel, non-coincident
        return [];
      }
    }
  };

  // math.polygonIntersectLine( x, y, basePoints, centerX, centerY, width, height, padding )
  // intersect a node polygon (pts transformed)
  //
  // math.polygonIntersectLine( x, y, basePoints, centerX, centerY )
  // intersect the points (no transform)
  var polygonIntersectLine = function polygonIntersectLine(x, y, basePoints, centerX, centerY, width, height, padding) {
    var intersections = [];
    var intersection;
    var transformedPoints = new Array(basePoints.length);
    var doTransform = true;
    if (width == null) {
      doTransform = false;
    }
    var points;
    if (doTransform) {
      for (var i = 0; i < transformedPoints.length / 2; i++) {
        transformedPoints[i * 2] = basePoints[i * 2] * width + centerX;
        transformedPoints[i * 2 + 1] = basePoints[i * 2 + 1] * height + centerY;
      }
      if (padding > 0) {
        var expandedLineSet = expandPolygon(transformedPoints, -padding);
        points = joinLines(expandedLineSet);
      } else {
        points = transformedPoints;
      }
    } else {
      points = basePoints;
    }
    var currentX, currentY, nextX, nextY;
    for (var _i2 = 0; _i2 < points.length / 2; _i2++) {
      currentX = points[_i2 * 2];
      currentY = points[_i2 * 2 + 1];
      if (_i2 < points.length / 2 - 1) {
        nextX = points[(_i2 + 1) * 2];
        nextY = points[(_i2 + 1) * 2 + 1];
      } else {
        nextX = points[0];
        nextY = points[1];
      }
      intersection = finiteLinesIntersect(x, y, centerX, centerY, currentX, currentY, nextX, nextY);
      if (intersection.length !== 0) {
        intersections.push(intersection[0], intersection[1]);
      }
    }
    return intersections;
  };
  var roundPolygonIntersectLine = function roundPolygonIntersectLine(x, y, basePoints, centerX, centerY, width, height, padding) {
    var intersections = [];
    var intersection;
    var lines = new Array(basePoints.length);
    var halfW = width / 2;
    var halfH = height / 2;
    var cornerRadius = getRoundPolygonRadius(width, height);
    for (var i = 0; i < basePoints.length / 4; i++) {
      var sourceUv = void 0,
        destUv = void 0;
      if (i === 0) {
        sourceUv = basePoints.length - 2;
      } else {
        sourceUv = i * 4 - 2;
      }
      destUv = i * 4 + 2;
      var px = centerX + halfW * basePoints[i * 4];
      var py = centerY + halfH * basePoints[i * 4 + 1];
      var cosTheta = -basePoints[sourceUv] * basePoints[destUv] - basePoints[sourceUv + 1] * basePoints[destUv + 1];
      var offset = cornerRadius / Math.tan(Math.acos(cosTheta) / 2);
      var cp0x = px - offset * basePoints[sourceUv];
      var cp0y = py - offset * basePoints[sourceUv + 1];
      var cp1x = px + offset * basePoints[destUv];
      var cp1y = py + offset * basePoints[destUv + 1];
      if (i === 0) {
        lines[basePoints.length - 2] = cp0x;
        lines[basePoints.length - 1] = cp0y;
      } else {
        lines[i * 4 - 2] = cp0x;
        lines[i * 4 - 1] = cp0y;
      }
      lines[i * 4] = cp1x;
      lines[i * 4 + 1] = cp1y;
      var orthx = basePoints[sourceUv + 1];
      var orthy = -basePoints[sourceUv];
      var cosAlpha = orthx * basePoints[destUv] + orthy * basePoints[destUv + 1];
      if (cosAlpha < 0) {
        orthx *= -1;
        orthy *= -1;
      }
      var cx = cp0x + orthx * cornerRadius;
      var cy = cp0y + orthy * cornerRadius;
      intersection = intersectLineCircle(x, y, centerX, centerY, cx, cy, cornerRadius);
      if (intersection.length !== 0) {
        intersections.push(intersection[0], intersection[1]);
      }
    }
    for (var _i3 = 0; _i3 < lines.length / 4; _i3++) {
      intersection = finiteLinesIntersect(x, y, centerX, centerY, lines[_i3 * 4], lines[_i3 * 4 + 1], lines[_i3 * 4 + 2], lines[_i3 * 4 + 3], false);
      if (intersection.length !== 0) {
        intersections.push(intersection[0], intersection[1]);
      }
    }
    if (intersections.length > 2) {
      var lowestIntersection = [intersections[0], intersections[1]];
      var lowestSquaredDistance = Math.pow(lowestIntersection[0] - x, 2) + Math.pow(lowestIntersection[1] - y, 2);
      for (var _i4 = 1; _i4 < intersections.length / 2; _i4++) {
        var squaredDistance = Math.pow(intersections[_i4 * 2] - x, 2) + Math.pow(intersections[_i4 * 2 + 1] - y, 2);
        if (squaredDistance <= lowestSquaredDistance) {
          lowestIntersection[0] = intersections[_i4 * 2];
          lowestIntersection[1] = intersections[_i4 * 2 + 1];
          lowestSquaredDistance = squaredDistance;
        }
      }
      return lowestIntersection;
    }
    return intersections;
  };
  var shortenIntersection = function shortenIntersection(intersection, offset, amount) {
    var disp = [intersection[0] - offset[0], intersection[1] - offset[1]];
    var length = Math.sqrt(disp[0] * disp[0] + disp[1] * disp[1]);
    var lenRatio = (length - amount) / length;
    if (lenRatio < 0) {
      lenRatio = 0.00001;
    }
    return [offset[0] + lenRatio * disp[0], offset[1] + lenRatio * disp[1]];
  };
  var generateUnitNgonPointsFitToSquare = function generateUnitNgonPointsFitToSquare(sides, rotationRadians) {
    var points = generateUnitNgonPoints(sides, rotationRadians);
    points = fitPolygonToSquare(points);
    return points;
  };
  var fitPolygonToSquare = function fitPolygonToSquare(points) {
    var x, y;
    var sides = points.length / 2;
    var minX = Infinity,
      minY = Infinity,
      maxX = -Infinity,
      maxY = -Infinity;
    for (var i = 0; i < sides; i++) {
      x = points[2 * i];
      y = points[2 * i + 1];
      minX = Math.min(minX, x);
      maxX = Math.max(maxX, x);
      minY = Math.min(minY, y);
      maxY = Math.max(maxY, y);
    }

    // stretch factors
    var sx = 2 / (maxX - minX);
    var sy = 2 / (maxY - minY);
    for (var _i5 = 0; _i5 < sides; _i5++) {
      x = points[2 * _i5] = points[2 * _i5] * sx;
      y = points[2 * _i5 + 1] = points[2 * _i5 + 1] * sy;
      minX = Math.min(minX, x);
      maxX = Math.max(maxX, x);
      minY = Math.min(minY, y);
      maxY = Math.max(maxY, y);
    }
    if (minY < -1) {
      for (var _i6 = 0; _i6 < sides; _i6++) {
        y = points[2 * _i6 + 1] = points[2 * _i6 + 1] + (-1 - minY);
      }
    }
    return points;
  };
  var generateUnitNgonPoints = function generateUnitNgonPoints(sides, rotationRadians) {
    var increment = 1.0 / sides * 2 * Math.PI;
    var startAngle = sides % 2 === 0 ? Math.PI / 2.0 + increment / 2.0 : Math.PI / 2.0;
    startAngle += rotationRadians;
    var points = new Array(sides * 2);
    var currentAngle;
    for (var i = 0; i < sides; i++) {
      currentAngle = i * increment + startAngle;
      points[2 * i] = Math.cos(currentAngle); // x
      points[2 * i + 1] = Math.sin(-currentAngle); // y
    }

    return points;
  };

  // Set the default radius, unless half of width or height is smaller than default
  var getRoundRectangleRadius = function getRoundRectangleRadius(width, height) {
    return Math.min(width / 4, height / 4, 8);
  };

  // Set the default radius
  var getRoundPolygonRadius = function getRoundPolygonRadius(width, height) {
    return Math.min(width / 10, height / 10, 8);
  };
  var getCutRectangleCornerLength = function getCutRectangleCornerLength() {
    return 8;
  };
  var bezierPtsToQuadCoeff = function bezierPtsToQuadCoeff(p0, p1, p2) {
    return [p0 - 2 * p1 + p2, 2 * (p1 - p0), p0];
  };

  // get curve width, height, and control point position offsets as a percentage of node height / width
  var getBarrelCurveConstants = function getBarrelCurveConstants(width, height) {
    return {
      heightOffset: Math.min(15, 0.05 * height),
      widthOffset: Math.min(100, 0.25 * width),
      ctrlPtOffsetPct: 0.05
    };
  };

  var pageRankDefaults = defaults$g({
    dampingFactor: 0.8,
    precision: 0.000001,
    iterations: 200,
    weight: function weight(edge) {
      return 1;
    }
  });
  var elesfn$o = {
    pageRank: function pageRank(options) {
      var _pageRankDefaults = pageRankDefaults(options),
        dampingFactor = _pageRankDefaults.dampingFactor,
        precision = _pageRankDefaults.precision,
        iterations = _pageRankDefaults.iterations,
        weight = _pageRankDefaults.weight;
      var cy = this._private.cy;
      var _this$byGroup = this.byGroup(),
        nodes = _this$byGroup.nodes,
        edges = _this$byGroup.edges;
      var numNodes = nodes.length;
      var numNodesSqd = numNodes * numNodes;
      var numEdges = edges.length;

      // Construct transposed adjacency matrix
      // First lets have a zeroed matrix of the right size
      // We'll also keep track of the sum of each column
      var matrix = new Array(numNodesSqd);
      var columnSum = new Array(numNodes);
      var additionalProb = (1 - dampingFactor) / numNodes;

      // Create null matrix
      for (var i = 0; i < numNodes; i++) {
        for (var j = 0; j < numNodes; j++) {
          var n = i * numNodes + j;
          matrix[n] = 0;
        }
        columnSum[i] = 0;
      }

      // Now, process edges
      for (var _i = 0; _i < numEdges; _i++) {
        var edge = edges[_i];
        var srcId = edge.data('source');
        var tgtId = edge.data('target');

        // Don't include loops in the matrix
        if (srcId === tgtId) {
          continue;
        }
        var s = nodes.indexOfId(srcId);
        var t = nodes.indexOfId(tgtId);
        var w = weight(edge);
        var _n = t * numNodes + s;

        // Update matrix
        matrix[_n] += w;

        // Update column sum
        columnSum[s] += w;
      }

      // Add additional probability based on damping factor
      // Also, take into account columns that have sum = 0
      var p = 1.0 / numNodes + additionalProb; // Shorthand

      // Traverse matrix, column by column
      for (var _j = 0; _j < numNodes; _j++) {
        if (columnSum[_j] === 0) {
          // No 'links' out from node jth, assume equal probability for each possible node
          for (var _i2 = 0; _i2 < numNodes; _i2++) {
            var _n2 = _i2 * numNodes + _j;
            matrix[_n2] = p;
          }
        } else {
          // Node jth has outgoing link, compute normalized probabilities
          for (var _i3 = 0; _i3 < numNodes; _i3++) {
            var _n3 = _i3 * numNodes + _j;
            matrix[_n3] = matrix[_n3] / columnSum[_j] + additionalProb;
          }
        }
      }

      // Compute dominant eigenvector using power method
      var eigenvector = new Array(numNodes);
      var temp = new Array(numNodes);
      var previous;

      // Start with a vector of all 1's
      // Also, initialize a null vector which will be used as shorthand
      for (var _i4 = 0; _i4 < numNodes; _i4++) {
        eigenvector[_i4] = 1;
      }
      for (var iter = 0; iter < iterations; iter++) {
        // Temp array with all 0's
        for (var _i5 = 0; _i5 < numNodes; _i5++) {
          temp[_i5] = 0;
        }

        // Multiply matrix with previous result
        for (var _i6 = 0; _i6 < numNodes; _i6++) {
          for (var _j2 = 0; _j2 < numNodes; _j2++) {
            var _n4 = _i6 * numNodes + _j2;
            temp[_i6] += matrix[_n4] * eigenvector[_j2];
          }
        }
        inPlaceSumNormalize(temp);
        previous = eigenvector;
        eigenvector = temp;
        temp = previous;
        var diff = 0;
        // Compute difference (squared module) of both vectors
        for (var _i7 = 0; _i7 < numNodes; _i7++) {
          var delta = previous[_i7] - eigenvector[_i7];
          diff += delta * delta;
        }

        // If difference is less than the desired threshold, stop iterating
        if (diff < precision) {
          break;
        }
      }

      // Construct result
      var res = {
        rank: function rank(node) {
          node = cy.collection(node)[0];
          return eigenvector[nodes.indexOf(node)];
        }
      };
      return res;
    } // pageRank
  }; // elesfn

  var defaults$f = defaults$g({
    root: null,
    weight: function weight(edge) {
      return 1;
    },
    directed: false,
    alpha: 0
  });
  var elesfn$n = {
    degreeCentralityNormalized: function degreeCentralityNormalized(options) {
      options = defaults$f(options);
      var cy = this.cy();
      var nodes = this.nodes();
      var numNodes = nodes.length;
      if (!options.directed) {
        var degrees = {};
        var maxDegree = 0;
        for (var i = 0; i < numNodes; i++) {
          var node = nodes[i];

          // add current node to the current options object and call degreeCentrality
          options.root = node;
          var currDegree = this.degreeCentrality(options);
          if (maxDegree < currDegree.degree) {
            maxDegree = currDegree.degree;
          }
          degrees[node.id()] = currDegree.degree;
        }
        return {
          degree: function degree(node) {
            if (maxDegree === 0) {
              return 0;
            }
            if (string(node)) {
              // from is a selector string
              node = cy.filter(node);
            }
            return degrees[node.id()] / maxDegree;
          }
        };
      } else {
        var indegrees = {};
        var outdegrees = {};
        var maxIndegree = 0;
        var maxOutdegree = 0;
        for (var _i = 0; _i < numNodes; _i++) {
          var _node = nodes[_i];
          var id = _node.id();

          // add current node to the current options object and call degreeCentrality
          options.root = _node;
          var _currDegree = this.degreeCentrality(options);
          if (maxIndegree < _currDegree.indegree) maxIndegree = _currDegree.indegree;
          if (maxOutdegree < _currDegree.outdegree) maxOutdegree = _currDegree.outdegree;
          indegrees[id] = _currDegree.indegree;
          outdegrees[id] = _currDegree.outdegree;
        }
        return {
          indegree: function indegree(node) {
            if (maxIndegree == 0) {
              return 0;
            }
            if (string(node)) {
              // from is a selector string
              node = cy.filter(node);
            }
            return indegrees[node.id()] / maxIndegree;
          },
          outdegree: function outdegree(node) {
            if (maxOutdegree === 0) {
              return 0;
            }
            if (string(node)) {
              // from is a selector string
              node = cy.filter(node);
            }
            return outdegrees[node.id()] / maxOutdegree;
          }
        };
      }
    },
    // degreeCentralityNormalized

    // Implemented from the algorithm in Opsahl's paper
    // "Node centrality in weighted networks: Generalizing degree and shortest paths"
    // check the heading 2 "Degree"
    degreeCentrality: function degreeCentrality(options) {
      options = defaults$f(options);
      var cy = this.cy();
      var callingEles = this;
      var _options = options,
        root = _options.root,
        weight = _options.weight,
        directed = _options.directed,
        alpha = _options.alpha;
      root = cy.collection(root)[0];
      if (!directed) {
        var connEdges = root.connectedEdges().intersection(callingEles);
        var k = connEdges.length;
        var s = 0;

        // Now, sum edge weights
        for (var i = 0; i < connEdges.length; i++) {
          s += weight(connEdges[i]);
        }
        return {
          degree: Math.pow(k, 1 - alpha) * Math.pow(s, alpha)
        };
      } else {
        var edges = root.connectedEdges();
        var incoming = edges.filter(function (edge) {
          return edge.target().same(root) && callingEles.has(edge);
        });
        var outgoing = edges.filter(function (edge) {
          return edge.source().same(root) && callingEles.has(edge);
        });
        var k_in = incoming.length;
        var k_out = outgoing.length;
        var s_in = 0;
        var s_out = 0;

        // Now, sum incoming edge weights
        for (var _i2 = 0; _i2 < incoming.length; _i2++) {
          s_in += weight(incoming[_i2]);
        }

        // Now, sum outgoing edge weights
        for (var _i3 = 0; _i3 < outgoing.length; _i3++) {
          s_out += weight(outgoing[_i3]);
        }
        return {
          indegree: Math.pow(k_in, 1 - alpha) * Math.pow(s_in, alpha),
          outdegree: Math.pow(k_out, 1 - alpha) * Math.pow(s_out, alpha)
        };
      }
    } // degreeCentrality
  }; // elesfn

  // nice, short mathematical alias
  elesfn$n.dc = elesfn$n.degreeCentrality;
  elesfn$n.dcn = elesfn$n.degreeCentralityNormalised = elesfn$n.degreeCentralityNormalized;

  var defaults$e = defaults$g({
    harmonic: true,
    weight: function weight() {
      return 1;
    },
    directed: false,
    root: null
  });
  var elesfn$m = {
    closenessCentralityNormalized: function closenessCentralityNormalized(options) {
      var _defaults = defaults$e(options),
        harmonic = _defaults.harmonic,
        weight = _defaults.weight,
        directed = _defaults.directed;
      var cy = this.cy();
      var closenesses = {};
      var maxCloseness = 0;
      var nodes = this.nodes();
      var fw = this.floydWarshall({
        weight: weight,
        directed: directed
      });

      // Compute closeness for every node and find the maximum closeness
      for (var i = 0; i < nodes.length; i++) {
        var currCloseness = 0;
        var node_i = nodes[i];
        for (var j = 0; j < nodes.length; j++) {
          if (i !== j) {
            var d = fw.distance(node_i, nodes[j]);
            if (harmonic) {
              currCloseness += 1 / d;
            } else {
              currCloseness += d;
            }
          }
        }
        if (!harmonic) {
          currCloseness = 1 / currCloseness;
        }
        if (maxCloseness < currCloseness) {
          maxCloseness = currCloseness;
        }
        closenesses[node_i.id()] = currCloseness;
      }
      return {
        closeness: function closeness(node) {
          if (maxCloseness == 0) {
            return 0;
          }
          if (string(node)) {
            // from is a selector string
            node = cy.filter(node)[0].id();
          } else {
            // from is a node
            node = node.id();
          }
          return closenesses[node] / maxCloseness;
        }
      };
    },
    // Implemented from pseudocode from wikipedia
    closenessCentrality: function closenessCentrality(options) {
      var _defaults2 = defaults$e(options),
        root = _defaults2.root,
        weight = _defaults2.weight,
        directed = _defaults2.directed,
        harmonic = _defaults2.harmonic;
      root = this.filter(root)[0];

      // we need distance from this node to every other node
      var dijkstra = this.dijkstra({
        root: root,
        weight: weight,
        directed: directed
      });
      var totalDistance = 0;
      var nodes = this.nodes();
      for (var i = 0; i < nodes.length; i++) {
        var n = nodes[i];
        if (!n.same(root)) {
          var d = dijkstra.distanceTo(n);
          if (harmonic) {
            totalDistance += 1 / d;
          } else {
            totalDistance += d;
          }
        }
      }
      return harmonic ? totalDistance : 1 / totalDistance;
    } // closenessCentrality
  }; // elesfn

  // nice, short mathematical alias
  elesfn$m.cc = elesfn$m.closenessCentrality;
  elesfn$m.ccn = elesfn$m.closenessCentralityNormalised = elesfn$m.closenessCentralityNormalized;

  var defaults$d = defaults$g({
    weight: null,
    directed: false
  });
  var elesfn$l = {
    // Implemented from the algorithm in the paper "On Variants of Shortest-Path Betweenness Centrality and their Generic Computation" by Ulrik Brandes
    betweennessCentrality: function betweennessCentrality(options) {
      var _defaults = defaults$d(options),
        directed = _defaults.directed,
        weight = _defaults.weight;
      var weighted = weight != null;
      var cy = this.cy();

      // starting
      var V = this.nodes();
      var A = {};
      var _C = {};
      var max = 0;
      var C = {
        set: function set(key, val) {
          _C[key] = val;
          if (val > max) {
            max = val;
          }
        },
        get: function get(key) {
          return _C[key];
        }
      };

      // A contains the neighborhoods of every node
      for (var i = 0; i < V.length; i++) {
        var v = V[i];
        var vid = v.id();
        if (directed) {
          A[vid] = v.outgoers().nodes(); // get outgoers of every node
        } else {
          A[vid] = v.openNeighborhood().nodes(); // get neighbors of every node
        }

        C.set(vid, 0);
      }
      var _loop = function _loop(s) {
        var sid = V[s].id();
        var S = []; // stack
        var P = {};
        var g = {};
        var d = {};
        var Q = new heap(function (a, b) {
          return d[a] - d[b];
        }); // queue

        // init dictionaries
        for (var _i = 0; _i < V.length; _i++) {
          var _vid = V[_i].id();
          P[_vid] = [];
          g[_vid] = 0;
          d[_vid] = Infinity;
        }
        g[sid] = 1; // sigma
        d[sid] = 0; // distance to s

        Q.push(sid);
        while (!Q.empty()) {
          var _v = Q.pop();
          S.push(_v);
          if (weighted) {
            for (var j = 0; j < A[_v].length; j++) {
              var w = A[_v][j];
              var vEle = cy.getElementById(_v);
              var edge = void 0;
              if (vEle.edgesTo(w).length > 0) {
                edge = vEle.edgesTo(w)[0];
              } else {
                edge = w.edgesTo(vEle)[0];
              }
              var edgeWeight = weight(edge);
              w = w.id();
              if (d[w] > d[_v] + edgeWeight) {
                d[w] = d[_v] + edgeWeight;
                if (Q.nodes.indexOf(w) < 0) {
                  //if w is not in Q
                  Q.push(w);
                } else {
                  // update position if w is in Q
                  Q.updateItem(w);
                }
                g[w] = 0;
                P[w] = [];
              }
              if (d[w] == d[_v] + edgeWeight) {
                g[w] = g[w] + g[_v];
                P[w].push(_v);
              }
            }
          } else {
            for (var _j = 0; _j < A[_v].length; _j++) {
              var _w = A[_v][_j].id();
              if (d[_w] == Infinity) {
                Q.push(_w);
                d[_w] = d[_v] + 1;
              }
              if (d[_w] == d[_v] + 1) {
                g[_w] = g[_w] + g[_v];
                P[_w].push(_v);
              }
            }
          }
        }
        var e = {};
        for (var _i2 = 0; _i2 < V.length; _i2++) {
          e[V[_i2].id()] = 0;
        }
        while (S.length > 0) {
          var _w2 = S.pop();
          for (var _j2 = 0; _j2 < P[_w2].length; _j2++) {
            var _v2 = P[_w2][_j2];
            e[_v2] = e[_v2] + g[_v2] / g[_w2] * (1 + e[_w2]);
          }
          if (_w2 != V[s].id()) {
            C.set(_w2, C.get(_w2) + e[_w2]);
          }
        }
      };
      for (var s = 0; s < V.length; s++) {
        _loop(s);
      }
      var ret = {
        betweenness: function betweenness(node) {
          var id = cy.collection(node).id();
          return C.get(id);
        },
        betweennessNormalized: function betweennessNormalized(node) {
          if (max == 0) {
            return 0;
          }
          var id = cy.collection(node).id();
          return C.get(id) / max;
        }
      };

      // alias
      ret.betweennessNormalised = ret.betweennessNormalized;
      return ret;
    } // betweennessCentrality
  }; // elesfn

  // nice, short mathematical alias
  elesfn$l.bc = elesfn$l.betweennessCentrality;

  // Implemented by Zoe Xi @zoexi for GSOC 2016

  /* eslint-disable no-unused-vars */
  var defaults$c = defaults$g({
    expandFactor: 2,
    // affects time of computation and cluster granularity to some extent: M * M
    inflateFactor: 2,
    // affects cluster granularity (the greater the value, the more clusters): M(i,j) / E(j)
    multFactor: 1,
    // optional self loops for each node. Use a neutral value to improve cluster computations.
    maxIterations: 20,
    // maximum number of iterations of the MCL algorithm in a single run
    attributes: [
    // attributes/features used to group nodes, ie. similarity values between nodes
    function (edge) {
      return 1;
    }]
  });
  /* eslint-enable */

  var setOptions$3 = function setOptions(options) {
    return defaults$c(options);
  };
  /* eslint-enable */

  var getSimilarity$1 = function getSimilarity(edge, attributes) {
    var total = 0;
    for (var i = 0; i < attributes.length; i++) {
      total += attributes[i](edge);
    }
    return total;
  };
  var addLoops = function addLoops(M, n, val) {
    for (var i = 0; i < n; i++) {
      M[i * n + i] = val;
    }
  };
  var normalize = function normalize(M, n) {
    var sum;
    for (var col = 0; col < n; col++) {
      sum = 0;
      for (var row = 0; row < n; row++) {
        sum += M[row * n + col];
      }
      for (var _row = 0; _row < n; _row++) {
        M[_row * n + col] = M[_row * n + col] / sum;
      }
    }
  };

  // TODO: blocked matrix multiplication?
  var mmult = function mmult(A, B, n) {
    var C = new Array(n * n);
    for (var i = 0; i < n; i++) {
      for (var j = 0; j < n; j++) {
        C[i * n + j] = 0;
      }
      for (var k = 0; k < n; k++) {
        for (var _j = 0; _j < n; _j++) {
          C[i * n + _j] += A[i * n + k] * B[k * n + _j];
        }
      }
    }
    return C;
  };
  var expand = function expand(M, n, expandFactor /** power **/) {
    var _M = M.slice(0);
    for (var p = 1; p < expandFactor; p++) {
      M = mmult(M, _M, n);
    }
    return M;
  };
  var inflate = function inflate(M, n, inflateFactor /** r **/) {
    var _M = new Array(n * n);

    // M(i,j) ^ inflatePower
    for (var i = 0; i < n * n; i++) {
      _M[i] = Math.pow(M[i], inflateFactor);
    }
    normalize(_M, n);
    return _M;
  };
  var hasConverged = function hasConverged(M, _M, n2, roundFactor) {
    // Check that both matrices have the same elements (i,j)
    for (var i = 0; i < n2; i++) {
      var v1 = Math.round(M[i] * Math.pow(10, roundFactor)) / Math.pow(10, roundFactor); // truncate to 'roundFactor' decimal places
      var v2 = Math.round(_M[i] * Math.pow(10, roundFactor)) / Math.pow(10, roundFactor);
      if (v1 !== v2) {
        return false;
      }
    }
    return true;
  };
  var assign$2 = function assign(M, n, nodes, cy) {
    var clusters = [];
    for (var i = 0; i < n; i++) {
      var cluster = [];
      for (var j = 0; j < n; j++) {
        // Row-wise attractors and elements that they attract belong in same cluster
        if (Math.round(M[i * n + j] * 1000) / 1000 > 0) {
          cluster.push(nodes[j]);
        }
      }
      if (cluster.length !== 0) {
        clusters.push(cy.collection(cluster));
      }
    }
    return clusters;
  };
  var isDuplicate = function isDuplicate(c1, c2) {
    for (var i = 0; i < c1.length; i++) {
      if (!c2[i] || c1[i].id() !== c2[i].id()) {
        return false;
      }
    }
    return true;
  };
  var removeDuplicates = function removeDuplicates(clusters) {
    for (var i = 0; i < clusters.length; i++) {
      for (var j = 0; j < clusters.length; j++) {
        if (i != j && isDuplicate(clusters[i], clusters[j])) {
          clusters.splice(j, 1);
        }
      }
    }
    return clusters;
  };
  var markovClustering = function markovClustering(options) {
    var nodes = this.nodes();
    var edges = this.edges();
    var cy = this.cy();

    // Set parameters of algorithm:
    var opts = setOptions$3(options);

    // Map each node to its position in node array
    var id2position = {};
    for (var i = 0; i < nodes.length; i++) {
      id2position[nodes[i].id()] = i;
    }

    // Generate stochastic matrix M from input graph G (should be symmetric/undirected)
    var n = nodes.length,
      n2 = n * n;
    var M = new Array(n2),
      _M;
    for (var _i = 0; _i < n2; _i++) {
      M[_i] = 0;
    }
    for (var e = 0; e < edges.length; e++) {
      var edge = edges[e];
      var _i2 = id2position[edge.source().id()];
      var j = id2position[edge.target().id()];
      var sim = getSimilarity$1(edge, opts.attributes);
      M[_i2 * n + j] += sim; // G should be symmetric and undirected
      M[j * n + _i2] += sim;
    }

    // Begin Markov cluster algorithm

    // Step 1: Add self loops to each node, ie. add multFactor to matrix diagonal
    addLoops(M, n, opts.multFactor);

    // Step 2: M = normalize( M );
    normalize(M, n);
    var isStillMoving = true;
    var iterations = 0;
    while (isStillMoving && iterations < opts.maxIterations) {
      isStillMoving = false;

      // Step 3:
      _M = expand(M, n, opts.expandFactor);

      // Step 4:
      M = inflate(_M, n, opts.inflateFactor);

      // Step 5: check to see if ~steady state has been reached
      if (!hasConverged(M, _M, n2, 4)) {
        isStillMoving = true;
      }
      iterations++;
    }

    // Build clusters from matrix
    var clusters = assign$2(M, n, nodes, cy);

    // Remove duplicate clusters due to symmetry of graph and M matrix
    clusters = removeDuplicates(clusters);
    return clusters;
  };
  var markovClustering$1 = {
    markovClustering: markovClustering,
    mcl: markovClustering
  };

  // Common distance metrics for clustering algorithms
  var identity = function identity(x) {
    return x;
  };
  var absDiff = function absDiff(p, q) {
    return Math.abs(q - p);
  };
  var addAbsDiff = function addAbsDiff(total, p, q) {
    return total + absDiff(p, q);
  };
  var addSquaredDiff = function addSquaredDiff(total, p, q) {
    return total + Math.pow(q - p, 2);
  };
  var sqrt = function sqrt(x) {
    return Math.sqrt(x);
  };
  var maxAbsDiff = function maxAbsDiff(currentMax, p, q) {
    return Math.max(currentMax, absDiff(p, q));
  };
  var getDistance = function getDistance(length, getP, getQ, init, visit) {
    var post = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : identity;
    var ret = init;
    var p, q;
    for (var dim = 0; dim < length; dim++) {
      p = getP(dim);
      q = getQ(dim);
      ret = visit(ret, p, q);
    }
    return post(ret);
  };
  var distances = {
    euclidean: function euclidean(length, getP, getQ) {
      if (length >= 2) {
        return getDistance(length, getP, getQ, 0, addSquaredDiff, sqrt);
      } else {
        // for single attr case, more efficient to avoid sqrt
        return getDistance(length, getP, getQ, 0, addAbsDiff);
      }
    },
    squaredEuclidean: function squaredEuclidean(length, getP, getQ) {
      return getDistance(length, getP, getQ, 0, addSquaredDiff);
    },
    manhattan: function manhattan(length, getP, getQ) {
      return getDistance(length, getP, getQ, 0, addAbsDiff);
    },
    max: function max(length, getP, getQ) {
      return getDistance(length, getP, getQ, -Infinity, maxAbsDiff);
    }
  };

  // in case the user accidentally doesn't use camel case
  distances['squared-euclidean'] = distances['squaredEuclidean'];
  distances['squaredeuclidean'] = distances['squaredEuclidean'];
  function clusteringDistance (method, length, getP, getQ, nodeP, nodeQ) {
    var impl;
    if (fn$6(method)) {
      impl = method;
    } else {
      impl = distances[method] || distances.euclidean;
    }
    if (length === 0 && fn$6(method)) {
      return impl(nodeP, nodeQ);
    } else {
      return impl(length, getP, getQ, nodeP, nodeQ);
    }
  }

  var defaults$b = defaults$g({
    k: 2,
    m: 2,
    sensitivityThreshold: 0.0001,
    distance: 'euclidean',
    maxIterations: 10,
    attributes: [],
    testMode: false,
    testCentroids: null
  });
  var setOptions$2 = function setOptions(options) {
    return defaults$b(options);
  };

  var getDist = function getDist(type, node, centroid, attributes, mode) {
    var noNodeP = mode !== 'kMedoids';
    var getP = noNodeP ? function (i) {
      return centroid[i];
    } : function (i) {
      return attributes[i](centroid);
    };
    var getQ = function getQ(i) {
      return attributes[i](node);
    };
    var nodeP = centroid;
    var nodeQ = node;
    return clusteringDistance(type, attributes.length, getP, getQ, nodeP, nodeQ);
  };
  var randomCentroids = function randomCentroids(nodes, k, attributes) {
    var ndim = attributes.length;
    var min = new Array(ndim);
    var max = new Array(ndim);
    var centroids = new Array(k);
    var centroid = null;

    // Find min, max values for each attribute dimension
    for (var i = 0; i < ndim; i++) {
      min[i] = nodes.min(attributes[i]).value;
      max[i] = nodes.max(attributes[i]).value;
    }

    // Build k centroids, each represented as an n-dim feature vector
    for (var c = 0; c < k; c++) {
      centroid = [];
      for (var _i = 0; _i < ndim; _i++) {
        centroid[_i] = Math.random() * (max[_i] - min[_i]) + min[_i]; // random initial value
      }

      centroids[c] = centroid;
    }
    return centroids;
  };
  var classify = function classify(node, centroids, distance, attributes, type) {
    var min = Infinity;
    var index = 0;
    for (var i = 0; i < centroids.length; i++) {
      var dist = getDist(distance, node, centroids[i], attributes, type);
      if (dist < min) {
        min = dist;
        index = i;
      }
    }
    return index;
  };
  var buildCluster = function buildCluster(centroid, nodes, assignment) {
    var cluster = [];
    var node = null;
    for (var n = 0; n < nodes.length; n++) {
      node = nodes[n];
      if (assignment[node.id()] === centroid) {
        //console.log("Node " + node.id() + " is associated with medoid #: " + m);
        cluster.push(node);
      }
    }
    return cluster;
  };
  var haveValuesConverged = function haveValuesConverged(v1, v2, sensitivityThreshold) {
    return Math.abs(v2 - v1) <= sensitivityThreshold;
  };
  var haveMatricesConverged = function haveMatricesConverged(v1, v2, sensitivityThreshold) {
    for (var i = 0; i < v1.length; i++) {
      for (var j = 0; j < v1[i].length; j++) {
        var diff = Math.abs(v1[i][j] - v2[i][j]);
        if (diff > sensitivityThreshold) {
          return false;
        }
      }
    }
    return true;
  };
  var seenBefore = function seenBefore(node, medoids, n) {
    for (var i = 0; i < n; i++) {
      if (node === medoids[i]) return true;
    }
    return false;
  };
  var randomMedoids = function randomMedoids(nodes, k) {
    var medoids = new Array(k);

    // For small data sets, the probability of medoid conflict is greater,
    // so we need to check to see if we've already seen or chose this node before.
    if (nodes.length < 50) {
      // Randomly select k medoids from the n nodes
      for (var i = 0; i < k; i++) {
        var node = nodes[Math.floor(Math.random() * nodes.length)];

        // If we've already chosen this node to be a medoid, don't choose it again (for small data sets).
        // Instead choose a different random node.
        while (seenBefore(node, medoids, i)) {
          node = nodes[Math.floor(Math.random() * nodes.length)];
        }
        medoids[i] = node;
      }
    } else {
      // Relatively large data set, so pretty safe to not check and just select random nodes
      for (var _i2 = 0; _i2 < k; _i2++) {
        medoids[_i2] = nodes[Math.floor(Math.random() * nodes.length)];
      }
    }
    return medoids;
  };
  var findCost = function findCost(potentialNewMedoid, cluster, attributes) {
    var cost = 0;
    for (var n = 0; n < cluster.length; n++) {
      cost += getDist('manhattan', cluster[n], potentialNewMedoid, attributes, 'kMedoids');
    }
    return cost;
  };
  var kMeans = function kMeans(options) {
    var cy = this.cy();
    var nodes = this.nodes();
    var node = null;

    // Set parameters of algorithm: # of clusters, distance metric, etc.
    var opts = setOptions$2(options);

    // Begin k-means algorithm
    var clusters = new Array(opts.k);
    var assignment = {};
    var centroids;

    // Step 1: Initialize centroid positions
    if (opts.testMode) {
      if (typeof opts.testCentroids === 'number') {
        // TODO: implement a seeded random number generator.
        opts.testCentroids;
        centroids = randomCentroids(nodes, opts.k, opts.attributes);
      } else if (_typeof(opts.testCentroids) === 'object') {
        centroids = opts.testCentroids;
      } else {
        centroids = randomCentroids(nodes, opts.k, opts.attributes);
      }
    } else {
      centroids = randomCentroids(nodes, opts.k, opts.attributes);
    }
    var isStillMoving = true;
    var iterations = 0;
    while (isStillMoving && iterations < opts.maxIterations) {
      // Step 2: Assign nodes to the nearest centroid
      for (var n = 0; n < nodes.length; n++) {
        node = nodes[n];
        // Determine which cluster this node belongs to: node id => cluster #
        assignment[node.id()] = classify(node, centroids, opts.distance, opts.attributes, 'kMeans');
      }

      // Step 3: For each of the k clusters, update its centroid
      isStillMoving = false;
      for (var c = 0; c < opts.k; c++) {
        // Get all nodes that belong to this cluster
        var cluster = buildCluster(c, nodes, assignment);
        if (cluster.length === 0) {
          // If cluster is empty, break out early & move to next cluster
          continue;
        }

        // Update centroids by calculating avg of all nodes within the cluster.
        var ndim = opts.attributes.length;
        var centroid = centroids[c]; // [ dim_1, dim_2, dim_3, ... , dim_n ]
        var newCentroid = new Array(ndim);
        var sum = new Array(ndim);
        for (var d = 0; d < ndim; d++) {
          sum[d] = 0.0;
          for (var i = 0; i < cluster.length; i++) {
            node = cluster[i];
            sum[d] += opts.attributes[d](node);
          }
          newCentroid[d] = sum[d] / cluster.length;

          // Check to see if algorithm has converged, i.e. when centroids no longer change
          if (!haveValuesConverged(newCentroid[d], centroid[d], opts.sensitivityThreshold)) {
            isStillMoving = true;
          }
        }
        centroids[c] = newCentroid;
        clusters[c] = cy.collection(cluster);
      }
      iterations++;
    }
    return clusters;
  };
  var kMedoids = function kMedoids(options) {
    var cy = this.cy();
    var nodes = this.nodes();
    var node = null;
    var opts = setOptions$2(options);

    // Begin k-medoids algorithm
    var clusters = new Array(opts.k);
    var medoids;
    var assignment = {};
    var curCost;
    var minCosts = new Array(opts.k); // minimum cost configuration for each cluster

    // Step 1: Initialize k medoids
    if (opts.testMode) {
      if (typeof opts.testCentroids === 'number') ; else if (_typeof(opts.testCentroids) === 'object') {
        medoids = opts.testCentroids;
      } else {
        medoids = randomMedoids(nodes, opts.k);
      }
    } else {
      medoids = randomMedoids(nodes, opts.k);
    }
    var isStillMoving = true;
    var iterations = 0;
    while (isStillMoving && iterations < opts.maxIterations) {
      // Step 2: Assign nodes to the nearest medoid
      for (var n = 0; n < nodes.length; n++) {
        node = nodes[n];
        // Determine which cluster this node belongs to: node id => cluster #
        assignment[node.id()] = classify(node, medoids, opts.distance, opts.attributes, 'kMedoids');
      }
      isStillMoving = false;
      // Step 3: For each medoid m, and for each node associated with mediod m,
      // select the node with the lowest configuration cost as new medoid.
      for (var m = 0; m < medoids.length; m++) {
        // Get all nodes that belong to this medoid
        var cluster = buildCluster(m, nodes, assignment);
        if (cluster.length === 0) {
          // If cluster is empty, break out early & move to next cluster
          continue;
        }
        minCosts[m] = findCost(medoids[m], cluster, opts.attributes); // original cost

        // Select different medoid if its configuration has the lowest cost
        for (var _n = 0; _n < cluster.length; _n++) {
          curCost = findCost(cluster[_n], cluster, opts.attributes);
          if (curCost < minCosts[m]) {
            minCosts[m] = curCost;
            medoids[m] = cluster[_n];
            isStillMoving = true;
          }
        }
        clusters[m] = cy.collection(cluster);
      }
      iterations++;
    }
    return clusters;
  };
  var updateCentroids = function updateCentroids(centroids, nodes, U, weight, opts) {
    var numerator, denominator;
    for (var n = 0; n < nodes.length; n++) {
      for (var c = 0; c < centroids.length; c++) {
        weight[n][c] = Math.pow(U[n][c], opts.m);
      }
    }
    for (var _c = 0; _c < centroids.length; _c++) {
      for (var dim = 0; dim < opts.attributes.length; dim++) {
        numerator = 0;
        denominator = 0;
        for (var _n2 = 0; _n2 < nodes.length; _n2++) {
          numerator += weight[_n2][_c] * opts.attributes[dim](nodes[_n2]);
          denominator += weight[_n2][_c];
        }
        centroids[_c][dim] = numerator / denominator;
      }
    }
  };
  var updateMembership = function updateMembership(U, _U, centroids, nodes, opts) {
    // Save previous step
    for (var i = 0; i < U.length; i++) {
      _U[i] = U[i].slice();
    }
    var sum, numerator, denominator;
    var pow = 2 / (opts.m - 1);
    for (var c = 0; c < centroids.length; c++) {
      for (var n = 0; n < nodes.length; n++) {
        sum = 0;
        for (var k = 0; k < centroids.length; k++) {
          // against all other centroids
          numerator = getDist(opts.distance, nodes[n], centroids[c], opts.attributes, 'cmeans');
          denominator = getDist(opts.distance, nodes[n], centroids[k], opts.attributes, 'cmeans');
          sum += Math.pow(numerator / denominator, pow);
        }
        U[n][c] = 1 / sum;
      }
    }
  };
  var assign$1 = function assign(nodes, U, opts, cy) {
    var clusters = new Array(opts.k);
    for (var c = 0; c < clusters.length; c++) {
      clusters[c] = [];
    }
    var max;
    var index;
    for (var n = 0; n < U.length; n++) {
      // for each node (U is N x C matrix)
      max = -Infinity;
      index = -1;
      // Determine which cluster the node is most likely to belong in
      for (var _c2 = 0; _c2 < U[0].length; _c2++) {
        if (U[n][_c2] > max) {
          max = U[n][_c2];
          index = _c2;
        }
      }
      clusters[index].push(nodes[n]);
    }

    // Turn every array into a collection of nodes
    for (var _c3 = 0; _c3 < clusters.length; _c3++) {
      clusters[_c3] = cy.collection(clusters[_c3]);
    }
    return clusters;
  };
  var fuzzyCMeans = function fuzzyCMeans(options) {
    var cy = this.cy();
    var nodes = this.nodes();
    var opts = setOptions$2(options);

    // Begin fuzzy c-means algorithm
    var clusters;
    var centroids;
    var U;
    var _U;
    var weight;

    // Step 1: Initialize letiables.
    _U = new Array(nodes.length);
    for (var i = 0; i < nodes.length; i++) {
      // N x C matrix
      _U[i] = new Array(opts.k);
    }
    U = new Array(nodes.length);
    for (var _i3 = 0; _i3 < nodes.length; _i3++) {
      // N x C matrix
      U[_i3] = new Array(opts.k);
    }
    for (var _i4 = 0; _i4 < nodes.length; _i4++) {
      var total = 0;
      for (var j = 0; j < opts.k; j++) {
        U[_i4][j] = Math.random();
        total += U[_i4][j];
      }
      for (var _j = 0; _j < opts.k; _j++) {
        U[_i4][_j] = U[_i4][_j] / total;
      }
    }
    centroids = new Array(opts.k);
    for (var _i5 = 0; _i5 < opts.k; _i5++) {
      centroids[_i5] = new Array(opts.attributes.length);
    }
    weight = new Array(nodes.length);
    for (var _i6 = 0; _i6 < nodes.length; _i6++) {
      // N x C matrix
      weight[_i6] = new Array(opts.k);
    }
    // end init FCM

    var isStillMoving = true;
    var iterations = 0;
    while (isStillMoving && iterations < opts.maxIterations) {
      isStillMoving = false;

      // Step 2: Calculate the centroids for each step.
      updateCentroids(centroids, nodes, U, weight, opts);

      // Step 3: Update the partition matrix U.
      updateMembership(U, _U, centroids, nodes, opts);

      // Step 4: Check for convergence.
      if (!haveMatricesConverged(U, _U, opts.sensitivityThreshold)) {
        isStillMoving = true;
      }
      iterations++;
    }

    // Assign nodes to clusters with highest probability.
    clusters = assign$1(nodes, U, opts, cy);
    return {
      clusters: clusters,
      degreeOfMembership: U
    };
  };
  var kClustering = {
    kMeans: kMeans,
    kMedoids: kMedoids,
    fuzzyCMeans: fuzzyCMeans,
    fcm: fuzzyCMeans
  };

  // Implemented by Zoe Xi @zoexi for GSOC 2016
  var defaults$a = defaults$g({
    distance: 'euclidean',
    // distance metric to compare nodes
    linkage: 'min',
    // linkage criterion : how to determine the distance between clusters of nodes
    mode: 'threshold',
    // mode:'threshold' => clusters must be threshold distance apart
    threshold: Infinity,
    // the distance threshold
    // mode:'dendrogram' => the nodes are organised as leaves in a tree (siblings are close), merging makes clusters
    addDendrogram: false,
    // whether to add the dendrogram to the graph for viz
    dendrogramDepth: 0,
    // depth at which dendrogram branches are merged into the returned clusters
    attributes: [] // array of attr functions
  });

  var linkageAliases = {
    'single': 'min',
    'complete': 'max'
  };
  var setOptions$1 = function setOptions(options) {
    var opts = defaults$a(options);
    var preferredAlias = linkageAliases[opts.linkage];
    if (preferredAlias != null) {
      opts.linkage = preferredAlias;
    }
    return opts;
  };
  var mergeClosest = function mergeClosest(clusters, index, dists, mins, opts) {
    // Find two closest clusters from cached mins
    var minKey = 0;
    var min = Infinity;
    var dist;
    var attrs = opts.attributes;
    var getDist = function getDist(n1, n2) {
      return clusteringDistance(opts.distance, attrs.length, function (i) {
        return attrs[i](n1);
      }, function (i) {
        return attrs[i](n2);
      }, n1, n2);
    };
    for (var i = 0; i < clusters.length; i++) {
      var key = clusters[i].key;
      var _dist = dists[key][mins[key]];
      if (_dist < min) {
        minKey = key;
        min = _dist;
      }
    }
    if (opts.mode === 'threshold' && min >= opts.threshold || opts.mode === 'dendrogram' && clusters.length === 1) {
      return false;
    }
    var c1 = index[minKey];
    var c2 = index[mins[minKey]];
    var merged;

    // Merge two closest clusters
    if (opts.mode === 'dendrogram') {
      merged = {
        left: c1,
        right: c2,
        key: c1.key
      };
    } else {
      merged = {
        value: c1.value.concat(c2.value),
        key: c1.key
      };
    }
    clusters[c1.index] = merged;
    clusters.splice(c2.index, 1);
    index[c1.key] = merged;

    // Update distances with new merged cluster
    for (var _i = 0; _i < clusters.length; _i++) {
      var cur = clusters[_i];
      if (c1.key === cur.key) {
        dist = Infinity;
      } else if (opts.linkage === 'min') {
        dist = dists[c1.key][cur.key];
        if (dists[c1.key][cur.key] > dists[c2.key][cur.key]) {
          dist = dists[c2.key][cur.key];
        }
      } else if (opts.linkage === 'max') {
        dist = dists[c1.key][cur.key];
        if (dists[c1.key][cur.key] < dists[c2.key][cur.key]) {
          dist = dists[c2.key][cur.key];
        }
      } else if (opts.linkage === 'mean') {
        dist = (dists[c1.key][cur.key] * c1.size + dists[c2.key][cur.key] * c2.size) / (c1.size + c2.size);
      } else {
        if (opts.mode === 'dendrogram') dist = getDist(cur.value, c1.value);else dist = getDist(cur.value[0], c1.value[0]);
      }
      dists[c1.key][cur.key] = dists[cur.key][c1.key] = dist; // distance matrix is symmetric
    }

    // Update cached mins
    for (var _i2 = 0; _i2 < clusters.length; _i2++) {
      var key1 = clusters[_i2].key;
      if (mins[key1] === c1.key || mins[key1] === c2.key) {
        var _min = key1;
        for (var j = 0; j < clusters.length; j++) {
          var key2 = clusters[j].key;
          if (dists[key1][key2] < dists[key1][_min]) {
            _min = key2;
          }
        }
        mins[key1] = _min;
      }
      clusters[_i2].index = _i2;
    }

    // Clean up meta data used for clustering
    c1.key = c2.key = c1.index = c2.index = null;
    return true;
  };
  var getAllChildren = function getAllChildren(root, arr, cy) {
    if (!root) return;
    if (root.value) {
      arr.push(root.value);
    } else {
      if (root.left) getAllChildren(root.left, arr);
      if (root.right) getAllChildren(root.right, arr);
    }
  };
  var buildDendrogram = function buildDendrogram(root, cy) {
    if (!root) return '';
    if (root.left && root.right) {
      var leftStr = buildDendrogram(root.left, cy);
      var rightStr = buildDendrogram(root.right, cy);
      var node = cy.add({
        group: 'nodes',
        data: {
          id: leftStr + ',' + rightStr
        }
      });
      cy.add({
        group: 'edges',
        data: {
          source: leftStr,
          target: node.id()
        }
      });
      cy.add({
        group: 'edges',
        data: {
          source: rightStr,
          target: node.id()
        }
      });
      return node.id();
    } else if (root.value) {
      return root.value.id();
    }
  };
  var buildClustersFromTree = function buildClustersFromTree(root, k, cy) {
    if (!root) return [];
    var left = [],
      right = [],
      leaves = [];
    if (k === 0) {
      // don't cut tree, simply return all nodes as 1 single cluster
      if (root.left) getAllChildren(root.left, left);
      if (root.right) getAllChildren(root.right, right);
      leaves = left.concat(right);
      return [cy.collection(leaves)];
    } else if (k === 1) {
      // cut at root

      if (root.value) {
        // leaf node
        return [cy.collection(root.value)];
      } else {
        if (root.left) getAllChildren(root.left, left);
        if (root.right) getAllChildren(root.right, right);
        return [cy.collection(left), cy.collection(right)];
      }
    } else {
      if (root.value) {
        return [cy.collection(root.value)];
      } else {
        if (root.left) left = buildClustersFromTree(root.left, k - 1, cy);
        if (root.right) right = buildClustersFromTree(root.right, k - 1, cy);
        return left.concat(right);
      }
    }
  };

  var hierarchicalClustering = function hierarchicalClustering(options) {
    var cy = this.cy();
    var nodes = this.nodes();

    // Set parameters of algorithm: linkage type, distance metric, etc.
    var opts = setOptions$1(options);
    var attrs = opts.attributes;
    var getDist = function getDist(n1, n2) {
      return clusteringDistance(opts.distance, attrs.length, function (i) {
        return attrs[i](n1);
      }, function (i) {
        return attrs[i](n2);
      }, n1, n2);
    };

    // Begin hierarchical algorithm
    var clusters = [];
    var dists = []; // distances between each pair of clusters
    var mins = []; // closest cluster for each cluster
    var index = []; // hash of all clusters by key

    // In agglomerative (bottom-up) clustering, each node starts as its own cluster
    for (var n = 0; n < nodes.length; n++) {
      var cluster = {
        value: opts.mode === 'dendrogram' ? nodes[n] : [nodes[n]],
        key: n,
        index: n
      };
      clusters[n] = cluster;
      index[n] = cluster;
      dists[n] = [];
      mins[n] = 0;
    }

    // Calculate the distance between each pair of clusters
    for (var i = 0; i < clusters.length; i++) {
      for (var j = 0; j <= i; j++) {
        var dist = void 0;
        if (opts.mode === 'dendrogram') {
          // modes store cluster values differently
          dist = i === j ? Infinity : getDist(clusters[i].value, clusters[j].value);
        } else {
          dist = i === j ? Infinity : getDist(clusters[i].value[0], clusters[j].value[0]);
        }
        dists[i][j] = dist;
        dists[j][i] = dist;
        if (dist < dists[i][mins[i]]) {
          mins[i] = j; // Cache mins: closest cluster to cluster i is cluster j
        }
      }
    }

    // Find the closest pair of clusters and merge them into a single cluster.
    // Update distances between new cluster and each of the old clusters, and loop until threshold reached.
    var merged = mergeClosest(clusters, index, dists, mins, opts);
    while (merged) {
      merged = mergeClosest(clusters, index, dists, mins, opts);
    }
    var retClusters;

    // Dendrogram mode builds the hierarchy and adds intermediary nodes + edges
    // in addition to returning the clusters.
    if (opts.mode === 'dendrogram') {
      retClusters = buildClustersFromTree(clusters[0], opts.dendrogramDepth, cy);
      if (opts.addDendrogram) buildDendrogram(clusters[0], cy);
    } else {
      // Regular mode simply returns the clusters

      retClusters = new Array(clusters.length);
      clusters.forEach(function (cluster, i) {
        // Clean up meta data used for clustering
        cluster.key = cluster.index = null;
        retClusters[i] = cy.collection(cluster.value);
      });
    }
    return retClusters;
  };
  var hierarchicalClustering$1 = {
    hierarchicalClustering: hierarchicalClustering,
    hca: hierarchicalClustering
  };

  // Implemented by Zoe Xi @zoexi for GSOC 2016
  var defaults$9 = defaults$g({
    distance: 'euclidean',
    // distance metric to compare attributes between two nodes
    preference: 'median',
    // suitability of a data point to serve as an exemplar
    damping: 0.8,
    // damping factor between [0.5, 1)
    maxIterations: 1000,
    // max number of iterations to run
    minIterations: 100,
    // min number of iterations to run in order for clustering to stop
    attributes: [// functions to quantify the similarity between any two points
      // e.g. node => node.data('weight')
    ]
  });
  var setOptions = function setOptions(options) {
    var dmp = options.damping;
    var pref = options.preference;
    if (!(0.5 <= dmp && dmp < 1)) {
      error("Damping must range on [0.5, 1).  Got: ".concat(dmp));
    }
    var validPrefs = ['median', 'mean', 'min', 'max'];
    if (!(validPrefs.some(function (v) {
      return v === pref;
    }) || number$1(pref))) {
      error("Preference must be one of [".concat(validPrefs.map(function (p) {
        return "'".concat(p, "'");
      }).join(', '), "] or a number.  Got: ").concat(pref));
    }
    return defaults$9(options);
  };

  var getSimilarity = function getSimilarity(type, n1, n2, attributes) {
    var attr = function attr(n, i) {
      return attributes[i](n);
    };

    // nb negative because similarity should have an inverse relationship to distance
    return -clusteringDistance(type, attributes.length, function (i) {
      return attr(n1, i);
    }, function (i) {
      return attr(n2, i);
    }, n1, n2);
  };
  var getPreference = function getPreference(S, preference) {
    // larger preference = greater # of clusters
    var p = null;
    if (preference === 'median') {
      p = median(S);
    } else if (preference === 'mean') {
      p = mean(S);
    } else if (preference === 'min') {
      p = min(S);
    } else if (preference === 'max') {
      p = max(S);
    } else {
      // Custom preference number, as set by user
      p = preference;
    }
    return p;
  };
  var findExemplars = function findExemplars(n, R, A) {
    var indices = [];
    for (var i = 0; i < n; i++) {
      if (R[i * n + i] + A[i * n + i] > 0) {
        indices.push(i);
      }
    }
    return indices;
  };
  var assignClusters = function assignClusters(n, S, exemplars) {
    var clusters = [];
    for (var i = 0; i < n; i++) {
      var index = -1;
      var max = -Infinity;
      for (var ei = 0; ei < exemplars.length; ei++) {
        var e = exemplars[ei];
        if (S[i * n + e] > max) {
          index = e;
          max = S[i * n + e];
        }
      }
      if (index > 0) {
        clusters.push(index);
      }
    }
    for (var _ei = 0; _ei < exemplars.length; _ei++) {
      clusters[exemplars[_ei]] = exemplars[_ei];
    }
    return clusters;
  };
  var assign = function assign(n, S, exemplars) {
    var clusters = assignClusters(n, S, exemplars);
    for (var ei = 0; ei < exemplars.length; ei++) {
      var ii = [];
      for (var c = 0; c < clusters.length; c++) {
        if (clusters[c] === exemplars[ei]) {
          ii.push(c);
        }
      }
      var maxI = -1;
      var maxSum = -Infinity;
      for (var i = 0; i < ii.length; i++) {
        var sum = 0;
        for (var j = 0; j < ii.length; j++) {
          sum += S[ii[j] * n + ii[i]];
        }
        if (sum > maxSum) {
          maxI = i;
          maxSum = sum;
        }
      }
      exemplars[ei] = ii[maxI];
    }
    clusters = assignClusters(n, S, exemplars);
    return clusters;
  };
  var affinityPropagation = function affinityPropagation(options) {
    var cy = this.cy();
    var nodes = this.nodes();
    var opts = setOptions(options);

    // Map each node to its position in node array
    var id2position = {};
    for (var i = 0; i < nodes.length; i++) {
      id2position[nodes[i].id()] = i;
    }

    // Begin affinity propagation algorithm

    var n; // number of data points
    var n2; // size of matrices
    var S; // similarity matrix (1D array)
    var p; // preference/suitability of a data point to serve as an exemplar
    var R; // responsibility matrix (1D array)
    var A; // availability matrix (1D array)

    n = nodes.length;
    n2 = n * n;

    // Initialize and build S similarity matrix
    S = new Array(n2);
    for (var _i = 0; _i < n2; _i++) {
      S[_i] = -Infinity; // for cases where two data points shouldn't be linked together
    }

    for (var _i2 = 0; _i2 < n; _i2++) {
      for (var j = 0; j < n; j++) {
        if (_i2 !== j) {
          S[_i2 * n + j] = getSimilarity(opts.distance, nodes[_i2], nodes[j], opts.attributes);
        }
      }
    }

    // Place preferences on the diagonal of S
    p = getPreference(S, opts.preference);
    for (var _i3 = 0; _i3 < n; _i3++) {
      S[_i3 * n + _i3] = p;
    }

    // Initialize R responsibility matrix
    R = new Array(n2);
    for (var _i4 = 0; _i4 < n2; _i4++) {
      R[_i4] = 0.0;
    }

    // Initialize A availability matrix
    A = new Array(n2);
    for (var _i5 = 0; _i5 < n2; _i5++) {
      A[_i5] = 0.0;
    }
    var old = new Array(n);
    var Rp = new Array(n);
    var se = new Array(n);
    for (var _i6 = 0; _i6 < n; _i6++) {
      old[_i6] = 0.0;
      Rp[_i6] = 0.0;
      se[_i6] = 0;
    }
    var e = new Array(n * opts.minIterations);
    for (var _i7 = 0; _i7 < e.length; _i7++) {
      e[_i7] = 0;
    }
    var iter;
    for (iter = 0; iter < opts.maxIterations; iter++) {
      // main algorithmic loop

      // Update R responsibility matrix
      for (var _i8 = 0; _i8 < n; _i8++) {
        var max = -Infinity,
          max2 = -Infinity,
          maxI = -1,
          AS = 0.0;
        for (var _j = 0; _j < n; _j++) {
          old[_j] = R[_i8 * n + _j];
          AS = A[_i8 * n + _j] + S[_i8 * n + _j];
          if (AS >= max) {
            max2 = max;
            max = AS;
            maxI = _j;
          } else if (AS > max2) {
            max2 = AS;
          }
        }
        for (var _j2 = 0; _j2 < n; _j2++) {
          R[_i8 * n + _j2] = (1 - opts.damping) * (S[_i8 * n + _j2] - max) + opts.damping * old[_j2];
        }
        R[_i8 * n + maxI] = (1 - opts.damping) * (S[_i8 * n + maxI] - max2) + opts.damping * old[maxI];
      }

      // Update A availability matrix
      for (var _i9 = 0; _i9 < n; _i9++) {
        var sum = 0;
        for (var _j3 = 0; _j3 < n; _j3++) {
          old[_j3] = A[_j3 * n + _i9];
          Rp[_j3] = Math.max(0, R[_j3 * n + _i9]);
          sum += Rp[_j3];
        }
        sum -= Rp[_i9];
        Rp[_i9] = R[_i9 * n + _i9];
        sum += Rp[_i9];
        for (var _j4 = 0; _j4 < n; _j4++) {
          A[_j4 * n + _i9] = (1 - opts.damping) * Math.min(0, sum - Rp[_j4]) + opts.damping * old[_j4];
        }
        A[_i9 * n + _i9] = (1 - opts.damping) * (sum - Rp[_i9]) + opts.damping * old[_i9];
      }

      // Check for convergence
      var K = 0;
      for (var _i10 = 0; _i10 < n; _i10++) {
        var E = A[_i10 * n + _i10] + R[_i10 * n + _i10] > 0 ? 1 : 0;
        e[iter % opts.minIterations * n + _i10] = E;
        K += E;
      }
      if (K > 0 && (iter >= opts.minIterations - 1 || iter == opts.maxIterations - 1)) {
        var _sum = 0;
        for (var _i11 = 0; _i11 < n; _i11++) {
          se[_i11] = 0;
          for (var _j5 = 0; _j5 < opts.minIterations; _j5++) {
            se[_i11] += e[_j5 * n + _i11];
          }
          if (se[_i11] === 0 || se[_i11] === opts.minIterations) {
            _sum++;
          }
        }
        if (_sum === n) {
          // then we have convergence
          break;
        }
      }
    }

    // Identify exemplars (cluster centers)
    var exemplarsIndices = findExemplars(n, R, A);

    // Assign nodes to clusters
    var clusterIndices = assign(n, S, exemplarsIndices);
    var clusters = {};
    for (var c = 0; c < exemplarsIndices.length; c++) {
      clusters[exemplarsIndices[c]] = [];
    }
    for (var _i12 = 0; _i12 < nodes.length; _i12++) {
      var pos = id2position[nodes[_i12].id()];
      var clusterIndex = clusterIndices[pos];
      if (clusterIndex != null) {
        // the node may have not been assigned a cluster if no valid attributes were specified
        clusters[clusterIndex].push(nodes[_i12]);
      }
    }
    var retClusters = new Array(exemplarsIndices.length);
    for (var _c = 0; _c < exemplarsIndices.length; _c++) {
      retClusters[_c] = cy.collection(clusters[exemplarsIndices[_c]]);
    }
    return retClusters;
  };
  var affinityPropagation$1 = {
    affinityPropagation: affinityPropagation,
    ap: affinityPropagation
  };

  var hierholzerDefaults = defaults$g({
    root: undefined,
    directed: false
  });
  var elesfn$k = {
    hierholzer: function hierholzer(options) {
      if (!plainObject(options)) {
        var args = arguments;
        options = {
          root: args[0],
          directed: args[1]
        };
      }
      var _hierholzerDefaults = hierholzerDefaults(options),
        root = _hierholzerDefaults.root,
        directed = _hierholzerDefaults.directed;
      var eles = this;
      var dflag = false;
      var oddIn;
      var oddOut;
      var startVertex;
      if (root) startVertex = string(root) ? this.filter(root)[0].id() : root[0].id();
      var nodes = {};
      var edges = {};
      if (directed) {
        eles.forEach(function (ele) {
          var id = ele.id();
          if (ele.isNode()) {
            var ind = ele.indegree(true);
            var outd = ele.outdegree(true);
            var d1 = ind - outd;
            var d2 = outd - ind;
            if (d1 == 1) {
              if (oddIn) dflag = true;else oddIn = id;
            } else if (d2 == 1) {
              if (oddOut) dflag = true;else oddOut = id;
            } else if (d2 > 1 || d1 > 1) {
              dflag = true;
            }
            nodes[id] = [];
            ele.outgoers().forEach(function (e) {
              if (e.isEdge()) nodes[id].push(e.id());
            });
          } else {
            edges[id] = [undefined, ele.target().id()];
          }
        });
      } else {
        eles.forEach(function (ele) {
          var id = ele.id();
          if (ele.isNode()) {
            var d = ele.degree(true);
            if (d % 2) {
              if (!oddIn) oddIn = id;else if (!oddOut) oddOut = id;else dflag = true;
            }
            nodes[id] = [];
            ele.connectedEdges().forEach(function (e) {
              return nodes[id].push(e.id());
            });
          } else {
            edges[id] = [ele.source().id(), ele.target().id()];
          }
        });
      }
      var result = {
        found: false,
        trail: undefined
      };
      if (dflag) return result;else if (oddOut && oddIn) {
        if (directed) {
          if (startVertex && oddOut != startVertex) {
            return result;
          }
          startVertex = oddOut;
        } else {
          if (startVertex && oddOut != startVertex && oddIn != startVertex) {
            return result;
          } else if (!startVertex) {
            startVertex = oddOut;
          }
        }
      } else {
        if (!startVertex) startVertex = eles[0].id();
      }
      var walk = function walk(v) {
        var currentNode = v;
        var subtour = [v];
        var adj, adjTail, adjHead;
        while (nodes[currentNode].length) {
          adj = nodes[currentNode].shift();
          adjTail = edges[adj][0];
          adjHead = edges[adj][1];
          if (currentNode != adjHead) {
            nodes[adjHead] = nodes[adjHead].filter(function (e) {
              return e != adj;
            });
            currentNode = adjHead;
          } else if (!directed && currentNode != adjTail) {
            nodes[adjTail] = nodes[adjTail].filter(function (e) {
              return e != adj;
            });
            currentNode = adjTail;
          }
          subtour.unshift(adj);
          subtour.unshift(currentNode);
        }
        return subtour;
      };
      var trail = [];
      var subtour = [];
      subtour = walk(startVertex);
      while (subtour.length != 1) {
        if (nodes[subtour[0]].length == 0) {
          trail.unshift(eles.getElementById(subtour.shift()));
          trail.unshift(eles.getElementById(subtour.shift()));
        } else {
          subtour = walk(subtour.shift()).concat(subtour);
        }
      }
      trail.unshift(eles.getElementById(subtour.shift())); // final node

      for (var d in nodes) {
        if (nodes[d].length) {
          return result;
        }
      }
      result.found = true;
      result.trail = this.spawn(trail, true);
      return result;
    }
  };

  var hopcroftTarjanBiconnected = function hopcroftTarjanBiconnected() {
    var eles = this;
    var nodes = {};
    var id = 0;
    var edgeCount = 0;
    var components = [];
    var stack = [];
    var visitedEdges = {};
    var buildComponent = function buildComponent(x, y) {
      var i = stack.length - 1;
      var cutset = [];
      var component = eles.spawn();
      while (stack[i].x != x || stack[i].y != y) {
        cutset.push(stack.pop().edge);
        i--;
      }
      cutset.push(stack.pop().edge);
      cutset.forEach(function (edge) {
        var connectedNodes = edge.connectedNodes().intersection(eles);
        component.merge(edge);
        connectedNodes.forEach(function (node) {
          var nodeId = node.id();
          var connectedEdges = node.connectedEdges().intersection(eles);
          component.merge(node);
          if (!nodes[nodeId].cutVertex) {
            component.merge(connectedEdges);
          } else {
            component.merge(connectedEdges.filter(function (edge) {
              return edge.isLoop();
            }));
          }
        });
      });
      components.push(component);
    };
    var biconnectedSearch = function biconnectedSearch(root, currentNode, parent) {
      if (root === parent) edgeCount += 1;
      nodes[currentNode] = {
        id: id,
        low: id++,
        cutVertex: false
      };
      var edges = eles.getElementById(currentNode).connectedEdges().intersection(eles);
      if (edges.size() === 0) {
        components.push(eles.spawn(eles.getElementById(currentNode)));
      } else {
        var sourceId, targetId, otherNodeId, edgeId;
        edges.forEach(function (edge) {
          sourceId = edge.source().id();
          targetId = edge.target().id();
          otherNodeId = sourceId === currentNode ? targetId : sourceId;
          if (otherNodeId !== parent) {
            edgeId = edge.id();
            if (!visitedEdges[edgeId]) {
              visitedEdges[edgeId] = true;
              stack.push({
                x: currentNode,
                y: otherNodeId,
                edge: edge
              });
            }
            if (!(otherNodeId in nodes)) {
              biconnectedSearch(root, otherNodeId, currentNode);
              nodes[currentNode].low = Math.min(nodes[currentNode].low, nodes[otherNodeId].low);
              if (nodes[currentNode].id <= nodes[otherNodeId].low) {
                nodes[currentNode].cutVertex = true;
                buildComponent(currentNode, otherNodeId);
              }
            } else {
              nodes[currentNode].low = Math.min(nodes[currentNode].low, nodes[otherNodeId].id);
            }
          }
        });
      }
    };
    eles.forEach(function (ele) {
      if (ele.isNode()) {
        var nodeId = ele.id();
        if (!(nodeId in nodes)) {
          edgeCount = 0;
          biconnectedSearch(nodeId, nodeId);
          nodes[nodeId].cutVertex = edgeCount > 1;
        }
      }
    });
    var cutVertices = Object.keys(nodes).filter(function (id) {
      return nodes[id].cutVertex;
    }).map(function (id) {
      return eles.getElementById(id);
    });
    return {
      cut: eles.spawn(cutVertices),
      components: components
    };
  };
  var hopcroftTarjanBiconnected$1 = {
    hopcroftTarjanBiconnected: hopcroftTarjanBiconnected,
    htbc: hopcroftTarjanBiconnected,
    htb: hopcroftTarjanBiconnected,
    hopcroftTarjanBiconnectedComponents: hopcroftTarjanBiconnected
  };

  var tarjanStronglyConnected = function tarjanStronglyConnected() {
    var eles = this;
    var nodes = {};
    var index = 0;
    var components = [];
    var stack = [];
    var cut = eles.spawn(eles);
    var stronglyConnectedSearch = function stronglyConnectedSearch(sourceNodeId) {
      stack.push(sourceNodeId);
      nodes[sourceNodeId] = {
        index: index,
        low: index++,
        explored: false
      };
      var connectedEdges = eles.getElementById(sourceNodeId).connectedEdges().intersection(eles);
      connectedEdges.forEach(function (edge) {
        var targetNodeId = edge.target().id();
        if (targetNodeId !== sourceNodeId) {
          if (!(targetNodeId in nodes)) {
            stronglyConnectedSearch(targetNodeId);
          }
          if (!nodes[targetNodeId].explored) {
            nodes[sourceNodeId].low = Math.min(nodes[sourceNodeId].low, nodes[targetNodeId].low);
          }
        }
      });
      if (nodes[sourceNodeId].index === nodes[sourceNodeId].low) {
        var componentNodes = eles.spawn();
        for (;;) {
          var nodeId = stack.pop();
          componentNodes.merge(eles.getElementById(nodeId));
          nodes[nodeId].low = nodes[sourceNodeId].index;
          nodes[nodeId].explored = true;
          if (nodeId === sourceNodeId) {
            break;
          }
        }
        var componentEdges = componentNodes.edgesWith(componentNodes);
        var component = componentNodes.merge(componentEdges);
        components.push(component);
        cut = cut.difference(component);
      }
    };
    eles.forEach(function (ele) {
      if (ele.isNode()) {
        var nodeId = ele.id();
        if (!(nodeId in nodes)) {
          stronglyConnectedSearch(nodeId);
        }
      }
    });
    return {
      cut: cut,
      components: components
    };
  };
  var tarjanStronglyConnected$1 = {
    tarjanStronglyConnected: tarjanStronglyConnected,
    tsc: tarjanStronglyConnected,
    tscc: tarjanStronglyConnected,
    tarjanStronglyConnectedComponents: tarjanStronglyConnected
  };

  var elesfn$j = {};
  [elesfn$v, elesfn$u, elesfn$t, elesfn$s, elesfn$r, elesfn$q, elesfn$p, elesfn$o, elesfn$n, elesfn$m, elesfn$l, markovClustering$1, kClustering, hierarchicalClustering$1, affinityPropagation$1, elesfn$k, hopcroftTarjanBiconnected$1, tarjanStronglyConnected$1].forEach(function (props) {
    extend(elesfn$j, props);
  });

  /*!
  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)
  */

  /*  promise states [Promises/A+ 2.1]  */
  var STATE_PENDING = 0; /*  [Promises/A+ 2.1.1]  */
  var STATE_FULFILLED = 1; /*  [Promises/A+ 2.1.2]  */
  var STATE_REJECTED = 2; /*  [Promises/A+ 2.1.3]  */

  /*  promise object constructor  */
  var api = function api(executor) {
    /*  optionally support non-constructor/plain-function call  */
    if (!(this instanceof api)) return new api(executor);

    /*  initialize object  */
    this.id = 'Thenable/1.0.7';
    this.state = STATE_PENDING; /*  initial state  */
    this.fulfillValue = undefined; /*  initial value  */ /*  [Promises/A+ 1.3, 2.1.2.2]  */
    this.rejectReason = undefined; /*  initial reason */ /*  [Promises/A+ 1.5, 2.1.3.2]  */
    this.onFulfilled = []; /*  initial handlers  */
    this.onRejected = []; /*  initial handlers  */

    /*  provide optional information-hiding proxy  */
    this.proxy = {
      then: this.then.bind(this)
    };

    /*  support optional executor function  */
    if (typeof executor === 'function') executor.call(this, this.fulfill.bind(this), this.reject.bind(this));
  };

  /*  promise API methods  */
  api.prototype = {
    /*  promise resolving methods  */
    fulfill: function fulfill(value) {
      return deliver(this, STATE_FULFILLED, 'fulfillValue', value);
    },
    reject: function reject(value) {
      return deliver(this, STATE_REJECTED, 'rejectReason', value);
    },
    /*  "The then Method" [Promises/A+ 1.1, 1.2, 2.2]  */
    then: function then(onFulfilled, onRejected) {
      var curr = this;
      var next = new api(); /*  [Promises/A+ 2.2.7]  */
      curr.onFulfilled.push(resolver(onFulfilled, next, 'fulfill')); /*  [Promises/A+ 2.2.2/2.2.6]  */
      curr.onRejected.push(resolver(onRejected, next, 'reject')); /*  [Promises/A+ 2.2.3/2.2.6]  */
      execute(curr);
      return next.proxy; /*  [Promises/A+ 2.2.7, 3.3]  */
    }
  };

  /*  deliver an action  */
  var deliver = function deliver(curr, state, name, value) {
    if (curr.state === STATE_PENDING) {
      curr.state = state; /*  [Promises/A+ 2.1.2.1, 2.1.3.1]  */
      curr[name] = value; /*  [Promises/A+ 2.1.2.2, 2.1.3.2]  */
      execute(curr);
    }
    return curr;
  };

  /*  execute all handlers  */
  var execute = function execute(curr) {
    if (curr.state === STATE_FULFILLED) execute_handlers(curr, 'onFulfilled', curr.fulfillValue);else if (curr.state === STATE_REJECTED) execute_handlers(curr, 'onRejected', curr.rejectReason);
  };

  /*  execute particular set of handlers  */
  var execute_handlers = function execute_handlers(curr, name, value) {
    /* global setImmediate: true */
    /* global setTimeout: true */

    /*  short-circuit processing  */
    if (curr[name].length === 0) return;

    /*  iterate over all handlers, exactly once  */
    var handlers = curr[name];
    curr[name] = []; /*  [Promises/A+ 2.2.2.3, 2.2.3.3]  */
    var func = function func() {
      for (var i = 0; i < handlers.length; i++) {
        handlers[i](value);
      } /*  [Promises/A+ 2.2.5]  */
    };

    /*  execute procedure asynchronously  */ /*  [Promises/A+ 2.2.4, 3.1]  */
    if (typeof setImmediate === 'function') setImmediate(func);else setTimeout(func, 0);
  };

  /*  generate a resolver function  */
  var resolver = function resolver(cb, next, method) {
    return function (value) {
      if (typeof cb !== 'function') /*  [Promises/A+ 2.2.1, 2.2.7.3, 2.2.7.4]  */
        next[method].call(next, value); /*  [Promises/A+ 2.2.7.3, 2.2.7.4]  */else {
        var result;
        try {
          result = cb(value);
        } /*  [Promises/A+ 2.2.2.1, 2.2.3.1, 2.2.5, 3.2]  */ catch (e) {
          next.reject(e); /*  [Promises/A+ 2.2.7.2]  */
          return;
        }
        resolve(next, result); /*  [Promises/A+ 2.2.7.1]  */
      }
    };
  };

  /*  "Promise Resolution Procedure"  */ /*  [Promises/A+ 2.3]  */
  var resolve = function resolve(promise, x) {
    /*  sanity check arguments  */ /*  [Promises/A+ 2.3.1]  */
    if (promise === x || promise.proxy === x) {
      promise.reject(new TypeError('cannot resolve promise with itself'));
      return;
    }

    /*  surgically check for a "then" method
      (mainly to just call the "getter" of "then" only once)  */
    var then;
    if (_typeof(x) === 'object' && x !== null || typeof x === 'function') {
      try {
        then = x.then;
      } /*  [Promises/A+ 2.3.3.1, 3.5]  */ catch (e) {
        promise.reject(e); /*  [Promises/A+ 2.3.3.2]  */
        return;
      }
    }

    /*  handle own Thenables    [Promises/A+ 2.3.2]
      and similar "thenables" [Promises/A+ 2.3.3]  */
    if (typeof then === 'function') {
      var resolved = false;
      try {
        /*  call retrieved "then" method */ /*  [Promises/A+ 2.3.3.3]  */
        then.call(x, /*  resolvePromise  */ /*  [Promises/A+ 2.3.3.3.1]  */
        function (y) {
          if (resolved) return;
          resolved = true; /*  [Promises/A+ 2.3.3.3.3]  */
          if (y === x) /*  [Promises/A+ 3.6]  */
            promise.reject(new TypeError('circular thenable chain'));else resolve(promise, y);
        }, /*  rejectPromise  */ /*  [Promises/A+ 2.3.3.3.2]  */
        function (r) {
          if (resolved) return;
          resolved = true; /*  [Promises/A+ 2.3.3.3.3]  */
          promise.reject(r);
        });
      } catch (e) {
        if (!resolved) /*  [Promises/A+ 2.3.3.3.3]  */
          promise.reject(e); /*  [Promises/A+ 2.3.3.3.4]  */
      }

      return;
    }

    /*  handle other values  */
    promise.fulfill(x); /*  [Promises/A+ 2.3.4, 2.3.3.4]  */
  };

  // so we always have Promise.all()
  api.all = function (ps) {
    return new api(function (resolveAll, rejectAll) {
      var vals = new Array(ps.length);
      var doneCount = 0;
      var fulfill = function fulfill(i, val) {
        vals[i] = val;
        doneCount++;
        if (doneCount === ps.length) {
          resolveAll(vals);
        }
      };
      for (var i = 0; i < ps.length; i++) {
        (function (i) {
          var p = ps[i];
          var isPromise = p != null && p.then != null;
          if (isPromise) {
            p.then(function (val) {
              fulfill(i, val);
            }, function (err) {
              rejectAll(err);
            });
          } else {
            var val = p;
            fulfill(i, val);
          }
        })(i);
      }
    });
  };
  api.resolve = function (val) {
    return new api(function (resolve, reject) {
      resolve(val);
    });
  };
  api.reject = function (val) {
    return new api(function (resolve, reject) {
      reject(val);
    });
  };
  var Promise$1 = typeof Promise !== 'undefined' ? Promise : api; // eslint-disable-line no-undef

  var Animation = function Animation(target, opts, opts2) {
    var isCore = core(target);
    var isEle = !isCore;
    var _p = this._private = extend({
      duration: 1000
    }, opts, opts2);
    _p.target = target;
    _p.style = _p.style || _p.css;
    _p.started = false;
    _p.playing = false;
    _p.hooked = false;
    _p.applying = false;
    _p.progress = 0;
    _p.completes = [];
    _p.frames = [];
    if (_p.complete && fn$6(_p.complete)) {
      _p.completes.push(_p.complete);
    }
    if (isEle) {
      var pos = target.position();
      _p.startPosition = _p.startPosition || {
        x: pos.x,
        y: pos.y
      };
      _p.startStyle = _p.startStyle || target.cy().style().getAnimationStartStyle(target, _p.style);
    }
    if (isCore) {
      var pan = target.pan();
      _p.startPan = {
        x: pan.x,
        y: pan.y
      };
      _p.startZoom = target.zoom();
    }

    // for future timeline/animations impl
    this.length = 1;
    this[0] = this;
  };
  var anifn = Animation.prototype;
  extend(anifn, {
    instanceString: function instanceString() {
      return 'animation';
    },
    hook: function hook() {
      var _p = this._private;
      if (!_p.hooked) {
        // add to target's animation queue
        var q;
        var tAni = _p.target._private.animation;
        if (_p.queue) {
          q = tAni.queue;
        } else {
          q = tAni.current;
        }
        q.push(this);

        // add to the animation loop pool
        if (elementOrCollection(_p.target)) {
          _p.target.cy().addToAnimationPool(_p.target);
        }
        _p.hooked = true;
      }
      return this;
    },
    play: function play() {
      var _p = this._private;

      // autorewind
      if (_p.progress === 1) {
        _p.progress = 0;
      }
      _p.playing = true;
      _p.started = false; // needs to be started by animation loop
      _p.stopped = false;
      this.hook();

      // the animation loop will start the animation...

      return this;
    },
    playing: function playing() {
      return this._private.playing;
    },
    apply: function apply() {
      var _p = this._private;
      _p.applying = true;
      _p.started = false; // needs to be started by animation loop
      _p.stopped = false;
      this.hook();

      // the animation loop will apply the animation at this progress

      return this;
    },
    applying: function applying() {
      return this._private.applying;
    },
    pause: function pause() {
      var _p = this._private;
      _p.playing = false;
      _p.started = false;
      return this;
    },
    stop: function stop() {
      var _p = this._private;
      _p.playing = false;
      _p.started = false;
      _p.stopped = true; // to be removed from animation queues

      return this;
    },
    rewind: function rewind() {
      return this.progress(0);
    },
    fastforward: function fastforward() {
      return this.progress(1);
    },
    time: function time(t) {
      var _p = this._private;
      if (t === undefined) {
        return _p.progress * _p.duration;
      } else {
        return this.progress(t / _p.duration);
      }
    },
    progress: function progress(p) {
      var _p = this._private;
      var wasPlaying = _p.playing;
      if (p === undefined) {
        return _p.progress;
      } else {
        if (wasPlaying) {
          this.pause();
        }
        _p.progress = p;
        _p.started = false;
        if (wasPlaying) {
          this.play();
        }
      }
      return this;
    },
    completed: function completed() {
      return this._private.progress === 1;
    },
    reverse: function reverse() {
      var _p = this._private;
      var wasPlaying = _p.playing;
      if (wasPlaying) {
        this.pause();
      }
      _p.progress = 1 - _p.progress;
      _p.started = false;
      var swap = function swap(a, b) {
        var _pa = _p[a];
        if (_pa == null) {
          return;
        }
        _p[a] = _p[b];
        _p[b] = _pa;
      };
      swap('zoom', 'startZoom');
      swap('pan', 'startPan');
      swap('position', 'startPosition');

      // swap styles
      if (_p.style) {
        for (var i = 0; i < _p.style.length; i++) {
          var prop = _p.style[i];
          var name = prop.name;
          var startStyleProp = _p.startStyle[name];
          _p.startStyle[name] = prop;
          _p.style[i] = startStyleProp;
        }
      }
      if (wasPlaying) {
        this.play();
      }
      return this;
    },
    promise: function promise(type) {
      var _p = this._private;
      var arr;
      switch (type) {
        case 'frame':
          arr = _p.frames;
          break;
        default:
        case 'complete':
        case 'completed':
          arr = _p.completes;
      }
      return new Promise$1(function (resolve, reject) {
        arr.push(function () {
          resolve();
        });
      });
    }
  });
  anifn.complete = anifn.completed;
  anifn.run = anifn.play;
  anifn.running = anifn.playing;

  var define$3 = {
    animated: function animated() {
      return function animatedImpl() {
        var self = this;
        var selfIsArrayLike = self.length !== undefined;
        var all = selfIsArrayLike ? self : [self]; // put in array if not array-like
        var cy = this._private.cy || this;
        if (!cy.styleEnabled()) {
          return false;
        }
        var ele = all[0];
        if (ele) {
          return ele._private.animation.current.length > 0;
        }
      };
    },
    // animated

    clearQueue: function clearQueue() {
      return function clearQueueImpl() {
        var self = this;
        var selfIsArrayLike = self.length !== undefined;
        var all = selfIsArrayLike ? self : [self]; // put in array if not array-like
        var cy = this._private.cy || this;
        if (!cy.styleEnabled()) {
          return this;
        }
        for (var i = 0; i < all.length; i++) {
          var ele = all[i];
          ele._private.animation.queue = [];
        }
        return this;
      };
    },
    // clearQueue

    delay: function delay() {
      return function delayImpl(time, complete) {
        var cy = this._private.cy || this;
        if (!cy.styleEnabled()) {
          return this;
        }
        return this.animate({
          delay: time,
          duration: time,
          complete: complete
        });
      };
    },
    // delay

    delayAnimation: function delayAnimation() {
      return function delayAnimationImpl(time, complete) {
        var cy = this._private.cy || this;
        if (!cy.styleEnabled()) {
          return this;
        }
        return this.animation({
          delay: time,
          duration: time,
          complete: complete
        });
      };
    },
    // delay

    animation: function animation() {
      return function animationImpl(properties, params) {
        var self = this;
        var selfIsArrayLike = self.length !== undefined;
        var all = selfIsArrayLike ? self : [self]; // put in array if not array-like
        var cy = this._private.cy || this;
        var isCore = !selfIsArrayLike;
        var isEles = !isCore;
        if (!cy.styleEnabled()) {
          return this;
        }
        var style = cy.style();
        properties = extend({}, properties, params);
        var propertiesEmpty = Object.keys(properties).length === 0;
        if (propertiesEmpty) {
          return new Animation(all[0], properties); // nothing to animate
        }

        if (properties.duration === undefined) {
          properties.duration = 400;
        }
        switch (properties.duration) {
          case 'slow':
            properties.duration = 600;
            break;
          case 'fast':
            properties.duration = 200;
            break;
        }
        if (isEles) {
          properties.style = style.getPropsList(properties.style || properties.css);
          properties.css = undefined;
        }
        if (isEles && properties.renderedPosition != null) {
          var rpos = properties.renderedPosition;
          var pan = cy.pan();
          var zoom = cy.zoom();
          properties.position = renderedToModelPosition(rpos, zoom, pan);
        }

        // override pan w/ panBy if set
        if (isCore && properties.panBy != null) {
          var panBy = properties.panBy;
          var cyPan = cy.pan();
          properties.pan = {
            x: cyPan.x + panBy.x,
            y: cyPan.y + panBy.y
          };
        }

        // override pan w/ center if set
        var center = properties.center || properties.centre;
        if (isCore && center != null) {
          var centerPan = cy.getCenterPan(center.eles, properties.zoom);
          if (centerPan != null) {
            properties.pan = centerPan;
          }
        }

        // override pan & zoom w/ fit if set
        if (isCore && properties.fit != null) {
          var fit = properties.fit;
          var fitVp = cy.getFitViewport(fit.eles || fit.boundingBox, fit.padding);
          if (fitVp != null) {
            properties.pan = fitVp.pan;
            properties.zoom = fitVp.zoom;
          }
        }

        // override zoom (& potentially pan) w/ zoom obj if set
        if (isCore && plainObject(properties.zoom)) {
          var vp = cy.getZoomedViewport(properties.zoom);
          if (vp != null) {
            if (vp.zoomed) {
              properties.zoom = vp.zoom;
            }
            if (vp.panned) {
              properties.pan = vp.pan;
            }
          } else {
            properties.zoom = null; // an inavalid zoom (e.g. no delta) gets automatically destroyed
          }
        }

        return new Animation(all[0], properties);
      };
    },
    // animate

    animate: function animate() {
      return function animateImpl(properties, params) {
        var self = this;
        var selfIsArrayLike = self.length !== undefined;
        var all = selfIsArrayLike ? self : [self]; // put in array if not array-like
        var cy = this._private.cy || this;
        if (!cy.styleEnabled()) {
          return this;
        }
        if (params) {
          properties = extend({}, properties, params);
        }

        // manually hook and run the animation
        for (var i = 0; i < all.length; i++) {
          var ele = all[i];
          var queue = ele.animated() && (properties.queue === undefined || properties.queue);
          var ani = ele.animation(properties, queue ? {
            queue: true
          } : undefined);
          ani.play();
        }
        return this; // chaining
      };
    },

    // animate

    stop: function stop() {
      return function stopImpl(clearQueue, jumpToEnd) {
        var self = this;
        var selfIsArrayLike = self.length !== undefined;
        var all = selfIsArrayLike ? self : [self]; // put in array if not array-like
        var cy = this._private.cy || this;
        if (!cy.styleEnabled()) {
          return this;
        }
        for (var i = 0; i < all.length; i++) {
          var ele = all[i];
          var _p = ele._private;
          var anis = _p.animation.current;
          for (var j = 0; j < anis.length; j++) {
            var ani = anis[j];
            var ani_p = ani._private;
            if (jumpToEnd) {
              // next iteration of the animation loop, the animation
              // will go straight to the end and be removed
              ani_p.duration = 0;
            }
          }

          // clear the queue of future animations
          if (clearQueue) {
            _p.animation.queue = [];
          }
          if (!jumpToEnd) {
            _p.animation.current = [];
          }
        }

        // we have to notify (the animation loop doesn't do it for us on `stop`)
        cy.notify('draw');
        return this;
      };
    } // stop
  }; // define

  /**
   * 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
   */
  var isArray = Array.isArray;

  var isArray_1 = isArray;

  /** Used to match property names within property paths. */
  var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
      reIsPlainProp = /^\w*$/;

  /**
   * 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`.
   */
  function isKey(value, object) {
    if (isArray_1(value)) {
      return false;
    }
    var type = typeof value;
    if (type == 'number' || type == 'symbol' || type == 'boolean' ||
        value == null || isSymbol_1(value)) {
      return true;
    }
    return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
      (object != null && value in Object(object));
  }

  var _isKey = isKey;

  /** `Object#toString` result references. */
  var asyncTag = '[object AsyncFunction]',
      funcTag = '[object Function]',
      genTag = '[object GeneratorFunction]',
      proxyTag = '[object Proxy]';

  /**
   * 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
   */
  function isFunction(value) {
    if (!isObject_1(value)) {
      return false;
    }
    // The use of `Object#toString` avoids issues with the `typeof` operator
    // in Safari 9 which returns 'object' for typed arrays and other constructors.
    var tag = _baseGetTag(value);
    return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
  }

  var isFunction_1 = isFunction;

  /** Used to detect overreaching core-js shims. */
  var coreJsData = _root['__core-js_shared__'];

  var _coreJsData = coreJsData;

  /** Used to detect methods masquerading as native. */
  var maskSrcKey = (function() {
    var uid = /[^.]+$/.exec(_coreJsData && _coreJsData.keys && _coreJsData.keys.IE_PROTO || '');
    return uid ? ('Symbol(src)_1.' + uid) : '';
  }());

  /**
   * 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`.
   */
  function isMasked(func) {
    return !!maskSrcKey && (maskSrcKey in func);
  }

  var _isMasked = isMasked;

  /** Used for built-in method references. */
  var funcProto$1 = Function.prototype;

  /** Used to resolve the decompiled source of functions. */
  var funcToString$1 = funcProto$1.toString;

  /**
   * Converts `func` to its source code.
   *
   * @private
   * @param {Function} func The function to convert.
   * @returns {string} Returns the source code.
   */
  function toSource(func) {
    if (func != null) {
      try {
        return funcToString$1.call(func);
      } catch (e) {}
      try {
        return (func + '');
      } catch (e) {}
    }
    return '';
  }

  var _toSource = toSource;

  /**
   * Used to match `RegExp`
   * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
   */
  var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;

  /** Used to detect host constructors (Safari). */
  var reIsHostCtor = /^\[object .+?Constructor\]$/;

  /** Used for built-in method references. */
  var funcProto = Function.prototype,
      objectProto$3 = Object.prototype;

  /** Used to resolve the decompiled source of functions. */
  var funcToString = funcProto.toString;

  /** Used to check objects for own properties. */
  var hasOwnProperty$3 = objectProto$3.hasOwnProperty;

  /** Used to detect if a method is native. */
  var reIsNative = RegExp('^' +
    funcToString.call(hasOwnProperty$3).replace(reRegExpChar, '\\$&')
    .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
  );

  /**
   * 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`.
   */
  function baseIsNative(value) {
    if (!isObject_1(value) || _isMasked(value)) {
      return false;
    }
    var pattern = isFunction_1(value) ? reIsNative : reIsHostCtor;
    return pattern.test(_toSource(value));
  }

  var _baseIsNative = baseIsNative;

  /**
   * 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.
   */
  function getValue$1(object, key) {
    return object == null ? undefined : object[key];
  }

  var _getValue = getValue$1;

  /**
   * 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`.
   */
  function getNative(object, key) {
    var value = _getValue(object, key);
    return _baseIsNative(value) ? value : undefined;
  }

  var _getNative = getNative;

  /* Built-in method references that are verified to be native. */
  var nativeCreate = _getNative(Object, 'create');

  var _nativeCreate = nativeCreate;

  /**
   * Removes all key-value entries from the hash.
   *
   * @private
   * @name clear
   * @memberOf Hash
   */
  function hashClear() {
    this.__data__ = _nativeCreate ? _nativeCreate(null) : {};
    this.size = 0;
  }

  var _hashClear = hashClear;

  /**
   * 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`.
   */
  function hashDelete(key) {
    var result = this.has(key) && delete this.__data__[key];
    this.size -= result ? 1 : 0;
    return result;
  }

  var _hashDelete = hashDelete;

  /** Used to stand-in for `undefined` hash values. */
  var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';

  /** Used for built-in method references. */
  var objectProto$2 = Object.prototype;

  /** Used to check objects for own properties. */
  var hasOwnProperty$2 = objectProto$2.hasOwnProperty;

  /**
   * 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.
   */
  function hashGet(key) {
    var data = this.__data__;
    if (_nativeCreate) {
      var result = data[key];
      return result === HASH_UNDEFINED$1 ? undefined : result;
    }
    return hasOwnProperty$2.call(data, key) ? data[key] : undefined;
  }

  var _hashGet = hashGet;

  /** Used for built-in method references. */
  var objectProto$1 = Object.prototype;

  /** Used to check objects for own properties. */
  var hasOwnProperty$1 = objectProto$1.hasOwnProperty;

  /**
   * 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`.
   */
  function hashHas(key) {
    var data = this.__data__;
    return _nativeCreate ? (data[key] !== undefined) : hasOwnProperty$1.call(data, key);
  }

  var _hashHas = hashHas;

  /** Used to stand-in for `undefined` hash values. */
  var HASH_UNDEFINED = '__lodash_hash_undefined__';

  /**
   * 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.
   */
  function hashSet(key, value) {
    var data = this.__data__;
    this.size += this.has(key) ? 0 : 1;
    data[key] = (_nativeCreate && value === undefined) ? HASH_UNDEFINED : value;
    return this;
  }

  var _hashSet = hashSet;

  /**
   * Creates a hash object.
   *
   * @private
   * @constructor
   * @param {Array} [entries] The key-value pairs to cache.
   */
  function Hash(entries) {
    var index = -1,
        length = entries == null ? 0 : entries.length;

    this.clear();
    while (++index < length) {
      var entry = entries[index];
      this.set(entry[0], entry[1]);
    }
  }

  // Add methods to `Hash`.
  Hash.prototype.clear = _hashClear;
  Hash.prototype['delete'] = _hashDelete;
  Hash.prototype.get = _hashGet;
  Hash.prototype.has = _hashHas;
  Hash.prototype.set = _hashSet;

  var _Hash = Hash;

  /**
   * Removes all key-value entries from the list cache.
   *
   * @private
   * @name clear
   * @memberOf ListCache
   */
  function listCacheClear() {
    this.__data__ = [];
    this.size = 0;
  }

  var _listCacheClear = listCacheClear;

  /**
   * 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
   */
  function eq(value, other) {
    return value === other || (value !== value && other !== other);
  }

  var eq_1 = eq;

  /**
   * 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`.
   */
  function assocIndexOf(array, key) {
    var length = array.length;
    while (length--) {
      if (eq_1(array[length][0], key)) {
        return length;
      }
    }
    return -1;
  }

  var _assocIndexOf = assocIndexOf;

  /** Used for built-in method references. */
  var arrayProto = Array.prototype;

  /** Built-in value references. */
  var splice = arrayProto.splice;

  /**
   * 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`.
   */
  function listCacheDelete(key) {
    var data = this.__data__,
        index = _assocIndexOf(data, key);

    if (index < 0) {
      return false;
    }
    var lastIndex = data.length - 1;
    if (index == lastIndex) {
      data.pop();
    } else {
      splice.call(data, index, 1);
    }
    --this.size;
    return true;
  }

  var _listCacheDelete = listCacheDelete;

  /**
   * 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.
   */
  function listCacheGet(key) {
    var data = this.__data__,
        index = _assocIndexOf(data, key);

    return index < 0 ? undefined : data[index][1];
  }

  var _listCacheGet = listCacheGet;

  /**
   * 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`.
   */
  function listCacheHas(key) {
    return _assocIndexOf(this.__data__, key) > -1;
  }

  var _listCacheHas = listCacheHas;

  /**
   * 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.
   */
  function listCacheSet(key, value) {
    var data = this.__data__,
        index = _assocIndexOf(data, key);

    if (index < 0) {
      ++this.size;
      data.push([key, value]);
    } else {
      data[index][1] = value;
    }
    return this;
  }

  var _listCacheSet = listCacheSet;

  /**
   * Creates an list cache object.
   *
   * @private
   * @constructor
   * @param {Array} [entries] The key-value pairs to cache.
   */
  function ListCache(entries) {
    var index = -1,
        length = entries == null ? 0 : entries.length;

    this.clear();
    while (++index < length) {
      var entry = entries[index];
      this.set(entry[0], entry[1]);
    }
  }

  // Add methods to `ListCache`.
  ListCache.prototype.clear = _listCacheClear;
  ListCache.prototype['delete'] = _listCacheDelete;
  ListCache.prototype.get = _listCacheGet;
  ListCache.prototype.has = _listCacheHas;
  ListCache.prototype.set = _listCacheSet;

  var _ListCache = ListCache;

  /* Built-in method references that are verified to be native. */
  var Map$1 = _getNative(_root, 'Map');

  var _Map = Map$1;

  /**
   * Removes all key-value entries from the map.
   *
   * @private
   * @name clear
   * @memberOf MapCache
   */
  function mapCacheClear() {
    this.size = 0;
    this.__data__ = {
      'hash': new _Hash,
      'map': new (_Map || _ListCache),
      'string': new _Hash
    };
  }

  var _mapCacheClear = mapCacheClear;

  /**
   * 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`.
   */
  function isKeyable(value) {
    var type = typeof value;
    return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')
      ? (value !== '__proto__')
      : (value === null);
  }

  var _isKeyable = isKeyable;

  /**
   * Gets the data for `map`.
   *
   * @private
   * @param {Object} map The map to query.
   * @param {string} key The reference key.
   * @returns {*} Returns the map data.
   */
  function getMapData(map, key) {
    var data = map.__data__;
    return _isKeyable(key)
      ? data[typeof key == 'string' ? 'string' : 'hash']
      : data.map;
  }

  var _getMapData = getMapData;

  /**
   * 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`.
   */
  function mapCacheDelete(key) {
    var result = _getMapData(this, key)['delete'](key);
    this.size -= result ? 1 : 0;
    return result;
  }

  var _mapCacheDelete = mapCacheDelete;

  /**
   * 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.
   */
  function mapCacheGet(key) {
    return _getMapData(this, key).get(key);
  }

  var _mapCacheGet = mapCacheGet;

  /**
   * 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`.
   */
  function mapCacheHas(key) {
    return _getMapData(this, key).has(key);
  }

  var _mapCacheHas = mapCacheHas;

  /**
   * 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.
   */
  function mapCacheSet(key, value) {
    var data = _getMapData(this, key),
        size = data.size;

    data.set(key, value);
    this.size += data.size == size ? 0 : 1;
    return this;
  }

  var _mapCacheSet = mapCacheSet;

  /**
   * Creates a map cache object to store key-value pairs.
   *
   * @private
   * @constructor
   * @param {Array} [entries] The key-value pairs to cache.
   */
  function MapCache(entries) {
    var index = -1,
        length = entries == null ? 0 : entries.length;

    this.clear();
    while (++index < length) {
      var entry = entries[index];
      this.set(entry[0], entry[1]);
    }
  }

  // Add methods to `MapCache`.
  MapCache.prototype.clear = _mapCacheClear;
  MapCache.prototype['delete'] = _mapCacheDelete;
  MapCache.prototype.get = _mapCacheGet;
  MapCache.prototype.has = _mapCacheHas;
  MapCache.prototype.set = _mapCacheSet;

  var _MapCache = MapCache;

  /** Error message constants. */
  var FUNC_ERROR_TEXT = 'Expected a 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;
   */
  function memoize(func, resolver) {
    if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {
      throw new TypeError(FUNC_ERROR_TEXT);
    }
    var memoized = function() {
      var args = arguments,
          key = resolver ? resolver.apply(this, args) : args[0],
          cache = memoized.cache;

      if (cache.has(key)) {
        return cache.get(key);
      }
      var result = func.apply(this, args);
      memoized.cache = cache.set(key, result) || cache;
      return result;
    };
    memoized.cache = new (memoize.Cache || _MapCache);
    return memoized;
  }

  // Expose `MapCache`.
  memoize.Cache = _MapCache;

  var memoize_1 = memoize;

  /** Used as the maximum memoize cache size. */
  var MAX_MEMOIZE_SIZE = 500;

  /**
   * 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.
   */
  function memoizeCapped(func) {
    var result = memoize_1(func, function(key) {
      if (cache.size === MAX_MEMOIZE_SIZE) {
        cache.clear();
      }
      return key;
    });

    var cache = result.cache;
    return result;
  }

  var _memoizeCapped = memoizeCapped;

  /** Used to match property names within property paths. */
  var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;

  /** Used to match backslashes in property paths. */
  var reEscapeChar = /\\(\\)?/g;

  /**
   * Converts `string` to a property path array.
   *
   * @private
   * @param {string} string The string to convert.
   * @returns {Array} Returns the property path array.
   */
  var stringToPath = _memoizeCapped(function(string) {
    var result = [];
    if (string.charCodeAt(0) === 46 /* . */) {
      result.push('');
    }
    string.replace(rePropName, function(match, number, quote, subString) {
      result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));
    });
    return result;
  });

  var _stringToPath = stringToPath;

  /**
   * 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.
   */
  function arrayMap(array, iteratee) {
    var index = -1,
        length = array == null ? 0 : array.length,
        result = Array(length);

    while (++index < length) {
      result[index] = iteratee(array[index], index, array);
    }
    return result;
  }

  var _arrayMap = arrayMap;

  /** Used as references for various `Number` constants. */
  var INFINITY$1 = 1 / 0;

  /** Used to convert symbols to primitives and strings. */
  var symbolProto = _Symbol ? _Symbol.prototype : undefined,
      symbolToString = symbolProto ? symbolProto.toString : undefined;

  /**
   * 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.
   */
  function baseToString(value) {
    // Exit early for strings to avoid a performance hit in some environments.
    if (typeof value == 'string') {
      return value;
    }
    if (isArray_1(value)) {
      // Recursively convert values (susceptible to call stack limits).
      return _arrayMap(value, baseToString) + '';
    }
    if (isSymbol_1(value)) {
      return symbolToString ? symbolToString.call(value) : '';
    }
    var result = (value + '');
    return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result;
  }

  var _baseToString = baseToString;

  /**
   * 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'
   */
  function toString$1(value) {
    return value == null ? '' : _baseToString(value);
  }

  var toString_1 = toString$1;

  /**
   * 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.
   */
  function castPath(value, object) {
    if (isArray_1(value)) {
      return value;
    }
    return _isKey(value, object) ? [value] : _stringToPath(toString_1(value));
  }

  var _castPath = castPath;

  /** Used as references for various `Number` constants. */
  var INFINITY = 1 / 0;

  /**
   * 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.
   */
  function toKey(value) {
    if (typeof value == 'string' || isSymbol_1(value)) {
      return value;
    }
    var result = (value + '');
    return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
  }

  var _toKey = toKey;

  /**
   * 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.
   */
  function baseGet(object, path) {
    path = _castPath(path, object);

    var index = 0,
        length = path.length;

    while (object != null && index < length) {
      object = object[_toKey(path[index++])];
    }
    return (index && index == length) ? object : undefined;
  }

  var _baseGet = baseGet;

  /**
   * 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'
   */
  function get(object, path, defaultValue) {
    var result = object == null ? undefined : _baseGet(object, path);
    return result === undefined ? defaultValue : result;
  }

  var get_1 = get;

  var defineProperty = (function() {
    try {
      var func = _getNative(Object, 'defineProperty');
      func({}, '', {});
      return func;
    } catch (e) {}
  }());

  var _defineProperty = defineProperty;

  /**
   * 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.
   */
  function baseAssignValue(object, key, value) {
    if (key == '__proto__' && _defineProperty) {
      _defineProperty(object, key, {
        'configurable': true,
        'enumerable': true,
        'value': value,
        'writable': true
      });
    } else {
      object[key] = value;
    }
  }

  var _baseAssignValue = baseAssignValue;

  /** Used for built-in method references. */
  var objectProto = Object.prototype;

  /** Used to check objects for own properties. */
  var hasOwnProperty = objectProto.hasOwnProperty;

  /**
   * 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.
   */
  function assignValue(object, key, value) {
    var objValue = object[key];
    if (!(hasOwnProperty.call(object, key) && eq_1(objValue, value)) ||
        (value === undefined && !(key in object))) {
      _baseAssignValue(object, key, value);
    }
  }

  var _assignValue = assignValue;

  /** Used as references for various `Number` constants. */
  var MAX_SAFE_INTEGER = 9007199254740991;

  /** Used to detect unsigned integer values. */
  var reIsUint = /^(?:0|[1-9]\d*)$/;

  /**
   * 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`.
   */
  function isIndex(value, length) {
    var type = typeof value;
    length = length == null ? MAX_SAFE_INTEGER : length;

    return !!length &&
      (type == 'number' ||
        (type != 'symbol' && reIsUint.test(value))) &&
          (value > -1 && value % 1 == 0 && value < length);
  }

  var _isIndex = isIndex;

  /**
   * 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`.
   */
  function baseSet(object, path, value, customizer) {
    if (!isObject_1(object)) {
      return object;
    }
    path = _castPath(path, object);

    var index = -1,
        length = path.length,
        lastIndex = length - 1,
        nested = object;

    while (nested != null && ++index < length) {
      var key = _toKey(path[index]),
          newValue = value;

      if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
        return object;
      }

      if (index != lastIndex) {
        var objValue = nested[key];
        newValue = customizer ? customizer(objValue, key, nested) : undefined;
        if (newValue === undefined) {
          newValue = isObject_1(objValue)
            ? objValue
            : (_isIndex(path[index + 1]) ? [] : {});
        }
      }
      _assignValue(nested, key, newValue);
      nested = nested[key];
    }
    return object;
  }

  var _baseSet = baseSet;

  /**
   * 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
   */
  function set(object, path, value) {
    return object == null ? object : _baseSet(object, path, value);
  }

  var set_1 = set;

  /**
   * 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`.
   */
  function copyArray(source, array) {
    var index = -1,
        length = source.length;

    array || (array = Array(length));
    while (++index < length) {
      array[index] = source[index];
    }
    return array;
  }

  var _copyArray = copyArray;

  /**
   * 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']
   */
  function toPath(value) {
    if (isArray_1(value)) {
      return _arrayMap(value, _toKey);
    }
    return isSymbol_1(value) ? [value] : _copyArray(_stringToPath(toString_1(value)));
  }

  var toPath_1 = toPath;

  var define$2 = {
    // access data field
    data: function data(params) {
      var defaults = {
        field: 'data',
        bindingEvent: 'data',
        allowBinding: false,
        allowSetting: false,
        allowGetting: false,
        settingEvent: 'data',
        settingTriggersEvent: false,
        triggerFnName: 'trigger',
        immutableKeys: {},
        // key => true if immutable
        updateStyle: false,
        beforeGet: function beforeGet(self) {},
        beforeSet: function beforeSet(self, obj) {},
        onSet: function onSet(self) {},
        canSet: function canSet(self) {
          return true;
        }
      };
      params = extend({}, defaults, params);
      return function dataImpl(name, value) {
        var p = params;
        var self = this;
        var selfIsArrayLike = self.length !== undefined;
        var all = selfIsArrayLike ? self : [self]; // put in array if not array-like
        var single = selfIsArrayLike ? self[0] : self;

        // .data('foo', ...)
        if (string(name)) {
          // set or get property
          var isPathLike = name.indexOf('.') !== -1; // there might be a normal field with a dot 
          var path = isPathLike && toPath_1(name);

          // .data('foo')
          if (p.allowGetting && value === undefined) {
            // get

            var ret;
            if (single) {
              p.beforeGet(single);

              // check if it's path and a field with the same name doesn't exist
              if (path && single._private[p.field][name] === undefined) {
                ret = get_1(single._private[p.field], path);
              } else {
                ret = single._private[p.field][name];
              }
            }
            return ret;

            // .data('foo', 'bar')
          } else if (p.allowSetting && value !== undefined) {
            // set
            var valid = !p.immutableKeys[name];
            if (valid) {
              var change = _defineProperty$1({}, name, value);
              p.beforeSet(self, change);
              for (var i = 0, l = all.length; i < l; i++) {
                var ele = all[i];
                if (p.canSet(ele)) {
                  if (path && single._private[p.field][name] === undefined) {
                    set_1(ele._private[p.field], path, value);
                  } else {
                    ele._private[p.field][name] = value;
                  }
                }
              }

              // update mappers if asked
              if (p.updateStyle) {
                self.updateStyle();
              }

              // call onSet callback
              p.onSet(self);
              if (p.settingTriggersEvent) {
                self[p.triggerFnName](p.settingEvent);
              }
            }
          }

          // .data({ 'foo': 'bar' })
        } else if (p.allowSetting && plainObject(name)) {
          // extend
          var obj = name;
          var k, v;
          var keys = Object.keys(obj);
          p.beforeSet(self, obj);
          for (var _i = 0; _i < keys.length; _i++) {
            k = keys[_i];
            v = obj[k];
            var _valid = !p.immutableKeys[k];
            if (_valid) {
              for (var j = 0; j < all.length; j++) {
                var _ele = all[j];
                if (p.canSet(_ele)) {
                  _ele._private[p.field][k] = v;
                }
              }
            }
          }

          // update mappers if asked
          if (p.updateStyle) {
            self.updateStyle();
          }

          // call onSet callback
          p.onSet(self);
          if (p.settingTriggersEvent) {
            self[p.triggerFnName](p.settingEvent);
          }

          // .data(function(){ ... })
        } else if (p.allowBinding && fn$6(name)) {
          // bind to event
          var fn = name;
          self.on(p.bindingEvent, fn);

          // .data()
        } else if (p.allowGetting && name === undefined) {
          // get whole object
          var _ret;
          if (single) {
            p.beforeGet(single);
            _ret = single._private[p.field];
          }
          return _ret;
        }
        return self; // maintain chainability
      }; // function
    },

    // data

    // remove data field
    removeData: function removeData(params) {
      var defaults = {
        field: 'data',
        event: 'data',
        triggerFnName: 'trigger',
        triggerEvent: false,
        immutableKeys: {} // key => true if immutable
      };

      params = extend({}, defaults, params);
      return function removeDataImpl(names) {
        var p = params;
        var self = this;
        var selfIsArrayLike = self.length !== undefined;
        var all = selfIsArrayLike ? self : [self]; // put in array if not array-like

        // .removeData('foo bar')
        if (string(names)) {
          // then get the list of keys, and delete them
          var keys = names.split(/\s+/);
          var l = keys.length;
          for (var i = 0; i < l; i++) {
            // delete each non-empty key
            var key = keys[i];
            if (emptyString(key)) {
              continue;
            }
            var valid = !p.immutableKeys[key]; // not valid if immutable
            if (valid) {
              for (var i_a = 0, l_a = all.length; i_a < l_a; i_a++) {
                all[i_a]._private[p.field][key] = undefined;
              }
            }
          }
          if (p.triggerEvent) {
            self[p.triggerFnName](p.event);
          }

          // .removeData()
        } else if (names === undefined) {
          // then delete all keys

          for (var _i_a = 0, _l_a = all.length; _i_a < _l_a; _i_a++) {
            var _privateFields = all[_i_a]._private[p.field];
            var _keys = Object.keys(_privateFields);
            for (var _i2 = 0; _i2 < _keys.length; _i2++) {
              var _key = _keys[_i2];
              var validKeyToDelete = !p.immutableKeys[_key];
              if (validKeyToDelete) {
                _privateFields[_key] = undefined;
              }
            }
          }
          if (p.triggerEvent) {
            self[p.triggerFnName](p.event);
          }
        }
        return self; // maintain chaining
      }; // function
    } // removeData
  }; // define

  var define$1 = {
    eventAliasesOn: function eventAliasesOn(proto) {
      var p = proto;
      p.addListener = p.listen = p.bind = p.on;
      p.unlisten = p.unbind = p.off = p.removeListener;
      p.trigger = p.emit;

      // this is just a wrapper alias of .on()
      p.pon = p.promiseOn = function (events, selector) {
        var self = this;
        var args = Array.prototype.slice.call(arguments, 0);
        return new Promise$1(function (resolve, reject) {
          var callback = function callback(e) {
            self.off.apply(self, offArgs);
            resolve(e);
          };
          var onArgs = args.concat([callback]);
          var offArgs = onArgs.concat([]);
          self.on.apply(self, onArgs);
        });
      };
    }
  }; // define

  // use this module to cherry pick functions into your prototype
  var define = {};
  [define$3, define$2, define$1].forEach(function (m) {
    extend(define, m);
  });

  var elesfn$i = {
    animate: define.animate(),
    animation: define.animation(),
    animated: define.animated(),
    clearQueue: define.clearQueue(),
    delay: define.delay(),
    delayAnimation: define.delayAnimation(),
    stop: define.stop()
  };

  var elesfn$h = {
    classes: function classes(_classes) {
      var self = this;
      if (_classes === undefined) {
        var ret = [];
        self[0]._private.classes.forEach(function (cls) {
          return ret.push(cls);
        });
        return ret;
      } else if (!array(_classes)) {
        // extract classes from string
        _classes = (_classes || '').match(/\S+/g) || [];
      }
      var changed = [];
      var classesSet = new Set$1(_classes);

      // check and update each ele
      for (var j = 0; j < self.length; j++) {
        var ele = self[j];
        var _p = ele._private;
        var eleClasses = _p.classes;
        var changedEle = false;

        // check if ele has all of the passed classes
        for (var i = 0; i < _classes.length; i++) {
          var cls = _classes[i];
          var eleHasClass = eleClasses.has(cls);
          if (!eleHasClass) {
            changedEle = true;
            break;
          }
        }

        // check if ele has classes outside of those passed
        if (!changedEle) {
          changedEle = eleClasses.size !== _classes.length;
        }
        if (changedEle) {
          _p.classes = classesSet;
          changed.push(ele);
        }
      }

      // trigger update style on those eles that had class changes
      if (changed.length > 0) {
        this.spawn(changed).updateStyle().emit('class');
      }
      return self;
    },
    addClass: function addClass(classes) {
      return this.toggleClass(classes, true);
    },
    hasClass: function hasClass(className) {
      var ele = this[0];
      return ele != null && ele._private.classes.has(className);
    },
    toggleClass: function toggleClass(classes, toggle) {
      if (!array(classes)) {
        // extract classes from string
        classes = classes.match(/\S+/g) || [];
      }
      var self = this;
      var toggleUndefd = toggle === undefined;
      var changed = []; // eles who had classes changed

      for (var i = 0, il = self.length; i < il; i++) {
        var ele = self[i];
        var eleClasses = ele._private.classes;
        var changedEle = false;
        for (var j = 0; j < classes.length; j++) {
          var cls = classes[j];
          var hasClass = eleClasses.has(cls);
          var changedNow = false;
          if (toggle || toggleUndefd && !hasClass) {
            eleClasses.add(cls);
            changedNow = true;
          } else if (!toggle || toggleUndefd && hasClass) {
            eleClasses["delete"](cls);
            changedNow = true;
          }
          if (!changedEle && changedNow) {
            changed.push(ele);
            changedEle = true;
          }
        } // for j classes
      } // for i eles

      // trigger update style on those eles that had class changes
      if (changed.length > 0) {
        this.spawn(changed).updateStyle().emit('class');
      }
      return self;
    },
    removeClass: function removeClass(classes) {
      return this.toggleClass(classes, false);
    },
    flashClass: function flashClass(classes, duration) {
      var self = this;
      if (duration == null) {
        duration = 250;
      } else if (duration === 0) {
        return self; // nothing to do really
      }

      self.addClass(classes);
      setTimeout(function () {
        self.removeClass(classes);
      }, duration);
      return self;
    }
  };
  elesfn$h.className = elesfn$h.classNames = elesfn$h.classes;

  // tokens in the query language
  var tokens = {
    metaChar: '[\\!\\"\\#\\$\\%\\&\\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]',
    // chars we need to escape in let names, etc
    comparatorOp: '=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=',
    // binary comparison op (used in data selectors)
    boolOp: '\\?|\\!|\\^',
    // boolean (unary) operators (used in data selectors)
    string: '"(?:\\\\"|[^"])*"' + '|' + "'(?:\\\\'|[^'])*'",
    // string literals (used in data selectors) -- doublequotes | singlequotes
    number: number,
    // number literal (used in data selectors) --- e.g. 0.1234, 1234, 12e123
    meta: 'degree|indegree|outdegree',
    // allowed metadata fields (i.e. allowed functions to use from Collection)
    separator: '\\s*,\\s*',
    // queries are separated by commas, e.g. edge[foo = 'bar'], node.someClass
    descendant: '\\s+',
    child: '\\s+>\\s+',
    subject: '\\$',
    group: 'node|edge|\\*',
    directedEdge: '\\s+->\\s+',
    undirectedEdge: '\\s+<->\\s+'
  };
  tokens.variable = '(?:[\\w-.]|(?:\\\\' + tokens.metaChar + '))+'; // a variable name can have letters, numbers, dashes, and periods
  tokens.className = '(?:[\\w-]|(?:\\\\' + tokens.metaChar + '))+'; // a class name has the same rules as a variable except it can't have a '.' in the name
  tokens.value = tokens.string + '|' + tokens.number; // a value literal, either a string or number
  tokens.id = tokens.variable; // an element id (follows variable conventions)

  (function () {
    var ops, op, i;

    // add @ variants to comparatorOp
    ops = tokens.comparatorOp.split('|');
    for (i = 0; i < ops.length; i++) {
      op = ops[i];
      tokens.comparatorOp += '|@' + op;
    }

    // add ! variants to comparatorOp
    ops = tokens.comparatorOp.split('|');
    for (i = 0; i < ops.length; i++) {
      op = ops[i];
      if (op.indexOf('!') >= 0) {
        continue;
      } // skip ops that explicitly contain !
      if (op === '=') {
        continue;
      } // skip = b/c != is explicitly defined

      tokens.comparatorOp += '|\\!' + op;
    }
  })();

  /**
   * 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
   */
  var newQuery = function newQuery() {
    return {
      checks: []
    };
  };

  /**
   * 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.
   */
  var Type = {
    /** E.g. node */
    GROUP: 0,
    /** A collection of elements */
    COLLECTION: 1,
    /** A filter(ele) function */
    FILTER: 2,
    /** E.g. [foo > 1] */
    DATA_COMPARE: 3,
    /** E.g. [foo] */
    DATA_EXIST: 4,
    /** E.g. [?foo] */
    DATA_BOOL: 5,
    /** E.g. [[degree > 2]] */
    META_COMPARE: 6,
    /** E.g. :selected */
    STATE: 7,
    /** E.g. #foo */
    ID: 8,
    /** E.g. .foo */
    CLASS: 9,
    /** E.g. #foo <-> #bar */
    UNDIRECTED_EDGE: 10,
    /** E.g. #foo -> #bar */
    DIRECTED_EDGE: 11,
    /** E.g. $#foo -> #bar */
    NODE_SOURCE: 12,
    /** E.g. #foo -> $#bar */
    NODE_TARGET: 13,
    /** E.g. $#foo <-> #bar */
    NODE_NEIGHBOR: 14,
    /** E.g. #foo > #bar */
    CHILD: 15,
    /** E.g. #foo #bar */
    DESCENDANT: 16,
    /** E.g. $#foo > #bar */
    PARENT: 17,
    /** E.g. $#foo #bar */
    ANCESTOR: 18,
    /** E.g. #foo > $bar > #baz */
    COMPOUND_SPLIT: 19,
    /** Always matches, useful placeholder for subject in `COMPOUND_SPLIT` */
    TRUE: 20
  };

  var stateSelectors = [{
    selector: ':selected',
    matches: function matches(ele) {
      return ele.selected();
    }
  }, {
    selector: ':unselected',
    matches: function matches(ele) {
      return !ele.selected();
    }
  }, {
    selector: ':selectable',
    matches: function matches(ele) {
      return ele.selectable();
    }
  }, {
    selector: ':unselectable',
    matches: function matches(ele) {
      return !ele.selectable();
    }
  }, {
    selector: ':locked',
    matches: function matches(ele) {
      return ele.locked();
    }
  }, {
    selector: ':unlocked',
    matches: function matches(ele) {
      return !ele.locked();
    }
  }, {
    selector: ':visible',
    matches: function matches(ele) {
      return ele.visible();
    }
  }, {
    selector: ':hidden',
    matches: function matches(ele) {
      return !ele.visible();
    }
  }, {
    selector: ':transparent',
    matches: function matches(ele) {
      return ele.transparent();
    }
  }, {
    selector: ':grabbed',
    matches: function matches(ele) {
      return ele.grabbed();
    }
  }, {
    selector: ':free',
    matches: function matches(ele) {
      return !ele.grabbed();
    }
  }, {
    selector: ':removed',
    matches: function matches(ele) {
      return ele.removed();
    }
  }, {
    selector: ':inside',
    matches: function matches(ele) {
      return !ele.removed();
    }
  }, {
    selector: ':grabbable',
    matches: function matches(ele) {
      return ele.grabbable();
    }
  }, {
    selector: ':ungrabbable',
    matches: function matches(ele) {
      return !ele.grabbable();
    }
  }, {
    selector: ':animated',
    matches: function matches(ele) {
      return ele.animated();
    }
  }, {
    selector: ':unanimated',
    matches: function matches(ele) {
      return !ele.animated();
    }
  }, {
    selector: ':parent',
    matches: function matches(ele) {
      return ele.isParent();
    }
  }, {
    selector: ':childless',
    matches: function matches(ele) {
      return ele.isChildless();
    }
  }, {
    selector: ':child',
    matches: function matches(ele) {
      return ele.isChild();
    }
  }, {
    selector: ':orphan',
    matches: function matches(ele) {
      return ele.isOrphan();
    }
  }, {
    selector: ':nonorphan',
    matches: function matches(ele) {
      return ele.isChild();
    }
  }, {
    selector: ':compound',
    matches: function matches(ele) {
      if (ele.isNode()) {
        return ele.isParent();
      } else {
        return ele.source().isParent() || ele.target().isParent();
      }
    }
  }, {
    selector: ':loop',
    matches: function matches(ele) {
      return ele.isLoop();
    }
  }, {
    selector: ':simple',
    matches: function matches(ele) {
      return ele.isSimple();
    }
  }, {
    selector: ':active',
    matches: function matches(ele) {
      return ele.active();
    }
  }, {
    selector: ':inactive',
    matches: function matches(ele) {
      return !ele.active();
    }
  }, {
    selector: ':backgrounding',
    matches: function matches(ele) {
      return ele.backgrounding();
    }
  }, {
    selector: ':nonbackgrounding',
    matches: function matches(ele) {
      return !ele.backgrounding();
    }
  }].sort(function (a, b) {
    // n.b. selectors that are starting substrings of others must have the longer ones first
    return descending(a.selector, b.selector);
  });
  var lookup = function () {
    var selToFn = {};
    var s;
    for (var i = 0; i < stateSelectors.length; i++) {
      s = stateSelectors[i];
      selToFn[s.selector] = s.matches;
    }
    return selToFn;
  }();
  var stateSelectorMatches = function stateSelectorMatches(sel, ele) {
    return lookup[sel](ele);
  };
  var stateSelectorRegex = '(' + stateSelectors.map(function (s) {
    return s.selector;
  }).join('|') + ')';

  // when a token like a variable has escaped meta characters, we need to clean the backslashes out
  // so that values get compared properly in Selector.filter()
  var cleanMetaChars = function cleanMetaChars(str) {
    return str.replace(new RegExp('\\\\(' + tokens.metaChar + ')', 'g'), function (match, $1) {
      return $1;
    });
  };
  var replaceLastQuery = function replaceLastQuery(selector, examiningQuery, replacementQuery) {
    selector[selector.length - 1] = replacementQuery;
  };

  // NOTE: add new expression syntax here to have it recognised by the parser;
  // - a query contains all adjacent (i.e. no separator in between) expressions;
  // - the current query is stored in selector[i]
  // - you need to check the query objects in match() for it actually filter properly, but that's pretty straight forward
  var exprs = [{
    name: 'group',
    // just used for identifying when debugging
    query: true,
    regex: '(' + tokens.group + ')',
    populate: function populate(selector, query, _ref) {
      var _ref2 = _slicedToArray(_ref, 1),
        group = _ref2[0];
      query.checks.push({
        type: Type.GROUP,
        value: group === '*' ? group : group + 's'
      });
    }
  }, {
    name: 'state',
    query: true,
    regex: stateSelectorRegex,
    populate: function populate(selector, query, _ref3) {
      var _ref4 = _slicedToArray(_ref3, 1),
        state = _ref4[0];
      query.checks.push({
        type: Type.STATE,
        value: state
      });
    }
  }, {
    name: 'id',
    query: true,
    regex: '\\#(' + tokens.id + ')',
    populate: function populate(selector, query, _ref5) {
      var _ref6 = _slicedToArray(_ref5, 1),
        id = _ref6[0];
      query.checks.push({
        type: Type.ID,
        value: cleanMetaChars(id)
      });
    }
  }, {
    name: 'className',
    query: true,
    regex: '\\.(' + tokens.className + ')',
    populate: function populate(selector, query, _ref7) {
      var _ref8 = _slicedToArray(_ref7, 1),
        className = _ref8[0];
      query.checks.push({
        type: Type.CLASS,
        value: cleanMetaChars(className)
      });
    }
  }, {
    name: 'dataExists',
    query: true,
    regex: '\\[\\s*(' + tokens.variable + ')\\s*\\]',
    populate: function populate(selector, query, _ref9) {
      var _ref10 = _slicedToArray(_ref9, 1),
        variable = _ref10[0];
      query.checks.push({
        type: Type.DATA_EXIST,
        field: cleanMetaChars(variable)
      });
    }
  }, {
    name: 'dataCompare',
    query: true,
    regex: '\\[\\s*(' + tokens.variable + ')\\s*(' + tokens.comparatorOp + ')\\s*(' + tokens.value + ')\\s*\\]',
    populate: function populate(selector, query, _ref11) {
      var _ref12 = _slicedToArray(_ref11, 3),
        variable = _ref12[0],
        comparatorOp = _ref12[1],
        value = _ref12[2];
      var valueIsString = new RegExp('^' + tokens.string + '$').exec(value) != null;
      if (valueIsString) {
        value = value.substring(1, value.length - 1);
      } else {
        value = parseFloat(value);
      }
      query.checks.push({
        type: Type.DATA_COMPARE,
        field: cleanMetaChars(variable),
        operator: comparatorOp,
        value: value
      });
    }
  }, {
    name: 'dataBool',
    query: true,
    regex: '\\[\\s*(' + tokens.boolOp + ')\\s*(' + tokens.variable + ')\\s*\\]',
    populate: function populate(selector, query, _ref13) {
      var _ref14 = _slicedToArray(_ref13, 2),
        boolOp = _ref14[0],
        variable = _ref14[1];
      query.checks.push({
        type: Type.DATA_BOOL,
        field: cleanMetaChars(variable),
        operator: boolOp
      });
    }
  }, {
    name: 'metaCompare',
    query: true,
    regex: '\\[\\[\\s*(' + tokens.meta + ')\\s*(' + tokens.comparatorOp + ')\\s*(' + tokens.number + ')\\s*\\]\\]',
    populate: function populate(selector, query, _ref15) {
      var _ref16 = _slicedToArray(_ref15, 3),
        meta = _ref16[0],
        comparatorOp = _ref16[1],
        number = _ref16[2];
      query.checks.push({
        type: Type.META_COMPARE,
        field: cleanMetaChars(meta),
        operator: comparatorOp,
        value: parseFloat(number)
      });
    }
  }, {
    name: 'nextQuery',
    separator: true,
    regex: tokens.separator,
    populate: function populate(selector, query) {
      var currentSubject = selector.currentSubject;
      var edgeCount = selector.edgeCount;
      var compoundCount = selector.compoundCount;
      var lastQ = selector[selector.length - 1];
      if (currentSubject != null) {
        lastQ.subject = currentSubject;
        selector.currentSubject = null;
      }
      lastQ.edgeCount = edgeCount;
      lastQ.compoundCount = compoundCount;
      selector.edgeCount = 0;
      selector.compoundCount = 0;

      // go on to next query
      var nextQuery = selector[selector.length++] = newQuery();
      return nextQuery; // this is the new query to be filled by the following exprs
    }
  }, {
    name: 'directedEdge',
    separator: true,
    regex: tokens.directedEdge,
    populate: function populate(selector, query) {
      if (selector.currentSubject == null) {
        // undirected edge
        var edgeQuery = newQuery();
        var source = query;
        var target = newQuery();
        edgeQuery.checks.push({
          type: Type.DIRECTED_EDGE,
          source: source,
          target: target
        });

        // the query in the selector should be the edge rather than the source
        replaceLastQuery(selector, query, edgeQuery);
        selector.edgeCount++;

        // we're now populating the target query with expressions that follow
        return target;
      } else {
        // source/target
        var srcTgtQ = newQuery();
        var _source = query;
        var _target = newQuery();
        srcTgtQ.checks.push({
          type: Type.NODE_SOURCE,
          source: _source,
          target: _target
        });

        // the query in the selector should be the neighbourhood rather than the node
        replaceLastQuery(selector, query, srcTgtQ);
        selector.edgeCount++;
        return _target; // now populating the target with the following expressions
      }
    }
  }, {
    name: 'undirectedEdge',
    separator: true,
    regex: tokens.undirectedEdge,
    populate: function populate(selector, query) {
      if (selector.currentSubject == null) {
        // undirected edge
        var edgeQuery = newQuery();
        var source = query;
        var target = newQuery();
        edgeQuery.checks.push({
          type: Type.UNDIRECTED_EDGE,
          nodes: [source, target]
        });

        // the query in the selector should be the edge rather than the source
        replaceLastQuery(selector, query, edgeQuery);
        selector.edgeCount++;

        // we're now populating the target query with expressions that follow
        return target;
      } else {
        // neighbourhood
        var nhoodQ = newQuery();
        var node = query;
        var neighbor = newQuery();
        nhoodQ.checks.push({
          type: Type.NODE_NEIGHBOR,
          node: node,
          neighbor: neighbor
        });

        // the query in the selector should be the neighbourhood rather than the node
        replaceLastQuery(selector, query, nhoodQ);
        return neighbor; // now populating the neighbor with following expressions
      }
    }
  }, {
    name: 'child',
    separator: true,
    regex: tokens.child,
    populate: function populate(selector, query) {
      if (selector.currentSubject == null) {
        // default: child query
        var parentChildQuery = newQuery();
        var child = newQuery();
        var parent = selector[selector.length - 1];
        parentChildQuery.checks.push({
          type: Type.CHILD,
          parent: parent,
          child: child
        });

        // the query in the selector should be the '>' itself
        replaceLastQuery(selector, query, parentChildQuery);
        selector.compoundCount++;

        // we're now populating the child query with expressions that follow
        return child;
      } else if (selector.currentSubject === query) {
        // compound split query
        var compound = newQuery();
        var left = selector[selector.length - 1];
        var right = newQuery();
        var subject = newQuery();
        var _child = newQuery();
        var _parent = newQuery();

        // set up the root compound q
        compound.checks.push({
          type: Type.COMPOUND_SPLIT,
          left: left,
          right: right,
          subject: subject
        });

        // populate the subject and replace the q at the old spot (within left) with TRUE
        subject.checks = query.checks; // take the checks from the left
        query.checks = [{
          type: Type.TRUE
        }]; // checks under left refs the subject implicitly

        // set up the right q
        _parent.checks.push({
          type: Type.TRUE
        }); // parent implicitly refs the subject
        right.checks.push({
          type: Type.PARENT,
          // type is swapped on right side queries
          parent: _parent,
          child: _child // empty for now
        });

        replaceLastQuery(selector, left, compound);

        // update the ref since we moved things around for `query`
        selector.currentSubject = subject;
        selector.compoundCount++;
        return _child; // now populating the right side's child
      } else {
        // parent query
        // info for parent query
        var _parent2 = newQuery();
        var _child2 = newQuery();
        var pcQChecks = [{
          type: Type.PARENT,
          parent: _parent2,
          child: _child2
        }];

        // the parent-child query takes the place of the query previously being populated
        _parent2.checks = query.checks; // the previous query contains the checks for the parent
        query.checks = pcQChecks; // pc query takes over

        selector.compoundCount++;
        return _child2; // we're now populating the child
      }
    }
  }, {
    name: 'descendant',
    separator: true,
    regex: tokens.descendant,
    populate: function populate(selector, query) {
      if (selector.currentSubject == null) {
        // default: descendant query
        var ancChQuery = newQuery();
        var descendant = newQuery();
        var ancestor = selector[selector.length - 1];
        ancChQuery.checks.push({
          type: Type.DESCENDANT,
          ancestor: ancestor,
          descendant: descendant
        });

        // the query in the selector should be the '>' itself
        replaceLastQuery(selector, query, ancChQuery);
        selector.compoundCount++;

        // we're now populating the descendant query with expressions that follow
        return descendant;
      } else if (selector.currentSubject === query) {
        // compound split query
        var compound = newQuery();
        var left = selector[selector.length - 1];
        var right = newQuery();
        var subject = newQuery();
        var _descendant = newQuery();
        var _ancestor = newQuery();

        // set up the root compound q
        compound.checks.push({
          type: Type.COMPOUND_SPLIT,
          left: left,
          right: right,
          subject: subject
        });

        // populate the subject and replace the q at the old spot (within left) with TRUE
        subject.checks = query.checks; // take the checks from the left
        query.checks = [{
          type: Type.TRUE
        }]; // checks under left refs the subject implicitly

        // set up the right q
        _ancestor.checks.push({
          type: Type.TRUE
        }); // ancestor implicitly refs the subject
        right.checks.push({
          type: Type.ANCESTOR,
          // type is swapped on right side queries
          ancestor: _ancestor,
          descendant: _descendant // empty for now
        });

        replaceLastQuery(selector, left, compound);

        // update the ref since we moved things around for `query`
        selector.currentSubject = subject;
        selector.compoundCount++;
        return _descendant; // now populating the right side's descendant
      } else {
        // ancestor query
        // info for parent query
        var _ancestor2 = newQuery();
        var _descendant2 = newQuery();
        var adQChecks = [{
          type: Type.ANCESTOR,
          ancestor: _ancestor2,
          descendant: _descendant2
        }];

        // the parent-child query takes the place of the query previously being populated
        _ancestor2.checks = query.checks; // the previous query contains the checks for the parent
        query.checks = adQChecks; // pc query takes over

        selector.compoundCount++;
        return _descendant2; // we're now populating the child
      }
    }
  }, {
    name: 'subject',
    modifier: true,
    regex: tokens.subject,
    populate: function populate(selector, query) {
      if (selector.currentSubject != null && selector.currentSubject !== query) {
        warn('Redefinition of subject in selector `' + selector.toString() + '`');
        return false;
      }
      selector.currentSubject = query;
      var topQ = selector[selector.length - 1];
      var topChk = topQ.checks[0];
      var topType = topChk == null ? null : topChk.type;
      if (topType === Type.DIRECTED_EDGE) {
        // directed edge with subject on the target

        // change to target node check
        topChk.type = Type.NODE_TARGET;
      } else if (topType === Type.UNDIRECTED_EDGE) {
        // undirected edge with subject on the second node

        // change to neighbor check
        topChk.type = Type.NODE_NEIGHBOR;
        topChk.node = topChk.nodes[1]; // second node is subject
        topChk.neighbor = topChk.nodes[0];

        // clean up unused fields for new type
        topChk.nodes = null;
      }
    }
  }];
  exprs.forEach(function (e) {
    return e.regexObj = new RegExp('^' + e.regex);
  });

  /**
   * 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 }`
   */
  var consumeExpr = function consumeExpr(remaining) {
    var expr;
    var match;
    var name;
    for (var j = 0; j < exprs.length; j++) {
      var e = exprs[j];
      var n = e.name;
      var m = remaining.match(e.regexObj);
      if (m != null) {
        match = m;
        expr = e;
        name = n;
        var consumed = m[0];
        remaining = remaining.substring(consumed.length);
        break; // we've consumed one expr, so we can return now
      }
    }

    return {
      expr: expr,
      match: match,
      name: name,
      remaining: remaining
    };
  };

  /**
   * Consume all the leading whitespace
   * @param {string} remaining The text to consume
   * @returns The text with the leading whitespace removed
   */
  var consumeWhitespace = function consumeWhitespace(remaining) {
    var match = remaining.match(/^\s+/);
    if (match) {
      var consumed = match[0];
      remaining = remaining.substring(consumed.length);
    }
    return remaining;
  };

  /**
   * Parse the string and store the parsed representation in the Selector.
   * @param {string} selector The selector string
   * @returns `true` if the selector was successfully parsed, `false` otherwise
   */
  var parse = function parse(selector) {
    var self = this;
    var remaining = self.inputText = selector;
    var currentQuery = self[0] = newQuery();
    self.length = 1;
    remaining = consumeWhitespace(remaining); // get rid of leading whitespace

    for (;;) {
      var exprInfo = consumeExpr(remaining);
      if (exprInfo.expr == null) {
        warn('The selector `' + selector + '`is invalid');
        return false;
      } else {
        var args = exprInfo.match.slice(1);

        // let the token populate the selector object in currentQuery
        var ret = exprInfo.expr.populate(self, currentQuery, args);
        if (ret === false) {
          return false; // exit if population failed
        } else if (ret != null) {
          currentQuery = ret; // change the current query to be filled if the expr specifies
        }
      }

      remaining = exprInfo.remaining;

      // we're done when there's nothing left to parse
      if (remaining.match(/^\s*$/)) {
        break;
      }
    }
    var lastQ = self[self.length - 1];
    if (self.currentSubject != null) {
      lastQ.subject = self.currentSubject;
    }
    lastQ.edgeCount = self.edgeCount;
    lastQ.compoundCount = self.compoundCount;
    for (var i = 0; i < self.length; i++) {
      var q = self[i];

      // in future, this could potentially be allowed if there were operator precedence and detection of invalid combinations
      if (q.compoundCount > 0 && q.edgeCount > 0) {
        warn('The selector `' + selector + '` is invalid because it uses both a compound selector and an edge selector');
        return false;
      }
      if (q.edgeCount > 1) {
        warn('The selector `' + selector + '` is invalid because it uses multiple edge selectors');
        return false;
      } else if (q.edgeCount === 1) {
        warn('The selector `' + selector + '` is deprecated.  Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons.  Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.');
      }
    }
    return true; // success
  };

  /**
   * Get the selector represented as a string.  This value uses default formatting,
   * so things like spacing may differ from the input text passed to the constructor.
   * @returns {string} The selector string
   */
  var toString = function toString() {
    if (this.toStringCache != null) {
      return this.toStringCache;
    }
    var clean = function clean(obj) {
      if (obj == null) {
        return '';
      } else {
        return obj;
      }
    };
    var cleanVal = function cleanVal(val) {
      if (string(val)) {
        return '"' + val + '"';
      } else {
        return clean(val);
      }
    };
    var space = function space(val) {
      return ' ' + val + ' ';
    };
    var checkToString = function checkToString(check, subject) {
      var type = check.type,
        value = check.value;
      switch (type) {
        case Type.GROUP:
          {
            var group = clean(value);
            return group.substring(0, group.length - 1);
          }
        case Type.DATA_COMPARE:
          {
            var field = check.field,
              operator = check.operator;
            return '[' + field + space(clean(operator)) + cleanVal(value) + ']';
          }
        case Type.DATA_BOOL:
          {
            var _operator = check.operator,
              _field = check.field;
            return '[' + clean(_operator) + _field + ']';
          }
        case Type.DATA_EXIST:
          {
            var _field2 = check.field;
            return '[' + _field2 + ']';
          }
        case Type.META_COMPARE:
          {
            var _operator2 = check.operator,
              _field3 = check.field;
            return '[[' + _field3 + space(clean(_operator2)) + cleanVal(value) + ']]';
          }
        case Type.STATE:
          {
            return value;
          }
        case Type.ID:
          {
            return '#' + value;
          }
        case Type.CLASS:
          {
            return '.' + value;
          }
        case Type.PARENT:
        case Type.CHILD:
          {
            return queryToString(check.parent, subject) + space('>') + queryToString(check.child, subject);
          }
        case Type.ANCESTOR:
        case Type.DESCENDANT:
          {
            return queryToString(check.ancestor, subject) + ' ' + queryToString(check.descendant, subject);
          }
        case Type.COMPOUND_SPLIT:
          {
            var lhs = queryToString(check.left, subject);
            var sub = queryToString(check.subject, subject);
            var rhs = queryToString(check.right, subject);
            return lhs + (lhs.length > 0 ? ' ' : '') + sub + rhs;
          }
        case Type.TRUE:
          {
            return '';
          }
      }
    };
    var queryToString = function queryToString(query, subject) {
      return query.checks.reduce(function (str, chk, i) {
        return str + (subject === query && i === 0 ? '$' : '') + checkToString(chk, subject);
      }, '');
    };
    var str = '';
    for (var i = 0; i < this.length; i++) {
      var query = this[i];
      str += queryToString(query, query.subject);
      if (this.length > 1 && i < this.length - 1) {
        str += ', ';
      }
    }
    this.toStringCache = str;
    return str;
  };
  var parse$1 = {
    parse: parse,
    toString: toString
  };

  var valCmp = function valCmp(fieldVal, operator, value) {
    var matches;
    var isFieldStr = string(fieldVal);
    var isFieldNum = number$1(fieldVal);
    var isValStr = string(value);
    var fieldStr, valStr;
    var caseInsensitive = false;
    var notExpr = false;
    var isIneqCmp = false;
    if (operator.indexOf('!') >= 0) {
      operator = operator.replace('!', '');
      notExpr = true;
    }
    if (operator.indexOf('@') >= 0) {
      operator = operator.replace('@', '');
      caseInsensitive = true;
    }
    if (isFieldStr || isValStr || caseInsensitive) {
      fieldStr = !isFieldStr && !isFieldNum ? '' : '' + fieldVal;
      valStr = '' + value;
    }

    // if we're doing a case insensitive comparison, then we're using a STRING comparison
    // even if we're comparing numbers
    if (caseInsensitive) {
      fieldVal = fieldStr = fieldStr.toLowerCase();
      value = valStr = valStr.toLowerCase();
    }
    switch (operator) {
      case '*=':
        matches = fieldStr.indexOf(valStr) >= 0;
        break;
      case '$=':
        matches = fieldStr.indexOf(valStr, fieldStr.length - valStr.length) >= 0;
        break;
      case '^=':
        matches = fieldStr.indexOf(valStr) === 0;
        break;
      case '=':
        matches = fieldVal === value;
        break;
      case '>':
        isIneqCmp = true;
        matches = fieldVal > value;
        break;
      case '>=':
        isIneqCmp = true;
        matches = fieldVal >= value;
        break;
      case '<':
        isIneqCmp = true;
        matches = fieldVal < value;
        break;
      case '<=':
        isIneqCmp = true;
        matches = fieldVal <= value;
        break;
      default:
        matches = false;
        break;
    }

    // apply the not op, but null vals for inequalities should always stay non-matching
    if (notExpr && (fieldVal != null || !isIneqCmp)) {
      matches = !matches;
    }
    return matches;
  };
  var boolCmp = function boolCmp(fieldVal, operator) {
    switch (operator) {
      case '?':
        return fieldVal ? true : false;
      case '!':
        return fieldVal ? false : true;
      case '^':
        return fieldVal === undefined;
    }
  };
  var existCmp = function existCmp(fieldVal) {
    return fieldVal !== undefined;
  };
  var data$1 = function data(ele, field) {
    return ele.data(field);
  };
  var meta = function meta(ele, field) {
    return ele[field]();
  };

  /** A lookup of `match(check, ele)` functions by `Type` int */
  var match = [];

  /**
   * Returns whether the query matches for the element
   * @param query The `{ type, value, ... }` query object
   * @param ele The element to compare against
  */
  var matches$1 = function matches(query, ele) {
    return query.checks.every(function (chk) {
      return match[chk.type](chk, ele);
    });
  };
  match[Type.GROUP] = function (check, ele) {
    var group = check.value;
    return group === '*' || group === ele.group();
  };
  match[Type.STATE] = function (check, ele) {
    var stateSelector = check.value;
    return stateSelectorMatches(stateSelector, ele);
  };
  match[Type.ID] = function (check, ele) {
    var id = check.value;
    return ele.id() === id;
  };
  match[Type.CLASS] = function (check, ele) {
    var cls = check.value;
    return ele.hasClass(cls);
  };
  match[Type.META_COMPARE] = function (check, ele) {
    var field = check.field,
      operator = check.operator,
      value = check.value;
    return valCmp(meta(ele, field), operator, value);
  };
  match[Type.DATA_COMPARE] = function (check, ele) {
    var field = check.field,
      operator = check.operator,
      value = check.value;
    return valCmp(data$1(ele, field), operator, value);
  };
  match[Type.DATA_BOOL] = function (check, ele) {
    var field = check.field,
      operator = check.operator;
    return boolCmp(data$1(ele, field), operator);
  };
  match[Type.DATA_EXIST] = function (check, ele) {
    var field = check.field;
      check.operator;
    return existCmp(data$1(ele, field));
  };
  match[Type.UNDIRECTED_EDGE] = function (check, ele) {
    var qA = check.nodes[0];
    var qB = check.nodes[1];
    var src = ele.source();
    var tgt = ele.target();
    return matches$1(qA, src) && matches$1(qB, tgt) || matches$1(qB, src) && matches$1(qA, tgt);
  };
  match[Type.NODE_NEIGHBOR] = function (check, ele) {
    return matches$1(check.node, ele) && ele.neighborhood().some(function (n) {
      return n.isNode() && matches$1(check.neighbor, n);
    });
  };
  match[Type.DIRECTED_EDGE] = function (check, ele) {
    return matches$1(check.source, ele.source()) && matches$1(check.target, ele.target());
  };
  match[Type.NODE_SOURCE] = function (check, ele) {
    return matches$1(check.source, ele) && ele.outgoers().some(function (n) {
      return n.isNode() && matches$1(check.target, n);
    });
  };
  match[Type.NODE_TARGET] = function (check, ele) {
    return matches$1(check.target, ele) && ele.incomers().some(function (n) {
      return n.isNode() && matches$1(check.source, n);
    });
  };
  match[Type.CHILD] = function (check, ele) {
    return matches$1(check.child, ele) && matches$1(check.parent, ele.parent());
  };
  match[Type.PARENT] = function (check, ele) {
    return matches$1(check.parent, ele) && ele.children().some(function (c) {
      return matches$1(check.child, c);
    });
  };
  match[Type.DESCENDANT] = function (check, ele) {
    return matches$1(check.descendant, ele) && ele.ancestors().some(function (a) {
      return matches$1(check.ancestor, a);
    });
  };
  match[Type.ANCESTOR] = function (check, ele) {
    return matches$1(check.ancestor, ele) && ele.descendants().some(function (d) {
      return matches$1(check.descendant, d);
    });
  };
  match[Type.COMPOUND_SPLIT] = function (check, ele) {
    return matches$1(check.subject, ele) && matches$1(check.left, ele) && matches$1(check.right, ele);
  };
  match[Type.TRUE] = function () {
    return true;
  };
  match[Type.COLLECTION] = function (check, ele) {
    var collection = check.value;
    return collection.has(ele);
  };
  match[Type.FILTER] = function (check, ele) {
    var filter = check.value;
    return filter(ele);
  };

  // filter an existing collection
  var filter = function filter(collection) {
    var self = this;

    // for 1 id #foo queries, just get the element
    if (self.length === 1 && self[0].checks.length === 1 && self[0].checks[0].type === Type.ID) {
      return collection.getElementById(self[0].checks[0].value).collection();
    }
    var selectorFunction = function selectorFunction(element) {
      for (var j = 0; j < self.length; j++) {
        var query = self[j];
        if (matches$1(query, element)) {
          return true;
        }
      }
      return false;
    };
    if (self.text() == null) {
      selectorFunction = function selectorFunction() {
        return true;
      };
    }
    return collection.filter(selectorFunction);
  }; // filter

  // does selector match a single element?
  var matches = function matches(ele) {
    var self = this;
    for (var j = 0; j < self.length; j++) {
      var query = self[j];
      if (matches$1(query, ele)) {
        return true;
      }
    }
    return false;
  }; // matches

  var matching = {
    matches: matches,
    filter: filter
  };

  var Selector = function Selector(selector) {
    this.inputText = selector;
    this.currentSubject = null;
    this.compoundCount = 0;
    this.edgeCount = 0;
    this.length = 0;
    if (selector == null || string(selector) && selector.match(/^\s*$/)) ; else if (elementOrCollection(selector)) {
      this.addQuery({
        checks: [{
          type: Type.COLLECTION,
          value: selector.collection()
        }]
      });
    } else if (fn$6(selector)) {
      this.addQuery({
        checks: [{
          type: Type.FILTER,
          value: selector
        }]
      });
    } else if (string(selector)) {
      if (!this.parse(selector)) {
        this.invalid = true;
      }
    } else {
      error('A selector must be created from a string; found ');
    }
  };
  var selfn = Selector.prototype;
  [parse$1, matching].forEach(function (p) {
    return extend(selfn, p);
  });
  selfn.text = function () {
    return this.inputText;
  };
  selfn.size = function () {
    return this.length;
  };
  selfn.eq = function (i) {
    return this[i];
  };
  selfn.sameText = function (otherSel) {
    return !this.invalid && !otherSel.invalid && this.text() === otherSel.text();
  };
  selfn.addQuery = function (q) {
    this[this.length++] = q;
  };
  selfn.selector = selfn.toString;

  var elesfn$g = {
    allAre: function allAre(selector) {
      var selObj = new Selector(selector);
      return this.every(function (ele) {
        return selObj.matches(ele);
      });
    },
    is: function is(selector) {
      var selObj = new Selector(selector);
      return this.some(function (ele) {
        return selObj.matches(ele);
      });
    },
    some: function some(fn, thisArg) {
      for (var i = 0; i < this.length; i++) {
        var ret = !thisArg ? fn(this[i], i, this) : fn.apply(thisArg, [this[i], i, this]);
        if (ret) {
          return true;
        }
      }
      return false;
    },
    every: function every(fn, thisArg) {
      for (var i = 0; i < this.length; i++) {
        var ret = !thisArg ? fn(this[i], i, this) : fn.apply(thisArg, [this[i], i, this]);
        if (!ret) {
          return false;
        }
      }
      return true;
    },
    same: function same(collection) {
      // cheap collection ref check
      if (this === collection) {
        return true;
      }
      collection = this.cy().collection(collection);
      var thisLength = this.length;
      var collectionLength = collection.length;

      // cheap length check
      if (thisLength !== collectionLength) {
        return false;
      }

      // cheap element ref check
      if (thisLength === 1) {
        return this[0] === collection[0];
      }
      return this.every(function (ele) {
        return collection.hasElementWithId(ele.id());
      });
    },
    anySame: function anySame(collection) {
      collection = this.cy().collection(collection);
      return this.some(function (ele) {
        return collection.hasElementWithId(ele.id());
      });
    },
    allAreNeighbors: function allAreNeighbors(collection) {
      collection = this.cy().collection(collection);
      var nhood = this.neighborhood();
      return collection.every(function (ele) {
        return nhood.hasElementWithId(ele.id());
      });
    },
    contains: function contains(collection) {
      collection = this.cy().collection(collection);
      var self = this;
      return collection.every(function (ele) {
        return self.hasElementWithId(ele.id());
      });
    }
  };
  elesfn$g.allAreNeighbours = elesfn$g.allAreNeighbors;
  elesfn$g.has = elesfn$g.contains;
  elesfn$g.equal = elesfn$g.equals = elesfn$g.same;

  var cache = function cache(fn, name) {
    return function traversalCache(arg1, arg2, arg3, arg4) {
      var selectorOrEles = arg1;
      var eles = this;
      var key;
      if (selectorOrEles == null) {
        key = '';
      } else if (elementOrCollection(selectorOrEles) && selectorOrEles.length === 1) {
        key = selectorOrEles.id();
      }
      if (eles.length === 1 && key) {
        var _p = eles[0]._private;
        var tch = _p.traversalCache = _p.traversalCache || {};
        var ch = tch[name] = tch[name] || [];
        var hash = hashString(key);
        var cacheHit = ch[hash];
        if (cacheHit) {
          return cacheHit;
        } else {
          return ch[hash] = fn.call(eles, arg1, arg2, arg3, arg4);
        }
      } else {
        return fn.call(eles, arg1, arg2, arg3, arg4);
      }
    };
  };

  var elesfn$f = {
    parent: function parent(selector) {
      var parents = [];

      // optimisation for single ele call
      if (this.length === 1) {
        var parent = this[0]._private.parent;
        if (parent) {
          return parent;
        }
      }
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        var _parent = ele._private.parent;
        if (_parent) {
          parents.push(_parent);
        }
      }
      return this.spawn(parents, true).filter(selector);
    },
    parents: function parents(selector) {
      var parents = [];
      var eles = this.parent();
      while (eles.nonempty()) {
        for (var i = 0; i < eles.length; i++) {
          var ele = eles[i];
          parents.push(ele);
        }
        eles = eles.parent();
      }
      return this.spawn(parents, true).filter(selector);
    },
    commonAncestors: function commonAncestors(selector) {
      var ancestors;
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        var parents = ele.parents();
        ancestors = ancestors || parents;
        ancestors = ancestors.intersect(parents); // current list must be common with current ele parents set
      }

      return ancestors.filter(selector);
    },
    orphans: function orphans(selector) {
      return this.stdFilter(function (ele) {
        return ele.isOrphan();
      }).filter(selector);
    },
    nonorphans: function nonorphans(selector) {
      return this.stdFilter(function (ele) {
        return ele.isChild();
      }).filter(selector);
    },
    children: cache(function (selector) {
      var children = [];
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        var eleChildren = ele._private.children;
        for (var j = 0; j < eleChildren.length; j++) {
          children.push(eleChildren[j]);
        }
      }
      return this.spawn(children, true).filter(selector);
    }, 'children'),
    siblings: function siblings(selector) {
      return this.parent().children().not(this).filter(selector);
    },
    isParent: function isParent() {
      var ele = this[0];
      if (ele) {
        return ele.isNode() && ele._private.children.length !== 0;
      }
    },
    isChildless: function isChildless() {
      var ele = this[0];
      if (ele) {
        return ele.isNode() && ele._private.children.length === 0;
      }
    },
    isChild: function isChild() {
      var ele = this[0];
      if (ele) {
        return ele.isNode() && ele._private.parent != null;
      }
    },
    isOrphan: function isOrphan() {
      var ele = this[0];
      if (ele) {
        return ele.isNode() && ele._private.parent == null;
      }
    },
    descendants: function descendants(selector) {
      var elements = [];
      function add(eles) {
        for (var i = 0; i < eles.length; i++) {
          var ele = eles[i];
          elements.push(ele);
          if (ele.children().nonempty()) {
            add(ele.children());
          }
        }
      }
      add(this.children());
      return this.spawn(elements, true).filter(selector);
    }
  };
  function forEachCompound(eles, fn, includeSelf, recursiveStep) {
    var q = [];
    var did = new Set$1();
    var cy = eles.cy();
    var hasCompounds = cy.hasCompoundNodes();
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      if (includeSelf) {
        q.push(ele);
      } else if (hasCompounds) {
        recursiveStep(q, did, ele);
      }
    }
    while (q.length > 0) {
      var _ele = q.shift();
      fn(_ele);
      did.add(_ele.id());
      if (hasCompounds) {
        recursiveStep(q, did, _ele);
      }
    }
    return eles;
  }
  function addChildren(q, did, ele) {
    if (ele.isParent()) {
      var children = ele._private.children;
      for (var i = 0; i < children.length; i++) {
        var child = children[i];
        if (!did.has(child.id())) {
          q.push(child);
        }
      }
    }
  }

  // very efficient version of eles.add( eles.descendants() ).forEach()
  // for internal use
  elesfn$f.forEachDown = function (fn) {
    var includeSelf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
    return forEachCompound(this, fn, includeSelf, addChildren);
  };
  function addParent(q, did, ele) {
    if (ele.isChild()) {
      var parent = ele._private.parent;
      if (!did.has(parent.id())) {
        q.push(parent);
      }
    }
  }
  elesfn$f.forEachUp = function (fn) {
    var includeSelf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
    return forEachCompound(this, fn, includeSelf, addParent);
  };
  function addParentAndChildren(q, did, ele) {
    addParent(q, did, ele);
    addChildren(q, did, ele);
  }
  elesfn$f.forEachUpAndDown = function (fn) {
    var includeSelf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
    return forEachCompound(this, fn, includeSelf, addParentAndChildren);
  };

  // aliases
  elesfn$f.ancestors = elesfn$f.parents;

  var fn$5, elesfn$e;
  fn$5 = elesfn$e = {
    data: define.data({
      field: 'data',
      bindingEvent: 'data',
      allowBinding: true,
      allowSetting: true,
      settingEvent: 'data',
      settingTriggersEvent: true,
      triggerFnName: 'trigger',
      allowGetting: true,
      immutableKeys: {
        'id': true,
        'source': true,
        'target': true,
        'parent': true
      },
      updateStyle: true
    }),
    removeData: define.removeData({
      field: 'data',
      event: 'data',
      triggerFnName: 'trigger',
      triggerEvent: true,
      immutableKeys: {
        'id': true,
        'source': true,
        'target': true,
        'parent': true
      },
      updateStyle: true
    }),
    scratch: define.data({
      field: 'scratch',
      bindingEvent: 'scratch',
      allowBinding: true,
      allowSetting: true,
      settingEvent: 'scratch',
      settingTriggersEvent: true,
      triggerFnName: 'trigger',
      allowGetting: true,
      updateStyle: true
    }),
    removeScratch: define.removeData({
      field: 'scratch',
      event: 'scratch',
      triggerFnName: 'trigger',
      triggerEvent: true,
      updateStyle: true
    }),
    rscratch: define.data({
      field: 'rscratch',
      allowBinding: false,
      allowSetting: true,
      settingTriggersEvent: false,
      allowGetting: true
    }),
    removeRscratch: define.removeData({
      field: 'rscratch',
      triggerEvent: false
    }),
    id: function id() {
      var ele = this[0];
      if (ele) {
        return ele._private.data.id;
      }
    }
  };

  // aliases
  fn$5.attr = fn$5.data;
  fn$5.removeAttr = fn$5.removeData;
  var data = elesfn$e;

  var elesfn$d = {};
  function defineDegreeFunction(callback) {
    return function (includeLoops) {
      var self = this;
      if (includeLoops === undefined) {
        includeLoops = true;
      }
      if (self.length === 0) {
        return;
      }
      if (self.isNode() && !self.removed()) {
        var degree = 0;
        var node = self[0];
        var connectedEdges = node._private.edges;
        for (var i = 0; i < connectedEdges.length; i++) {
          var edge = connectedEdges[i];
          if (!includeLoops && edge.isLoop()) {
            continue;
          }
          degree += callback(node, edge);
        }
        return degree;
      } else {
        return;
      }
    };
  }
  extend(elesfn$d, {
    degree: defineDegreeFunction(function (node, edge) {
      if (edge.source().same(edge.target())) {
        return 2;
      } else {
        return 1;
      }
    }),
    indegree: defineDegreeFunction(function (node, edge) {
      if (edge.target().same(node)) {
        return 1;
      } else {
        return 0;
      }
    }),
    outdegree: defineDegreeFunction(function (node, edge) {
      if (edge.source().same(node)) {
        return 1;
      } else {
        return 0;
      }
    })
  });
  function defineDegreeBoundsFunction(degreeFn, callback) {
    return function (includeLoops) {
      var ret;
      var nodes = this.nodes();
      for (var i = 0; i < nodes.length; i++) {
        var ele = nodes[i];
        var degree = ele[degreeFn](includeLoops);
        if (degree !== undefined && (ret === undefined || callback(degree, ret))) {
          ret = degree;
        }
      }
      return ret;
    };
  }
  extend(elesfn$d, {
    minDegree: defineDegreeBoundsFunction('degree', function (degree, min) {
      return degree < min;
    }),
    maxDegree: defineDegreeBoundsFunction('degree', function (degree, max) {
      return degree > max;
    }),
    minIndegree: defineDegreeBoundsFunction('indegree', function (degree, min) {
      return degree < min;
    }),
    maxIndegree: defineDegreeBoundsFunction('indegree', function (degree, max) {
      return degree > max;
    }),
    minOutdegree: defineDegreeBoundsFunction('outdegree', function (degree, min) {
      return degree < min;
    }),
    maxOutdegree: defineDegreeBoundsFunction('outdegree', function (degree, max) {
      return degree > max;
    })
  });
  extend(elesfn$d, {
    totalDegree: function totalDegree(includeLoops) {
      var total = 0;
      var nodes = this.nodes();
      for (var i = 0; i < nodes.length; i++) {
        total += nodes[i].degree(includeLoops);
      }
      return total;
    }
  });

  var fn$4, elesfn$c;
  var beforePositionSet = function beforePositionSet(eles, newPos, silent) {
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      if (!ele.locked()) {
        var oldPos = ele._private.position;
        var delta = {
          x: newPos.x != null ? newPos.x - oldPos.x : 0,
          y: newPos.y != null ? newPos.y - oldPos.y : 0
        };
        if (ele.isParent() && !(delta.x === 0 && delta.y === 0)) {
          ele.children().shift(delta, silent);
        }
        ele.dirtyBoundingBoxCache();
      }
    }
  };
  var positionDef = {
    field: 'position',
    bindingEvent: 'position',
    allowBinding: true,
    allowSetting: true,
    settingEvent: 'position',
    settingTriggersEvent: true,
    triggerFnName: 'emitAndNotify',
    allowGetting: true,
    validKeys: ['x', 'y'],
    beforeGet: function beforeGet(ele) {
      ele.updateCompoundBounds();
    },
    beforeSet: function beforeSet(eles, newPos) {
      beforePositionSet(eles, newPos, false);
    },
    onSet: function onSet(eles) {
      eles.dirtyCompoundBoundsCache();
    },
    canSet: function canSet(ele) {
      return !ele.locked();
    }
  };
  fn$4 = elesfn$c = {
    position: define.data(positionDef),
    // position but no notification to renderer
    silentPosition: define.data(extend({}, positionDef, {
      allowBinding: false,
      allowSetting: true,
      settingTriggersEvent: false,
      allowGetting: false,
      beforeSet: function beforeSet(eles, newPos) {
        beforePositionSet(eles, newPos, true);
      },
      onSet: function onSet(eles) {
        eles.dirtyCompoundBoundsCache();
      }
    })),
    positions: function positions(pos, silent) {
      if (plainObject(pos)) {
        if (silent) {
          this.silentPosition(pos);
        } else {
          this.position(pos);
        }
      } else if (fn$6(pos)) {
        var _fn = pos;
        var cy = this.cy();
        cy.startBatch();
        for (var i = 0; i < this.length; i++) {
          var ele = this[i];
          var _pos = void 0;
          if (_pos = _fn(ele, i)) {
            if (silent) {
              ele.silentPosition(_pos);
            } else {
              ele.position(_pos);
            }
          }
        }
        cy.endBatch();
      }
      return this; // chaining
    },

    silentPositions: function silentPositions(pos) {
      return this.positions(pos, true);
    },
    shift: function shift(dim, val, silent) {
      var delta;
      if (plainObject(dim)) {
        delta = {
          x: number$1(dim.x) ? dim.x : 0,
          y: number$1(dim.y) ? dim.y : 0
        };
        silent = val;
      } else if (string(dim) && number$1(val)) {
        delta = {
          x: 0,
          y: 0
        };
        delta[dim] = val;
      }
      if (delta != null) {
        var cy = this.cy();
        cy.startBatch();
        for (var i = 0; i < this.length; i++) {
          var ele = this[i];

          // exclude any node that is a descendant of the calling collection
          if (cy.hasCompoundNodes() && ele.isChild() && ele.ancestors().anySame(this)) {
            continue;
          }
          var pos = ele.position();
          var newPos = {
            x: pos.x + delta.x,
            y: pos.y + delta.y
          };
          if (silent) {
            ele.silentPosition(newPos);
          } else {
            ele.position(newPos);
          }
        }
        cy.endBatch();
      }
      return this;
    },
    silentShift: function silentShift(dim, val) {
      if (plainObject(dim)) {
        this.shift(dim, true);
      } else if (string(dim) && number$1(val)) {
        this.shift(dim, val, true);
      }
      return this;
    },
    // get/set the rendered (i.e. on screen) positon of the element
    renderedPosition: function renderedPosition(dim, val) {
      var ele = this[0];
      var cy = this.cy();
      var zoom = cy.zoom();
      var pan = cy.pan();
      var rpos = plainObject(dim) ? dim : undefined;
      var setting = rpos !== undefined || val !== undefined && string(dim);
      if (ele && ele.isNode()) {
        // must have an element and must be a node to return position
        if (setting) {
          for (var i = 0; i < this.length; i++) {
            var _ele = this[i];
            if (val !== undefined) {
              // set one dimension
              _ele.position(dim, (val - pan[dim]) / zoom);
            } else if (rpos !== undefined) {
              // set whole position
              _ele.position(renderedToModelPosition(rpos, zoom, pan));
            }
          }
        } else {
          // getting
          var pos = ele.position();
          rpos = modelToRenderedPosition(pos, zoom, pan);
          if (dim === undefined) {
            // then return the whole rendered position
            return rpos;
          } else {
            // then return the specified dimension
            return rpos[dim];
          }
        }
      } else if (!setting) {
        return undefined; // for empty collection case
      }

      return this; // chaining
    },

    // get/set the position relative to the parent
    relativePosition: function relativePosition(dim, val) {
      var ele = this[0];
      var cy = this.cy();
      var ppos = plainObject(dim) ? dim : undefined;
      var setting = ppos !== undefined || val !== undefined && string(dim);
      var hasCompoundNodes = cy.hasCompoundNodes();
      if (ele && ele.isNode()) {
        // must have an element and must be a node to return position
        if (setting) {
          for (var i = 0; i < this.length; i++) {
            var _ele2 = this[i];
            var parent = hasCompoundNodes ? _ele2.parent() : null;
            var hasParent = parent && parent.length > 0;
            var relativeToParent = hasParent;
            if (hasParent) {
              parent = parent[0];
            }
            var origin = relativeToParent ? parent.position() : {
              x: 0,
              y: 0
            };
            if (val !== undefined) {
              // set one dimension
              _ele2.position(dim, val + origin[dim]);
            } else if (ppos !== undefined) {
              // set whole position
              _ele2.position({
                x: ppos.x + origin.x,
                y: ppos.y + origin.y
              });
            }
          }
        } else {
          // getting
          var pos = ele.position();
          var _parent = hasCompoundNodes ? ele.parent() : null;
          var _hasParent = _parent && _parent.length > 0;
          var _relativeToParent = _hasParent;
          if (_hasParent) {
            _parent = _parent[0];
          }
          var _origin = _relativeToParent ? _parent.position() : {
            x: 0,
            y: 0
          };
          ppos = {
            x: pos.x - _origin.x,
            y: pos.y - _origin.y
          };
          if (dim === undefined) {
            // then return the whole rendered position
            return ppos;
          } else {
            // then return the specified dimension
            return ppos[dim];
          }
        }
      } else if (!setting) {
        return undefined; // for empty collection case
      }

      return this; // chaining
    }
  };

  // aliases
  fn$4.modelPosition = fn$4.point = fn$4.position;
  fn$4.modelPositions = fn$4.points = fn$4.positions;
  fn$4.renderedPoint = fn$4.renderedPosition;
  fn$4.relativePoint = fn$4.relativePosition;
  var position = elesfn$c;

  var fn$3, elesfn$b;
  fn$3 = elesfn$b = {};
  elesfn$b.renderedBoundingBox = function (options) {
    var bb = this.boundingBox(options);
    var cy = this.cy();
    var zoom = cy.zoom();
    var pan = cy.pan();
    var x1 = bb.x1 * zoom + pan.x;
    var x2 = bb.x2 * zoom + pan.x;
    var y1 = bb.y1 * zoom + pan.y;
    var y2 = bb.y2 * zoom + pan.y;
    return {
      x1: x1,
      x2: x2,
      y1: y1,
      y2: y2,
      w: x2 - x1,
      h: y2 - y1
    };
  };
  elesfn$b.dirtyCompoundBoundsCache = function () {
    var silent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
    var cy = this.cy();
    if (!cy.styleEnabled() || !cy.hasCompoundNodes()) {
      return this;
    }
    this.forEachUp(function (ele) {
      if (ele.isParent()) {
        var _p = ele._private;
        _p.compoundBoundsClean = false;
        _p.bbCache = null;
        if (!silent) {
          ele.emitAndNotify('bounds');
        }
      }
    });
    return this;
  };
  elesfn$b.updateCompoundBounds = function () {
    var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
    var cy = this.cy();

    // not possible to do on non-compound graphs or with the style disabled
    if (!cy.styleEnabled() || !cy.hasCompoundNodes()) {
      return this;
    }

    // save cycles when batching -- but bounds will be stale (or not exist yet)
    if (!force && cy.batching()) {
      return this;
    }
    function update(parent) {
      if (!parent.isParent()) {
        return;
      }
      var _p = parent._private;
      var children = parent.children();
      var includeLabels = parent.pstyle('compound-sizing-wrt-labels').value === 'include';
      var min = {
        width: {
          val: parent.pstyle('min-width').pfValue,
          left: parent.pstyle('min-width-bias-left'),
          right: parent.pstyle('min-width-bias-right')
        },
        height: {
          val: parent.pstyle('min-height').pfValue,
          top: parent.pstyle('min-height-bias-top'),
          bottom: parent.pstyle('min-height-bias-bottom')
        }
      };
      var bb = children.boundingBox({
        includeLabels: includeLabels,
        includeOverlays: false,
        // updating the compound bounds happens outside of the regular
        // cache cycle (i.e. before fired events)
        useCache: false
      });
      var pos = _p.position;

      // if children take up zero area then keep position and fall back on stylesheet w/h
      if (bb.w === 0 || bb.h === 0) {
        bb = {
          w: parent.pstyle('width').pfValue,
          h: parent.pstyle('height').pfValue
        };
        bb.x1 = pos.x - bb.w / 2;
        bb.x2 = pos.x + bb.w / 2;
        bb.y1 = pos.y - bb.h / 2;
        bb.y2 = pos.y + bb.h / 2;
      }
      function computeBiasValues(propDiff, propBias, propBiasComplement) {
        var biasDiff = 0;
        var biasComplementDiff = 0;
        var biasTotal = propBias + propBiasComplement;
        if (propDiff > 0 && biasTotal > 0) {
          biasDiff = propBias / biasTotal * propDiff;
          biasComplementDiff = propBiasComplement / biasTotal * propDiff;
        }
        return {
          biasDiff: biasDiff,
          biasComplementDiff: biasComplementDiff
        };
      }
      function computePaddingValues(width, height, paddingObject, relativeTo) {
        // Assuming percentage is number from 0 to 1
        if (paddingObject.units === '%') {
          switch (relativeTo) {
            case 'width':
              return width > 0 ? paddingObject.pfValue * width : 0;
            case 'height':
              return height > 0 ? paddingObject.pfValue * height : 0;
            case 'average':
              return width > 0 && height > 0 ? paddingObject.pfValue * (width + height) / 2 : 0;
            case 'min':
              return width > 0 && height > 0 ? width > height ? paddingObject.pfValue * height : paddingObject.pfValue * width : 0;
            case 'max':
              return width > 0 && height > 0 ? width > height ? paddingObject.pfValue * width : paddingObject.pfValue * height : 0;
            default:
              return 0;
          }
        } else if (paddingObject.units === 'px') {
          return paddingObject.pfValue;
        } else {
          return 0;
        }
      }
      var leftVal = min.width.left.value;
      if (min.width.left.units === 'px' && min.width.val > 0) {
        leftVal = leftVal * 100 / min.width.val;
      }
      var rightVal = min.width.right.value;
      if (min.width.right.units === 'px' && min.width.val > 0) {
        rightVal = rightVal * 100 / min.width.val;
      }
      var topVal = min.height.top.value;
      if (min.height.top.units === 'px' && min.height.val > 0) {
        topVal = topVal * 100 / min.height.val;
      }
      var bottomVal = min.height.bottom.value;
      if (min.height.bottom.units === 'px' && min.height.val > 0) {
        bottomVal = bottomVal * 100 / min.height.val;
      }
      var widthBiasDiffs = computeBiasValues(min.width.val - bb.w, leftVal, rightVal);
      var diffLeft = widthBiasDiffs.biasDiff;
      var diffRight = widthBiasDiffs.biasComplementDiff;
      var heightBiasDiffs = computeBiasValues(min.height.val - bb.h, topVal, bottomVal);
      var diffTop = heightBiasDiffs.biasDiff;
      var diffBottom = heightBiasDiffs.biasComplementDiff;
      _p.autoPadding = computePaddingValues(bb.w, bb.h, parent.pstyle('padding'), parent.pstyle('padding-relative-to').value);
      _p.autoWidth = Math.max(bb.w, min.width.val);
      pos.x = (-diffLeft + bb.x1 + bb.x2 + diffRight) / 2;
      _p.autoHeight = Math.max(bb.h, min.height.val);
      pos.y = (-diffTop + bb.y1 + bb.y2 + diffBottom) / 2;
    }
    for (var i = 0; i < this.length; i++) {
      var ele = this[i];
      var _p = ele._private;
      if (!_p.compoundBoundsClean || force) {
        update(ele);
        if (!cy.batching()) {
          _p.compoundBoundsClean = true;
        }
      }
    }
    return this;
  };
  var noninf = function noninf(x) {
    if (x === Infinity || x === -Infinity) {
      return 0;
    }
    return x;
  };
  var updateBounds = function updateBounds(b, x1, y1, x2, y2) {
    // don't update with zero area boxes
    if (x2 - x1 === 0 || y2 - y1 === 0) {
      return;
    }

    // don't update with null dim
    if (x1 == null || y1 == null || x2 == null || y2 == null) {
      return;
    }
    b.x1 = x1 < b.x1 ? x1 : b.x1;
    b.x2 = x2 > b.x2 ? x2 : b.x2;
    b.y1 = y1 < b.y1 ? y1 : b.y1;
    b.y2 = y2 > b.y2 ? y2 : b.y2;
    b.w = b.x2 - b.x1;
    b.h = b.y2 - b.y1;
  };
  var updateBoundsFromBox = function updateBoundsFromBox(b, b2) {
    if (b2 == null) {
      return b;
    }
    return updateBounds(b, b2.x1, b2.y1, b2.x2, b2.y2);
  };
  var prefixedProperty = function prefixedProperty(obj, field, prefix) {
    return getPrefixedProperty(obj, field, prefix);
  };
  var updateBoundsFromArrow = function updateBoundsFromArrow(bounds, ele, prefix) {
    if (ele.cy().headless()) {
      return;
    }
    var _p = ele._private;
    var rstyle = _p.rstyle;
    var halfArW = rstyle.arrowWidth / 2;
    var arrowType = ele.pstyle(prefix + '-arrow-shape').value;
    var x;
    var y;
    if (arrowType !== 'none') {
      if (prefix === 'source') {
        x = rstyle.srcX;
        y = rstyle.srcY;
      } else if (prefix === 'target') {
        x = rstyle.tgtX;
        y = rstyle.tgtY;
      } else {
        x = rstyle.midX;
        y = rstyle.midY;
      }

      // always store the individual arrow bounds
      var bbs = _p.arrowBounds = _p.arrowBounds || {};
      var bb = bbs[prefix] = bbs[prefix] || {};
      bb.x1 = x - halfArW;
      bb.y1 = y - halfArW;
      bb.x2 = x + halfArW;
      bb.y2 = y + halfArW;
      bb.w = bb.x2 - bb.x1;
      bb.h = bb.y2 - bb.y1;
      expandBoundingBox(bb, 1);
      updateBounds(bounds, bb.x1, bb.y1, bb.x2, bb.y2);
    }
  };
  var updateBoundsFromLabel = function updateBoundsFromLabel(bounds, ele, prefix) {
    if (ele.cy().headless()) {
      return;
    }
    var prefixDash;
    if (prefix) {
      prefixDash = prefix + '-';
    } else {
      prefixDash = '';
    }
    var _p = ele._private;
    var rstyle = _p.rstyle;
    var label = ele.pstyle(prefixDash + 'label').strValue;
    if (label) {
      var halign = ele.pstyle('text-halign');
      var valign = ele.pstyle('text-valign');
      var labelWidth = prefixedProperty(rstyle, 'labelWidth', prefix);
      var labelHeight = prefixedProperty(rstyle, 'labelHeight', prefix);
      var labelX = prefixedProperty(rstyle, 'labelX', prefix);
      var labelY = prefixedProperty(rstyle, 'labelY', prefix);
      var marginX = ele.pstyle(prefixDash + 'text-margin-x').pfValue;
      var marginY = ele.pstyle(prefixDash + 'text-margin-y').pfValue;
      var isEdge = ele.isEdge();
      var rotation = ele.pstyle(prefixDash + 'text-rotation');
      var outlineWidth = ele.pstyle('text-outline-width').pfValue;
      var borderWidth = ele.pstyle('text-border-width').pfValue;
      var halfBorderWidth = borderWidth / 2;
      var padding = ele.pstyle('text-background-padding').pfValue;
      var marginOfError = 2; // expand to work around browser dimension inaccuracies

      var lh = labelHeight;
      var lw = labelWidth;
      var lw_2 = lw / 2;
      var lh_2 = lh / 2;
      var lx1, lx2, ly1, ly2;
      if (isEdge) {
        lx1 = labelX - lw_2;
        lx2 = labelX + lw_2;
        ly1 = labelY - lh_2;
        ly2 = labelY + lh_2;
      } else {
        switch (halign.value) {
          case 'left':
            lx1 = labelX - lw;
            lx2 = labelX;
            break;
          case 'center':
            lx1 = labelX - lw_2;
            lx2 = labelX + lw_2;
            break;
          case 'right':
            lx1 = labelX;
            lx2 = labelX + lw;
            break;
        }
        switch (valign.value) {
          case 'top':
            ly1 = labelY - lh;
            ly2 = labelY;
            break;
          case 'center':
            ly1 = labelY - lh_2;
            ly2 = labelY + lh_2;
            break;
          case 'bottom':
            ly1 = labelY;
            ly2 = labelY + lh;
            break;
        }
      }

      // shift by margin and expand by outline and border
      lx1 += marginX - Math.max(outlineWidth, halfBorderWidth) - padding - marginOfError;
      lx2 += marginX + Math.max(outlineWidth, halfBorderWidth) + padding + marginOfError;
      ly1 += marginY - Math.max(outlineWidth, halfBorderWidth) - padding - marginOfError;
      ly2 += marginY + Math.max(outlineWidth, halfBorderWidth) + padding + marginOfError;

      // always store the unrotated label bounds separately
      var bbPrefix = prefix || 'main';
      var bbs = _p.labelBounds;
      var bb = bbs[bbPrefix] = bbs[bbPrefix] || {};
      bb.x1 = lx1;
      bb.y1 = ly1;
      bb.x2 = lx2;
      bb.y2 = ly2;
      bb.w = lx2 - lx1;
      bb.h = ly2 - ly1;
      var isAutorotate = isEdge && rotation.strValue === 'autorotate';
      var isPfValue = rotation.pfValue != null && rotation.pfValue !== 0;
      if (isAutorotate || isPfValue) {
        var theta = isAutorotate ? prefixedProperty(_p.rstyle, 'labelAngle', prefix) : rotation.pfValue;
        var cos = Math.cos(theta);
        var sin = Math.sin(theta);

        // rotation point (default value for center-center)
        var xo = (lx1 + lx2) / 2;
        var yo = (ly1 + ly2) / 2;
        if (!isEdge) {
          switch (halign.value) {
            case 'left':
              xo = lx2;
              break;
            case 'right':
              xo = lx1;
              break;
          }
          switch (valign.value) {
            case 'top':
              yo = ly2;
              break;
            case 'bottom':
              yo = ly1;
              break;
          }
        }
        var rotate = function rotate(x, y) {
          x = x - xo;
          y = y - yo;
          return {
            x: x * cos - y * sin + xo,
            y: x * sin + y * cos + yo
          };
        };
        var px1y1 = rotate(lx1, ly1);
        var px1y2 = rotate(lx1, ly2);
        var px2y1 = rotate(lx2, ly1);
        var px2y2 = rotate(lx2, ly2);
        lx1 = Math.min(px1y1.x, px1y2.x, px2y1.x, px2y2.x);
        lx2 = Math.max(px1y1.x, px1y2.x, px2y1.x, px2y2.x);
        ly1 = Math.min(px1y1.y, px1y2.y, px2y1.y, px2y2.y);
        ly2 = Math.max(px1y1.y, px1y2.y, px2y1.y, px2y2.y);
      }
      var bbPrefixRot = bbPrefix + 'Rot';
      var bbRot = bbs[bbPrefixRot] = bbs[bbPrefixRot] || {};
      bbRot.x1 = lx1;
      bbRot.y1 = ly1;
      bbRot.x2 = lx2;
      bbRot.y2 = ly2;
      bbRot.w = lx2 - lx1;
      bbRot.h = ly2 - ly1;
      updateBounds(bounds, lx1, ly1, lx2, ly2);
      updateBounds(_p.labelBounds.all, lx1, ly1, lx2, ly2);
    }
    return bounds;
  };
  var updateBoundsFromOutline = function updateBoundsFromOutline(bounds, ele) {
    if (ele.cy().headless()) {
      return;
    }
    var outlineOpacity = ele.pstyle('outline-opacity').value;
    var outlineWidth = ele.pstyle('outline-width').value;
    if (outlineOpacity > 0 && outlineWidth > 0) {
      var outlineOffset = ele.pstyle('outline-offset').value;
      var nodeShape = ele.pstyle('shape').value;
      var outlineSize = outlineWidth + outlineOffset;
      var scaleX = (bounds.w + outlineSize * 2) / bounds.w;
      var scaleY = (bounds.h + outlineSize * 2) / bounds.h;
      var xOffset = 0;
      var yOffset = 0;
      if (["diamond", "pentagon", "round-triangle"].includes(nodeShape)) {
        scaleX = (bounds.w + outlineSize * 2.4) / bounds.w;
        yOffset = -outlineSize / 3.6;
      } else if (["concave-hexagon", "rhomboid", "right-rhomboid"].includes(nodeShape)) {
        scaleX = (bounds.w + outlineSize * 2.4) / bounds.w;
      } else if (nodeShape === "star") {
        scaleX = (bounds.w + outlineSize * 2.8) / bounds.w;
        scaleY = (bounds.h + outlineSize * 2.6) / bounds.h;
        yOffset = -outlineSize / 3.8;
      } else if (nodeShape === "triangle") {
        scaleX = (bounds.w + outlineSize * 2.8) / bounds.w;
        scaleY = (bounds.h + outlineSize * 2.4) / bounds.h;
        yOffset = -outlineSize / 1.4;
      } else if (nodeShape === "vee") {
        scaleX = (bounds.w + outlineSize * 4.4) / bounds.w;
        scaleY = (bounds.h + outlineSize * 3.8) / bounds.h;
        yOffset = -outlineSize * .5;
      }
      var hDelta = bounds.h * scaleY - bounds.h;
      var wDelta = bounds.w * scaleX - bounds.w;
      expandBoundingBoxSides(bounds, [Math.ceil(hDelta / 2), Math.ceil(wDelta / 2)]);
      if (xOffset != 0 || yOffset !== 0) {
        var oBounds = shiftBoundingBox(bounds, xOffset, yOffset);
        updateBoundingBox(bounds, oBounds);
      }
    }
  };

  // get the bounding box of the elements (in raw model position)
  var boundingBoxImpl = function boundingBoxImpl(ele, options) {
    var cy = ele._private.cy;
    var styleEnabled = cy.styleEnabled();
    var headless = cy.headless();
    var bounds = makeBoundingBox();
    var _p = ele._private;
    var isNode = ele.isNode();
    var isEdge = ele.isEdge();
    var ex1, ex2, ey1, ey2; // extrema of body / lines
    var x, y; // node pos
    var rstyle = _p.rstyle;
    var manualExpansion = isNode && styleEnabled ? ele.pstyle('bounds-expansion').pfValue : [0];

    // must use `display` prop only, as reading `compound.width()` causes recursion
    // (other factors like width values will be considered later in this function anyway)
    var isDisplayed = function isDisplayed(ele) {
      return ele.pstyle('display').value !== 'none';
    };
    var displayed = !styleEnabled || isDisplayed(ele)

    // must take into account connected nodes b/c of implicit edge hiding on display:none node
    && (!isEdge || isDisplayed(ele.source()) && isDisplayed(ele.target()));
    if (displayed) {
      // displayed suffices, since we will find zero area eles anyway
      var overlayOpacity = 0;
      var overlayPadding = 0;
      if (styleEnabled && options.includeOverlays) {
        overlayOpacity = ele.pstyle('overlay-opacity').value;
        if (overlayOpacity !== 0) {
          overlayPadding = ele.pstyle('overlay-padding').value;
        }
      }
      var underlayOpacity = 0;
      var underlayPadding = 0;
      if (styleEnabled && options.includeUnderlays) {
        underlayOpacity = ele.pstyle('underlay-opacity').value;
        if (underlayOpacity !== 0) {
          underlayPadding = ele.pstyle('underlay-padding').value;
        }
      }
      var padding = Math.max(overlayPadding, underlayPadding);
      var w = 0;
      var wHalf = 0;
      if (styleEnabled) {
        w = ele.pstyle('width').pfValue;
        wHalf = w / 2;
      }
      if (isNode && options.includeNodes) {
        var pos = ele.position();
        x = pos.x;
        y = pos.y;
        var _w = ele.outerWidth();
        var halfW = _w / 2;
        var h = ele.outerHeight();
        var halfH = h / 2;

        // handle node dimensions
        /////////////////////////

        ex1 = x - halfW;
        ex2 = x + halfW;
        ey1 = y - halfH;
        ey2 = y + halfH;
        updateBounds(bounds, ex1, ey1, ex2, ey2);
        if (styleEnabled && options.includeOutlines) {
          updateBoundsFromOutline(bounds, ele);
        }
      } else if (isEdge && options.includeEdges) {
        if (styleEnabled && !headless) {
          var curveStyle = ele.pstyle('curve-style').strValue;

          // handle edge dimensions (rough box estimate)
          //////////////////////////////////////////////

          ex1 = Math.min(rstyle.srcX, rstyle.midX, rstyle.tgtX);
          ex2 = Math.max(rstyle.srcX, rstyle.midX, rstyle.tgtX);
          ey1 = Math.min(rstyle.srcY, rstyle.midY, rstyle.tgtY);
          ey2 = Math.max(rstyle.srcY, rstyle.midY, rstyle.tgtY);

          // take into account edge width
          ex1 -= wHalf;
          ex2 += wHalf;
          ey1 -= wHalf;
          ey2 += wHalf;
          updateBounds(bounds, ex1, ey1, ex2, ey2);

          // precise edges
          ////////////////

          if (curveStyle === 'haystack') {
            var hpts = rstyle.haystackPts;
            if (hpts && hpts.length === 2) {
              ex1 = hpts[0].x;
              ey1 = hpts[0].y;
              ex2 = hpts[1].x;
              ey2 = hpts[1].y;
              if (ex1 > ex2) {
                var temp = ex1;
                ex1 = ex2;
                ex2 = temp;
              }
              if (ey1 > ey2) {
                var _temp = ey1;
                ey1 = ey2;
                ey2 = _temp;
              }
              updateBounds(bounds, ex1 - wHalf, ey1 - wHalf, ex2 + wHalf, ey2 + wHalf);
            }
          } else if (curveStyle === 'bezier' || curveStyle === 'unbundled-bezier' || curveStyle === 'segments' || curveStyle === 'taxi') {
            var pts;
            switch (curveStyle) {
              case 'bezier':
              case 'unbundled-bezier':
                pts = rstyle.bezierPts;
                break;
              case 'segments':
              case 'taxi':
                pts = rstyle.linePts;
                break;
            }
            if (pts != null) {
              for (var j = 0; j < pts.length; j++) {
                var pt = pts[j];
                ex1 = pt.x - wHalf;
                ex2 = pt.x + wHalf;
                ey1 = pt.y - wHalf;
                ey2 = pt.y + wHalf;
                updateBounds(bounds, ex1, ey1, ex2, ey2);
              }
            }
          } // bezier-like or segment-like edge
        } else {
          // headless or style disabled

          // fallback on source and target positions
          //////////////////////////////////////////

          var n1 = ele.source();
          var n1pos = n1.position();
          var n2 = ele.target();
          var n2pos = n2.position();
          ex1 = n1pos.x;
          ex2 = n2pos.x;
          ey1 = n1pos.y;
          ey2 = n2pos.y;
          if (ex1 > ex2) {
            var _temp2 = ex1;
            ex1 = ex2;
            ex2 = _temp2;
          }
          if (ey1 > ey2) {
            var _temp3 = ey1;
            ey1 = ey2;
            ey2 = _temp3;
          }

          // take into account edge width
          ex1 -= wHalf;
          ex2 += wHalf;
          ey1 -= wHalf;
          ey2 += wHalf;
          updateBounds(bounds, ex1, ey1, ex2, ey2);
        } // headless or style disabled
      } // edges

      // handle edge arrow size
      /////////////////////////

      if (styleEnabled && options.includeEdges && isEdge) {
        updateBoundsFromArrow(bounds, ele, 'mid-source');
        updateBoundsFromArrow(bounds, ele, 'mid-target');
        updateBoundsFromArrow(bounds, ele, 'source');
        updateBoundsFromArrow(bounds, ele, 'target');
      }

      // ghost
      ////////

      if (styleEnabled) {
        var ghost = ele.pstyle('ghost').value === 'yes';
        if (ghost) {
          var gx = ele.pstyle('ghost-offset-x').pfValue;
          var gy = ele.pstyle('ghost-offset-y').pfValue;
          updateBounds(bounds, bounds.x1 + gx, bounds.y1 + gy, bounds.x2 + gx, bounds.y2 + gy);
        }
      }

      // always store the body bounds separately from the labels
      var bbBody = _p.bodyBounds = _p.bodyBounds || {};
      assignBoundingBox(bbBody, bounds);
      expandBoundingBoxSides(bbBody, manualExpansion);
      expandBoundingBox(bbBody, 1); // expand to work around browser dimension inaccuracies

      // overlay
      //////////

      if (styleEnabled) {
        ex1 = bounds.x1;
        ex2 = bounds.x2;
        ey1 = bounds.y1;
        ey2 = bounds.y2;
        updateBounds(bounds, ex1 - padding, ey1 - padding, ex2 + padding, ey2 + padding);
      }

      // always store the body bounds separately from the labels
      var bbOverlay = _p.overlayBounds = _p.overlayBounds || {};
      assignBoundingBox(bbOverlay, bounds);
      expandBoundingBoxSides(bbOverlay, manualExpansion);
      expandBoundingBox(bbOverlay, 1); // expand to work around browser dimension inaccuracies

      // handle label dimensions
      //////////////////////////

      var bbLabels = _p.labelBounds = _p.labelBounds || {};
      if (bbLabels.all != null) {
        clearBoundingBox(bbLabels.all);
      } else {
        bbLabels.all = makeBoundingBox();
      }
      if (styleEnabled && options.includeLabels) {
        if (options.includeMainLabels) {
          updateBoundsFromLabel(bounds, ele, null);
        }
        if (isEdge) {
          if (options.includeSourceLabels) {
            updateBoundsFromLabel(bounds, ele, 'source');
          }
          if (options.includeTargetLabels) {
            updateBoundsFromLabel(bounds, ele, 'target');
          }
        }
      } // style enabled for labels
    } // if displayed

    bounds.x1 = noninf(bounds.x1);
    bounds.y1 = noninf(bounds.y1);
    bounds.x2 = noninf(bounds.x2);
    bounds.y2 = noninf(bounds.y2);
    bounds.w = noninf(bounds.x2 - bounds.x1);
    bounds.h = noninf(bounds.y2 - bounds.y1);
    if (bounds.w > 0 && bounds.h > 0 && displayed) {
      expandBoundingBoxSides(bounds, manualExpansion);

      // expand bounds by 1 because antialiasing can increase the visual/effective size by 1 on all sides
      expandBoundingBox(bounds, 1);
    }
    return bounds;
  };
  var getKey = function getKey(opts) {
    var i = 0;
    var tf = function tf(val) {
      return (val ? 1 : 0) << i++;
    };
    var key = 0;
    key += tf(opts.incudeNodes);
    key += tf(opts.includeEdges);
    key += tf(opts.includeLabels);
    key += tf(opts.includeMainLabels);
    key += tf(opts.includeSourceLabels);
    key += tf(opts.includeTargetLabels);
    key += tf(opts.includeOverlays);
    key += tf(opts.includeOutlines);
    return key;
  };
  var getBoundingBoxPosKey = function getBoundingBoxPosKey(ele) {
    if (ele.isEdge()) {
      var p1 = ele.source().position();
      var p2 = ele.target().position();
      var r = function r(x) {
        return Math.round(x);
      };
      return hashIntsArray([r(p1.x), r(p1.y), r(p2.x), r(p2.y)]);
    } else {
      return 0;
    }
  };
  var cachedBoundingBoxImpl = function cachedBoundingBoxImpl(ele, opts) {
    var _p = ele._private;
    var bb;
    var isEdge = ele.isEdge();
    var key = opts == null ? defBbOptsKey : getKey(opts);
    var usingDefOpts = key === defBbOptsKey;
    var currPosKey = getBoundingBoxPosKey(ele);
    var isPosKeySame = _p.bbCachePosKey === currPosKey;
    var useCache = opts.useCache && isPosKeySame;
    var isDirty = function isDirty(ele) {
      return ele._private.bbCache == null || ele._private.styleDirty;
    };
    var needRecalc = !useCache || isDirty(ele) || isEdge && isDirty(ele.source()) || isDirty(ele.target());
    if (needRecalc) {
      if (!isPosKeySame) {
        ele.recalculateRenderedStyle(useCache);
      }
      bb = boundingBoxImpl(ele, defBbOpts);
      _p.bbCache = bb;
      _p.bbCachePosKey = currPosKey;
    } else {
      bb = _p.bbCache;
    }

    // not using def opts => need to build up bb from combination of sub bbs
    if (!usingDefOpts) {
      var isNode = ele.isNode();
      bb = makeBoundingBox();
      if (opts.includeNodes && isNode || opts.includeEdges && !isNode) {
        if (opts.includeOverlays) {
          updateBoundsFromBox(bb, _p.overlayBounds);
        } else {
          updateBoundsFromBox(bb, _p.bodyBounds);
        }
      }
      if (opts.includeLabels) {
        if (opts.includeMainLabels && (!isEdge || opts.includeSourceLabels && opts.includeTargetLabels)) {
          updateBoundsFromBox(bb, _p.labelBounds.all);
        } else {
          if (opts.includeMainLabels) {
            updateBoundsFromBox(bb, _p.labelBounds.mainRot);
          }
          if (opts.includeSourceLabels) {
            updateBoundsFromBox(bb, _p.labelBounds.sourceRot);
          }
          if (opts.includeTargetLabels) {
            updateBoundsFromBox(bb, _p.labelBounds.targetRot);
          }
        }
      }
      bb.w = bb.x2 - bb.x1;
      bb.h = bb.y2 - bb.y1;
    }
    return bb;
  };
  var defBbOpts = {
    includeNodes: true,
    includeEdges: true,
    includeLabels: true,
    includeMainLabels: true,
    includeSourceLabels: true,
    includeTargetLabels: true,
    includeOverlays: true,
    includeUnderlays: true,
    includeOutlines: true,
    useCache: true
  };
  var defBbOptsKey = getKey(defBbOpts);
  var filledBbOpts = defaults$g(defBbOpts);
  elesfn$b.boundingBox = function (options) {
    var bounds;

    // the main usecase is ele.boundingBox() for a single element with no/def options
    // specified s.t. the cache is used, so check for this case to make it faster by
    // avoiding the overhead of the rest of the function
    if (this.length === 1 && this[0]._private.bbCache != null && !this[0]._private.styleDirty && (options === undefined || options.useCache === undefined || options.useCache === true)) {
      if (options === undefined) {
        options = defBbOpts;
      } else {
        options = filledBbOpts(options);
      }
      bounds = cachedBoundingBoxImpl(this[0], options);
    } else {
      bounds = makeBoundingBox();
      options = options || defBbOpts;
      var opts = filledBbOpts(options);
      var eles = this;
      var cy = eles.cy();
      var styleEnabled = cy.styleEnabled();
      if (styleEnabled) {
        for (var i = 0; i < eles.length; i++) {
          var ele = eles[i];
          var _p = ele._private;
          var currPosKey = getBoundingBoxPosKey(ele);
          var isPosKeySame = _p.bbCachePosKey === currPosKey;
          var useCache = opts.useCache && isPosKeySame && !_p.styleDirty;
          ele.recalculateRenderedStyle(useCache);
        }
      }
      this.updateCompoundBounds(!options.useCache);
      for (var _i = 0; _i < eles.length; _i++) {
        var _ele = eles[_i];
        updateBoundsFromBox(bounds, cachedBoundingBoxImpl(_ele, opts));
      }
    }
    bounds.x1 = noninf(bounds.x1);
    bounds.y1 = noninf(bounds.y1);
    bounds.x2 = noninf(bounds.x2);
    bounds.y2 = noninf(bounds.y2);
    bounds.w = noninf(bounds.x2 - bounds.x1);
    bounds.h = noninf(bounds.y2 - bounds.y1);
    return bounds;
  };
  elesfn$b.dirtyBoundingBoxCache = function () {
    for (var i = 0; i < this.length; i++) {
      var _p = this[i]._private;
      _p.bbCache = null;
      _p.bbCachePosKey = null;
      _p.bodyBounds = null;
      _p.overlayBounds = null;
      _p.labelBounds.all = null;
      _p.labelBounds.source = null;
      _p.labelBounds.target = null;
      _p.labelBounds.main = null;
      _p.labelBounds.sourceRot = null;
      _p.labelBounds.targetRot = null;
      _p.labelBounds.mainRot = null;
      _p.arrowBounds.source = null;
      _p.arrowBounds.target = null;
      _p.arrowBounds['mid-source'] = null;
      _p.arrowBounds['mid-target'] = null;
    }
    this.emitAndNotify('bounds');
    return this;
  };

  // private helper to get bounding box for custom node positions
  // - good for perf in certain cases but currently requires dirtying the rendered style
  // - would be better to not modify the nodes but the nodes are read directly everywhere in the renderer...
  // - try to use for only things like discrete layouts where the node position would change anyway
  elesfn$b.boundingBoxAt = function (fn) {
    var nodes = this.nodes();
    var cy = this.cy();
    var hasCompoundNodes = cy.hasCompoundNodes();
    var parents = cy.collection();
    if (hasCompoundNodes) {
      parents = nodes.filter(function (node) {
        return node.isParent();
      });
      nodes = nodes.not(parents);
    }
    if (plainObject(fn)) {
      var obj = fn;
      fn = function fn() {
        return obj;
      };
    }
    var storeOldPos = function storeOldPos(node, i) {
      return node._private.bbAtOldPos = fn(node, i);
    };
    var getOldPos = function getOldPos(node) {
      return node._private.bbAtOldPos;
    };
    cy.startBatch();
    nodes.forEach(storeOldPos).silentPositions(fn);
    if (hasCompoundNodes) {
      parents.dirtyCompoundBoundsCache();
      parents.dirtyBoundingBoxCache();
      parents.updateCompoundBounds(true); // force update b/c we're inside a batch cycle
    }

    var bb = copyBoundingBox(this.boundingBox({
      useCache: false
    }));
    nodes.silentPositions(getOldPos);
    if (hasCompoundNodes) {
      parents.dirtyCompoundBoundsCache();
      parents.dirtyBoundingBoxCache();
      parents.updateCompoundBounds(true); // force update b/c we're inside a batch cycle
    }

    cy.endBatch();
    return bb;
  };
  fn$3.boundingbox = fn$3.bb = fn$3.boundingBox;
  fn$3.renderedBoundingbox = fn$3.renderedBoundingBox;
  var bounds = elesfn$b;

  var fn$2, elesfn$a;
  fn$2 = elesfn$a = {};
  var defineDimFns = function defineDimFns(opts) {
    opts.uppercaseName = capitalize(opts.name);
    opts.autoName = 'auto' + opts.uppercaseName;
    opts.labelName = 'label' + opts.uppercaseName;
    opts.outerName = 'outer' + opts.uppercaseName;
    opts.uppercaseOuterName = capitalize(opts.outerName);
    fn$2[opts.name] = function dimImpl() {
      var ele = this[0];
      var _p = ele._private;
      var cy = _p.cy;
      var styleEnabled = cy._private.styleEnabled;
      if (ele) {
        if (styleEnabled) {
          if (ele.isParent()) {
            ele.updateCompoundBounds();
            return _p[opts.autoName] || 0;
          }
          var d = ele.pstyle(opts.name);
          switch (d.strValue) {
            case 'label':
              ele.recalculateRenderedStyle();
              return _p.rstyle[opts.labelName] || 0;
            default:
              return d.pfValue;
          }
        } else {
          return 1;
        }
      }
    };
    fn$2['outer' + opts.uppercaseName] = function outerDimImpl() {
      var ele = this[0];
      var _p = ele._private;
      var cy = _p.cy;
      var styleEnabled = cy._private.styleEnabled;
      if (ele) {
        if (styleEnabled) {
          var dim = ele[opts.name]();
          var border = ele.pstyle('border-width').pfValue; // n.b. 1/2 each side
          var padding = 2 * ele.padding();
          return dim + border + padding;
        } else {
          return 1;
        }
      }
    };
    fn$2['rendered' + opts.uppercaseName] = function renderedDimImpl() {
      var ele = this[0];
      if (ele) {
        var d = ele[opts.name]();
        return d * this.cy().zoom();
      }
    };
    fn$2['rendered' + opts.uppercaseOuterName] = function renderedOuterDimImpl() {
      var ele = this[0];
      if (ele) {
        var od = ele[opts.outerName]();
        return od * this.cy().zoom();
      }
    };
  };
  defineDimFns({
    name: 'width'
  });
  defineDimFns({
    name: 'height'
  });
  elesfn$a.padding = function () {
    var ele = this[0];
    var _p = ele._private;
    if (ele.isParent()) {
      ele.updateCompoundBounds();
      if (_p.autoPadding !== undefined) {
        return _p.autoPadding;
      } else {
        return ele.pstyle('padding').pfValue;
      }
    } else {
      return ele.pstyle('padding').pfValue;
    }
  };
  elesfn$a.paddedHeight = function () {
    var ele = this[0];
    return ele.height() + 2 * ele.padding();
  };
  elesfn$a.paddedWidth = function () {
    var ele = this[0];
    return ele.width() + 2 * ele.padding();
  };
  var widthHeight = elesfn$a;

  var ifEdge = function ifEdge(ele, getValue) {
    if (ele.isEdge()) {
      return getValue(ele);
    }
  };
  var ifEdgeRenderedPosition = function ifEdgeRenderedPosition(ele, getPoint) {
    if (ele.isEdge()) {
      var cy = ele.cy();
      return modelToRenderedPosition(getPoint(ele), cy.zoom(), cy.pan());
    }
  };
  var ifEdgeRenderedPositions = function ifEdgeRenderedPositions(ele, getPoints) {
    if (ele.isEdge()) {
      var cy = ele.cy();
      var pan = cy.pan();
      var zoom = cy.zoom();
      return getPoints(ele).map(function (p) {
        return modelToRenderedPosition(p, zoom, pan);
      });
    }
  };
  var controlPoints = function controlPoints(ele) {
    return ele.renderer().getControlPoints(ele);
  };
  var segmentPoints = function segmentPoints(ele) {
    return ele.renderer().getSegmentPoints(ele);
  };
  var sourceEndpoint = function sourceEndpoint(ele) {
    return ele.renderer().getSourceEndpoint(ele);
  };
  var targetEndpoint = function targetEndpoint(ele) {
    return ele.renderer().getTargetEndpoint(ele);
  };
  var midpoint = function midpoint(ele) {
    return ele.renderer().getEdgeMidpoint(ele);
  };
  var pts = {
    controlPoints: {
      get: controlPoints,
      mult: true
    },
    segmentPoints: {
      get: segmentPoints,
      mult: true
    },
    sourceEndpoint: {
      get: sourceEndpoint
    },
    targetEndpoint: {
      get: targetEndpoint
    },
    midpoint: {
      get: midpoint
    }
  };
  var renderedName = function renderedName(name) {
    return 'rendered' + name[0].toUpperCase() + name.substr(1);
  };
  var edgePoints = Object.keys(pts).reduce(function (obj, name) {
    var spec = pts[name];
    var rName = renderedName(name);
    obj[name] = function () {
      return ifEdge(this, spec.get);
    };
    if (spec.mult) {
      obj[rName] = function () {
        return ifEdgeRenderedPositions(this, spec.get);
      };
    } else {
      obj[rName] = function () {
        return ifEdgeRenderedPosition(this, spec.get);
      };
    }
    return obj;
  }, {});

  var dimensions = extend({}, position, bounds, widthHeight, edgePoints);

  /*!
  Event object based on jQuery events, MIT license

  https://jquery.org/license/
  https://tldrlegal.com/license/mit-license
  https://github.com/jquery/jquery/blob/master/src/event.js
  */

  var Event = function Event(src, props) {
    this.recycle(src, props);
  };
  function returnFalse() {
    return false;
  }
  function returnTrue() {
    return true;
  }

  // http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
  Event.prototype = {
    instanceString: function instanceString() {
      return 'event';
    },
    recycle: function recycle(src, props) {
      this.isImmediatePropagationStopped = this.isPropagationStopped = this.isDefaultPrevented = returnFalse;
      if (src != null && src.preventDefault) {
        // Browser Event object
        this.type = src.type;

        // Events bubbling up the document may have been marked as prevented
        // by a handler lower down the tree; reflect the correct value.
        this.isDefaultPrevented = src.defaultPrevented ? returnTrue : returnFalse;
      } else if (src != null && src.type) {
        // Plain object containing all event details
        props = src;
      } else {
        // Event string
        this.type = src;
      }

      // Put explicitly provided properties onto the event object
      if (props != null) {
        // more efficient to manually copy fields we use
        this.originalEvent = props.originalEvent;
        this.type = props.type != null ? props.type : this.type;
        this.cy = props.cy;
        this.target = props.target;
        this.position = props.position;
        this.renderedPosition = props.renderedPosition;
        this.namespace = props.namespace;
        this.layout = props.layout;
      }
      if (this.cy != null && this.position != null && this.renderedPosition == null) {
        // create a rendered position based on the passed position
        var pos = this.position;
        var zoom = this.cy.zoom();
        var pan = this.cy.pan();
        this.renderedPosition = {
          x: pos.x * zoom + pan.x,
          y: pos.y * zoom + pan.y
        };
      }

      // Create a timestamp if incoming event doesn't have one
      this.timeStamp = src && src.timeStamp || Date.now();
    },
    preventDefault: function preventDefault() {
      this.isDefaultPrevented = returnTrue;
      var e = this.originalEvent;
      if (!e) {
        return;
      }

      // if preventDefault exists run it on the original event
      if (e.preventDefault) {
        e.preventDefault();
      }
    },
    stopPropagation: function stopPropagation() {
      this.isPropagationStopped = returnTrue;
      var e = this.originalEvent;
      if (!e) {
        return;
      }

      // if stopPropagation exists run it on the original event
      if (e.stopPropagation) {
        e.stopPropagation();
      }
    },
    stopImmediatePropagation: function stopImmediatePropagation() {
      this.isImmediatePropagationStopped = returnTrue;
      this.stopPropagation();
    },
    isDefaultPrevented: returnFalse,
    isPropagationStopped: returnFalse,
    isImmediatePropagationStopped: returnFalse
  };

  var eventRegex = /^([^.]+)(\.(?:[^.]+))?$/; // regex for matching event strings (e.g. "click.namespace")
  var universalNamespace = '.*'; // matches as if no namespace specified and prevents users from unbinding accidentally

  var defaults$8 = {
    qualifierCompare: function qualifierCompare(q1, q2) {
      return q1 === q2;
    },
    eventMatches: function eventMatches( /*context, listener, eventObj*/
    ) {
      return true;
    },
    addEventFields: function addEventFields( /*context, evt*/
    ) {},
    callbackContext: function callbackContext(context /*, listener, eventObj*/) {
      return context;
    },
    beforeEmit: function beforeEmit( /* context, listener, eventObj */
    ) {},
    afterEmit: function afterEmit( /* context, listener, eventObj */
    ) {},
    bubble: function bubble( /*context*/
    ) {
      return false;
    },
    parent: function parent( /*context*/
    ) {
      return null;
    },
    context: null
  };
  var defaultsKeys = Object.keys(defaults$8);
  var emptyOpts = {};
  function Emitter() {
    var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : emptyOpts;
    var context = arguments.length > 1 ? arguments[1] : undefined;
    // micro-optimisation vs Object.assign() -- reduces Element instantiation time
    for (var i = 0; i < defaultsKeys.length; i++) {
      var key = defaultsKeys[i];
      this[key] = opts[key] || defaults$8[key];
    }
    this.context = context || this.context;
    this.listeners = [];
    this.emitting = 0;
  }
  var p = Emitter.prototype;
  var forEachEvent = function forEachEvent(self, handler, events, qualifier, callback, conf, confOverrides) {
    if (fn$6(qualifier)) {
      callback = qualifier;
      qualifier = null;
    }
    if (confOverrides) {
      if (conf == null) {
        conf = confOverrides;
      } else {
        conf = extend({}, conf, confOverrides);
      }
    }
    var eventList = array(events) ? events : events.split(/\s+/);
    for (var i = 0; i < eventList.length; i++) {
      var evt = eventList[i];
      if (emptyString(evt)) {
        continue;
      }
      var match = evt.match(eventRegex); // type[.namespace]

      if (match) {
        var type = match[1];
        var namespace = match[2] ? match[2] : null;
        var ret = handler(self, evt, type, namespace, qualifier, callback, conf);
        if (ret === false) {
          break;
        } // allow exiting early
      }
    }
  };

  var makeEventObj = function makeEventObj(self, obj) {
    self.addEventFields(self.context, obj);
    return new Event(obj.type, obj);
  };
  var forEachEventObj = function forEachEventObj(self, handler, events) {
    if (event(events)) {
      handler(self, events);
      return;
    } else if (plainObject(events)) {
      handler(self, makeEventObj(self, events));
      return;
    }
    var eventList = array(events) ? events : events.split(/\s+/);
    for (var i = 0; i < eventList.length; i++) {
      var evt = eventList[i];
      if (emptyString(evt)) {
        continue;
      }
      var match = evt.match(eventRegex); // type[.namespace]

      if (match) {
        var type = match[1];
        var namespace = match[2] ? match[2] : null;
        var eventObj = makeEventObj(self, {
          type: type,
          namespace: namespace,
          target: self.context
        });
        handler(self, eventObj);
      }
    }
  };
  p.on = p.addListener = function (events, qualifier, callback, conf, confOverrides) {
    forEachEvent(this, function (self, event, type, namespace, qualifier, callback, conf) {
      if (fn$6(callback)) {
        self.listeners.push({
          event: event,
          // full event string
          callback: callback,
          // callback to run
          type: type,
          // the event type (e.g. 'click')
          namespace: namespace,
          // the event namespace (e.g. ".foo")
          qualifier: qualifier,
          // a restriction on whether to match this emitter
          conf: conf // additional configuration
        });
      }
    }, events, qualifier, callback, conf, confOverrides);
    return this;
  };
  p.one = function (events, qualifier, callback, conf) {
    return this.on(events, qualifier, callback, conf, {
      one: true
    });
  };
  p.removeListener = p.off = function (events, qualifier, callback, conf) {
    var _this = this;
    if (this.emitting !== 0) {
      this.listeners = copyArray$1(this.listeners);
    }
    var listeners = this.listeners;
    var _loop = function _loop(i) {
      var listener = listeners[i];
      forEachEvent(_this, function (self, event, type, namespace, qualifier, callback /*, conf*/) {
        if ((listener.type === type || events === '*') && (!namespace && listener.namespace !== '.*' || listener.namespace === namespace) && (!qualifier || self.qualifierCompare(listener.qualifier, qualifier)) && (!callback || listener.callback === callback)) {
          listeners.splice(i, 1);
          return false;
        }
      }, events, qualifier, callback, conf);
    };
    for (var i = listeners.length - 1; i >= 0; i--) {
      _loop(i);
    }
    return this;
  };
  p.removeAllListeners = function () {
    return this.removeListener('*');
  };
  p.emit = p.trigger = function (events, extraParams, manualCallback) {
    var listeners = this.listeners;
    var numListenersBeforeEmit = listeners.length;
    this.emitting++;
    if (!array(extraParams)) {
      extraParams = [extraParams];
    }
    forEachEventObj(this, function (self, eventObj) {
      if (manualCallback != null) {
        listeners = [{
          event: eventObj.event,
          type: eventObj.type,
          namespace: eventObj.namespace,
          callback: manualCallback
        }];
        numListenersBeforeEmit = listeners.length;
      }
      var _loop2 = function _loop2(i) {
        var listener = listeners[i];
        if (listener.type === eventObj.type && (!listener.namespace || listener.namespace === eventObj.namespace || listener.namespace === universalNamespace) && self.eventMatches(self.context, listener, eventObj)) {
          var args = [eventObj];
          if (extraParams != null) {
            push(args, extraParams);
          }
          self.beforeEmit(self.context, listener, eventObj);
          if (listener.conf && listener.conf.one) {
            self.listeners = self.listeners.filter(function (l) {
              return l !== listener;
            });
          }
          var context = self.callbackContext(self.context, listener, eventObj);
          var ret = listener.callback.apply(context, args);
          self.afterEmit(self.context, listener, eventObj);
          if (ret === false) {
            eventObj.stopPropagation();
            eventObj.preventDefault();
          }
        } // if listener matches
      };
      for (var i = 0; i < numListenersBeforeEmit; i++) {
        _loop2(i);
      } // for listener

      if (self.bubble(self.context) && !eventObj.isPropagationStopped()) {
        self.parent(self.context).emit(eventObj, extraParams);
      }
    }, events);
    this.emitting--;
    return this;
  };

  var emitterOptions$1 = {
    qualifierCompare: function qualifierCompare(selector1, selector2) {
      if (selector1 == null || selector2 == null) {
        return selector1 == null && selector2 == null;
      } else {
        return selector1.sameText(selector2);
      }
    },
    eventMatches: function eventMatches(ele, listener, eventObj) {
      var selector = listener.qualifier;
      if (selector != null) {
        return ele !== eventObj.target && element(eventObj.target) && selector.matches(eventObj.target);
      }
      return true;
    },
    addEventFields: function addEventFields(ele, evt) {
      evt.cy = ele.cy();
      evt.target = ele;
    },
    callbackContext: function callbackContext(ele, listener, eventObj) {
      return listener.qualifier != null ? eventObj.target : ele;
    },
    beforeEmit: function beforeEmit(context, listener /*, eventObj*/) {
      if (listener.conf && listener.conf.once) {
        listener.conf.onceCollection.removeListener(listener.event, listener.qualifier, listener.callback);
      }
    },
    bubble: function bubble() {
      return true;
    },
    parent: function parent(ele) {
      return ele.isChild() ? ele.parent() : ele.cy();
    }
  };
  var argSelector$1 = function argSelector(arg) {
    if (string(arg)) {
      return new Selector(arg);
    } else {
      return arg;
    }
  };
  var elesfn$9 = {
    createEmitter: function createEmitter() {
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        var _p = ele._private;
        if (!_p.emitter) {
          _p.emitter = new Emitter(emitterOptions$1, ele);
        }
      }
      return this;
    },
    emitter: function emitter() {
      return this._private.emitter;
    },
    on: function on(events, selector, callback) {
      var argSel = argSelector$1(selector);
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        ele.emitter().on(events, argSel, callback);
      }
      return this;
    },
    removeListener: function removeListener(events, selector, callback) {
      var argSel = argSelector$1(selector);
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        ele.emitter().removeListener(events, argSel, callback);
      }
      return this;
    },
    removeAllListeners: function removeAllListeners() {
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        ele.emitter().removeAllListeners();
      }
      return this;
    },
    one: function one(events, selector, callback) {
      var argSel = argSelector$1(selector);
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        ele.emitter().one(events, argSel, callback);
      }
      return this;
    },
    once: function once(events, selector, callback) {
      var argSel = argSelector$1(selector);
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        ele.emitter().on(events, argSel, callback, {
          once: true,
          onceCollection: this
        });
      }
    },
    emit: function emit(events, extraParams) {
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        ele.emitter().emit(events, extraParams);
      }
      return this;
    },
    emitAndNotify: function emitAndNotify(event, extraParams) {
      // for internal use only
      if (this.length === 0) {
        return;
      } // empty collections don't need to notify anything

      // notify renderer
      this.cy().notify(event, this);
      this.emit(event, extraParams);
      return this;
    }
  };
  define.eventAliasesOn(elesfn$9);

  var elesfn$8 = {
    nodes: function nodes(selector) {
      return this.filter(function (ele) {
        return ele.isNode();
      }).filter(selector);
    },
    edges: function edges(selector) {
      return this.filter(function (ele) {
        return ele.isEdge();
      }).filter(selector);
    },
    // internal helper to get nodes and edges as separate collections with single iteration over elements
    byGroup: function byGroup() {
      var nodes = this.spawn();
      var edges = this.spawn();
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        if (ele.isNode()) {
          nodes.push(ele);
        } else {
          edges.push(ele);
        }
      }
      return {
        nodes: nodes,
        edges: edges
      };
    },
    filter: function filter(_filter, thisArg) {
      if (_filter === undefined) {
        // check this first b/c it's the most common/performant case
        return this;
      } else if (string(_filter) || elementOrCollection(_filter)) {
        return new Selector(_filter).filter(this);
      } else if (fn$6(_filter)) {
        var filterEles = this.spawn();
        var eles = this;
        for (var i = 0; i < eles.length; i++) {
          var ele = eles[i];
          var include = thisArg ? _filter.apply(thisArg, [ele, i, eles]) : _filter(ele, i, eles);
          if (include) {
            filterEles.push(ele);
          }
        }
        return filterEles;
      }
      return this.spawn(); // if not handled by above, give 'em an empty collection
    },

    not: function not(toRemove) {
      if (!toRemove) {
        return this;
      } else {
        if (string(toRemove)) {
          toRemove = this.filter(toRemove);
        }
        var elements = this.spawn();
        for (var i = 0; i < this.length; i++) {
          var element = this[i];
          var remove = toRemove.has(element);
          if (!remove) {
            elements.push(element);
          }
        }
        return elements;
      }
    },
    absoluteComplement: function absoluteComplement() {
      var cy = this.cy();
      return cy.mutableElements().not(this);
    },
    intersect: function intersect(other) {
      // if a selector is specified, then filter by it instead
      if (string(other)) {
        var selector = other;
        return this.filter(selector);
      }
      var elements = this.spawn();
      var col1 = this;
      var col2 = other;
      var col1Smaller = this.length < other.length;
      var colS = col1Smaller ? col1 : col2;
      var colL = col1Smaller ? col2 : col1;
      for (var i = 0; i < colS.length; i++) {
        var ele = colS[i];
        if (colL.has(ele)) {
          elements.push(ele);
        }
      }
      return elements;
    },
    xor: function xor(other) {
      var cy = this._private.cy;
      if (string(other)) {
        other = cy.$(other);
      }
      var elements = this.spawn();
      var col1 = this;
      var col2 = other;
      var add = function add(col, other) {
        for (var i = 0; i < col.length; i++) {
          var ele = col[i];
          var id = ele._private.data.id;
          var inOther = other.hasElementWithId(id);
          if (!inOther) {
            elements.push(ele);
          }
        }
      };
      add(col1, col2);
      add(col2, col1);
      return elements;
    },
    diff: function diff(other) {
      var cy = this._private.cy;
      if (string(other)) {
        other = cy.$(other);
      }
      var left = this.spawn();
      var right = this.spawn();
      var both = this.spawn();
      var col1 = this;
      var col2 = other;
      var add = function add(col, other, retEles) {
        for (var i = 0; i < col.length; i++) {
          var ele = col[i];
          var id = ele._private.data.id;
          var inOther = other.hasElementWithId(id);
          if (inOther) {
            both.merge(ele);
          } else {
            retEles.push(ele);
          }
        }
      };
      add(col1, col2, left);
      add(col2, col1, right);
      return {
        left: left,
        right: right,
        both: both
      };
    },
    add: function add(toAdd) {
      var cy = this._private.cy;
      if (!toAdd) {
        return this;
      }
      if (string(toAdd)) {
        var selector = toAdd;
        toAdd = cy.mutableElements().filter(selector);
      }
      var elements = this.spawnSelf();
      for (var i = 0; i < toAdd.length; i++) {
        var ele = toAdd[i];
        var add = !this.has(ele);
        if (add) {
          elements.push(ele);
        }
      }
      return elements;
    },
    // in place merge on calling collection
    merge: function merge(toAdd) {
      var _p = this._private;
      var cy = _p.cy;
      if (!toAdd) {
        return this;
      }
      if (toAdd && string(toAdd)) {
        var selector = toAdd;
        toAdd = cy.mutableElements().filter(selector);
      }
      var map = _p.map;
      for (var i = 0; i < toAdd.length; i++) {
        var toAddEle = toAdd[i];
        var id = toAddEle._private.data.id;
        var add = !map.has(id);
        if (add) {
          var index = this.length++;
          this[index] = toAddEle;
          map.set(id, {
            ele: toAddEle,
            index: index
          });
        }
      }
      return this; // chaining
    },

    unmergeAt: function unmergeAt(i) {
      var ele = this[i];
      var id = ele.id();
      var _p = this._private;
      var map = _p.map;

      // remove ele
      this[i] = undefined;
      map["delete"](id);
      var unmergedLastEle = i === this.length - 1;

      // replace empty spot with last ele in collection
      if (this.length > 1 && !unmergedLastEle) {
        var lastEleI = this.length - 1;
        var lastEle = this[lastEleI];
        var lastEleId = lastEle._private.data.id;
        this[lastEleI] = undefined;
        this[i] = lastEle;
        map.set(lastEleId, {
          ele: lastEle,
          index: i
        });
      }

      // the collection is now 1 ele smaller
      this.length--;
      return this;
    },
    // remove single ele in place in calling collection
    unmergeOne: function unmergeOne(ele) {
      ele = ele[0];
      var _p = this._private;
      var id = ele._private.data.id;
      var map = _p.map;
      var entry = map.get(id);
      if (!entry) {
        return this; // no need to remove
      }

      var i = entry.index;
      this.unmergeAt(i);
      return this;
    },
    // remove eles in place on calling collection
    unmerge: function unmerge(toRemove) {
      var cy = this._private.cy;
      if (!toRemove) {
        return this;
      }
      if (toRemove && string(toRemove)) {
        var selector = toRemove;
        toRemove = cy.mutableElements().filter(selector);
      }
      for (var i = 0; i < toRemove.length; i++) {
        this.unmergeOne(toRemove[i]);
      }
      return this; // chaining
    },

    unmergeBy: function unmergeBy(toRmFn) {
      for (var i = this.length - 1; i >= 0; i--) {
        var ele = this[i];
        if (toRmFn(ele)) {
          this.unmergeAt(i);
        }
      }
      return this;
    },
    map: function map(mapFn, thisArg) {
      var arr = [];
      var eles = this;
      for (var i = 0; i < eles.length; i++) {
        var ele = eles[i];
        var ret = thisArg ? mapFn.apply(thisArg, [ele, i, eles]) : mapFn(ele, i, eles);
        arr.push(ret);
      }
      return arr;
    },
    reduce: function reduce(fn, initialValue) {
      var val = initialValue;
      var eles = this;
      for (var i = 0; i < eles.length; i++) {
        val = fn(val, eles[i], i, eles);
      }
      return val;
    },
    max: function max(valFn, thisArg) {
      var max = -Infinity;
      var maxEle;
      var eles = this;
      for (var i = 0; i < eles.length; i++) {
        var ele = eles[i];
        var val = thisArg ? valFn.apply(thisArg, [ele, i, eles]) : valFn(ele, i, eles);
        if (val > max) {
          max = val;
          maxEle = ele;
        }
      }
      return {
        value: max,
        ele: maxEle
      };
    },
    min: function min(valFn, thisArg) {
      var min = Infinity;
      var minEle;
      var eles = this;
      for (var i = 0; i < eles.length; i++) {
        var ele = eles[i];
        var val = thisArg ? valFn.apply(thisArg, [ele, i, eles]) : valFn(ele, i, eles);
        if (val < min) {
          min = val;
          minEle = ele;
        }
      }
      return {
        value: min,
        ele: minEle
      };
    }
  };

  // aliases
  var fn$1 = elesfn$8;
  fn$1['u'] = fn$1['|'] = fn$1['+'] = fn$1.union = fn$1.or = fn$1.add;
  fn$1['\\'] = fn$1['!'] = fn$1['-'] = fn$1.difference = fn$1.relativeComplement = fn$1.subtract = fn$1.not;
  fn$1['n'] = fn$1['&'] = fn$1['.'] = fn$1.and = fn$1.intersection = fn$1.intersect;
  fn$1['^'] = fn$1['(+)'] = fn$1['(-)'] = fn$1.symmetricDifference = fn$1.symdiff = fn$1.xor;
  fn$1.fnFilter = fn$1.filterFn = fn$1.stdFilter = fn$1.filter;
  fn$1.complement = fn$1.abscomp = fn$1.absoluteComplement;

  var elesfn$7 = {
    isNode: function isNode() {
      return this.group() === 'nodes';
    },
    isEdge: function isEdge() {
      return this.group() === 'edges';
    },
    isLoop: function isLoop() {
      return this.isEdge() && this.source()[0] === this.target()[0];
    },
    isSimple: function isSimple() {
      return this.isEdge() && this.source()[0] !== this.target()[0];
    },
    group: function group() {
      var ele = this[0];
      if (ele) {
        return ele._private.group;
      }
    }
  };

  /**
   *  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`.
   */
  var zIndexSort = function zIndexSort(a, b) {
    var cy = a.cy();
    var hasCompoundNodes = cy.hasCompoundNodes();
    function getDepth(ele) {
      var style = ele.pstyle('z-compound-depth');
      if (style.value === 'auto') {
        return hasCompoundNodes ? ele.zDepth() : 0;
      } else if (style.value === 'bottom') {
        return -1;
      } else if (style.value === 'top') {
        return MAX_INT$1;
      }
      // 'orphan'
      return 0;
    }
    var depthDiff = getDepth(a) - getDepth(b);
    if (depthDiff !== 0) {
      return depthDiff;
    }
    function getEleDepth(ele) {
      var style = ele.pstyle('z-index-compare');
      if (style.value === 'auto') {
        return ele.isNode() ? 1 : 0;
      }
      // 'manual'
      return 0;
    }
    var eleDiff = getEleDepth(a) - getEleDepth(b);
    if (eleDiff !== 0) {
      return eleDiff;
    }
    var zDiff = a.pstyle('z-index').value - b.pstyle('z-index').value;
    if (zDiff !== 0) {
      return zDiff;
    }
    // compare indices in the core (order added to graph w/ last on top)
    return a.poolIndex() - b.poolIndex();
  };

  var elesfn$6 = {
    forEach: function forEach(fn, thisArg) {
      if (fn$6(fn)) {
        var N = this.length;
        for (var i = 0; i < N; i++) {
          var ele = this[i];
          var ret = thisArg ? fn.apply(thisArg, [ele, i, this]) : fn(ele, i, this);
          if (ret === false) {
            break;
          } // exit each early on return false
        }
      }

      return this;
    },
    toArray: function toArray() {
      var array = [];
      for (var i = 0; i < this.length; i++) {
        array.push(this[i]);
      }
      return array;
    },
    slice: function slice(start, end) {
      var array = [];
      var thisSize = this.length;
      if (end == null) {
        end = thisSize;
      }
      if (start == null) {
        start = 0;
      }
      if (start < 0) {
        start = thisSize + start;
      }
      if (end < 0) {
        end = thisSize + end;
      }
      for (var i = start; i >= 0 && i < end && i < thisSize; i++) {
        array.push(this[i]);
      }
      return this.spawn(array);
    },
    size: function size() {
      return this.length;
    },
    eq: function eq(i) {
      return this[i] || this.spawn();
    },
    first: function first() {
      return this[0] || this.spawn();
    },
    last: function last() {
      return this[this.length - 1] || this.spawn();
    },
    empty: function empty() {
      return this.length === 0;
    },
    nonempty: function nonempty() {
      return !this.empty();
    },
    sort: function sort(sortFn) {
      if (!fn$6(sortFn)) {
        return this;
      }
      var sorted = this.toArray().sort(sortFn);
      return this.spawn(sorted);
    },
    sortByZIndex: function sortByZIndex() {
      return this.sort(zIndexSort);
    },
    zDepth: function zDepth() {
      var ele = this[0];
      if (!ele) {
        return undefined;
      }

      // let cy = ele.cy();
      var _p = ele._private;
      var group = _p.group;
      if (group === 'nodes') {
        var depth = _p.data.parent ? ele.parents().size() : 0;
        if (!ele.isParent()) {
          return MAX_INT$1 - 1; // childless nodes always on top
        }

        return depth;
      } else {
        var src = _p.source;
        var tgt = _p.target;
        var srcDepth = src.zDepth();
        var tgtDepth = tgt.zDepth();
        return Math.max(srcDepth, tgtDepth, 0); // depth of deepest parent
      }
    }
  };

  elesfn$6.each = elesfn$6.forEach;
  var defineSymbolIterator = function defineSymbolIterator() {
    var typeofUndef = "undefined" ;
    var isIteratorSupported = (typeof Symbol === "undefined" ? "undefined" : _typeof(Symbol)) != typeofUndef && _typeof(Symbol.iterator) != typeofUndef; // eslint-disable-line no-undef

    if (isIteratorSupported) {
      elesfn$6[Symbol.iterator] = function () {
        var _this = this;
        // eslint-disable-line no-undef
        var entry = {
          value: undefined,
          done: false
        };
        var i = 0;
        var length = this.length;
        return _defineProperty$1({
          next: function next() {
            if (i < length) {
              entry.value = _this[i++];
            } else {
              entry.value = undefined;
              entry.done = true;
            }
            return entry;
          }
        }, Symbol.iterator, function () {
          // eslint-disable-line no-undef
          return this;
        });
      };
    }
  };
  defineSymbolIterator();

  var getLayoutDimensionOptions = defaults$g({
    nodeDimensionsIncludeLabels: false
  });
  var elesfn$5 = {
    // Calculates and returns node dimensions { x, y } based on options given
    layoutDimensions: function layoutDimensions(options) {
      options = getLayoutDimensionOptions(options);
      var dims;
      if (!this.takesUpSpace()) {
        dims = {
          w: 0,
          h: 0
        };
      } else if (options.nodeDimensionsIncludeLabels) {
        var bbDim = this.boundingBox();
        dims = {
          w: bbDim.w,
          h: bbDim.h
        };
      } else {
        dims = {
          w: this.outerWidth(),
          h: this.outerHeight()
        };
      }

      // sanitise the dimensions for external layouts (avoid division by zero)
      if (dims.w === 0 || dims.h === 0) {
        dims.w = dims.h = 1;
      }
      return dims;
    },
    // using standard layout options, apply position function (w/ or w/o animation)
    layoutPositions: function layoutPositions(layout, options, fn) {
      var nodes = this.nodes().filter(function (n) {
        return !n.isParent();
      });
      var cy = this.cy();
      var layoutEles = options.eles; // nodes & edges
      var getMemoizeKey = function getMemoizeKey(node) {
        return node.id();
      };
      var fnMem = memoize$1(fn, getMemoizeKey); // memoized version of position function

      layout.emit({
        type: 'layoutstart',
        layout: layout
      });
      layout.animations = [];
      var calculateSpacing = function calculateSpacing(spacing, nodesBb, pos) {
        var center = {
          x: nodesBb.x1 + nodesBb.w / 2,
          y: nodesBb.y1 + nodesBb.h / 2
        };
        var spacingVector = {
          // scale from center of bounding box (not necessarily 0,0)
          x: (pos.x - center.x) * spacing,
          y: (pos.y - center.y) * spacing
        };
        return {
          x: center.x + spacingVector.x,
          y: center.y + spacingVector.y
        };
      };
      var useSpacingFactor = options.spacingFactor && options.spacingFactor !== 1;
      var spacingBb = function spacingBb() {
        if (!useSpacingFactor) {
          return null;
        }
        var bb = makeBoundingBox();
        for (var i = 0; i < nodes.length; i++) {
          var node = nodes[i];
          var pos = fnMem(node, i);
          expandBoundingBoxByPoint(bb, pos.x, pos.y);
        }
        return bb;
      };
      var bb = spacingBb();
      var getFinalPos = memoize$1(function (node, i) {
        var newPos = fnMem(node, i);
        if (useSpacingFactor) {
          var spacing = Math.abs(options.spacingFactor);
          newPos = calculateSpacing(spacing, bb, newPos);
        }
        if (options.transform != null) {
          newPos = options.transform(node, newPos);
        }
        return newPos;
      }, getMemoizeKey);
      if (options.animate) {
        for (var i = 0; i < nodes.length; i++) {
          var node = nodes[i];
          var newPos = getFinalPos(node, i);
          var animateNode = options.animateFilter == null || options.animateFilter(node, i);
          if (animateNode) {
            var ani = node.animation({
              position: newPos,
              duration: options.animationDuration,
              easing: options.animationEasing
            });
            layout.animations.push(ani);
          } else {
            node.position(newPos);
          }
        }
        if (options.fit) {
          var fitAni = cy.animation({
            fit: {
              boundingBox: layoutEles.boundingBoxAt(getFinalPos),
              padding: options.padding
            },
            duration: options.animationDuration,
            easing: options.animationEasing
          });
          layout.animations.push(fitAni);
        } else if (options.zoom !== undefined && options.pan !== undefined) {
          var zoomPanAni = cy.animation({
            zoom: options.zoom,
            pan: options.pan,
            duration: options.animationDuration,
            easing: options.animationEasing
          });
          layout.animations.push(zoomPanAni);
        }
        layout.animations.forEach(function (ani) {
          return ani.play();
        });
        layout.one('layoutready', options.ready);
        layout.emit({
          type: 'layoutready',
          layout: layout
        });
        Promise$1.all(layout.animations.map(function (ani) {
          return ani.promise();
        })).then(function () {
          layout.one('layoutstop', options.stop);
          layout.emit({
            type: 'layoutstop',
            layout: layout
          });
        });
      } else {
        nodes.positions(getFinalPos);
        if (options.fit) {
          cy.fit(options.eles, options.padding);
        }
        if (options.zoom != null) {
          cy.zoom(options.zoom);
        }
        if (options.pan) {
          cy.pan(options.pan);
        }
        layout.one('layoutready', options.ready);
        layout.emit({
          type: 'layoutready',
          layout: layout
        });
        layout.one('layoutstop', options.stop);
        layout.emit({
          type: 'layoutstop',
          layout: layout
        });
      }
      return this; // chaining
    },

    layout: function layout(options) {
      var cy = this.cy();
      return cy.makeLayout(extend({}, options, {
        eles: this
      }));
    }
  };

  // aliases:
  elesfn$5.createLayout = elesfn$5.makeLayout = elesfn$5.layout;

  function styleCache(key, fn, ele) {
    var _p = ele._private;
    var cache = _p.styleCache = _p.styleCache || [];
    var val;
    if ((val = cache[key]) != null) {
      return val;
    } else {
      val = cache[key] = fn(ele);
      return val;
    }
  }
  function cacheStyleFunction(key, fn) {
    key = hashString(key);
    return function cachedStyleFunction(ele) {
      return styleCache(key, fn, ele);
    };
  }
  function cachePrototypeStyleFunction(key, fn) {
    key = hashString(key);
    var selfFn = function selfFn(ele) {
      return fn.call(ele);
    };
    return function cachedPrototypeStyleFunction() {
      var ele = this[0];
      if (ele) {
        return styleCache(key, selfFn, ele);
      }
    };
  }
  var elesfn$4 = {
    recalculateRenderedStyle: function recalculateRenderedStyle(useCache) {
      var cy = this.cy();
      var renderer = cy.renderer();
      var styleEnabled = cy.styleEnabled();
      if (renderer && styleEnabled) {
        renderer.recalculateRenderedStyle(this, useCache);
      }
      return this;
    },
    dirtyStyleCache: function dirtyStyleCache() {
      var cy = this.cy();
      var dirty = function dirty(ele) {
        return ele._private.styleCache = null;
      };
      if (cy.hasCompoundNodes()) {
        var eles;
        eles = this.spawnSelf().merge(this.descendants()).merge(this.parents());
        eles.merge(eles.connectedEdges());
        eles.forEach(dirty);
      } else {
        this.forEach(function (ele) {
          dirty(ele);
          ele.connectedEdges().forEach(dirty);
        });
      }
      return this;
    },
    // fully updates (recalculates) the style for the elements
    updateStyle: function updateStyle(notifyRenderer) {
      var cy = this._private.cy;
      if (!cy.styleEnabled()) {
        return this;
      }
      if (cy.batching()) {
        var bEles = cy._private.batchStyleEles;
        bEles.merge(this);
        return this; // chaining and exit early when batching
      }

      var hasCompounds = cy.hasCompoundNodes();
      var updatedEles = this;
      notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false;
      if (hasCompounds) {
        // then add everything up and down for compound selector checks
        updatedEles = this.spawnSelf().merge(this.descendants()).merge(this.parents());
      }

      // let changedEles = style.apply( updatedEles );
      var changedEles = updatedEles;
      if (notifyRenderer) {
        changedEles.emitAndNotify('style'); // let renderer know we changed style
      } else {
        changedEles.emit('style'); // just fire the event
      }

      updatedEles.forEach(function (ele) {
        return ele._private.styleDirty = true;
      });
      return this; // chaining
    },

    // private: clears dirty flag and recalculates style
    cleanStyle: function cleanStyle() {
      var cy = this.cy();
      if (!cy.styleEnabled()) {
        return;
      }
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        if (ele._private.styleDirty) {
          // n.b. this flag should be set before apply() to avoid potential infinite recursion
          ele._private.styleDirty = false;
          cy.style().apply(ele);
        }
      }
    },
    // get the internal parsed style object for the specified property
    parsedStyle: function parsedStyle(property) {
      var includeNonDefault = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var ele = this[0];
      var cy = ele.cy();
      if (!cy.styleEnabled()) {
        return;
      }
      if (ele) {
        this.cleanStyle();
        var overriddenStyle = ele._private.style[property];
        if (overriddenStyle != null) {
          return overriddenStyle;
        } else if (includeNonDefault) {
          return cy.style().getDefaultProperty(property);
        } else {
          return null;
        }
      }
    },
    numericStyle: function numericStyle(property) {
      var ele = this[0];
      if (!ele.cy().styleEnabled()) {
        return;
      }
      if (ele) {
        var pstyle = ele.pstyle(property);
        return pstyle.pfValue !== undefined ? pstyle.pfValue : pstyle.value;
      }
    },
    numericStyleUnits: function numericStyleUnits(property) {
      var ele = this[0];
      if (!ele.cy().styleEnabled()) {
        return;
      }
      if (ele) {
        return ele.pstyle(property).units;
      }
    },
    // get the specified css property as a rendered value (i.e. on-screen value)
    // or get the whole rendered style if no property specified (NB doesn't allow setting)
    renderedStyle: function renderedStyle(property) {
      var cy = this.cy();
      if (!cy.styleEnabled()) {
        return this;
      }
      var ele = this[0];
      if (ele) {
        return cy.style().getRenderedStyle(ele, property);
      }
    },
    // read the calculated css style of the element or override the style (via a bypass)
    style: function style(name, value) {
      var cy = this.cy();
      if (!cy.styleEnabled()) {
        return this;
      }
      var updateTransitions = false;
      var style = cy.style();
      if (plainObject(name)) {
        // then extend the bypass
        var props = name;
        style.applyBypass(this, props, updateTransitions);
        this.emitAndNotify('style'); // let the renderer know we've updated style
      } else if (string(name)) {
        if (value === undefined) {
          // then get the property from the style
          var ele = this[0];
          if (ele) {
            return style.getStylePropertyValue(ele, name);
          } else {
            // empty collection => can't get any value
            return;
          }
        } else {
          // then set the bypass with the property value
          style.applyBypass(this, name, value, updateTransitions);
          this.emitAndNotify('style'); // let the renderer know we've updated style
        }
      } else if (name === undefined) {
        var _ele = this[0];
        if (_ele) {
          return style.getRawStyle(_ele);
        } else {
          // empty collection => can't get any value
          return;
        }
      }
      return this; // chaining
    },

    removeStyle: function removeStyle(names) {
      var cy = this.cy();
      if (!cy.styleEnabled()) {
        return this;
      }
      var updateTransitions = false;
      var style = cy.style();
      var eles = this;
      if (names === undefined) {
        for (var i = 0; i < eles.length; i++) {
          var ele = eles[i];
          style.removeAllBypasses(ele, updateTransitions);
        }
      } else {
        names = names.split(/\s+/);
        for (var _i = 0; _i < eles.length; _i++) {
          var _ele2 = eles[_i];
          style.removeBypasses(_ele2, names, updateTransitions);
        }
      }
      this.emitAndNotify('style'); // let the renderer know we've updated style

      return this; // chaining
    },

    show: function show() {
      this.css('display', 'element');
      return this; // chaining
    },

    hide: function hide() {
      this.css('display', 'none');
      return this; // chaining
    },

    effectiveOpacity: function effectiveOpacity() {
      var cy = this.cy();
      if (!cy.styleEnabled()) {
        return 1;
      }
      var hasCompoundNodes = cy.hasCompoundNodes();
      var ele = this[0];
      if (ele) {
        var _p = ele._private;
        var parentOpacity = ele.pstyle('opacity').value;
        if (!hasCompoundNodes) {
          return parentOpacity;
        }
        var parents = !_p.data.parent ? null : ele.parents();
        if (parents) {
          for (var i = 0; i < parents.length; i++) {
            var parent = parents[i];
            var opacity = parent.pstyle('opacity').value;
            parentOpacity = opacity * parentOpacity;
          }
        }
        return parentOpacity;
      }
    },
    transparent: function transparent() {
      var cy = this.cy();
      if (!cy.styleEnabled()) {
        return false;
      }
      var ele = this[0];
      var hasCompoundNodes = ele.cy().hasCompoundNodes();
      if (ele) {
        if (!hasCompoundNodes) {
          return ele.pstyle('opacity').value === 0;
        } else {
          return ele.effectiveOpacity() === 0;
        }
      }
    },
    backgrounding: function backgrounding() {
      var cy = this.cy();
      if (!cy.styleEnabled()) {
        return false;
      }
      var ele = this[0];
      return ele._private.backgrounding ? true : false;
    }
  };
  function checkCompound(ele, parentOk) {
    var _p = ele._private;
    var parents = _p.data.parent ? ele.parents() : null;
    if (parents) {
      for (var i = 0; i < parents.length; i++) {
        var parent = parents[i];
        if (!parentOk(parent)) {
          return false;
        }
      }
    }
    return true;
  }
  function defineDerivedStateFunction(specs) {
    var ok = specs.ok;
    var edgeOkViaNode = specs.edgeOkViaNode || specs.ok;
    var parentOk = specs.parentOk || specs.ok;
    return function () {
      var cy = this.cy();
      if (!cy.styleEnabled()) {
        return true;
      }
      var ele = this[0];
      var hasCompoundNodes = cy.hasCompoundNodes();
      if (ele) {
        var _p = ele._private;
        if (!ok(ele)) {
          return false;
        }
        if (ele.isNode()) {
          return !hasCompoundNodes || checkCompound(ele, parentOk);
        } else {
          var src = _p.source;
          var tgt = _p.target;
          return edgeOkViaNode(src) && (!hasCompoundNodes || checkCompound(src, edgeOkViaNode)) && (src === tgt || edgeOkViaNode(tgt) && (!hasCompoundNodes || checkCompound(tgt, edgeOkViaNode)));
        }
      }
    };
  }
  var eleTakesUpSpace = cacheStyleFunction('eleTakesUpSpace', function (ele) {
    return ele.pstyle('display').value === 'element' && ele.width() !== 0 && (ele.isNode() ? ele.height() !== 0 : true);
  });
  elesfn$4.takesUpSpace = cachePrototypeStyleFunction('takesUpSpace', defineDerivedStateFunction({
    ok: eleTakesUpSpace
  }));
  var eleInteractive = cacheStyleFunction('eleInteractive', function (ele) {
    return ele.pstyle('events').value === 'yes' && ele.pstyle('visibility').value === 'visible' && eleTakesUpSpace(ele);
  });
  var parentInteractive = cacheStyleFunction('parentInteractive', function (parent) {
    return parent.pstyle('visibility').value === 'visible' && eleTakesUpSpace(parent);
  });
  elesfn$4.interactive = cachePrototypeStyleFunction('interactive', defineDerivedStateFunction({
    ok: eleInteractive,
    parentOk: parentInteractive,
    edgeOkViaNode: eleTakesUpSpace
  }));
  elesfn$4.noninteractive = function () {
    var ele = this[0];
    if (ele) {
      return !ele.interactive();
    }
  };
  var eleVisible = cacheStyleFunction('eleVisible', function (ele) {
    return ele.pstyle('visibility').value === 'visible' && ele.pstyle('opacity').pfValue !== 0 && eleTakesUpSpace(ele);
  });
  var edgeVisibleViaNode = eleTakesUpSpace;
  elesfn$4.visible = cachePrototypeStyleFunction('visible', defineDerivedStateFunction({
    ok: eleVisible,
    edgeOkViaNode: edgeVisibleViaNode
  }));
  elesfn$4.hidden = function () {
    var ele = this[0];
    if (ele) {
      return !ele.visible();
    }
  };
  elesfn$4.isBundledBezier = cachePrototypeStyleFunction('isBundledBezier', function () {
    if (!this.cy().styleEnabled()) {
      return false;
    }
    return !this.removed() && this.pstyle('curve-style').value === 'bezier' && this.takesUpSpace();
  });
  elesfn$4.bypass = elesfn$4.css = elesfn$4.style;
  elesfn$4.renderedCss = elesfn$4.renderedStyle;
  elesfn$4.removeBypass = elesfn$4.removeCss = elesfn$4.removeStyle;
  elesfn$4.pstyle = elesfn$4.parsedStyle;

  var elesfn$3 = {};
  function defineSwitchFunction(params) {
    return function () {
      var args = arguments;
      var changedEles = [];

      // e.g. cy.nodes().select( data, handler )
      if (args.length === 2) {
        var data = args[0];
        var handler = args[1];
        this.on(params.event, data, handler);
      }

      // e.g. cy.nodes().select( handler )
      else if (args.length === 1 && fn$6(args[0])) {
        var _handler = args[0];
        this.on(params.event, _handler);
      }

      // e.g. cy.nodes().select()
      // e.g. (private) cy.nodes().select(['tapselect'])
      else if (args.length === 0 || args.length === 1 && array(args[0])) {
        var addlEvents = args.length === 1 ? args[0] : null;
        for (var i = 0; i < this.length; i++) {
          var ele = this[i];
          var able = !params.ableField || ele._private[params.ableField];
          var changed = ele._private[params.field] != params.value;
          if (params.overrideAble) {
            var overrideAble = params.overrideAble(ele);
            if (overrideAble !== undefined) {
              able = overrideAble;
              if (!overrideAble) {
                return this;
              } // to save cycles assume not able for all on override
            }
          }

          if (able) {
            ele._private[params.field] = params.value;
            if (changed) {
              changedEles.push(ele);
            }
          }
        }
        var changedColl = this.spawn(changedEles);
        changedColl.updateStyle(); // change of state => possible change of style
        changedColl.emit(params.event);
        if (addlEvents) {
          changedColl.emit(addlEvents);
        }
      }
      return this;
    };
  }
  function defineSwitchSet(params) {
    elesfn$3[params.field] = function () {
      var ele = this[0];
      if (ele) {
        if (params.overrideField) {
          var val = params.overrideField(ele);
          if (val !== undefined) {
            return val;
          }
        }
        return ele._private[params.field];
      }
    };
    elesfn$3[params.on] = defineSwitchFunction({
      event: params.on,
      field: params.field,
      ableField: params.ableField,
      overrideAble: params.overrideAble,
      value: true
    });
    elesfn$3[params.off] = defineSwitchFunction({
      event: params.off,
      field: params.field,
      ableField: params.ableField,
      overrideAble: params.overrideAble,
      value: false
    });
  }
  defineSwitchSet({
    field: 'locked',
    overrideField: function overrideField(ele) {
      return ele.cy().autolock() ? true : undefined;
    },
    on: 'lock',
    off: 'unlock'
  });
  defineSwitchSet({
    field: 'grabbable',
    overrideField: function overrideField(ele) {
      return ele.cy().autoungrabify() || ele.pannable() ? false : undefined;
    },
    on: 'grabify',
    off: 'ungrabify'
  });
  defineSwitchSet({
    field: 'selected',
    ableField: 'selectable',
    overrideAble: function overrideAble(ele) {
      return ele.cy().autounselectify() ? false : undefined;
    },
    on: 'select',
    off: 'unselect'
  });
  defineSwitchSet({
    field: 'selectable',
    overrideField: function overrideField(ele) {
      return ele.cy().autounselectify() ? false : undefined;
    },
    on: 'selectify',
    off: 'unselectify'
  });
  elesfn$3.deselect = elesfn$3.unselect;
  elesfn$3.grabbed = function () {
    var ele = this[0];
    if (ele) {
      return ele._private.grabbed;
    }
  };
  defineSwitchSet({
    field: 'active',
    on: 'activate',
    off: 'unactivate'
  });
  defineSwitchSet({
    field: 'pannable',
    on: 'panify',
    off: 'unpanify'
  });
  elesfn$3.inactive = function () {
    var ele = this[0];
    if (ele) {
      return !ele._private.active;
    }
  };

  var elesfn$2 = {};

  // DAG functions
  ////////////////

  var defineDagExtremity = function defineDagExtremity(params) {
    return function dagExtremityImpl(selector) {
      var eles = this;
      var ret = [];
      for (var i = 0; i < eles.length; i++) {
        var ele = eles[i];
        if (!ele.isNode()) {
          continue;
        }
        var disqualified = false;
        var edges = ele.connectedEdges();
        for (var j = 0; j < edges.length; j++) {
          var edge = edges[j];
          var src = edge.source();
          var tgt = edge.target();
          if (params.noIncomingEdges && tgt === ele && src !== ele || params.noOutgoingEdges && src === ele && tgt !== ele) {
            disqualified = true;
            break;
          }
        }
        if (!disqualified) {
          ret.push(ele);
        }
      }
      return this.spawn(ret, true).filter(selector);
    };
  };
  var defineDagOneHop = function defineDagOneHop(params) {
    return function (selector) {
      var eles = this;
      var oEles = [];
      for (var i = 0; i < eles.length; i++) {
        var ele = eles[i];
        if (!ele.isNode()) {
          continue;
        }
        var edges = ele.connectedEdges();
        for (var j = 0; j < edges.length; j++) {
          var edge = edges[j];
          var src = edge.source();
          var tgt = edge.target();
          if (params.outgoing && src === ele) {
            oEles.push(edge);
            oEles.push(tgt);
          } else if (params.incoming && tgt === ele) {
            oEles.push(edge);
            oEles.push(src);
          }
        }
      }
      return this.spawn(oEles, true).filter(selector);
    };
  };
  var defineDagAllHops = function defineDagAllHops(params) {
    return function (selector) {
      var eles = this;
      var sEles = [];
      var sElesIds = {};
      for (;;) {
        var next = params.outgoing ? eles.outgoers() : eles.incomers();
        if (next.length === 0) {
          break;
        } // done if none left

        var newNext = false;
        for (var i = 0; i < next.length; i++) {
          var n = next[i];
          var nid = n.id();
          if (!sElesIds[nid]) {
            sElesIds[nid] = true;
            sEles.push(n);
            newNext = true;
          }
        }
        if (!newNext) {
          break;
        } // done if touched all outgoers already

        eles = next;
      }
      return this.spawn(sEles, true).filter(selector);
    };
  };
  elesfn$2.clearTraversalCache = function () {
    for (var i = 0; i < this.length; i++) {
      this[i]._private.traversalCache = null;
    }
  };
  extend(elesfn$2, {
    // get the root nodes in the DAG
    roots: defineDagExtremity({
      noIncomingEdges: true
    }),
    // get the leaf nodes in the DAG
    leaves: defineDagExtremity({
      noOutgoingEdges: true
    }),
    // normally called children in graph theory
    // these nodes =edges=> outgoing nodes
    outgoers: cache(defineDagOneHop({
      outgoing: true
    }), 'outgoers'),
    // aka DAG descendants
    successors: defineDagAllHops({
      outgoing: true
    }),
    // normally called parents in graph theory
    // these nodes <=edges= incoming nodes
    incomers: cache(defineDagOneHop({
      incoming: true
    }), 'incomers'),
    // aka DAG ancestors
    predecessors: defineDagAllHops({
      incoming: true
    })
  });

  // Neighbourhood functions
  //////////////////////////

  extend(elesfn$2, {
    neighborhood: cache(function (selector) {
      var elements = [];
      var nodes = this.nodes();
      for (var i = 0; i < nodes.length; i++) {
        // for all nodes
        var node = nodes[i];
        var connectedEdges = node.connectedEdges();

        // for each connected edge, add the edge and the other node
        for (var j = 0; j < connectedEdges.length; j++) {
          var edge = connectedEdges[j];
          var src = edge.source();
          var tgt = edge.target();
          var otherNode = node === src ? tgt : src;

          // need check in case of loop
          if (otherNode.length > 0) {
            elements.push(otherNode[0]); // add node 1 hop away
          }

          // add connected edge
          elements.push(edge[0]);
        }
      }
      return this.spawn(elements, true).filter(selector);
    }, 'neighborhood'),
    closedNeighborhood: function closedNeighborhood(selector) {
      return this.neighborhood().add(this).filter(selector);
    },
    openNeighborhood: function openNeighborhood(selector) {
      return this.neighborhood(selector);
    }
  });

  // aliases
  elesfn$2.neighbourhood = elesfn$2.neighborhood;
  elesfn$2.closedNeighbourhood = elesfn$2.closedNeighborhood;
  elesfn$2.openNeighbourhood = elesfn$2.openNeighborhood;

  // Edge functions
  /////////////////

  extend(elesfn$2, {
    source: cache(function sourceImpl(selector) {
      var ele = this[0];
      var src;
      if (ele) {
        src = ele._private.source || ele.cy().collection();
      }
      return src && selector ? src.filter(selector) : src;
    }, 'source'),
    target: cache(function targetImpl(selector) {
      var ele = this[0];
      var tgt;
      if (ele) {
        tgt = ele._private.target || ele.cy().collection();
      }
      return tgt && selector ? tgt.filter(selector) : tgt;
    }, 'target'),
    sources: defineSourceFunction({
      attr: 'source'
    }),
    targets: defineSourceFunction({
      attr: 'target'
    })
  });
  function defineSourceFunction(params) {
    return function sourceImpl(selector) {
      var sources = [];
      for (var i = 0; i < this.length; i++) {
        var ele = this[i];
        var src = ele._private[params.attr];
        if (src) {
          sources.push(src);
        }
      }
      return this.spawn(sources, true).filter(selector);
    };
  }
  extend(elesfn$2, {
    edgesWith: cache(defineEdgesWithFunction(), 'edgesWith'),
    edgesTo: cache(defineEdgesWithFunction({
      thisIsSrc: true
    }), 'edgesTo')
  });
  function defineEdgesWithFunction(params) {
    return function edgesWithImpl(otherNodes) {
      var elements = [];
      var cy = this._private.cy;
      var p = params || {};

      // get elements if a selector is specified
      if (string(otherNodes)) {
        otherNodes = cy.$(otherNodes);
      }
      for (var h = 0; h < otherNodes.length; h++) {
        var edges = otherNodes[h]._private.edges;
        for (var i = 0; i < edges.length; i++) {
          var edge = edges[i];
          var edgeData = edge._private.data;
          var thisToOther = this.hasElementWithId(edgeData.source) && otherNodes.hasElementWithId(edgeData.target);
          var otherToThis = otherNodes.hasElementWithId(edgeData.source) && this.hasElementWithId(edgeData.target);
          var edgeConnectsThisAndOther = thisToOther || otherToThis;
          if (!edgeConnectsThisAndOther) {
            continue;
          }
          if (p.thisIsSrc || p.thisIsTgt) {
            if (p.thisIsSrc && !thisToOther) {
              continue;
            }
            if (p.thisIsTgt && !otherToThis) {
              continue;
            }
          }
          elements.push(edge);
        }
      }
      return this.spawn(elements, true);
    };
  }
  extend(elesfn$2, {
    connectedEdges: cache(function (selector) {
      var retEles = [];
      var eles = this;
      for (var i = 0; i < eles.length; i++) {
        var node = eles[i];
        if (!node.isNode()) {
          continue;
        }
        var edges = node._private.edges;
        for (var j = 0; j < edges.length; j++) {
          var edge = edges[j];
          retEles.push(edge);
        }
      }
      return this.spawn(retEles, true).filter(selector);
    }, 'connectedEdges'),
    connectedNodes: cache(function (selector) {
      var retEles = [];
      var eles = this;
      for (var i = 0; i < eles.length; i++) {
        var edge = eles[i];
        if (!edge.isEdge()) {
          continue;
        }
        retEles.push(edge.source()[0]);
        retEles.push(edge.target()[0]);
      }
      return this.spawn(retEles, true).filter(selector);
    }, 'connectedNodes'),
    parallelEdges: cache(defineParallelEdgesFunction(), 'parallelEdges'),
    codirectedEdges: cache(defineParallelEdgesFunction({
      codirected: true
    }), 'codirectedEdges')
  });
  function defineParallelEdgesFunction(params) {
    var defaults = {
      codirected: false
    };
    params = extend({}, defaults, params);
    return function parallelEdgesImpl(selector) {
      // micro-optimised for renderer
      var elements = [];
      var edges = this.edges();
      var p = params;

      // look at all the edges in the collection
      for (var i = 0; i < edges.length; i++) {
        var edge1 = edges[i];
        var edge1_p = edge1._private;
        var src1 = edge1_p.source;
        var srcid1 = src1._private.data.id;
        var tgtid1 = edge1_p.data.target;
        var srcEdges1 = src1._private.edges;

        // look at edges connected to the src node of this edge
        for (var j = 0; j < srcEdges1.length; j++) {
          var edge2 = srcEdges1[j];
          var edge2data = edge2._private.data;
          var tgtid2 = edge2data.target;
          var srcid2 = edge2data.source;
          var codirected = tgtid2 === tgtid1 && srcid2 === srcid1;
          var oppdirected = srcid1 === tgtid2 && tgtid1 === srcid2;
          if (p.codirected && codirected || !p.codirected && (codirected || oppdirected)) {
            elements.push(edge2);
          }
        }
      }
      return this.spawn(elements, true).filter(selector);
    };
  }

  // Misc functions
  /////////////////

  extend(elesfn$2, {
    components: function components(root) {
      var self = this;
      var cy = self.cy();
      var visited = cy.collection();
      var unvisited = root == null ? self.nodes() : root.nodes();
      var components = [];
      if (root != null && unvisited.empty()) {
        // root may contain only edges
        unvisited = root.sources(); // doesn't matter which node to use (undirected), so just use the source sides
      }

      var visitInComponent = function visitInComponent(node, component) {
        visited.merge(node);
        unvisited.unmerge(node);
        component.merge(node);
      };
      if (unvisited.empty()) {
        return self.spawn();
      }
      var _loop = function _loop() {
        // each iteration yields a component
        var cmpt = cy.collection();
        components.push(cmpt);
        var root = unvisited[0];
        visitInComponent(root, cmpt);
        self.bfs({
          directed: false,
          roots: root,
          visit: function visit(v) {
            return visitInComponent(v, cmpt);
          }
        });
        cmpt.forEach(function (node) {
          node.connectedEdges().forEach(function (e) {
            // connectedEdges() usually cached
            if (self.has(e) && cmpt.has(e.source()) && cmpt.has(e.target())) {
              // has() is cheap
              cmpt.merge(e); // forEach() only considers nodes -- sets N at call time
            }
          });
        });
      };
      do {
        _loop();
      } while (unvisited.length > 0);
      return components;
    },
    component: function component() {
      var ele = this[0];
      return ele.cy().mutableElements().components(ele)[0];
    }
  });
  elesfn$2.componentsOf = elesfn$2.components;

  // represents a set of nodes, edges, or both together
  var Collection = function Collection(cy, elements) {
    var unique = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
    var removed = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
    if (cy === undefined) {
      error('A collection must have a reference to the core');
      return;
    }
    var map = new Map$2();
    var createdElements = false;
    if (!elements) {
      elements = [];
    } else if (elements.length > 0 && plainObject(elements[0]) && !element(elements[0])) {
      createdElements = true;

      // make elements from json and restore all at once later
      var eles = [];
      var elesIds = new Set$1();
      for (var i = 0, l = elements.length; i < l; i++) {
        var json = elements[i];
        if (json.data == null) {
          json.data = {};
        }
        var _data = json.data;

        // make sure newly created elements have valid ids
        if (_data.id == null) {
          _data.id = uuid();
        } else if (cy.hasElementWithId(_data.id) || elesIds.has(_data.id)) {
          continue; // can't create element if prior id already exists
        }

        var ele = new Element(cy, json, false);
        eles.push(ele);
        elesIds.add(_data.id);
      }
      elements = eles;
    }
    this.length = 0;
    for (var _i = 0, _l = elements.length; _i < _l; _i++) {
      var element$1 = elements[_i][0]; // [0] in case elements is an array of collections, rather than array of elements
      if (element$1 == null) {
        continue;
      }
      var id = element$1._private.data.id;
      if (!unique || !map.has(id)) {
        if (unique) {
          map.set(id, {
            index: this.length,
            ele: element$1
          });
        }
        this[this.length] = element$1;
        this.length++;
      }
    }
    this._private = {
      eles: this,
      cy: cy,
      get map() {
        if (this.lazyMap == null) {
          this.rebuildMap();
        }
        return this.lazyMap;
      },
      set map(m) {
        this.lazyMap = m;
      },
      rebuildMap: function rebuildMap() {
        var m = this.lazyMap = new Map$2();
        var eles = this.eles;
        for (var _i2 = 0; _i2 < eles.length; _i2++) {
          var _ele = eles[_i2];
          m.set(_ele.id(), {
            index: _i2,
            ele: _ele
          });
        }
      }
    };
    if (unique) {
      this._private.map = map;
    }

    // restore the elements if we created them from json
    if (createdElements && !removed) {
      this.restore();
    }
  };

  // Functions
  ////////////////////////////////////////////////////////////////////////////////////////////////////

  // keep the prototypes in sync (an element has the same functions as a collection)
  // and use elefn and elesfn as shorthands to the prototypes
  var elesfn$1 = Element.prototype = Collection.prototype = Object.create(Array.prototype);
  elesfn$1.instanceString = function () {
    return 'collection';
  };
  elesfn$1.spawn = function (eles, unique) {
    return new Collection(this.cy(), eles, unique);
  };
  elesfn$1.spawnSelf = function () {
    return this.spawn(this);
  };
  elesfn$1.cy = function () {
    return this._private.cy;
  };
  elesfn$1.renderer = function () {
    return this._private.cy.renderer();
  };
  elesfn$1.element = function () {
    return this[0];
  };
  elesfn$1.collection = function () {
    if (collection(this)) {
      return this;
    } else {
      // an element
      return new Collection(this._private.cy, [this]);
    }
  };
  elesfn$1.unique = function () {
    return new Collection(this._private.cy, this, true);
  };
  elesfn$1.hasElementWithId = function (id) {
    id = '' + id; // id must be string

    return this._private.map.has(id);
  };
  elesfn$1.getElementById = function (id) {
    id = '' + id; // id must be string

    var cy = this._private.cy;
    var entry = this._private.map.get(id);
    return entry ? entry.ele : new Collection(cy); // get ele or empty collection
  };

  elesfn$1.$id = elesfn$1.getElementById;
  elesfn$1.poolIndex = function () {
    var cy = this._private.cy;
    var eles = cy._private.elements;
    var id = this[0]._private.data.id;
    return eles._private.map.get(id).index;
  };
  elesfn$1.indexOf = function (ele) {
    var id = ele[0]._private.data.id;
    return this._private.map.get(id).index;
  };
  elesfn$1.indexOfId = function (id) {
    id = '' + id; // id must be string

    return this._private.map.get(id).index;
  };
  elesfn$1.json = function (obj) {
    var ele = this.element();
    var cy = this.cy();
    if (ele == null && obj) {
      return this;
    } // can't set to no eles

    if (ele == null) {
      return undefined;
    } // can't get from no eles

    var p = ele._private;
    if (plainObject(obj)) {
      // set

      cy.startBatch();
      if (obj.data) {
        ele.data(obj.data);
        var _data2 = p.data;
        if (ele.isEdge()) {
          // source and target are immutable via data()
          var move = false;
          var spec = {};
          var src = obj.data.source;
          var tgt = obj.data.target;
          if (src != null && src != _data2.source) {
            spec.source = '' + src; // id must be string
            move = true;
          }
          if (tgt != null && tgt != _data2.target) {
            spec.target = '' + tgt; // id must be string
            move = true;
          }
          if (move) {
            ele = ele.move(spec);
          }
        } else {
          // parent is immutable via data()
          var newParentValSpecd = ('parent' in obj.data);
          var parent = obj.data.parent;
          if (newParentValSpecd && (parent != null || _data2.parent != null) && parent != _data2.parent) {
            if (parent === undefined) {
              // can't set undefined imperatively, so use null
              parent = null;
            }
            if (parent != null) {
              parent = '' + parent; // id must be string
            }

            ele = ele.move({
              parent: parent
            });
          }
        }
      }
      if (obj.position) {
        ele.position(obj.position);
      }

      // ignore group -- immutable

      var checkSwitch = function checkSwitch(k, trueFnName, falseFnName) {
        var obj_k = obj[k];
        if (obj_k != null && obj_k !== p[k]) {
          if (obj_k) {
            ele[trueFnName]();
          } else {
            ele[falseFnName]();
          }
        }
      };
      checkSwitch('removed', 'remove', 'restore');
      checkSwitch('selected', 'select', 'unselect');
      checkSwitch('selectable', 'selectify', 'unselectify');
      checkSwitch('locked', 'lock', 'unlock');
      checkSwitch('grabbable', 'grabify', 'ungrabify');
      checkSwitch('pannable', 'panify', 'unpanify');
      if (obj.classes != null) {
        ele.classes(obj.classes);
      }
      cy.endBatch();
      return this;
    } else if (obj === undefined) {
      // get

      var json = {
        data: copy(p.data),
        position: copy(p.position),
        group: p.group,
        removed: p.removed,
        selected: p.selected,
        selectable: p.selectable,
        locked: p.locked,
        grabbable: p.grabbable,
        pannable: p.pannable,
        classes: null
      };
      json.classes = '';
      var i = 0;
      p.classes.forEach(function (cls) {
        return json.classes += i++ === 0 ? cls : ' ' + cls;
      });
      return json;
    }
  };
  elesfn$1.jsons = function () {
    var jsons = [];
    for (var i = 0; i < this.length; i++) {
      var ele = this[i];
      var json = ele.json();
      jsons.push(json);
    }
    return jsons;
  };
  elesfn$1.clone = function () {
    var cy = this.cy();
    var elesArr = [];
    for (var i = 0; i < this.length; i++) {
      var ele = this[i];
      var json = ele.json();
      var clone = new Element(cy, json, false); // NB no restore

      elesArr.push(clone);
    }
    return new Collection(cy, elesArr);
  };
  elesfn$1.copy = elesfn$1.clone;
  elesfn$1.restore = function () {
    var notifyRenderer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
    var addToPool = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
    var self = this;
    var cy = self.cy();
    var cy_p = cy._private;

    // create arrays of nodes and edges, since we need to
    // restore the nodes first
    var nodes = [];
    var edges = [];
    var elements;
    for (var _i3 = 0, l = self.length; _i3 < l; _i3++) {
      var ele = self[_i3];
      if (addToPool && !ele.removed()) {
        // don't need to handle this ele
        continue;
      }

      // keep nodes first in the array and edges after
      if (ele.isNode()) {
        // put to front of array if node
        nodes.push(ele);
      } else {
        // put to end of array if edge
        edges.push(ele);
      }
    }
    elements = nodes.concat(edges);
    var i;
    var removeFromElements = function removeFromElements() {
      elements.splice(i, 1);
      i--;
    };

    // now, restore each element
    for (i = 0; i < elements.length; i++) {
      var _ele2 = elements[i];
      var _private = _ele2._private;
      var _data3 = _private.data;

      // the traversal cache should start fresh when ele is added
      _ele2.clearTraversalCache();

      // set id and validate
      if (!addToPool && !_private.removed) ; else if (_data3.id === undefined) {
        _data3.id = uuid();
      } else if (number$1(_data3.id)) {
        _data3.id = '' + _data3.id; // now it's a string
      } else if (emptyString(_data3.id) || !string(_data3.id)) {
        error('Can not create element with invalid string ID `' + _data3.id + '`');

        // can't create element if it has empty string as id or non-string id
        removeFromElements();
        continue;
      } else if (cy.hasElementWithId(_data3.id)) {
        error('Can not create second element with ID `' + _data3.id + '`');

        // can't create element if one already has that id
        removeFromElements();
        continue;
      }
      var id = _data3.id; // id is finalised, now let's keep a ref

      if (_ele2.isNode()) {
        // extra checks for nodes
        var pos = _private.position;

        // make sure the nodes have a defined position

        if (pos.x == null) {
          pos.x = 0;
        }
        if (pos.y == null) {
          pos.y = 0;
        }
      }
      if (_ele2.isEdge()) {
        // extra checks for edges

        var edge = _ele2;
        var fields = ['source', 'target'];
        var fieldsLength = fields.length;
        var badSourceOrTarget = false;
        for (var j = 0; j < fieldsLength; j++) {
          var field = fields[j];
          var val = _data3[field];
          if (number$1(val)) {
            val = _data3[field] = '' + _data3[field]; // now string
          }

          if (val == null || val === '') {
            // can't create if source or target is not defined properly
            error('Can not create edge `' + id + '` with unspecified ' + field);
            badSourceOrTarget = true;
          } else if (!cy.hasElementWithId(val)) {
            // can't create edge if one of its nodes doesn't exist
            error('Can not create edge `' + id + '` with nonexistant ' + field + ' `' + val + '`');
            badSourceOrTarget = true;
          }
        }
        if (badSourceOrTarget) {
          removeFromElements();
          continue;
        } // can't create this

        var src = cy.getElementById(_data3.source);
        var tgt = cy.getElementById(_data3.target);

        // only one edge in node if loop
        if (src.same(tgt)) {
          src._private.edges.push(edge);
        } else {
          src._private.edges.push(edge);
          tgt._private.edges.push(edge);
        }
        edge._private.source = src;
        edge._private.target = tgt;
      } // if is edge

      // create mock ids / indexes maps for element so it can be used like collections
      _private.map = new Map$2();
      _private.map.set(id, {
        ele: _ele2,
        index: 0
      });
      _private.removed = false;
      if (addToPool) {
        cy.addToPool(_ele2);
      }
    } // for each element

    // do compound node sanity checks
    for (var _i4 = 0; _i4 < nodes.length; _i4++) {
      // each node
      var node = nodes[_i4];
      var _data4 = node._private.data;
      if (number$1(_data4.parent)) {
        // then automake string
        _data4.parent = '' + _data4.parent;
      }
      var parentId = _data4.parent;
      var specifiedParent = parentId != null;
      if (specifiedParent || node._private.parent) {
        var parent = node._private.parent ? cy.collection().merge(node._private.parent) : cy.getElementById(parentId);
        if (parent.empty()) {
          // non-existant parent; just remove it
          _data4.parent = undefined;
        } else if (parent[0].removed()) {
          warn('Node added with missing parent, reference to parent removed');
          _data4.parent = undefined;
          node._private.parent = null;
        } else {
          var selfAsParent = false;
          var ancestor = parent;
          while (!ancestor.empty()) {
            if (node.same(ancestor)) {
              // mark self as parent and remove from data
              selfAsParent = true;
              _data4.parent = undefined; // remove parent reference

              // exit or we loop forever
              break;
            }
            ancestor = ancestor.parent();
          }
          if (!selfAsParent) {
            // connect with children
            parent[0]._private.children.push(node);
            node._private.parent = parent[0];

            // let the core know we have a compound graph
            cy_p.hasCompoundNodes = true;
          }
        } // else
      } // if specified parent
    } // for each node

    if (elements.length > 0) {
      var restored = elements.length === self.length ? self : new Collection(cy, elements);
      for (var _i5 = 0; _i5 < restored.length; _i5++) {
        var _ele3 = restored[_i5];
        if (_ele3.isNode()) {
          continue;
        }

        // adding an edge invalidates the traversal caches for the parallel edges
        _ele3.parallelEdges().clearTraversalCache();

        // adding an edge invalidates the traversal cache for the connected nodes
        _ele3.source().clearTraversalCache();
        _ele3.target().clearTraversalCache();
      }
      var toUpdateStyle;
      if (cy_p.hasCompoundNodes) {
        toUpdateStyle = cy.collection().merge(restored).merge(restored.connectedNodes()).merge(restored.parent());
      } else {
        toUpdateStyle = restored;
      }
      toUpdateStyle.dirtyCompoundBoundsCache().dirtyBoundingBoxCache().updateStyle(notifyRenderer);
      if (notifyRenderer) {
        restored.emitAndNotify('add');
      } else if (addToPool) {
        restored.emit('add');
      }
    }
    return self; // chainability
  };

  elesfn$1.removed = function () {
    var ele = this[0];
    return ele && ele._private.removed;
  };
  elesfn$1.inside = function () {
    var ele = this[0];
    return ele && !ele._private.removed;
  };
  elesfn$1.remove = function () {
    var notifyRenderer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
    var removeFromPool = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
    var self = this;
    var elesToRemove = [];
    var elesToRemoveIds = {};
    var cy = self._private.cy;

    // add connected edges
    function addConnectedEdges(node) {
      var edges = node._private.edges;
      for (var i = 0; i < edges.length; i++) {
        add(edges[i]);
      }
    }

    // add descendant nodes
    function addChildren(node) {
      var children = node._private.children;
      for (var i = 0; i < children.length; i++) {
        add(children[i]);
      }
    }
    function add(ele) {
      var alreadyAdded = elesToRemoveIds[ele.id()];
      if (removeFromPool && ele.removed() || alreadyAdded) {
        return;
      } else {
        elesToRemoveIds[ele.id()] = true;
      }
      if (ele.isNode()) {
        elesToRemove.push(ele); // nodes are removed last

        addConnectedEdges(ele);
        addChildren(ele);
      } else {
        elesToRemove.unshift(ele); // edges are removed first
      }
    }

    // make the list of elements to remove
    // (may be removing more than specified due to connected edges etc)

    for (var i = 0, l = self.length; i < l; i++) {
      var ele = self[i];
      add(ele);
    }
    function removeEdgeRef(node, edge) {
      var connectedEdges = node._private.edges;
      removeFromArray(connectedEdges, edge);

      // removing an edges invalidates the traversal cache for its nodes
      node.clearTraversalCache();
    }
    function removeParallelRef(pllEdge) {
      // removing an edge invalidates the traversal caches for the parallel edges
      pllEdge.clearTraversalCache();
    }
    var alteredParents = [];
    alteredParents.ids = {};
    function removeChildRef(parent, ele) {
      ele = ele[0];
      parent = parent[0];
      var children = parent._private.children;
      var pid = parent.id();
      removeFromArray(children, ele); // remove parent => child ref

      ele._private.parent = null; // remove child => parent ref

      if (!alteredParents.ids[pid]) {
        alteredParents.ids[pid] = true;
        alteredParents.push(parent);
      }
    }
    self.dirtyCompoundBoundsCache();
    if (removeFromPool) {
      cy.removeFromPool(elesToRemove); // remove from core pool
    }

    for (var _i6 = 0; _i6 < elesToRemove.length; _i6++) {
      var _ele4 = elesToRemove[_i6];
      if (_ele4.isEdge()) {
        // remove references to this edge in its connected nodes
        var src = _ele4.source()[0];
        var tgt = _ele4.target()[0];
        removeEdgeRef(src, _ele4);
        removeEdgeRef(tgt, _ele4);
        var pllEdges = _ele4.parallelEdges();
        for (var j = 0; j < pllEdges.length; j++) {
          var pllEdge = pllEdges[j];
          removeParallelRef(pllEdge);
          if (pllEdge.isBundledBezier()) {
            pllEdge.dirtyBoundingBoxCache();
          }
        }
      } else {
        // remove reference to parent
        var parent = _ele4.parent();
        if (parent.length !== 0) {
          removeChildRef(parent, _ele4);
        }
      }
      if (removeFromPool) {
        // mark as removed
        _ele4._private.removed = true;
      }
    }

    // check to see if we have a compound graph or not
    var elesStillInside = cy._private.elements;
    cy._private.hasCompoundNodes = false;
    for (var _i7 = 0; _i7 < elesStillInside.length; _i7++) {
      var _ele5 = elesStillInside[_i7];
      if (_ele5.isParent()) {
        cy._private.hasCompoundNodes = true;
        break;
      }
    }
    var removedElements = new Collection(this.cy(), elesToRemove);
    if (removedElements.size() > 0) {
      // must manually notify since trigger won't do this automatically once removed

      if (notifyRenderer) {
        removedElements.emitAndNotify('remove');
      } else if (removeFromPool) {
        removedElements.emit('remove');
      }
    }

    // the parents who were modified by the removal need their style updated
    for (var _i8 = 0; _i8 < alteredParents.length; _i8++) {
      var _ele6 = alteredParents[_i8];
      if (!removeFromPool || !_ele6.removed()) {
        _ele6.updateStyle();
      }
    }
    return removedElements;
  };
  elesfn$1.move = function (struct) {
    var cy = this._private.cy;
    var eles = this;

    // just clean up refs, caches, etc. in the same way as when removing and then restoring
    // (our calls to remove/restore do not remove from the graph or make events)
    var notifyRenderer = false;
    var modifyPool = false;
    var toString = function toString(id) {
      return id == null ? id : '' + id;
    }; // id must be string

    if (struct.source !== undefined || struct.target !== undefined) {
      var srcId = toString(struct.source);
      var tgtId = toString(struct.target);
      var srcExists = srcId != null && cy.hasElementWithId(srcId);
      var tgtExists = tgtId != null && cy.hasElementWithId(tgtId);
      if (srcExists || tgtExists) {
        cy.batch(function () {
          // avoid duplicate style updates
          eles.remove(notifyRenderer, modifyPool); // clean up refs etc.
          eles.emitAndNotify('moveout');
          for (var i = 0; i < eles.length; i++) {
            var ele = eles[i];
            var _data5 = ele._private.data;
            if (ele.isEdge()) {
              if (srcExists) {
                _data5.source = srcId;
              }
              if (tgtExists) {
                _data5.target = tgtId;
              }
            }
          }
          eles.restore(notifyRenderer, modifyPool); // make new refs, style, etc.
        });

        eles.emitAndNotify('move');
      }
    } else if (struct.parent !== undefined) {
      // move node to new parent
      var parentId = toString(struct.parent);
      var parentExists = parentId === null || cy.hasElementWithId(parentId);
      if (parentExists) {
        var pidToAssign = parentId === null ? undefined : parentId;
        cy.batch(function () {
          // avoid duplicate style updates
          var updated = eles.remove(notifyRenderer, modifyPool); // clean up refs etc.
          updated.emitAndNotify('moveout');
          for (var i = 0; i < eles.length; i++) {
            var ele = eles[i];
            var _data6 = ele._private.data;
            if (ele.isNode()) {
              _data6.parent = pidToAssign;
            }
          }
          updated.restore(notifyRenderer, modifyPool); // make new refs, style, etc.
        });

        eles.emitAndNotify('move');
      }
    }
    return this;
  };
  [elesfn$j, elesfn$i, elesfn$h, elesfn$g, elesfn$f, data, elesfn$d, dimensions, elesfn$9, elesfn$8, elesfn$7, elesfn$6, elesfn$5, elesfn$4, elesfn$3, elesfn$2].forEach(function (props) {
    extend(elesfn$1, props);
  });

  var corefn$9 = {
    add: function add(opts) {
      var elements;
      var cy = this;

      // add the elements
      if (elementOrCollection(opts)) {
        var eles = opts;
        if (eles._private.cy === cy) {
          // same instance => just restore
          elements = eles.restore();
        } else {
          // otherwise, copy from json
          var jsons = [];
          for (var i = 0; i < eles.length; i++) {
            var ele = eles[i];
            jsons.push(ele.json());
          }
          elements = new Collection(cy, jsons);
        }
      }

      // specify an array of options
      else if (array(opts)) {
        var _jsons = opts;
        elements = new Collection(cy, _jsons);
      }

      // specify via opts.nodes and opts.edges
      else if (plainObject(opts) && (array(opts.nodes) || array(opts.edges))) {
        var elesByGroup = opts;
        var _jsons2 = [];
        var grs = ['nodes', 'edges'];
        for (var _i = 0, il = grs.length; _i < il; _i++) {
          var group = grs[_i];
          var elesArray = elesByGroup[group];
          if (array(elesArray)) {
            for (var j = 0, jl = elesArray.length; j < jl; j++) {
              var json = extend({
                group: group
              }, elesArray[j]);
              _jsons2.push(json);
            }
          }
        }
        elements = new Collection(cy, _jsons2);
      }

      // specify options for one element
      else {
        var _json = opts;
        elements = new Element(cy, _json).collection();
      }
      return elements;
    },
    remove: function remove(collection) {
      if (elementOrCollection(collection)) ; else if (string(collection)) {
        var selector = collection;
        collection = this.$(selector);
      }
      return collection.remove();
    }
  };

  /* global Float32Array */

  /*! Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License */
  function generateCubicBezier(mX1, mY1, mX2, mY2) {
    var NEWTON_ITERATIONS = 4,
      NEWTON_MIN_SLOPE = 0.001,
      SUBDIVISION_PRECISION = 0.0000001,
      SUBDIVISION_MAX_ITERATIONS = 10,
      kSplineTableSize = 11,
      kSampleStepSize = 1.0 / (kSplineTableSize - 1.0),
      float32ArraySupported = typeof Float32Array !== 'undefined';

    /* Must contain four arguments. */
    if (arguments.length !== 4) {
      return false;
    }

    /* Arguments must be numbers. */
    for (var i = 0; i < 4; ++i) {
      if (typeof arguments[i] !== "number" || isNaN(arguments[i]) || !isFinite(arguments[i])) {
        return false;
      }
    }

    /* X values must be in the [0, 1] range. */
    mX1 = Math.min(mX1, 1);
    mX2 = Math.min(mX2, 1);
    mX1 = Math.max(mX1, 0);
    mX2 = Math.max(mX2, 0);
    var mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);
    function A(aA1, aA2) {
      return 1.0 - 3.0 * aA2 + 3.0 * aA1;
    }
    function B(aA1, aA2) {
      return 3.0 * aA2 - 6.0 * aA1;
    }
    function C(aA1) {
      return 3.0 * aA1;
    }
    function calcBezier(aT, aA1, aA2) {
      return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;
    }
    function getSlope(aT, aA1, aA2) {
      return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);
    }
    function newtonRaphsonIterate(aX, aGuessT) {
      for (var _i = 0; _i < NEWTON_ITERATIONS; ++_i) {
        var currentSlope = getSlope(aGuessT, mX1, mX2);
        if (currentSlope === 0.0) {
          return aGuessT;
        }
        var currentX = calcBezier(aGuessT, mX1, mX2) - aX;
        aGuessT -= currentX / currentSlope;
      }
      return aGuessT;
    }
    function calcSampleValues() {
      for (var _i2 = 0; _i2 < kSplineTableSize; ++_i2) {
        mSampleValues[_i2] = calcBezier(_i2 * kSampleStepSize, mX1, mX2);
      }
    }
    function binarySubdivide(aX, aA, aB) {
      var currentX,
        currentT,
        i = 0;
      do {
        currentT = aA + (aB - aA) / 2.0;
        currentX = calcBezier(currentT, mX1, mX2) - aX;
        if (currentX > 0.0) {
          aB = currentT;
        } else {
          aA = currentT;
        }
      } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);
      return currentT;
    }
    function getTForX(aX) {
      var intervalStart = 0.0,
        currentSample = 1,
        lastSample = kSplineTableSize - 1;
      for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {
        intervalStart += kSampleStepSize;
      }
      --currentSample;
      var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]),
        guessForT = intervalStart + dist * kSampleStepSize,
        initialSlope = getSlope(guessForT, mX1, mX2);
      if (initialSlope >= NEWTON_MIN_SLOPE) {
        return newtonRaphsonIterate(aX, guessForT);
      } else if (initialSlope === 0.0) {
        return guessForT;
      } else {
        return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize);
      }
    }
    var _precomputed = false;
    function precompute() {
      _precomputed = true;
      if (mX1 !== mY1 || mX2 !== mY2) {
        calcSampleValues();
      }
    }
    var f = function f(aX) {
      if (!_precomputed) {
        precompute();
      }
      if (mX1 === mY1 && mX2 === mY2) {
        return aX;
      }
      if (aX === 0) {
        return 0;
      }
      if (aX === 1) {
        return 1;
      }
      return calcBezier(getTForX(aX), mY1, mY2);
    };
    f.getControlPoints = function () {
      return [{
        x: mX1,
        y: mY1
      }, {
        x: mX2,
        y: mY2
      }];
    };
    var str = "generateBezier(" + [mX1, mY1, mX2, mY2] + ")";
    f.toString = function () {
      return str;
    };
    return f;
  }

  /*! Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */
  /* 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. */
  var generateSpringRK4 = function () {
    function springAccelerationForState(state) {
      return -state.tension * state.x - state.friction * state.v;
    }
    function springEvaluateStateWithDerivative(initialState, dt, derivative) {
      var state = {
        x: initialState.x + derivative.dx * dt,
        v: initialState.v + derivative.dv * dt,
        tension: initialState.tension,
        friction: initialState.friction
      };
      return {
        dx: state.v,
        dv: springAccelerationForState(state)
      };
    }
    function springIntegrateState(state, dt) {
      var a = {
          dx: state.v,
          dv: springAccelerationForState(state)
        },
        b = springEvaluateStateWithDerivative(state, dt * 0.5, a),
        c = springEvaluateStateWithDerivative(state, dt * 0.5, b),
        d = springEvaluateStateWithDerivative(state, dt, c),
        dxdt = 1.0 / 6.0 * (a.dx + 2.0 * (b.dx + c.dx) + d.dx),
        dvdt = 1.0 / 6.0 * (a.dv + 2.0 * (b.dv + c.dv) + d.dv);
      state.x = state.x + dxdt * dt;
      state.v = state.v + dvdt * dt;
      return state;
    }
    return function springRK4Factory(tension, friction, duration) {
      var initState = {
          x: -1,
          v: 0,
          tension: null,
          friction: null
        },
        path = [0],
        time_lapsed = 0,
        tolerance = 1 / 10000,
        DT = 16 / 1000,
        have_duration,
        dt,
        last_state;
      tension = parseFloat(tension) || 500;
      friction = parseFloat(friction) || 20;
      duration = duration || null;
      initState.tension = tension;
      initState.friction = friction;
      have_duration = duration !== null;

      /* Calculate the actual time it takes for this animation to complete with the provided conditions. */
      if (have_duration) {
        /* Run the simulation without a duration. */
        time_lapsed = springRK4Factory(tension, friction);
        /* Compute the adjusted time delta. */
        dt = time_lapsed / duration * DT;
      } else {
        dt = DT;
      }
      for (;;) {
        /* Next/step function .*/
        last_state = springIntegrateState(last_state || initState, dt);
        /* Store the position. */
        path.push(1 + last_state.x);
        time_lapsed += 16;
        /* If the change threshold is reached, break. */
        if (!(Math.abs(last_state.x) > tolerance && Math.abs(last_state.v) > tolerance)) {
          break;
        }
      }

      /* 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. */
      return !have_duration ? time_lapsed : function (percentComplete) {
        return path[percentComplete * (path.length - 1) | 0];
      };
    };
  }();

  var cubicBezier = function cubicBezier(t1, p1, t2, p2) {
    var bezier = generateCubicBezier(t1, p1, t2, p2);
    return function (start, end, percent) {
      return start + (end - start) * bezier(percent);
    };
  };
  var easings = {
    'linear': function linear(start, end, percent) {
      return start + (end - start) * percent;
    },
    // default easings
    'ease': cubicBezier(0.25, 0.1, 0.25, 1),
    'ease-in': cubicBezier(0.42, 0, 1, 1),
    'ease-out': cubicBezier(0, 0, 0.58, 1),
    'ease-in-out': cubicBezier(0.42, 0, 0.58, 1),
    // sine
    'ease-in-sine': cubicBezier(0.47, 0, 0.745, 0.715),
    'ease-out-sine': cubicBezier(0.39, 0.575, 0.565, 1),
    'ease-in-out-sine': cubicBezier(0.445, 0.05, 0.55, 0.95),
    // quad
    'ease-in-quad': cubicBezier(0.55, 0.085, 0.68, 0.53),
    'ease-out-quad': cubicBezier(0.25, 0.46, 0.45, 0.94),
    'ease-in-out-quad': cubicBezier(0.455, 0.03, 0.515, 0.955),
    // cubic
    'ease-in-cubic': cubicBezier(0.55, 0.055, 0.675, 0.19),
    'ease-out-cubic': cubicBezier(0.215, 0.61, 0.355, 1),
    'ease-in-out-cubic': cubicBezier(0.645, 0.045, 0.355, 1),
    // quart
    'ease-in-quart': cubicBezier(0.895, 0.03, 0.685, 0.22),
    'ease-out-quart': cubicBezier(0.165, 0.84, 0.44, 1),
    'ease-in-out-quart': cubicBezier(0.77, 0, 0.175, 1),
    // quint
    'ease-in-quint': cubicBezier(0.755, 0.05, 0.855, 0.06),
    'ease-out-quint': cubicBezier(0.23, 1, 0.32, 1),
    'ease-in-out-quint': cubicBezier(0.86, 0, 0.07, 1),
    // expo
    'ease-in-expo': cubicBezier(0.95, 0.05, 0.795, 0.035),
    'ease-out-expo': cubicBezier(0.19, 1, 0.22, 1),
    'ease-in-out-expo': cubicBezier(1, 0, 0, 1),
    // circ
    'ease-in-circ': cubicBezier(0.6, 0.04, 0.98, 0.335),
    'ease-out-circ': cubicBezier(0.075, 0.82, 0.165, 1),
    'ease-in-out-circ': cubicBezier(0.785, 0.135, 0.15, 0.86),
    // user param easings...

    'spring': function spring(tension, friction, duration) {
      if (duration === 0) {
        // can't get a spring w/ duration 0
        return easings.linear; // duration 0 => jump to end so impl doesn't matter
      }

      var spring = generateSpringRK4(tension, friction, duration);
      return function (start, end, percent) {
        return start + (end - start) * spring(percent);
      };
    },
    'cubic-bezier': cubicBezier
  };

  function getEasedValue(type, start, end, percent, easingFn) {
    if (percent === 1) {
      return end;
    }
    if (start === end) {
      return end;
    }
    var val = easingFn(start, end, percent);
    if (type == null) {
      return val;
    }
    if (type.roundValue || type.color) {
      val = Math.round(val);
    }
    if (type.min !== undefined) {
      val = Math.max(val, type.min);
    }
    if (type.max !== undefined) {
      val = Math.min(val, type.max);
    }
    return val;
  }
  function getValue(prop, spec) {
    if (prop.pfValue != null || prop.value != null) {
      if (prop.pfValue != null && (spec == null || spec.type.units !== '%')) {
        return prop.pfValue;
      } else {
        return prop.value;
      }
    } else {
      return prop;
    }
  }
  function ease(startProp, endProp, percent, easingFn, propSpec) {
    var type = propSpec != null ? propSpec.type : null;
    if (percent < 0) {
      percent = 0;
    } else if (percent > 1) {
      percent = 1;
    }
    var start = getValue(startProp, propSpec);
    var end = getValue(endProp, propSpec);
    if (number$1(start) && number$1(end)) {
      return getEasedValue(type, start, end, percent, easingFn);
    } else if (array(start) && array(end)) {
      var easedArr = [];
      for (var i = 0; i < end.length; i++) {
        var si = start[i];
        var ei = end[i];
        if (si != null && ei != null) {
          var val = getEasedValue(type, si, ei, percent, easingFn);
          easedArr.push(val);
        } else {
          easedArr.push(ei);
        }
      }
      return easedArr;
    }
    return undefined;
  }

  function step$1(self, ani, now, isCore) {
    var isEles = !isCore;
    var _p = self._private;
    var ani_p = ani._private;
    var pEasing = ani_p.easing;
    var startTime = ani_p.startTime;
    var cy = isCore ? self : self.cy();
    var style = cy.style();
    if (!ani_p.easingImpl) {
      if (pEasing == null) {
        // use default
        ani_p.easingImpl = easings['linear'];
      } else {
        // then define w/ name
        var easingVals;
        if (string(pEasing)) {
          var easingProp = style.parse('transition-timing-function', pEasing);
          easingVals = easingProp.value;
        } else {
          // then assume preparsed array
          easingVals = pEasing;
        }
        var name, args;
        if (string(easingVals)) {
          name = easingVals;
          args = [];
        } else {
          name = easingVals[1];
          args = easingVals.slice(2).map(function (n) {
            return +n;
          });
        }
        if (args.length > 0) {
          // create with args
          if (name === 'spring') {
            args.push(ani_p.duration); // need duration to generate spring
          }

          ani_p.easingImpl = easings[name].apply(null, args);
        } else {
          // static impl by name
          ani_p.easingImpl = easings[name];
        }
      }
    }
    var easing = ani_p.easingImpl;
    var percent;
    if (ani_p.duration === 0) {
      percent = 1;
    } else {
      percent = (now - startTime) / ani_p.duration;
    }
    if (ani_p.applying) {
      percent = ani_p.progress;
    }
    if (percent < 0) {
      percent = 0;
    } else if (percent > 1) {
      percent = 1;
    }
    if (ani_p.delay == null) {
      // then update

      var startPos = ani_p.startPosition;
      var endPos = ani_p.position;
      if (endPos && isEles && !self.locked()) {
        var newPos = {};
        if (valid(startPos.x, endPos.x)) {
          newPos.x = ease(startPos.x, endPos.x, percent, easing);
        }
        if (valid(startPos.y, endPos.y)) {
          newPos.y = ease(startPos.y, endPos.y, percent, easing);
        }
        self.position(newPos);
      }
      var startPan = ani_p.startPan;
      var endPan = ani_p.pan;
      var pan = _p.pan;
      var animatingPan = endPan != null && isCore;
      if (animatingPan) {
        if (valid(startPan.x, endPan.x)) {
          pan.x = ease(startPan.x, endPan.x, percent, easing);
        }
        if (valid(startPan.y, endPan.y)) {
          pan.y = ease(startPan.y, endPan.y, percent, easing);
        }
        self.emit('pan');
      }
      var startZoom = ani_p.startZoom;
      var endZoom = ani_p.zoom;
      var animatingZoom = endZoom != null && isCore;
      if (animatingZoom) {
        if (valid(startZoom, endZoom)) {
          _p.zoom = bound(_p.minZoom, ease(startZoom, endZoom, percent, easing), _p.maxZoom);
        }
        self.emit('zoom');
      }
      if (animatingPan || animatingZoom) {
        self.emit('viewport');
      }
      var props = ani_p.style;
      if (props && props.length > 0 && isEles) {
        for (var i = 0; i < props.length; i++) {
          var prop = props[i];
          var _name = prop.name;
          var end = prop;
          var start = ani_p.startStyle[_name];
          var propSpec = style.properties[start.name];
          var easedVal = ease(start, end, percent, easing, propSpec);
          style.overrideBypass(self, _name, easedVal);
        } // for props

        self.emit('style');
      } // if
    }

    ani_p.progress = percent;
    return percent;
  }
  function valid(start, end) {
    if (start == null || end == null) {
      return false;
    }
    if (number$1(start) && number$1(end)) {
      return true;
    } else if (start && end) {
      return true;
    }
    return false;
  }

  function startAnimation(self, ani, now, isCore) {
    var ani_p = ani._private;
    ani_p.started = true;
    ani_p.startTime = now - ani_p.progress * ani_p.duration;
  }

  function stepAll(now, cy) {
    var eles = cy._private.aniEles;
    var doneEles = [];
    function stepOne(ele, isCore) {
      var _p = ele._private;
      var current = _p.animation.current;
      var queue = _p.animation.queue;
      var ranAnis = false;

      // if nothing currently animating, get something from the queue
      if (current.length === 0) {
        var next = queue.shift();
        if (next) {
          current.push(next);
        }
      }
      var callbacks = function callbacks(_callbacks) {
        for (var j = _callbacks.length - 1; j >= 0; j--) {
          var cb = _callbacks[j];
          cb();
        }
        _callbacks.splice(0, _callbacks.length);
      };

      // step and remove if done
      for (var i = current.length - 1; i >= 0; i--) {
        var ani = current[i];
        var ani_p = ani._private;
        if (ani_p.stopped) {
          current.splice(i, 1);
          ani_p.hooked = false;
          ani_p.playing = false;
          ani_p.started = false;
          callbacks(ani_p.frames);
          continue;
        }
        if (!ani_p.playing && !ani_p.applying) {
          continue;
        }

        // an apply() while playing shouldn't do anything
        if (ani_p.playing && ani_p.applying) {
          ani_p.applying = false;
        }
        if (!ani_p.started) {
          startAnimation(ele, ani, now);
        }
        step$1(ele, ani, now, isCore);
        if (ani_p.applying) {
          ani_p.applying = false;
        }
        callbacks(ani_p.frames);
        if (ani_p.step != null) {
          ani_p.step(now);
        }
        if (ani.completed()) {
          current.splice(i, 1);
          ani_p.hooked = false;
          ani_p.playing = false;
          ani_p.started = false;
          callbacks(ani_p.completes);
        }
        ranAnis = true;
      }
      if (!isCore && current.length === 0 && queue.length === 0) {
        doneEles.push(ele);
      }
      return ranAnis;
    } // stepElement

    // handle all eles
    var ranEleAni = false;
    for (var e = 0; e < eles.length; e++) {
      var ele = eles[e];
      var handledThisEle = stepOne(ele);
      ranEleAni = ranEleAni || handledThisEle;
    } // each element

    var ranCoreAni = stepOne(cy, true);

    // notify renderer
    if (ranEleAni || ranCoreAni) {
      if (eles.length > 0) {
        cy.notify('draw', eles);
      } else {
        cy.notify('draw');
      }
    }

    // remove elements from list of currently animating if its queues are empty
    eles.unmerge(doneEles);
    cy.emit('step');
  } // stepAll

  var corefn$8 = {
    // pull in animation functions
    animate: define.animate(),
    animation: define.animation(),
    animated: define.animated(),
    clearQueue: define.clearQueue(),
    delay: define.delay(),
    delayAnimation: define.delayAnimation(),
    stop: define.stop(),
    addToAnimationPool: function addToAnimationPool(eles) {
      var cy = this;
      if (!cy.styleEnabled()) {
        return;
      } // save cycles when no style used

      cy._private.aniEles.merge(eles);
    },
    stopAnimationLoop: function stopAnimationLoop() {
      this._private.animationsRunning = false;
    },
    startAnimationLoop: function startAnimationLoop() {
      var cy = this;
      cy._private.animationsRunning = true;
      if (!cy.styleEnabled()) {
        return;
      } // save cycles when no style used

      // NB the animation loop will exec in headless environments if style enabled
      // and explicit cy.destroy() is necessary to stop the loop

      function headlessStep() {
        if (!cy._private.animationsRunning) {
          return;
        }
        requestAnimationFrame(function animationStep(now) {
          stepAll(now, cy);
          headlessStep();
        });
      }
      var renderer = cy.renderer();
      if (renderer && renderer.beforeRender) {
        // let the renderer schedule animations
        renderer.beforeRender(function rendererAnimationStep(willDraw, now) {
          stepAll(now, cy);
        }, renderer.beforeRenderPriorities.animations);
      } else {
        // manage the animation loop ourselves
        headlessStep(); // first call
      }
    }
  };

  var emitterOptions = {
    qualifierCompare: function qualifierCompare(selector1, selector2) {
      if (selector1 == null || selector2 == null) {
        return selector1 == null && selector2 == null;
      } else {
        return selector1.sameText(selector2);
      }
    },
    eventMatches: function eventMatches(cy, listener, eventObj) {
      var selector = listener.qualifier;
      if (selector != null) {
        return cy !== eventObj.target && element(eventObj.target) && selector.matches(eventObj.target);
      }
      return true;
    },
    addEventFields: function addEventFields(cy, evt) {
      evt.cy = cy;
      evt.target = cy;
    },
    callbackContext: function callbackContext(cy, listener, eventObj) {
      return listener.qualifier != null ? eventObj.target : cy;
    }
  };
  var argSelector = function argSelector(arg) {
    if (string(arg)) {
      return new Selector(arg);
    } else {
      return arg;
    }
  };
  var elesfn = {
    createEmitter: function createEmitter() {
      var _p = this._private;
      if (!_p.emitter) {
        _p.emitter = new Emitter(emitterOptions, this);
      }
      return this;
    },
    emitter: function emitter() {
      return this._private.emitter;
    },
    on: function on(events, selector, callback) {
      this.emitter().on(events, argSelector(selector), callback);
      return this;
    },
    removeListener: function removeListener(events, selector, callback) {
      this.emitter().removeListener(events, argSelector(selector), callback);
      return this;
    },
    removeAllListeners: function removeAllListeners() {
      this.emitter().removeAllListeners();
      return this;
    },
    one: function one(events, selector, callback) {
      this.emitter().one(events, argSelector(selector), callback);
      return this;
    },
    once: function once(events, selector, callback) {
      this.emitter().one(events, argSelector(selector), callback);
      return this;
    },
    emit: function emit(events, extraParams) {
      this.emitter().emit(events, extraParams);
      return this;
    },
    emitAndNotify: function emitAndNotify(event, eles) {
      this.emit(event);
      this.notify(event, eles);
      return this;
    }
  };
  define.eventAliasesOn(elesfn);

  var corefn$7 = {
    png: function png(options) {
      var renderer = this._private.renderer;
      options = options || {};
      return renderer.png(options);
    },
    jpg: function jpg(options) {
      var renderer = this._private.renderer;
      options = options || {};
      options.bg = options.bg || '#fff';
      return renderer.jpg(options);
    }
  };
  corefn$7.jpeg = corefn$7.jpg;

  var corefn$6 = {
    layout: function layout(options) {
      var cy = this;
      if (options == null) {
        error('Layout options must be specified to make a layout');
        return;
      }
      if (options.name == null) {
        error('A `name` must be specified to make a layout');
        return;
      }
      var name = options.name;
      var Layout = cy.extension('layout', name);
      if (Layout == null) {
        error('No such layout `' + name + '` found.  Did you forget to import it and `cytoscape.use()` it?');
        return;
      }
      var eles;
      if (string(options.eles)) {
        eles = cy.$(options.eles);
      } else {
        eles = options.eles != null ? options.eles : cy.$();
      }
      var layout = new Layout(extend({}, options, {
        cy: cy,
        eles: eles
      }));
      return layout;
    }
  };
  corefn$6.createLayout = corefn$6.makeLayout = corefn$6.layout;

  var corefn$5 = {
    notify: function notify(eventName, eventEles) {
      var _p = this._private;
      if (this.batching()) {
        _p.batchNotifications = _p.batchNotifications || {};
        var eles = _p.batchNotifications[eventName] = _p.batchNotifications[eventName] || this.collection();
        if (eventEles != null) {
          eles.merge(eventEles);
        }
        return; // notifications are disabled during batching
      }

      if (!_p.notificationsEnabled) {
        return;
      } // exit on disabled

      var renderer = this.renderer();

      // exit if destroy() called on core or renderer in between frames #1499 #1528
      if (this.destroyed() || !renderer) {
        return;
      }
      renderer.notify(eventName, eventEles);
    },
    notifications: function notifications(bool) {
      var p = this._private;
      if (bool === undefined) {
        return p.notificationsEnabled;
      } else {
        p.notificationsEnabled = bool ? true : false;
      }
      return this;
    },
    noNotifications: function noNotifications(callback) {
      this.notifications(false);
      callback();
      this.notifications(true);
    },
    batching: function batching() {
      return this._private.batchCount > 0;
    },
    startBatch: function startBatch() {
      var _p = this._private;
      if (_p.batchCount == null) {
        _p.batchCount = 0;
      }
      if (_p.batchCount === 0) {
        _p.batchStyleEles = this.collection();
        _p.batchNotifications = {};
      }
      _p.batchCount++;
      return this;
    },
    endBatch: function endBatch() {
      var _p = this._private;
      if (_p.batchCount === 0) {
        return this;
      }
      _p.batchCount--;
      if (_p.batchCount === 0) {
        // update style for dirty eles
        _p.batchStyleEles.updateStyle();
        var renderer = this.renderer();

        // notify the renderer of queued eles and event types
        Object.keys(_p.batchNotifications).forEach(function (eventName) {
          var eles = _p.batchNotifications[eventName];
          if (eles.empty()) {
            renderer.notify(eventName);
          } else {
            renderer.notify(eventName, eles);
          }
        });
      }
      return this;
    },
    batch: function batch(callback) {
      this.startBatch();
      callback();
      this.endBatch();
      return this;
    },
    // for backwards compatibility
    batchData: function batchData(map) {
      var cy = this;
      return this.batch(function () {
        var ids = Object.keys(map);
        for (var i = 0; i < ids.length; i++) {
          var id = ids[i];
          var data = map[id];
          var ele = cy.getElementById(id);
          ele.data(data);
        }
      });
    }
  };

  var rendererDefaults = defaults$g({
    hideEdgesOnViewport: false,
    textureOnViewport: false,
    motionBlur: false,
    motionBlurOpacity: 0.05,
    pixelRatio: undefined,
    desktopTapThreshold: 4,
    touchTapThreshold: 8,
    wheelSensitivity: 1,
    debug: false,
    showFps: false
  });
  var corefn$4 = {
    renderTo: function renderTo(context, zoom, pan, pxRatio) {
      var r = this._private.renderer;
      r.renderTo(context, zoom, pan, pxRatio);
      return this;
    },
    renderer: function renderer() {
      return this._private.renderer;
    },
    forceRender: function forceRender() {
      this.notify('draw');
      return this;
    },
    resize: function resize() {
      this.invalidateSize();
      this.emitAndNotify('resize');
      return this;
    },
    initRenderer: function initRenderer(options) {
      var cy = this;
      var RendererProto = cy.extension('renderer', options.name);
      if (RendererProto == null) {
        error("Can not initialise: No such renderer `".concat(options.name, "` found. Did you forget to import it and `cytoscape.use()` it?"));
        return;
      }
      if (options.wheelSensitivity !== undefined) {
        warn("You have set a custom wheel sensitivity.  This will make your app zoom unnaturally when using mainstream mice.  You should change this value from the default only if you can guarantee that all your users will use the same hardware and OS configuration as your current machine.");
      }
      var rOpts = rendererDefaults(options);
      rOpts.cy = cy;
      cy._private.renderer = new RendererProto(rOpts);
      this.notify('init');
    },
    destroyRenderer: function destroyRenderer() {
      var cy = this;
      cy.notify('destroy'); // destroy the renderer

      var domEle = cy.container();
      if (domEle) {
        domEle._cyreg = null;
        while (domEle.childNodes.length > 0) {
          domEle.removeChild(domEle.childNodes[0]);
        }
      }
      cy._private.renderer = null; // to be extra safe, remove the ref
      cy.mutableElements().forEach(function (ele) {
        var _p = ele._private;
        _p.rscratch = {};
        _p.rstyle = {};
        _p.animation.current = [];
        _p.animation.queue = [];
      });
    },
    onRender: function onRender(fn) {
      return this.on('render', fn);
    },
    offRender: function offRender(fn) {
      return this.off('render', fn);
    }
  };
  corefn$4.invalidateDimensions = corefn$4.resize;

  var corefn$3 = {
    // get a collection
    // - empty collection on no args
    // - collection of elements in the graph on selector arg
    // - guarantee a returned collection when elements or collection specified
    collection: function collection(eles, opts) {
      if (string(eles)) {
        return this.$(eles);
      } else if (elementOrCollection(eles)) {
        return eles.collection();
      } else if (array(eles)) {
        if (!opts) {
          opts = {};
        }
        return new Collection(this, eles, opts.unique, opts.removed);
      }
      return new Collection(this);
    },
    nodes: function nodes(selector) {
      var nodes = this.$(function (ele) {
        return ele.isNode();
      });
      if (selector) {
        return nodes.filter(selector);
      }
      return nodes;
    },
    edges: function edges(selector) {
      var edges = this.$(function (ele) {
        return ele.isEdge();
      });
      if (selector) {
        return edges.filter(selector);
      }
      return edges;
    },
    // search the graph like jQuery
    $: function $(selector) {
      var eles = this._private.elements;
      if (selector) {
        return eles.filter(selector);
      } else {
        return eles.spawnSelf();
      }
    },
    mutableElements: function mutableElements() {
      return this._private.elements;
    }
  };

  // aliases
  corefn$3.elements = corefn$3.filter = corefn$3.$;

  var styfn$8 = {};

  // keys for style blocks, e.g. ttfftt
  var TRUE = 't';
  var FALSE = 'f';

  // (potentially expensive calculation)
  // apply the style to the element based on
  // - its bypass
  // - what selectors match it
  styfn$8.apply = function (eles) {
    var self = this;
    var _p = self._private;
    var cy = _p.cy;
    var updatedEles = cy.collection();
    for (var ie = 0; ie < eles.length; ie++) {
      var ele = eles[ie];
      var cxtMeta = self.getContextMeta(ele);
      if (cxtMeta.empty) {
        continue;
      }
      var cxtStyle = self.getContextStyle(cxtMeta);
      var app = self.applyContextStyle(cxtMeta, cxtStyle, ele);
      if (ele._private.appliedInitStyle) {
        self.updateTransitions(ele, app.diffProps);
      } else {
        ele._private.appliedInitStyle = true;
      }
      var hintsDiff = self.updateStyleHints(ele);
      if (hintsDiff) {
        updatedEles.push(ele);
      }
    } // for elements

    return updatedEles;
  };
  styfn$8.getPropertiesDiff = function (oldCxtKey, newCxtKey) {
    var self = this;
    var cache = self._private.propDiffs = self._private.propDiffs || {};
    var dualCxtKey = oldCxtKey + '-' + newCxtKey;
    var cachedVal = cache[dualCxtKey];
    if (cachedVal) {
      return cachedVal;
    }
    var diffProps = [];
    var addedProp = {};
    for (var i = 0; i < self.length; i++) {
      var cxt = self[i];
      var oldHasCxt = oldCxtKey[i] === TRUE;
      var newHasCxt = newCxtKey[i] === TRUE;
      var cxtHasDiffed = oldHasCxt !== newHasCxt;
      var cxtHasMappedProps = cxt.mappedProperties.length > 0;
      if (cxtHasDiffed || newHasCxt && cxtHasMappedProps) {
        var props = void 0;
        if (cxtHasDiffed && cxtHasMappedProps) {
          props = cxt.properties; // suffices b/c mappedProperties is a subset of properties
        } else if (cxtHasDiffed) {
          props = cxt.properties; // need to check them all
        } else if (cxtHasMappedProps) {
          props = cxt.mappedProperties; // only need to check mapped
        }

        for (var j = 0; j < props.length; j++) {
          var prop = props[j];
          var name = prop.name;

          // if a later context overrides this property, then the fact that this context has switched/diffed doesn't matter
          // (semi expensive check since it makes this function O(n^2) on context length, but worth it since overall result
          // is cached)
          var laterCxtOverrides = false;
          for (var k = i + 1; k < self.length; k++) {
            var laterCxt = self[k];
            var hasLaterCxt = newCxtKey[k] === TRUE;
            if (!hasLaterCxt) {
              continue;
            } // can't override unless the context is active

            laterCxtOverrides = laterCxt.properties[prop.name] != null;
            if (laterCxtOverrides) {
              break;
            } // exit early as long as one later context overrides
          }

          if (!addedProp[name] && !laterCxtOverrides) {
            addedProp[name] = true;
            diffProps.push(name);
          }
        } // for props
      } // if
    } // for contexts

    cache[dualCxtKey] = diffProps;
    return diffProps;
  };
  styfn$8.getContextMeta = function (ele) {
    var self = this;
    var cxtKey = '';
    var diffProps;
    var prevKey = ele._private.styleCxtKey || '';

    // get the cxt key
    for (var i = 0; i < self.length; i++) {
      var context = self[i];
      var contextSelectorMatches = context.selector && context.selector.matches(ele); // NB: context.selector may be null for 'core'

      if (contextSelectorMatches) {
        cxtKey += TRUE;
      } else {
        cxtKey += FALSE;
      }
    } // for context

    diffProps = self.getPropertiesDiff(prevKey, cxtKey);
    ele._private.styleCxtKey = cxtKey;
    return {
      key: cxtKey,
      diffPropNames: diffProps,
      empty: diffProps.length === 0
    };
  };

  // gets a computed ele style object based on matched contexts
  styfn$8.getContextStyle = function (cxtMeta) {
    var cxtKey = cxtMeta.key;
    var self = this;
    var cxtStyles = this._private.contextStyles = this._private.contextStyles || {};

    // if already computed style, returned cached copy
    if (cxtStyles[cxtKey]) {
      return cxtStyles[cxtKey];
    }
    var style = {
      _private: {
        key: cxtKey
      }
    };
    for (var i = 0; i < self.length; i++) {
      var cxt = self[i];
      var hasCxt = cxtKey[i] === TRUE;
      if (!hasCxt) {
        continue;
      }
      for (var j = 0; j < cxt.properties.length; j++) {
        var prop = cxt.properties[j];
        style[prop.name] = prop;
      }
    }
    cxtStyles[cxtKey] = style;
    return style;
  };
  styfn$8.applyContextStyle = function (cxtMeta, cxtStyle, ele) {
    var self = this;
    var diffProps = cxtMeta.diffPropNames;
    var retDiffProps = {};
    var types = self.types;
    for (var i = 0; i < diffProps.length; i++) {
      var diffPropName = diffProps[i];
      var cxtProp = cxtStyle[diffPropName];
      var eleProp = ele.pstyle(diffPropName);
      if (!cxtProp) {
        // no context prop means delete
        if (!eleProp) {
          continue; // no existing prop means nothing needs to be removed
          // nb affects initial application on mapped values like control-point-distances
        } else if (eleProp.bypass) {
          cxtProp = {
            name: diffPropName,
            deleteBypassed: true
          };
        } else {
          cxtProp = {
            name: diffPropName,
            "delete": true
          };
        }
      }

      // save cycles when the context prop doesn't need to be applied
      if (eleProp === cxtProp) {
        continue;
      }

      // save cycles when a mapped context prop doesn't need to be applied
      if (cxtProp.mapped === types.fn // context prop is function mapper
      && eleProp != null // some props can be null even by default (e.g. a prop that overrides another one)
      && eleProp.mapping != null // ele prop is a concrete value from from a mapper
      && eleProp.mapping.value === cxtProp.value // the current prop on the ele is a flat prop value for the function mapper
      ) {
        // NB don't write to cxtProp, as it's shared among eles (stored in stylesheet)
        var mapping = eleProp.mapping; // can write to mapping, as it's a per-ele copy
        var fnValue = mapping.fnValue = cxtProp.value(ele); // temporarily cache the value in case of a miss

        if (fnValue === mapping.prevFnValue) {
          continue;
        }
      }
      var retDiffProp = retDiffProps[diffPropName] = {
        prev: eleProp
      };
      self.applyParsedProperty(ele, cxtProp);
      retDiffProp.next = ele.pstyle(diffPropName);
      if (retDiffProp.next && retDiffProp.next.bypass) {
        retDiffProp.next = retDiffProp.next.bypassed;
      }
    }
    return {
      diffProps: retDiffProps
    };
  };
  styfn$8.updateStyleHints = function (ele) {
    var _p = ele._private;
    var self = this;
    var propNames = self.propertyGroupNames;
    var propGrKeys = self.propertyGroupKeys;
    var propHash = function propHash(ele, propNames, seedKey) {
      return self.getPropertiesHash(ele, propNames, seedKey);
    };
    var oldStyleKey = _p.styleKey;
    if (ele.removed()) {
      return false;
    }
    var isNode = _p.group === 'nodes';

    // get the style key hashes per prop group
    // but lazily -- only use non-default prop values to reduce the number of hashes
    //

    var overriddenStyles = ele._private.style;
    propNames = Object.keys(overriddenStyles);
    for (var i = 0; i < propGrKeys.length; i++) {
      var grKey = propGrKeys[i];
      _p.styleKeys[grKey] = [DEFAULT_HASH_SEED, DEFAULT_HASH_SEED_ALT];
    }
    var updateGrKey1 = function updateGrKey1(val, grKey) {
      return _p.styleKeys[grKey][0] = hashInt(val, _p.styleKeys[grKey][0]);
    };
    var updateGrKey2 = function updateGrKey2(val, grKey) {
      return _p.styleKeys[grKey][1] = hashIntAlt(val, _p.styleKeys[grKey][1]);
    };
    var updateGrKey = function updateGrKey(val, grKey) {
      updateGrKey1(val, grKey);
      updateGrKey2(val, grKey);
    };
    var updateGrKeyWStr = function updateGrKeyWStr(strVal, grKey) {
      for (var j = 0; j < strVal.length; j++) {
        var ch = strVal.charCodeAt(j);
        updateGrKey1(ch, grKey);
        updateGrKey2(ch, grKey);
      }
    };

    // - hashing works on 32 bit ints b/c we use bitwise ops
    // - small numbers get cut off (e.g. 0.123 is seen as 0 by the hashing function)
    // - raise up small numbers so more significant digits are seen by hashing
    // - make small numbers larger than a normal value to avoid collisions
    // - works in practice and it's relatively cheap
    var N = 2000000000;
    var cleanNum = function cleanNum(val) {
      return -128 < val && val < 128 && Math.floor(val) !== val ? N - (val * 1024 | 0) : val;
    };
    for (var _i = 0; _i < propNames.length; _i++) {
      var name = propNames[_i];
      var parsedProp = overriddenStyles[name];
      if (parsedProp == null) {
        continue;
      }
      var propInfo = this.properties[name];
      var type = propInfo.type;
      var _grKey = propInfo.groupKey;
      var normalizedNumberVal = void 0;
      if (propInfo.hashOverride != null) {
        normalizedNumberVal = propInfo.hashOverride(ele, parsedProp);
      } else if (parsedProp.pfValue != null) {
        normalizedNumberVal = parsedProp.pfValue;
      }

      // might not be a number if it allows enums
      var numberVal = propInfo.enums == null ? parsedProp.value : null;
      var haveNormNum = normalizedNumberVal != null;
      var haveUnitedNum = numberVal != null;
      var haveNum = haveNormNum || haveUnitedNum;
      var units = parsedProp.units;

      // numbers are cheaper to hash than strings
      // 1 hash op vs n hash ops (for length n string)
      if (type.number && haveNum && !type.multiple) {
        var v = haveNormNum ? normalizedNumberVal : numberVal;
        updateGrKey(cleanNum(v), _grKey);
        if (!haveNormNum && units != null) {
          updateGrKeyWStr(units, _grKey);
        }
      } else {
        updateGrKeyWStr(parsedProp.strValue, _grKey);
      }
    }

    // overall style key
    //

    var hash = [DEFAULT_HASH_SEED, DEFAULT_HASH_SEED_ALT];
    for (var _i2 = 0; _i2 < propGrKeys.length; _i2++) {
      var _grKey2 = propGrKeys[_i2];
      var grHash = _p.styleKeys[_grKey2];
      hash[0] = hashInt(grHash[0], hash[0]);
      hash[1] = hashIntAlt(grHash[1], hash[1]);
    }
    _p.styleKey = combineHashes(hash[0], hash[1]);

    // label dims
    //

    var sk = _p.styleKeys;
    _p.labelDimsKey = combineHashesArray(sk.labelDimensions);
    var labelKeys = propHash(ele, ['label'], sk.labelDimensions);
    _p.labelKey = combineHashesArray(labelKeys);
    _p.labelStyleKey = combineHashesArray(hashArrays(sk.commonLabel, labelKeys));
    if (!isNode) {
      var sourceLabelKeys = propHash(ele, ['source-label'], sk.labelDimensions);
      _p.sourceLabelKey = combineHashesArray(sourceLabelKeys);
      _p.sourceLabelStyleKey = combineHashesArray(hashArrays(sk.commonLabel, sourceLabelKeys));
      var targetLabelKeys = propHash(ele, ['target-label'], sk.labelDimensions);
      _p.targetLabelKey = combineHashesArray(targetLabelKeys);
      _p.targetLabelStyleKey = combineHashesArray(hashArrays(sk.commonLabel, targetLabelKeys));
    }

    // node
    //

    if (isNode) {
      var _p$styleKeys = _p.styleKeys,
        nodeBody = _p$styleKeys.nodeBody,
        nodeBorder = _p$styleKeys.nodeBorder,
        nodeOutline = _p$styleKeys.nodeOutline,
        backgroundImage = _p$styleKeys.backgroundImage,
        compound = _p$styleKeys.compound,
        pie = _p$styleKeys.pie;
      var nodeKeys = [nodeBody, nodeBorder, nodeOutline, backgroundImage, compound, pie].filter(function (k) {
        return k != null;
      }).reduce(hashArrays, [DEFAULT_HASH_SEED, DEFAULT_HASH_SEED_ALT]);
      _p.nodeKey = combineHashesArray(nodeKeys);
      _p.hasPie = pie != null && pie[0] !== DEFAULT_HASH_SEED && pie[1] !== DEFAULT_HASH_SEED_ALT;
    }
    return oldStyleKey !== _p.styleKey;
  };
  styfn$8.clearStyleHints = function (ele) {
    var _p = ele._private;
    _p.styleCxtKey = '';
    _p.styleKeys = {};
    _p.styleKey = null;
    _p.labelKey = null;
    _p.labelStyleKey = null;
    _p.sourceLabelKey = null;
    _p.sourceLabelStyleKey = null;
    _p.targetLabelKey = null;
    _p.targetLabelStyleKey = null;
    _p.nodeKey = null;
    _p.hasPie = null;
  };

  // apply a property to the style (for internal use)
  // returns whether application was successful
  //
  // now, this function flattens the property, and here's how:
  //
  // for parsedProp:{ bypass: true, deleteBypass: true }
  // no property is generated, instead the bypass property in the
  // element's style is replaced by what's pointed to by the `bypassed`
  // field in the bypass property (i.e. restoring the property the
  // bypass was overriding)
  //
  // for parsedProp:{ mapped: truthy }
  // the generated flattenedProp:{ mapping: prop }
  //
  // for parsedProp:{ bypass: true }
  // the generated flattenedProp:{ bypassed: parsedProp }
  styfn$8.applyParsedProperty = function (ele, parsedProp) {
    var self = this;
    var prop = parsedProp;
    var style = ele._private.style;
    var flatProp;
    var types = self.types;
    var type = self.properties[prop.name].type;
    var propIsBypass = prop.bypass;
    var origProp = style[prop.name];
    var origPropIsBypass = origProp && origProp.bypass;
    var _p = ele._private;
    var flatPropMapping = 'mapping';
    var getVal = function getVal(p) {
      if (p == null) {
        return null;
      } else if (p.pfValue != null) {
        return p.pfValue;
      } else {
        return p.value;
      }
    };
    var checkTriggers = function checkTriggers() {
      var fromVal = getVal(origProp);
      var toVal = getVal(prop);
      self.checkTriggers(ele, prop.name, fromVal, toVal);
    };

    // edge sanity checks to prevent the client from making serious mistakes
    if (parsedProp.name === 'curve-style' && ele.isEdge() && (
    // loops must be bundled beziers
    parsedProp.value !== 'bezier' && ele.isLoop() ||
    // edges connected to compound nodes can not be haystacks
    parsedProp.value === 'haystack' && (ele.source().isParent() || ele.target().isParent()))) {
      prop = parsedProp = this.parse(parsedProp.name, 'bezier', propIsBypass);
    }
    if (prop["delete"]) {
      // delete the property and use the default value on falsey value
      style[prop.name] = undefined;
      checkTriggers();
      return true;
    }
    if (prop.deleteBypassed) {
      // delete the property that the
      if (!origProp) {
        checkTriggers();
        return true; // can't delete if no prop
      } else if (origProp.bypass) {
        // delete bypassed
        origProp.bypassed = undefined;
        checkTriggers();
        return true;
      } else {
        return false; // we're unsuccessful deleting the bypassed
      }
    }

    // check if we need to delete the current bypass
    if (prop.deleteBypass) {
      // then this property is just here to indicate we need to delete
      if (!origProp) {
        checkTriggers();
        return true; // property is already not defined
      } else if (origProp.bypass) {
        // then replace the bypass property with the original
        // because the bypassed property was already applied (and therefore parsed), we can just replace it (no reapplying necessary)
        style[prop.name] = origProp.bypassed;
        checkTriggers();
        return true;
      } else {
        return false; // we're unsuccessful deleting the bypass
      }
    }

    var printMappingErr = function printMappingErr() {
      warn('Do not assign mappings to elements without corresponding data (i.e. ele `' + ele.id() + '` has no mapping for property `' + prop.name + '` with data field `' + prop.field + '`); try a `[' + prop.field + ']` selector to limit scope to elements with `' + prop.field + '` defined');
    };

    // put the property in the style objects
    switch (prop.mapped) {
      // flatten the property if mapped
      case types.mapData:
        {
          // flatten the field (e.g. data.foo.bar)
          var fields = prop.field.split('.');
          var fieldVal = _p.data;
          for (var i = 0; i < fields.length && fieldVal; i++) {
            var field = fields[i];
            fieldVal = fieldVal[field];
          }
          if (fieldVal == null) {
            printMappingErr();
            return false;
          }
          var percent;
          if (!number$1(fieldVal)) {
            // then don't apply and fall back on the existing style
            warn('Do not use continuous mappers without specifying numeric data (i.e. `' + prop.field + ': ' + fieldVal + '` for `' + ele.id() + '` is non-numeric)');
            return false;
          } else {
            var fieldWidth = prop.fieldMax - prop.fieldMin;
            if (fieldWidth === 0) {
              // safety check -- not strictly necessary as no props of zero range should be passed here
              percent = 0;
            } else {
              percent = (fieldVal - prop.fieldMin) / fieldWidth;
            }
          }

          // make sure to bound percent value
          if (percent < 0) {
            percent = 0;
          } else if (percent > 1) {
            percent = 1;
          }
          if (type.color) {
            var r1 = prop.valueMin[0];
            var r2 = prop.valueMax[0];
            var g1 = prop.valueMin[1];
            var g2 = prop.valueMax[1];
            var b1 = prop.valueMin[2];
            var b2 = prop.valueMax[2];
            var a1 = prop.valueMin[3] == null ? 1 : prop.valueMin[3];
            var a2 = prop.valueMax[3] == null ? 1 : prop.valueMax[3];
            var clr = [Math.round(r1 + (r2 - r1) * percent), Math.round(g1 + (g2 - g1) * percent), Math.round(b1 + (b2 - b1) * percent), Math.round(a1 + (a2 - a1) * percent)];
            flatProp = {
              // colours are simple, so just create the flat property instead of expensive string parsing
              bypass: prop.bypass,
              // we're a bypass if the mapping property is a bypass
              name: prop.name,
              value: clr,
              strValue: 'rgb(' + clr[0] + ', ' + clr[1] + ', ' + clr[2] + ')'
            };
          } else if (type.number) {
            var calcValue = prop.valueMin + (prop.valueMax - prop.valueMin) * percent;
            flatProp = this.parse(prop.name, calcValue, prop.bypass, flatPropMapping);
          } else {
            return false; // can only map to colours and numbers
          }

          if (!flatProp) {
            // if we can't flatten the property, then don't apply the property and fall back on the existing style
            printMappingErr();
            return false;
          }
          flatProp.mapping = prop; // keep a reference to the mapping
          prop = flatProp; // the flattened (mapped) property is the one we want

          break;
        }

      // direct mapping
      case types.data:
        {
          // flatten the field (e.g. data.foo.bar)
          var _fields = prop.field.split('.');
          var _fieldVal = _p.data;
          for (var _i3 = 0; _i3 < _fields.length && _fieldVal; _i3++) {
            var _field = _fields[_i3];
            _fieldVal = _fieldVal[_field];
          }
          if (_fieldVal != null) {
            flatProp = this.parse(prop.name, _fieldVal, prop.bypass, flatPropMapping);
          }
          if (!flatProp) {
            // if we can't flatten the property, then don't apply and fall back on the existing style
            printMappingErr();
            return false;
          }
          flatProp.mapping = prop; // keep a reference to the mapping
          prop = flatProp; // the flattened (mapped) property is the one we want

          break;
        }
      case types.fn:
        {
          var fn = prop.value;
          var fnRetVal = prop.fnValue != null ? prop.fnValue : fn(ele); // check for cached value before calling function

          prop.prevFnValue = fnRetVal;
          if (fnRetVal == null) {
            warn('Custom function mappers may not return null (i.e. `' + prop.name + '` for ele `' + ele.id() + '` is null)');
            return false;
          }
          flatProp = this.parse(prop.name, fnRetVal, prop.bypass, flatPropMapping);
          if (!flatProp) {
            warn('Custom function mappers may not return invalid values for the property type (i.e. `' + prop.name + '` for ele `' + ele.id() + '` is invalid)');
            return false;
          }
          flatProp.mapping = copy(prop); // keep a reference to the mapping
          prop = flatProp; // the flattened (mapped) property is the one we want

          break;
        }
      case undefined:
        break;
      // just set the property

      default:
        return false;
      // not a valid mapping
    }

    // if the property is a bypass property, then link the resultant property to the original one
    if (propIsBypass) {
      if (origPropIsBypass) {
        // then this bypass overrides the existing one
        prop.bypassed = origProp.bypassed; // steal bypassed prop from old bypass
      } else {
        // then link the orig prop to the new bypass
        prop.bypassed = origProp;
      }
      style[prop.name] = prop; // and set
    } else {
      // prop is not bypass
      if (origPropIsBypass) {
        // then keep the orig prop (since it's a bypass) and link to the new prop
        origProp.bypassed = prop;
      } else {
        // then just replace the old prop with the new one
        style[prop.name] = prop;
      }
    }
    checkTriggers();
    return true;
  };
  styfn$8.cleanElements = function (eles, keepBypasses) {
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      this.clearStyleHints(ele);
      ele.dirtyCompoundBoundsCache();
      ele.dirtyBoundingBoxCache();
      if (!keepBypasses) {
        ele._private.style = {};
      } else {
        var style = ele._private.style;
        var propNames = Object.keys(style);
        for (var j = 0; j < propNames.length; j++) {
          var propName = propNames[j];
          var eleProp = style[propName];
          if (eleProp != null) {
            if (eleProp.bypass) {
              eleProp.bypassed = null;
            } else {
              style[propName] = null;
            }
          }
        }
      }
    }
  };

  // updates the visual style for all elements (useful for manual style modification after init)
  styfn$8.update = function () {
    var cy = this._private.cy;
    var eles = cy.mutableElements();
    eles.updateStyle();
  };

  // diffProps : { name => { prev, next } }
  styfn$8.updateTransitions = function (ele, diffProps) {
    var self = this;
    var _p = ele._private;
    var props = ele.pstyle('transition-property').value;
    var duration = ele.pstyle('transition-duration').pfValue;
    var delay = ele.pstyle('transition-delay').pfValue;
    if (props.length > 0 && duration > 0) {
      var style = {};

      // build up the style to animate towards
      var anyPrev = false;
      for (var i = 0; i < props.length; i++) {
        var prop = props[i];
        var styProp = ele.pstyle(prop);
        var diffProp = diffProps[prop];
        if (!diffProp) {
          continue;
        }
        var prevProp = diffProp.prev;
        var fromProp = prevProp;
        var toProp = diffProp.next != null ? diffProp.next : styProp;
        var diff = false;
        var initVal = void 0;
        var initDt = 0.000001; // delta time % value for initVal (allows animating out of init zero opacity)

        if (!fromProp) {
          continue;
        }

        // consider px values
        if (number$1(fromProp.pfValue) && number$1(toProp.pfValue)) {
          diff = toProp.pfValue - fromProp.pfValue; // nonzero is truthy
          initVal = fromProp.pfValue + initDt * diff;

          // consider numerical values
        } else if (number$1(fromProp.value) && number$1(toProp.value)) {
          diff = toProp.value - fromProp.value; // nonzero is truthy
          initVal = fromProp.value + initDt * diff;

          // consider colour values
        } else if (array(fromProp.value) && array(toProp.value)) {
          diff = fromProp.value[0] !== toProp.value[0] || fromProp.value[1] !== toProp.value[1] || fromProp.value[2] !== toProp.value[2];
          initVal = fromProp.strValue;
        }

        // the previous value is good for an animation only if it's different
        if (diff) {
          style[prop] = toProp.strValue; // to val
          this.applyBypass(ele, prop, initVal); // from val
          anyPrev = true;
        }
      } // end if props allow ani

      // can't transition if there's nothing previous to transition from
      if (!anyPrev) {
        return;
      }
      _p.transitioning = true;
      new Promise$1(function (resolve) {
        if (delay > 0) {
          ele.delayAnimation(delay).play().promise().then(resolve);
        } else {
          resolve();
        }
      }).then(function () {
        return ele.animation({
          style: style,
          duration: duration,
          easing: ele.pstyle('transition-timing-function').value,
          queue: false
        }).play().promise();
      }).then(function () {
        // if( !isBypass ){
        self.removeBypasses(ele, props);
        ele.emitAndNotify('style');
        // }

        _p.transitioning = false;
      });
    } else if (_p.transitioning) {
      this.removeBypasses(ele, props);
      ele.emitAndNotify('style');
      _p.transitioning = false;
    }
  };
  styfn$8.checkTrigger = function (ele, name, fromValue, toValue, getTrigger, onTrigger) {
    var prop = this.properties[name];
    var triggerCheck = getTrigger(prop);
    if (triggerCheck != null && triggerCheck(fromValue, toValue)) {
      onTrigger(prop);
    }
  };
  styfn$8.checkZOrderTrigger = function (ele, name, fromValue, toValue) {
    var _this = this;
    this.checkTrigger(ele, name, fromValue, toValue, function (prop) {
      return prop.triggersZOrder;
    }, function () {
      _this._private.cy.notify('zorder', ele);
    });
  };
  styfn$8.checkBoundsTrigger = function (ele, name, fromValue, toValue) {
    this.checkTrigger(ele, name, fromValue, toValue, function (prop) {
      return prop.triggersBounds;
    }, function (prop) {
      ele.dirtyCompoundBoundsCache();
      ele.dirtyBoundingBoxCache();

      // if the prop change makes the bb of pll bezier edges invalid,
      // then dirty the pll edge bb cache as well
      if (
      // only for beziers -- so performance of other edges isn't affected
      prop.triggersBoundsOfParallelBeziers && name === 'curve-style' && (fromValue === 'bezier' || toValue === 'bezier')) {
        ele.parallelEdges().forEach(function (pllEdge) {
          if (pllEdge.isBundledBezier()) {
            pllEdge.dirtyBoundingBoxCache();
          }
        });
      }
      if (prop.triggersBoundsOfConnectedEdges && name === 'display' && (fromValue === 'none' || toValue === 'none')) {
        ele.connectedEdges().forEach(function (edge) {
          edge.dirtyBoundingBoxCache();
        });
      }
    });
  };
  styfn$8.checkTriggers = function (ele, name, fromValue, toValue) {
    ele.dirtyStyleCache();
    this.checkZOrderTrigger(ele, name, fromValue, toValue);
    this.checkBoundsTrigger(ele, name, fromValue, toValue);
  };

  var styfn$7 = {};

  // bypasses are applied to an existing style on an element, and just tacked on temporarily
  // returns true iff application was successful for at least 1 specified property
  styfn$7.applyBypass = function (eles, name, value, updateTransitions) {
    var self = this;
    var props = [];
    var isBypass = true;

    // put all the properties (can specify one or many) in an array after parsing them
    if (name === '*' || name === '**') {
      // apply to all property names

      if (value !== undefined) {
        for (var i = 0; i < self.properties.length; i++) {
          var prop = self.properties[i];
          var _name = prop.name;
          var parsedProp = this.parse(_name, value, true);
          if (parsedProp) {
            props.push(parsedProp);
          }
        }
      }
    } else if (string(name)) {
      // then parse the single property
      var _parsedProp = this.parse(name, value, true);
      if (_parsedProp) {
        props.push(_parsedProp);
      }
    } else if (plainObject(name)) {
      // then parse each property
      var specifiedProps = name;
      updateTransitions = value;
      var names = Object.keys(specifiedProps);
      for (var _i = 0; _i < names.length; _i++) {
        var _name2 = names[_i];
        var _value = specifiedProps[_name2];
        if (_value === undefined) {
          // try camel case name too
          _value = specifiedProps[dash2camel(_name2)];
        }
        if (_value !== undefined) {
          var _parsedProp2 = this.parse(_name2, _value, true);
          if (_parsedProp2) {
            props.push(_parsedProp2);
          }
        }
      }
    } else {
      // can't do anything without well defined properties
      return false;
    }

    // we've failed if there are no valid properties
    if (props.length === 0) {
      return false;
    }

    // now, apply the bypass properties on the elements
    var ret = false; // return true if at least one succesful bypass applied
    for (var _i2 = 0; _i2 < eles.length; _i2++) {
      // for each ele
      var ele = eles[_i2];
      var diffProps = {};
      var diffProp = void 0;
      for (var j = 0; j < props.length; j++) {
        // for each prop
        var _prop = props[j];
        if (updateTransitions) {
          var prevProp = ele.pstyle(_prop.name);
          diffProp = diffProps[_prop.name] = {
            prev: prevProp
          };
        }
        ret = this.applyParsedProperty(ele, copy(_prop)) || ret;
        if (updateTransitions) {
          diffProp.next = ele.pstyle(_prop.name);
        }
      } // for props

      if (ret) {
        this.updateStyleHints(ele);
      }
      if (updateTransitions) {
        this.updateTransitions(ele, diffProps, isBypass);
      }
    } // for eles

    return ret;
  };

  // only useful in specific cases like animation
  styfn$7.overrideBypass = function (eles, name, value) {
    name = camel2dash(name);
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      var prop = ele._private.style[name];
      var type = this.properties[name].type;
      var isColor = type.color;
      var isMulti = type.mutiple;
      var oldValue = !prop ? null : prop.pfValue != null ? prop.pfValue : prop.value;
      if (!prop || !prop.bypass) {
        // need a bypass if one doesn't exist
        this.applyBypass(ele, name, value);
      } else {
        prop.value = value;
        if (prop.pfValue != null) {
          prop.pfValue = value;
        }
        if (isColor) {
          prop.strValue = 'rgb(' + value.join(',') + ')';
        } else if (isMulti) {
          prop.strValue = value.join(' ');
        } else {
          prop.strValue = '' + value;
        }
        this.updateStyleHints(ele);
      }
      this.checkTriggers(ele, name, oldValue, value);
    }
  };
  styfn$7.removeAllBypasses = function (eles, updateTransitions) {
    return this.removeBypasses(eles, this.propertyNames, updateTransitions);
  };
  styfn$7.removeBypasses = function (eles, props, updateTransitions) {
    var isBypass = true;
    for (var j = 0; j < eles.length; j++) {
      var ele = eles[j];
      var diffProps = {};
      for (var i = 0; i < props.length; i++) {
        var name = props[i];
        var prop = this.properties[name];
        var prevProp = ele.pstyle(prop.name);
        if (!prevProp || !prevProp.bypass) {
          // if a bypass doesn't exist for the prop, nothing needs to be removed
          continue;
        }
        var value = ''; // empty => remove bypass
        var parsedProp = this.parse(name, value, true);
        var diffProp = diffProps[prop.name] = {
          prev: prevProp
        };
        this.applyParsedProperty(ele, parsedProp);
        diffProp.next = ele.pstyle(prop.name);
      } // for props

      this.updateStyleHints(ele);
      if (updateTransitions) {
        this.updateTransitions(ele, diffProps, isBypass);
      }
    } // for eles
  };

  var styfn$6 = {};

  // gets what an em size corresponds to in pixels relative to a dom element
  styfn$6.getEmSizeInPixels = function () {
    var px = this.containerCss('font-size');
    if (px != null) {
      return parseFloat(px);
    } else {
      return 1; // for headless
    }
  };

  // gets css property from the core container
  styfn$6.containerCss = function (propName) {
    var cy = this._private.cy;
    var domElement = cy.container();
    var containerWindow = cy.window();
    if (containerWindow && domElement && containerWindow.getComputedStyle) {
      return containerWindow.getComputedStyle(domElement).getPropertyValue(propName);
    }
  };

  var styfn$5 = {};

  // gets the rendered style for an element
  styfn$5.getRenderedStyle = function (ele, prop) {
    if (prop) {
      return this.getStylePropertyValue(ele, prop, true);
    } else {
      return this.getRawStyle(ele, true);
    }
  };

  // gets the raw style for an element
  styfn$5.getRawStyle = function (ele, isRenderedVal) {
    var self = this;
    ele = ele[0]; // insure it's an element

    if (ele) {
      var rstyle = {};
      for (var i = 0; i < self.properties.length; i++) {
        var prop = self.properties[i];
        var val = self.getStylePropertyValue(ele, prop.name, isRenderedVal);
        if (val != null) {
          rstyle[prop.name] = val;
          rstyle[dash2camel(prop.name)] = val;
        }
      }
      return rstyle;
    }
  };
  styfn$5.getIndexedStyle = function (ele, property, subproperty, index) {
    var pstyle = ele.pstyle(property)[subproperty][index];
    return pstyle != null ? pstyle : ele.cy().style().getDefaultProperty(property)[subproperty][0];
  };
  styfn$5.getStylePropertyValue = function (ele, propName, isRenderedVal) {
    var self = this;
    ele = ele[0]; // insure it's an element

    if (ele) {
      var prop = self.properties[propName];
      if (prop.alias) {
        prop = prop.pointsTo;
      }
      var type = prop.type;
      var styleProp = ele.pstyle(prop.name);
      if (styleProp) {
        var value = styleProp.value,
          units = styleProp.units,
          strValue = styleProp.strValue;
        if (isRenderedVal && type.number && value != null && number$1(value)) {
          var zoom = ele.cy().zoom();
          var getRenderedValue = function getRenderedValue(val) {
            return val * zoom;
          };
          var getValueStringWithUnits = function getValueStringWithUnits(val, units) {
            return getRenderedValue(val) + units;
          };
          var isArrayValue = array(value);
          var haveUnits = isArrayValue ? units.every(function (u) {
            return u != null;
          }) : units != null;
          if (haveUnits) {
            if (isArrayValue) {
              return value.map(function (v, i) {
                return getValueStringWithUnits(v, units[i]);
              }).join(' ');
            } else {
              return getValueStringWithUnits(value, units);
            }
          } else {
            if (isArrayValue) {
              return value.map(function (v) {
                return string(v) ? v : '' + getRenderedValue(v);
              }).join(' ');
            } else {
              return '' + getRenderedValue(value);
            }
          }
        } else if (strValue != null) {
          return strValue;
        }
      }
      return null;
    }
  };
  styfn$5.getAnimationStartStyle = function (ele, aniProps) {
    var rstyle = {};
    for (var i = 0; i < aniProps.length; i++) {
      var aniProp = aniProps[i];
      var name = aniProp.name;
      var styleProp = ele.pstyle(name);
      if (styleProp !== undefined) {
        // then make a prop of it
        if (plainObject(styleProp)) {
          styleProp = this.parse(name, styleProp.strValue);
        } else {
          styleProp = this.parse(name, styleProp);
        }
      }
      if (styleProp) {
        rstyle[name] = styleProp;
      }
    }
    return rstyle;
  };
  styfn$5.getPropsList = function (propsObj) {
    var self = this;
    var rstyle = [];
    var style = propsObj;
    var props = self.properties;
    if (style) {
      var names = Object.keys(style);
      for (var i = 0; i < names.length; i++) {
        var name = names[i];
        var val = style[name];
        var prop = props[name] || props[camel2dash(name)];
        var styleProp = this.parse(prop.name, val);
        if (styleProp) {
          rstyle.push(styleProp);
        }
      }
    }
    return rstyle;
  };
  styfn$5.getNonDefaultPropertiesHash = function (ele, propNames, seed) {
    var hash = seed.slice();
    var name, val, strVal, chVal;
    var i, j;
    for (i = 0; i < propNames.length; i++) {
      name = propNames[i];
      val = ele.pstyle(name, false);
      if (val == null) {
        continue;
      } else if (val.pfValue != null) {
        hash[0] = hashInt(chVal, hash[0]);
        hash[1] = hashIntAlt(chVal, hash[1]);
      } else {
        strVal = val.strValue;
        for (j = 0; j < strVal.length; j++) {
          chVal = strVal.charCodeAt(j);
          hash[0] = hashInt(chVal, hash[0]);
          hash[1] = hashIntAlt(chVal, hash[1]);
        }
      }
    }
    return hash;
  };
  styfn$5.getPropertiesHash = styfn$5.getNonDefaultPropertiesHash;

  var styfn$4 = {};
  styfn$4.appendFromJson = function (json) {
    var style = this;
    for (var i = 0; i < json.length; i++) {
      var context = json[i];
      var selector = context.selector;
      var props = context.style || context.css;
      var names = Object.keys(props);
      style.selector(selector); // apply selector

      for (var j = 0; j < names.length; j++) {
        var name = names[j];
        var value = props[name];
        style.css(name, value); // apply property
      }
    }

    return style;
  };

  // accessible cy.style() function
  styfn$4.fromJson = function (json) {
    var style = this;
    style.resetToDefault();
    style.appendFromJson(json);
    return style;
  };

  // get json from cy.style() api
  styfn$4.json = function () {
    var json = [];
    for (var i = this.defaultLength; i < this.length; i++) {
      var cxt = this[i];
      var selector = cxt.selector;
      var props = cxt.properties;
      var css = {};
      for (var j = 0; j < props.length; j++) {
        var prop = props[j];
        css[prop.name] = prop.strValue;
      }
      json.push({
        selector: !selector ? 'core' : selector.toString(),
        style: css
      });
    }
    return json;
  };

  var styfn$3 = {};
  styfn$3.appendFromString = function (string) {
    var self = this;
    var style = this;
    var remaining = '' + string;
    var selAndBlockStr;
    var blockRem;
    var propAndValStr;

    // remove comments from the style string
    remaining = remaining.replace(/[/][*](\s|.)+?[*][/]/g, '');
    function removeSelAndBlockFromRemaining() {
      // remove the parsed selector and block from the remaining text to parse
      if (remaining.length > selAndBlockStr.length) {
        remaining = remaining.substr(selAndBlockStr.length);
      } else {
        remaining = '';
      }
    }
    function removePropAndValFromRem() {
      // remove the parsed property and value from the remaining block text to parse
      if (blockRem.length > propAndValStr.length) {
        blockRem = blockRem.substr(propAndValStr.length);
      } else {
        blockRem = '';
      }
    }
    for (;;) {
      var nothingLeftToParse = remaining.match(/^\s*$/);
      if (nothingLeftToParse) {
        break;
      }
      var selAndBlock = remaining.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);
      if (!selAndBlock) {
        warn('Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: ' + remaining);
        break;
      }
      selAndBlockStr = selAndBlock[0];

      // parse the selector
      var selectorStr = selAndBlock[1];
      if (selectorStr !== 'core') {
        var selector = new Selector(selectorStr);
        if (selector.invalid) {
          warn('Skipping parsing of block: Invalid selector found in string stylesheet: ' + selectorStr);

          // skip this selector and block
          removeSelAndBlockFromRemaining();
          continue;
        }
      }

      // parse the block of properties and values
      var blockStr = selAndBlock[2];
      var invalidBlock = false;
      blockRem = blockStr;
      var props = [];
      for (;;) {
        var _nothingLeftToParse = blockRem.match(/^\s*$/);
        if (_nothingLeftToParse) {
          break;
        }
        var propAndVal = blockRem.match(/^\s*(.+?)\s*:\s*(.+?)(?:\s*;|\s*$)/);
        if (!propAndVal) {
          warn('Skipping parsing of block: Invalid formatting of style property and value definitions found in:' + blockStr);
          invalidBlock = true;
          break;
        }
        propAndValStr = propAndVal[0];
        var propStr = propAndVal[1];
        var valStr = propAndVal[2];
        var prop = self.properties[propStr];
        if (!prop) {
          warn('Skipping property: Invalid property name in: ' + propAndValStr);

          // skip this property in the block
          removePropAndValFromRem();
          continue;
        }
        var parsedProp = style.parse(propStr, valStr);
        if (!parsedProp) {
          warn('Skipping property: Invalid property definition in: ' + propAndValStr);

          // skip this property in the block
          removePropAndValFromRem();
          continue;
        }
        props.push({
          name: propStr,
          val: valStr
        });
        removePropAndValFromRem();
      }
      if (invalidBlock) {
        removeSelAndBlockFromRemaining();
        break;
      }

      // put the parsed block in the style
      style.selector(selectorStr);
      for (var i = 0; i < props.length; i++) {
        var _prop = props[i];
        style.css(_prop.name, _prop.val);
      }
      removeSelAndBlockFromRemaining();
    }
    return style;
  };
  styfn$3.fromString = function (string) {
    var style = this;
    style.resetToDefault();
    style.appendFromString(string);
    return style;
  };

  var styfn$2 = {};
  (function () {
    var number$1 = number;
    var rgba = rgbaNoBackRefs;
    var hsla = hslaNoBackRefs;
    var hex3$1 = hex3;
    var hex6$1 = hex6;
    var data = function data(prefix) {
      return '^' + prefix + '\\s*\\(\\s*([\\w\\.]+)\\s*\\)$';
    };
    var mapData = function mapData(prefix) {
      var mapArg = number$1 + '|\\w+|' + rgba + '|' + hsla + '|' + hex3$1 + '|' + hex6$1;
      return '^' + prefix + '\\s*\\(([\\w\\.]+)\\s*\\,\\s*(' + number$1 + ')\\s*\\,\\s*(' + number$1 + ')\\s*,\\s*(' + mapArg + ')\\s*\\,\\s*(' + mapArg + ')\\)$';
    };
    var urlRegexes = ['^url\\s*\\(\\s*[\'"]?(.+?)[\'"]?\\s*\\)$', '^(none)$', '^(.+)$'];

    // each visual style property has a type and needs to be validated according to it
    styfn$2.types = {
      time: {
        number: true,
        min: 0,
        units: 's|ms',
        implicitUnits: 'ms'
      },
      percent: {
        number: true,
        min: 0,
        max: 100,
        units: '%',
        implicitUnits: '%'
      },
      percentages: {
        number: true,
        min: 0,
        max: 100,
        units: '%',
        implicitUnits: '%',
        multiple: true
      },
      zeroOneNumber: {
        number: true,
        min: 0,
        max: 1,
        unitless: true
      },
      zeroOneNumbers: {
        number: true,
        min: 0,
        max: 1,
        unitless: true,
        multiple: true
      },
      nOneOneNumber: {
        number: true,
        min: -1,
        max: 1,
        unitless: true
      },
      nonNegativeInt: {
        number: true,
        min: 0,
        integer: true,
        unitless: true
      },
      nonNegativeNumber: {
        number: true,
        min: 0,
        unitless: true
      },
      position: {
        enums: ['parent', 'origin']
      },
      nodeSize: {
        number: true,
        min: 0,
        enums: ['label']
      },
      number: {
        number: true,
        unitless: true
      },
      numbers: {
        number: true,
        unitless: true,
        multiple: true
      },
      positiveNumber: {
        number: true,
        unitless: true,
        min: 0,
        strictMin: true
      },
      size: {
        number: true,
        min: 0
      },
      bidirectionalSize: {
        number: true
      },
      // allows negative
      bidirectionalSizeMaybePercent: {
        number: true,
        allowPercent: true
      },
      // allows negative
      bidirectionalSizes: {
        number: true,
        multiple: true
      },
      // allows negative
      sizeMaybePercent: {
        number: true,
        min: 0,
        allowPercent: true
      },
      axisDirection: {
        enums: ['horizontal', 'leftward', 'rightward', 'vertical', 'upward', 'downward', 'auto']
      },
      paddingRelativeTo: {
        enums: ['width', 'height', 'average', 'min', 'max']
      },
      bgWH: {
        number: true,
        min: 0,
        allowPercent: true,
        enums: ['auto'],
        multiple: true
      },
      bgPos: {
        number: true,
        allowPercent: true,
        multiple: true
      },
      bgRelativeTo: {
        enums: ['inner', 'include-padding'],
        multiple: true
      },
      bgRepeat: {
        enums: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat'],
        multiple: true
      },
      bgFit: {
        enums: ['none', 'contain', 'cover'],
        multiple: true
      },
      bgCrossOrigin: {
        enums: ['anonymous', 'use-credentials', 'null'],
        multiple: true
      },
      bgClip: {
        enums: ['none', 'node'],
        multiple: true
      },
      bgContainment: {
        enums: ['inside', 'over'],
        multiple: true
      },
      color: {
        color: true
      },
      colors: {
        color: true,
        multiple: true
      },
      fill: {
        enums: ['solid', 'linear-gradient', 'radial-gradient']
      },
      bool: {
        enums: ['yes', 'no']
      },
      bools: {
        enums: ['yes', 'no'],
        multiple: true
      },
      lineStyle: {
        enums: ['solid', 'dotted', 'dashed']
      },
      lineCap: {
        enums: ['butt', 'round', 'square']
      },
      borderStyle: {
        enums: ['solid', 'dotted', 'dashed', 'double']
      },
      curveStyle: {
        enums: ['bezier', 'unbundled-bezier', 'haystack', 'segments', 'straight', 'straight-triangle', 'taxi']
      },
      fontFamily: {
        regex: '^([\\w- \\"]+(?:\\s*,\\s*[\\w- \\"]+)*)$'
      },
      fontStyle: {
        enums: ['italic', 'normal', 'oblique']
      },
      fontWeight: {
        enums: ['normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '800', '900', 100, 200, 300, 400, 500, 600, 700, 800, 900]
      },
      textDecoration: {
        enums: ['none', 'underline', 'overline', 'line-through']
      },
      textTransform: {
        enums: ['none', 'uppercase', 'lowercase']
      },
      textWrap: {
        enums: ['none', 'wrap', 'ellipsis']
      },
      textOverflowWrap: {
        enums: ['whitespace', 'anywhere']
      },
      textBackgroundShape: {
        enums: ['rectangle', 'roundrectangle', 'round-rectangle']
      },
      nodeShape: {
        enums: ['rectangle', 'roundrectangle', 'round-rectangle', 'cutrectangle', 'cut-rectangle', 'bottomroundrectangle', 'bottom-round-rectangle', 'barrel', 'ellipse', 'triangle', 'round-triangle', 'square', 'pentagon', 'round-pentagon', 'hexagon', 'round-hexagon', 'concavehexagon', 'concave-hexagon', 'heptagon', 'round-heptagon', 'octagon', 'round-octagon', 'tag', 'round-tag', 'star', 'diamond', 'round-diamond', 'vee', 'rhomboid', 'right-rhomboid', 'polygon']
      },
      overlayShape: {
        enums: ['roundrectangle', 'round-rectangle', 'ellipse']
      },
      compoundIncludeLabels: {
        enums: ['include', 'exclude']
      },
      arrowShape: {
        enums: ['tee', 'triangle', 'triangle-tee', 'circle-triangle', 'triangle-cross', 'triangle-backcurve', 'vee', 'square', 'circle', 'diamond', 'chevron', 'none']
      },
      arrowFill: {
        enums: ['filled', 'hollow']
      },
      arrowWidth: {
        number: true,
        units: '%|px|em',
        implicitUnits: 'px',
        enums: ['match-line']
      },
      display: {
        enums: ['element', 'none']
      },
      visibility: {
        enums: ['hidden', 'visible']
      },
      zCompoundDepth: {
        enums: ['bottom', 'orphan', 'auto', 'top']
      },
      zIndexCompare: {
        enums: ['auto', 'manual']
      },
      valign: {
        enums: ['top', 'center', 'bottom']
      },
      halign: {
        enums: ['left', 'center', 'right']
      },
      justification: {
        enums: ['left', 'center', 'right', 'auto']
      },
      text: {
        string: true
      },
      data: {
        mapping: true,
        regex: data('data')
      },
      layoutData: {
        mapping: true,
        regex: data('layoutData')
      },
      scratch: {
        mapping: true,
        regex: data('scratch')
      },
      mapData: {
        mapping: true,
        regex: mapData('mapData')
      },
      mapLayoutData: {
        mapping: true,
        regex: mapData('mapLayoutData')
      },
      mapScratch: {
        mapping: true,
        regex: mapData('mapScratch')
      },
      fn: {
        mapping: true,
        fn: true
      },
      url: {
        regexes: urlRegexes,
        singleRegexMatchValue: true
      },
      urls: {
        regexes: urlRegexes,
        singleRegexMatchValue: true,
        multiple: true
      },
      propList: {
        propList: true
      },
      angle: {
        number: true,
        units: 'deg|rad',
        implicitUnits: 'rad'
      },
      textRotation: {
        number: true,
        units: 'deg|rad',
        implicitUnits: 'rad',
        enums: ['none', 'autorotate']
      },
      polygonPointList: {
        number: true,
        multiple: true,
        evenMultiple: true,
        min: -1,
        max: 1,
        unitless: true
      },
      edgeDistances: {
        enums: ['intersection', 'node-position', 'endpoints']
      },
      edgeEndpoint: {
        number: true,
        multiple: true,
        units: '%|px|em|deg|rad',
        implicitUnits: 'px',
        enums: ['inside-to-node', 'outside-to-node', 'outside-to-node-or-label', 'outside-to-line', 'outside-to-line-or-label'],
        singleEnum: true,
        validate: function validate(valArr, unitsArr) {
          switch (valArr.length) {
            case 2:
              // can be % or px only
              return unitsArr[0] !== 'deg' && unitsArr[0] !== 'rad' && unitsArr[1] !== 'deg' && unitsArr[1] !== 'rad';
            case 1:
              // can be enum, deg, or rad only
              return string(valArr[0]) || unitsArr[0] === 'deg' || unitsArr[0] === 'rad';
            default:
              return false;
          }
        }
      },
      easing: {
        regexes: ['^(spring)\\s*\\(\\s*(' + number$1 + ')\\s*,\\s*(' + number$1 + ')\\s*\\)$', '^(cubic-bezier)\\s*\\(\\s*(' + number$1 + ')\\s*,\\s*(' + number$1 + ')\\s*,\\s*(' + number$1 + ')\\s*,\\s*(' + number$1 + ')\\s*\\)$'],
        enums: ['linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out', 'ease-in-sine', 'ease-out-sine', 'ease-in-out-sine', 'ease-in-quad', 'ease-out-quad', 'ease-in-out-quad', 'ease-in-cubic', 'ease-out-cubic', 'ease-in-out-cubic', 'ease-in-quart', 'ease-out-quart', 'ease-in-out-quart', 'ease-in-quint', 'ease-out-quint', 'ease-in-out-quint', 'ease-in-expo', 'ease-out-expo', 'ease-in-out-expo', 'ease-in-circ', 'ease-out-circ', 'ease-in-out-circ']
      },
      gradientDirection: {
        enums: ['to-bottom', 'to-top', 'to-left', 'to-right', 'to-bottom-right', 'to-bottom-left', 'to-top-right', 'to-top-left', 'to-right-bottom', 'to-left-bottom', 'to-right-top', 'to-left-top' // different order
        ]
      },

      boundsExpansion: {
        number: true,
        multiple: true,
        min: 0,
        validate: function validate(valArr) {
          var length = valArr.length;
          return length === 1 || length === 2 || length === 4;
        }
      }
    };
    var diff = {
      zeroNonZero: function zeroNonZero(val1, val2) {
        if ((val1 == null || val2 == null) && val1 !== val2) {
          return true; // null cases could represent any value
        }
        if (val1 == 0 && val2 != 0) {
          return true;
        } else if (val1 != 0 && val2 == 0) {
          return true;
        } else {
          return false;
        }
      },
      any: function any(val1, val2) {
        return val1 != val2;
      },
      emptyNonEmpty: function emptyNonEmpty(str1, str2) {
        var empty1 = emptyString(str1);
        var empty2 = emptyString(str2);
        return empty1 && !empty2 || !empty1 && empty2;
      }
    };

    // define visual style properties
    //
    // - n.b. adding a new group of props may require updates to updateStyleHints()
    // - adding new props to an existing group gets handled automatically

    var t = styfn$2.types;
    var mainLabel = [{
      name: 'label',
      type: t.text,
      triggersBounds: diff.any,
      triggersZOrder: diff.emptyNonEmpty
    }, {
      name: 'text-rotation',
      type: t.textRotation,
      triggersBounds: diff.any
    }, {
      name: 'text-margin-x',
      type: t.bidirectionalSize,
      triggersBounds: diff.any
    }, {
      name: 'text-margin-y',
      type: t.bidirectionalSize,
      triggersBounds: diff.any
    }];
    var sourceLabel = [{
      name: 'source-label',
      type: t.text,
      triggersBounds: diff.any
    }, {
      name: 'source-text-rotation',
      type: t.textRotation,
      triggersBounds: diff.any
    }, {
      name: 'source-text-margin-x',
      type: t.bidirectionalSize,
      triggersBounds: diff.any
    }, {
      name: 'source-text-margin-y',
      type: t.bidirectionalSize,
      triggersBounds: diff.any
    }, {
      name: 'source-text-offset',
      type: t.size,
      triggersBounds: diff.any
    }];
    var targetLabel = [{
      name: 'target-label',
      type: t.text,
      triggersBounds: diff.any
    }, {
      name: 'target-text-rotation',
      type: t.textRotation,
      triggersBounds: diff.any
    }, {
      name: 'target-text-margin-x',
      type: t.bidirectionalSize,
      triggersBounds: diff.any
    }, {
      name: 'target-text-margin-y',
      type: t.bidirectionalSize,
      triggersBounds: diff.any
    }, {
      name: 'target-text-offset',
      type: t.size,
      triggersBounds: diff.any
    }];
    var labelDimensions = [{
      name: 'font-family',
      type: t.fontFamily,
      triggersBounds: diff.any
    }, {
      name: 'font-style',
      type: t.fontStyle,
      triggersBounds: diff.any
    }, {
      name: 'font-weight',
      type: t.fontWeight,
      triggersBounds: diff.any
    }, {
      name: 'font-size',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'text-transform',
      type: t.textTransform,
      triggersBounds: diff.any
    }, {
      name: 'text-wrap',
      type: t.textWrap,
      triggersBounds: diff.any
    }, {
      name: 'text-overflow-wrap',
      type: t.textOverflowWrap,
      triggersBounds: diff.any
    }, {
      name: 'text-max-width',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'text-outline-width',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'line-height',
      type: t.positiveNumber,
      triggersBounds: diff.any
    }];
    var commonLabel = [{
      name: 'text-valign',
      type: t.valign,
      triggersBounds: diff.any
    }, {
      name: 'text-halign',
      type: t.halign,
      triggersBounds: diff.any
    }, {
      name: 'color',
      type: t.color
    }, {
      name: 'text-outline-color',
      type: t.color
    }, {
      name: 'text-outline-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'text-background-color',
      type: t.color
    }, {
      name: 'text-background-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'text-background-padding',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'text-border-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'text-border-color',
      type: t.color
    }, {
      name: 'text-border-width',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'text-border-style',
      type: t.borderStyle,
      triggersBounds: diff.any
    }, {
      name: 'text-background-shape',
      type: t.textBackgroundShape,
      triggersBounds: diff.any
    }, {
      name: 'text-justification',
      type: t.justification
    }];
    var behavior = [{
      name: 'events',
      type: t.bool,
      triggersZOrder: diff.any
    }, {
      name: 'text-events',
      type: t.bool,
      triggersZOrder: diff.any
    }];
    var visibility = [{
      name: 'display',
      type: t.display,
      triggersZOrder: diff.any,
      triggersBounds: diff.any,
      triggersBoundsOfConnectedEdges: true
    }, {
      name: 'visibility',
      type: t.visibility,
      triggersZOrder: diff.any
    }, {
      name: 'opacity',
      type: t.zeroOneNumber,
      triggersZOrder: diff.zeroNonZero
    }, {
      name: 'text-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'min-zoomed-font-size',
      type: t.size
    }, {
      name: 'z-compound-depth',
      type: t.zCompoundDepth,
      triggersZOrder: diff.any
    }, {
      name: 'z-index-compare',
      type: t.zIndexCompare,
      triggersZOrder: diff.any
    }, {
      name: 'z-index',
      type: t.number,
      triggersZOrder: diff.any
    }];
    var overlay = [{
      name: 'overlay-padding',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'overlay-color',
      type: t.color
    }, {
      name: 'overlay-opacity',
      type: t.zeroOneNumber,
      triggersBounds: diff.zeroNonZero
    }, {
      name: 'overlay-shape',
      type: t.overlayShape,
      triggersBounds: diff.any
    }];
    var underlay = [{
      name: 'underlay-padding',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'underlay-color',
      type: t.color
    }, {
      name: 'underlay-opacity',
      type: t.zeroOneNumber,
      triggersBounds: diff.zeroNonZero
    }, {
      name: 'underlay-shape',
      type: t.overlayShape,
      triggersBounds: diff.any
    }];
    var transition = [{
      name: 'transition-property',
      type: t.propList
    }, {
      name: 'transition-duration',
      type: t.time
    }, {
      name: 'transition-delay',
      type: t.time
    }, {
      name: 'transition-timing-function',
      type: t.easing
    }];
    var nodeSizeHashOverride = function nodeSizeHashOverride(ele, parsedProp) {
      if (parsedProp.value === 'label') {
        return -ele.poolIndex(); // no hash key hits is using label size (hitrate for perf probably low anyway)
      } else {
        return parsedProp.pfValue;
      }
    };
    var nodeBody = [{
      name: 'height',
      type: t.nodeSize,
      triggersBounds: diff.any,
      hashOverride: nodeSizeHashOverride
    }, {
      name: 'width',
      type: t.nodeSize,
      triggersBounds: diff.any,
      hashOverride: nodeSizeHashOverride
    }, {
      name: 'shape',
      type: t.nodeShape,
      triggersBounds: diff.any
    }, {
      name: 'shape-polygon-points',
      type: t.polygonPointList,
      triggersBounds: diff.any
    }, {
      name: 'background-color',
      type: t.color
    }, {
      name: 'background-fill',
      type: t.fill
    }, {
      name: 'background-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'background-blacken',
      type: t.nOneOneNumber
    }, {
      name: 'background-gradient-stop-colors',
      type: t.colors
    }, {
      name: 'background-gradient-stop-positions',
      type: t.percentages
    }, {
      name: 'background-gradient-direction',
      type: t.gradientDirection
    }, {
      name: 'padding',
      type: t.sizeMaybePercent,
      triggersBounds: diff.any
    }, {
      name: 'padding-relative-to',
      type: t.paddingRelativeTo,
      triggersBounds: diff.any
    }, {
      name: 'bounds-expansion',
      type: t.boundsExpansion,
      triggersBounds: diff.any
    }];
    var nodeBorder = [{
      name: 'border-color',
      type: t.color
    }, {
      name: 'border-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'border-width',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'border-style',
      type: t.borderStyle
    }];
    var nodeOutline = [{
      name: 'outline-color',
      type: t.color
    }, {
      name: 'outline-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'outline-width',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'outline-style',
      type: t.borderStyle
    }, {
      name: 'outline-offset',
      type: t.size,
      triggersBounds: diff.any
    }];
    var backgroundImage = [{
      name: 'background-image',
      type: t.urls
    }, {
      name: 'background-image-crossorigin',
      type: t.bgCrossOrigin
    }, {
      name: 'background-image-opacity',
      type: t.zeroOneNumbers
    }, {
      name: 'background-image-containment',
      type: t.bgContainment
    }, {
      name: 'background-image-smoothing',
      type: t.bools
    }, {
      name: 'background-position-x',
      type: t.bgPos
    }, {
      name: 'background-position-y',
      type: t.bgPos
    }, {
      name: 'background-width-relative-to',
      type: t.bgRelativeTo
    }, {
      name: 'background-height-relative-to',
      type: t.bgRelativeTo
    }, {
      name: 'background-repeat',
      type: t.bgRepeat
    }, {
      name: 'background-fit',
      type: t.bgFit
    }, {
      name: 'background-clip',
      type: t.bgClip
    }, {
      name: 'background-width',
      type: t.bgWH
    }, {
      name: 'background-height',
      type: t.bgWH
    }, {
      name: 'background-offset-x',
      type: t.bgPos
    }, {
      name: 'background-offset-y',
      type: t.bgPos
    }];
    var compound = [{
      name: 'position',
      type: t.position,
      triggersBounds: diff.any
    }, {
      name: 'compound-sizing-wrt-labels',
      type: t.compoundIncludeLabels,
      triggersBounds: diff.any
    }, {
      name: 'min-width',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'min-width-bias-left',
      type: t.sizeMaybePercent,
      triggersBounds: diff.any
    }, {
      name: 'min-width-bias-right',
      type: t.sizeMaybePercent,
      triggersBounds: diff.any
    }, {
      name: 'min-height',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'min-height-bias-top',
      type: t.sizeMaybePercent,
      triggersBounds: diff.any
    }, {
      name: 'min-height-bias-bottom',
      type: t.sizeMaybePercent,
      triggersBounds: diff.any
    }];
    var edgeLine = [{
      name: 'line-style',
      type: t.lineStyle
    }, {
      name: 'line-color',
      type: t.color
    }, {
      name: 'line-fill',
      type: t.fill
    }, {
      name: 'line-cap',
      type: t.lineCap
    }, {
      name: 'line-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'line-dash-pattern',
      type: t.numbers
    }, {
      name: 'line-dash-offset',
      type: t.number
    }, {
      name: 'line-gradient-stop-colors',
      type: t.colors
    }, {
      name: 'line-gradient-stop-positions',
      type: t.percentages
    }, {
      name: 'curve-style',
      type: t.curveStyle,
      triggersBounds: diff.any,
      triggersBoundsOfParallelBeziers: true
    }, {
      name: 'haystack-radius',
      type: t.zeroOneNumber,
      triggersBounds: diff.any
    }, {
      name: 'source-endpoint',
      type: t.edgeEndpoint,
      triggersBounds: diff.any
    }, {
      name: 'target-endpoint',
      type: t.edgeEndpoint,
      triggersBounds: diff.any
    }, {
      name: 'control-point-step-size',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'control-point-distances',
      type: t.bidirectionalSizes,
      triggersBounds: diff.any
    }, {
      name: 'control-point-weights',
      type: t.numbers,
      triggersBounds: diff.any
    }, {
      name: 'segment-distances',
      type: t.bidirectionalSizes,
      triggersBounds: diff.any
    }, {
      name: 'segment-weights',
      type: t.numbers,
      triggersBounds: diff.any
    }, {
      name: 'taxi-turn',
      type: t.bidirectionalSizeMaybePercent,
      triggersBounds: diff.any
    }, {
      name: 'taxi-turn-min-distance',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'taxi-direction',
      type: t.axisDirection,
      triggersBounds: diff.any
    }, {
      name: 'edge-distances',
      type: t.edgeDistances,
      triggersBounds: diff.any
    }, {
      name: 'arrow-scale',
      type: t.positiveNumber,
      triggersBounds: diff.any
    }, {
      name: 'loop-direction',
      type: t.angle,
      triggersBounds: diff.any
    }, {
      name: 'loop-sweep',
      type: t.angle,
      triggersBounds: diff.any
    }, {
      name: 'source-distance-from-node',
      type: t.size,
      triggersBounds: diff.any
    }, {
      name: 'target-distance-from-node',
      type: t.size,
      triggersBounds: diff.any
    }];
    var ghost = [{
      name: 'ghost',
      type: t.bool,
      triggersBounds: diff.any
    }, {
      name: 'ghost-offset-x',
      type: t.bidirectionalSize,
      triggersBounds: diff.any
    }, {
      name: 'ghost-offset-y',
      type: t.bidirectionalSize,
      triggersBounds: diff.any
    }, {
      name: 'ghost-opacity',
      type: t.zeroOneNumber
    }];
    var core = [{
      name: 'selection-box-color',
      type: t.color
    }, {
      name: 'selection-box-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'selection-box-border-color',
      type: t.color
    }, {
      name: 'selection-box-border-width',
      type: t.size
    }, {
      name: 'active-bg-color',
      type: t.color
    }, {
      name: 'active-bg-opacity',
      type: t.zeroOneNumber
    }, {
      name: 'active-bg-size',
      type: t.size
    }, {
      name: 'outside-texture-bg-color',
      type: t.color
    }, {
      name: 'outside-texture-bg-opacity',
      type: t.zeroOneNumber
    }];

    // pie backgrounds for nodes
    var pie = [];
    styfn$2.pieBackgroundN = 16; // because the pie properties are numbered, give access to a constant N (for renderer use)
    pie.push({
      name: 'pie-size',
      type: t.sizeMaybePercent
    });
    for (var i = 1; i <= styfn$2.pieBackgroundN; i++) {
      pie.push({
        name: 'pie-' + i + '-background-color',
        type: t.color
      });
      pie.push({
        name: 'pie-' + i + '-background-size',
        type: t.percent
      });
      pie.push({
        name: 'pie-' + i + '-background-opacity',
        type: t.zeroOneNumber
      });
    }

    // edge arrows
    var edgeArrow = [];
    var arrowPrefixes = styfn$2.arrowPrefixes = ['source', 'mid-source', 'target', 'mid-target'];
    [{
      name: 'arrow-shape',
      type: t.arrowShape,
      triggersBounds: diff.any
    }, {
      name: 'arrow-color',
      type: t.color
    }, {
      name: 'arrow-fill',
      type: t.arrowFill
    }, {
      name: 'arrow-width',
      type: t.arrowWidth
    }].forEach(function (prop) {
      arrowPrefixes.forEach(function (prefix) {
        var name = prefix + '-' + prop.name;
        var type = prop.type,
          triggersBounds = prop.triggersBounds;
        edgeArrow.push({
          name: name,
          type: type,
          triggersBounds: triggersBounds
        });
      });
    }, {});
    var props = styfn$2.properties = [].concat(behavior, transition, visibility, overlay, underlay, ghost, commonLabel, labelDimensions, mainLabel, sourceLabel, targetLabel, nodeBody, nodeBorder, nodeOutline, backgroundImage, pie, compound, edgeLine, edgeArrow, core);
    var propGroups = styfn$2.propertyGroups = {
      // common to all eles
      behavior: behavior,
      transition: transition,
      visibility: visibility,
      overlay: overlay,
      underlay: underlay,
      ghost: ghost,
      // labels
      commonLabel: commonLabel,
      labelDimensions: labelDimensions,
      mainLabel: mainLabel,
      sourceLabel: sourceLabel,
      targetLabel: targetLabel,
      // node props
      nodeBody: nodeBody,
      nodeBorder: nodeBorder,
      nodeOutline: nodeOutline,
      backgroundImage: backgroundImage,
      pie: pie,
      compound: compound,
      // edge props
      edgeLine: edgeLine,
      edgeArrow: edgeArrow,
      core: core
    };
    var propGroupNames = styfn$2.propertyGroupNames = {};
    var propGroupKeys = styfn$2.propertyGroupKeys = Object.keys(propGroups);
    propGroupKeys.forEach(function (key) {
      propGroupNames[key] = propGroups[key].map(function (prop) {
        return prop.name;
      });
      propGroups[key].forEach(function (prop) {
        return prop.groupKey = key;
      });
    });

    // define aliases
    var aliases = styfn$2.aliases = [{
      name: 'content',
      pointsTo: 'label'
    }, {
      name: 'control-point-distance',
      pointsTo: 'control-point-distances'
    }, {
      name: 'control-point-weight',
      pointsTo: 'control-point-weights'
    }, {
      name: 'edge-text-rotation',
      pointsTo: 'text-rotation'
    }, {
      name: 'padding-left',
      pointsTo: 'padding'
    }, {
      name: 'padding-right',
      pointsTo: 'padding'
    }, {
      name: 'padding-top',
      pointsTo: 'padding'
    }, {
      name: 'padding-bottom',
      pointsTo: 'padding'
    }];

    // list of property names
    styfn$2.propertyNames = props.map(function (p) {
      return p.name;
    });

    // allow access of properties by name ( e.g. style.properties.height )
    for (var _i = 0; _i < props.length; _i++) {
      var prop = props[_i];
      props[prop.name] = prop; // allow lookup by name
    }

    // map aliases
    for (var _i2 = 0; _i2 < aliases.length; _i2++) {
      var alias = aliases[_i2];
      var pointsToProp = props[alias.pointsTo];
      var aliasProp = {
        name: alias.name,
        alias: true,
        pointsTo: pointsToProp
      };

      // add alias prop for parsing
      props.push(aliasProp);
      props[alias.name] = aliasProp; // allow lookup by name
    }
  })();

  styfn$2.getDefaultProperty = function (name) {
    return this.getDefaultProperties()[name];
  };
  styfn$2.getDefaultProperties = function () {
    var _p = this._private;
    if (_p.defaultProperties != null) {
      return _p.defaultProperties;
    }
    var rawProps = extend({
      // core props
      'selection-box-color': '#ddd',
      'selection-box-opacity': 0.65,
      'selection-box-border-color': '#aaa',
      'selection-box-border-width': 1,
      'active-bg-color': 'black',
      'active-bg-opacity': 0.15,
      'active-bg-size': 30,
      'outside-texture-bg-color': '#000',
      'outside-texture-bg-opacity': 0.125,
      // common node/edge props
      'events': 'yes',
      'text-events': 'no',
      'text-valign': 'top',
      'text-halign': 'center',
      'text-justification': 'auto',
      'line-height': 1,
      'color': '#000',
      'text-outline-color': '#000',
      'text-outline-width': 0,
      'text-outline-opacity': 1,
      'text-opacity': 1,
      'text-decoration': 'none',
      'text-transform': 'none',
      'text-wrap': 'none',
      'text-overflow-wrap': 'whitespace',
      'text-max-width': 9999,
      'text-background-color': '#000',
      'text-background-opacity': 0,
      'text-background-shape': 'rectangle',
      'text-background-padding': 0,
      'text-border-opacity': 0,
      'text-border-width': 0,
      'text-border-style': 'solid',
      'text-border-color': '#000',
      'font-family': 'Helvetica Neue, Helvetica, sans-serif',
      'font-style': 'normal',
      'font-weight': 'normal',
      'font-size': 16,
      'min-zoomed-font-size': 0,
      'text-rotation': 'none',
      'source-text-rotation': 'none',
      'target-text-rotation': 'none',
      'visibility': 'visible',
      'display': 'element',
      'opacity': 1,
      'z-compound-depth': 'auto',
      'z-index-compare': 'auto',
      'z-index': 0,
      'label': '',
      'text-margin-x': 0,
      'text-margin-y': 0,
      'source-label': '',
      'source-text-offset': 0,
      'source-text-margin-x': 0,
      'source-text-margin-y': 0,
      'target-label': '',
      'target-text-offset': 0,
      'target-text-margin-x': 0,
      'target-text-margin-y': 0,
      'overlay-opacity': 0,
      'overlay-color': '#000',
      'overlay-padding': 10,
      'overlay-shape': 'round-rectangle',
      'underlay-opacity': 0,
      'underlay-color': '#000',
      'underlay-padding': 10,
      'underlay-shape': 'round-rectangle',
      'transition-property': 'none',
      'transition-duration': 0,
      'transition-delay': 0,
      'transition-timing-function': 'linear',
      // node props
      'background-blacken': 0,
      'background-color': '#999',
      'background-fill': 'solid',
      'background-opacity': 1,
      'background-image': 'none',
      'background-image-crossorigin': 'anonymous',
      'background-image-opacity': 1,
      'background-image-containment': 'inside',
      'background-image-smoothing': 'yes',
      'background-position-x': '50%',
      'background-position-y': '50%',
      'background-offset-x': 0,
      'background-offset-y': 0,
      'background-width-relative-to': 'include-padding',
      'background-height-relative-to': 'include-padding',
      'background-repeat': 'no-repeat',
      'background-fit': 'none',
      'background-clip': 'node',
      'background-width': 'auto',
      'background-height': 'auto',
      'border-color': '#000',
      'border-opacity': 1,
      'border-width': 0,
      'border-style': 'solid',
      'outline-color': '#999',
      'outline-opacity': 1,
      'outline-width': 0,
      'outline-offset': 0,
      'outline-style': 'solid',
      'height': 30,
      'width': 30,
      'shape': 'ellipse',
      'shape-polygon-points': '-1, -1,   1, -1,   1, 1,   -1, 1',
      'bounds-expansion': 0,
      // node gradient
      'background-gradient-direction': 'to-bottom',
      'background-gradient-stop-colors': '#999',
      'background-gradient-stop-positions': '0%',
      // ghost props
      'ghost': 'no',
      'ghost-offset-y': 0,
      'ghost-offset-x': 0,
      'ghost-opacity': 0,
      // compound props
      'padding': 0,
      'padding-relative-to': 'width',
      'position': 'origin',
      'compound-sizing-wrt-labels': 'include',
      'min-width': 0,
      'min-width-bias-left': 0,
      'min-width-bias-right': 0,
      'min-height': 0,
      'min-height-bias-top': 0,
      'min-height-bias-bottom': 0
    }, {
      // node pie bg
      'pie-size': '100%'
    }, [{
      name: 'pie-{{i}}-background-color',
      value: 'black'
    }, {
      name: 'pie-{{i}}-background-size',
      value: '0%'
    }, {
      name: 'pie-{{i}}-background-opacity',
      value: 1
    }].reduce(function (css, prop) {
      for (var i = 1; i <= styfn$2.pieBackgroundN; i++) {
        var name = prop.name.replace('{{i}}', i);
        var val = prop.value;
        css[name] = val;
      }
      return css;
    }, {}), {
      // edge props
      'line-style': 'solid',
      'line-color': '#999',
      'line-fill': 'solid',
      'line-cap': 'butt',
      'line-opacity': 1,
      'line-gradient-stop-colors': '#999',
      'line-gradient-stop-positions': '0%',
      'control-point-step-size': 40,
      'control-point-weights': 0.5,
      'segment-weights': 0.5,
      'segment-distances': 20,
      'taxi-turn': '50%',
      'taxi-turn-min-distance': 10,
      'taxi-direction': 'auto',
      'edge-distances': 'intersection',
      'curve-style': 'haystack',
      'haystack-radius': 0,
      'arrow-scale': 1,
      'loop-direction': '-45deg',
      'loop-sweep': '-90deg',
      'source-distance-from-node': 0,
      'target-distance-from-node': 0,
      'source-endpoint': 'outside-to-node',
      'target-endpoint': 'outside-to-node',
      'line-dash-pattern': [6, 3],
      'line-dash-offset': 0
    }, [{
      name: 'arrow-shape',
      value: 'none'
    }, {
      name: 'arrow-color',
      value: '#999'
    }, {
      name: 'arrow-fill',
      value: 'filled'
    }, {
      name: 'arrow-width',
      value: 1
    }].reduce(function (css, prop) {
      styfn$2.arrowPrefixes.forEach(function (prefix) {
        var name = prefix + '-' + prop.name;
        var val = prop.value;
        css[name] = val;
      });
      return css;
    }, {}));
    var parsedProps = {};
    for (var i = 0; i < this.properties.length; i++) {
      var prop = this.properties[i];
      if (prop.pointsTo) {
        continue;
      }
      var name = prop.name;
      var val = rawProps[name];
      var parsedProp = this.parse(name, val);
      parsedProps[name] = parsedProp;
    }
    _p.defaultProperties = parsedProps;
    return _p.defaultProperties;
  };
  styfn$2.addDefaultStylesheet = function () {
    this.selector(':parent').css({
      'shape': 'rectangle',
      'padding': 10,
      'background-color': '#eee',
      'border-color': '#ccc',
      'border-width': 1
    }).selector('edge').css({
      'width': 3
    }).selector(':loop').css({
      'curve-style': 'bezier'
    }).selector('edge:compound').css({
      'curve-style': 'bezier',
      'source-endpoint': 'outside-to-line',
      'target-endpoint': 'outside-to-line'
    }).selector(':selected').css({
      'background-color': '#0169D9',
      'line-color': '#0169D9',
      'source-arrow-color': '#0169D9',
      'target-arrow-color': '#0169D9',
      'mid-source-arrow-color': '#0169D9',
      'mid-target-arrow-color': '#0169D9'
    }).selector(':parent:selected').css({
      'background-color': '#CCE1F9',
      'border-color': '#aec8e5'
    }).selector(':active').css({
      'overlay-color': 'black',
      'overlay-padding': 10,
      'overlay-opacity': 0.25
    });
    this.defaultLength = this.length;
  };

  var styfn$1 = {};

  // a caching layer for property parsing
  styfn$1.parse = function (name, value, propIsBypass, propIsFlat) {
    var self = this;

    // function values can't be cached in all cases, and there isn't much benefit of caching them anyway
    if (fn$6(value)) {
      return self.parseImplWarn(name, value, propIsBypass, propIsFlat);
    }
    var flatKey = propIsFlat === 'mapping' || propIsFlat === true || propIsFlat === false || propIsFlat == null ? 'dontcare' : propIsFlat;
    var bypassKey = propIsBypass ? 't' : 'f';
    var valueKey = '' + value;
    var argHash = hashStrings(name, valueKey, bypassKey, flatKey);
    var propCache = self.propCache = self.propCache || [];
    var ret;
    if (!(ret = propCache[argHash])) {
      ret = propCache[argHash] = self.parseImplWarn(name, value, propIsBypass, propIsFlat);
    }

    // - bypasses can't be shared b/c the value can be changed by animations or otherwise overridden
    // - mappings can't be shared b/c mappings are per-element
    if (propIsBypass || propIsFlat === 'mapping') {
      // need a copy since props are mutated later in their lifecycles
      ret = copy(ret);
      if (ret) {
        ret.value = copy(ret.value); // because it could be an array, e.g. colour
      }
    }

    return ret;
  };
  styfn$1.parseImplWarn = function (name, value, propIsBypass, propIsFlat) {
    var prop = this.parseImpl(name, value, propIsBypass, propIsFlat);
    if (!prop && value != null) {
      warn("The style property `".concat(name, ": ").concat(value, "` is invalid"));
    }
    if (prop && (prop.name === 'width' || prop.name === 'height') && value === 'label') {
      warn('The style value of `label` is deprecated for `' + prop.name + '`');
    }
    return prop;
  };

  // parse a property; return null on invalid; return parsed property otherwise
  // fields :
  // - name : the name of the property
  // - value : the parsed, native-typed value of the property
  // - strValue : a string value that represents the property value in valid css
  // - bypass : true iff the property is a bypass property
  styfn$1.parseImpl = function (name, value, propIsBypass, propIsFlat) {
    var self = this;
    name = camel2dash(name); // make sure the property name is in dash form (e.g. 'property-name' not 'propertyName')

    var property = self.properties[name];
    var passedValue = value;
    var types = self.types;
    if (!property) {
      return null;
    } // return null on property of unknown name
    if (value === undefined) {
      return null;
    } // can't assign undefined

    // the property may be an alias
    if (property.alias) {
      property = property.pointsTo;
      name = property.name;
    }
    var valueIsString = string(value);
    if (valueIsString) {
      // trim the value to make parsing easier
      value = value.trim();
    }
    var type = property.type;
    if (!type) {
      return null;
    } // no type, no luck

    // check if bypass is null or empty string (i.e. indication to delete bypass property)
    if (propIsBypass && (value === '' || value === null)) {
      return {
        name: name,
        value: value,
        bypass: true,
        deleteBypass: true
      };
    }

    // check if value is a function used as a mapper
    if (fn$6(value)) {
      return {
        name: name,
        value: value,
        strValue: 'fn',
        mapped: types.fn,
        bypass: propIsBypass
      };
    }

    // check if value is mapped
    var data, mapData;
    if (!valueIsString || propIsFlat || value.length < 7 || value[1] !== 'a') ; else if (value.length >= 7 && value[0] === 'd' && (data = new RegExp(types.data.regex).exec(value))) {
      if (propIsBypass) {
        return false;
      } // mappers not allowed in bypass

      var mapped = types.data;
      return {
        name: name,
        value: data,
        strValue: '' + value,
        mapped: mapped,
        field: data[1],
        bypass: propIsBypass
      };
    } else if (value.length >= 10 && value[0] === 'm' && (mapData = new RegExp(types.mapData.regex).exec(value))) {
      if (propIsBypass) {
        return false;
      } // mappers not allowed in bypass
      if (type.multiple) {
        return false;
      } // impossible to map to num

      var _mapped = types.mapData;

      // we can map only if the type is a colour or a number
      if (!(type.color || type.number)) {
        return false;
      }
      var valueMin = this.parse(name, mapData[4]); // parse to validate
      if (!valueMin || valueMin.mapped) {
        return false;
      } // can't be invalid or mapped

      var valueMax = this.parse(name, mapData[5]); // parse to validate
      if (!valueMax || valueMax.mapped) {
        return false;
      } // can't be invalid or mapped

      // check if valueMin and valueMax are the same
      if (valueMin.pfValue === valueMax.pfValue || valueMin.strValue === valueMax.strValue) {
        warn('`' + name + ': ' + value + '` is not a valid mapper because the output range is zero; converting to `' + name + ': ' + valueMin.strValue + '`');
        return this.parse(name, valueMin.strValue); // can't make much of a mapper without a range
      } else if (type.color) {
        var c1 = valueMin.value;
        var c2 = valueMax.value;
        var same = c1[0] === c2[0] // red
        && c1[1] === c2[1] // green
        && c1[2] === c2[2] // blue
        && (
        // optional alpha
        c1[3] === c2[3] // same alpha outright
        || (c1[3] == null || c1[3] === 1 // full opacity for colour 1?
        ) && (c2[3] == null || c2[3] === 1) // full opacity for colour 2?
        );

        if (same) {
          return false;
        } // can't make a mapper without a range
      }

      return {
        name: name,
        value: mapData,
        strValue: '' + value,
        mapped: _mapped,
        field: mapData[1],
        fieldMin: parseFloat(mapData[2]),
        // min & max are numeric
        fieldMax: parseFloat(mapData[3]),
        valueMin: valueMin.value,
        valueMax: valueMax.value,
        bypass: propIsBypass
      };
    }
    if (type.multiple && propIsFlat !== 'multiple') {
      var vals;
      if (valueIsString) {
        vals = value.split(/\s+/);
      } else if (array(value)) {
        vals = value;
      } else {
        vals = [value];
      }
      if (type.evenMultiple && vals.length % 2 !== 0) {
        return null;
      }
      var valArr = [];
      var unitsArr = [];
      var pfValArr = [];
      var strVal = '';
      var hasEnum = false;
      for (var i = 0; i < vals.length; i++) {
        var p = self.parse(name, vals[i], propIsBypass, 'multiple');
        hasEnum = hasEnum || string(p.value);
        valArr.push(p.value);
        pfValArr.push(p.pfValue != null ? p.pfValue : p.value);
        unitsArr.push(p.units);
        strVal += (i > 0 ? ' ' : '') + p.strValue;
      }
      if (type.validate && !type.validate(valArr, unitsArr)) {
        return null;
      }
      if (type.singleEnum && hasEnum) {
        if (valArr.length === 1 && string(valArr[0])) {
          return {
            name: name,
            value: valArr[0],
            strValue: valArr[0],
            bypass: propIsBypass
          };
        } else {
          return null;
        }
      }
      return {
        name: name,
        value: valArr,
        pfValue: pfValArr,
        strValue: strVal,
        bypass: propIsBypass,
        units: unitsArr
      };
    }

    // several types also allow enums
    var checkEnums = function checkEnums() {
      for (var _i = 0; _i < type.enums.length; _i++) {
        var en = type.enums[_i];
        if (en === value) {
          return {
            name: name,
            value: value,
            strValue: '' + value,
            bypass: propIsBypass
          };
        }
      }
      return null;
    };

    // check the type and return the appropriate object
    if (type.number) {
      var units;
      var implicitUnits = 'px'; // not set => px

      if (type.units) {
        // use specified units if set
        units = type.units;
      }
      if (type.implicitUnits) {
        implicitUnits = type.implicitUnits;
      }
      if (!type.unitless) {
        if (valueIsString) {
          var unitsRegex = 'px|em' + (type.allowPercent ? '|\\%' : '');
          if (units) {
            unitsRegex = units;
          } // only allow explicit units if so set
          var match = value.match('^(' + number + ')(' + unitsRegex + ')?' + '$');
          if (match) {
            value = match[1];
            units = match[2] || implicitUnits;
          }
        } else if (!units || type.implicitUnits) {
          units = implicitUnits; // implicitly px if unspecified
        }
      }

      value = parseFloat(value);

      // if not a number and enums not allowed, then the value is invalid
      if (isNaN(value) && type.enums === undefined) {
        return null;
      }

      // check if this number type also accepts special keywords in place of numbers
      // (i.e. `left`, `auto`, etc)
      if (isNaN(value) && type.enums !== undefined) {
        value = passedValue;
        return checkEnums();
      }

      // check if value must be an integer
      if (type.integer && !integer(value)) {
        return null;
      }

      // check value is within range
      if (type.min !== undefined && (value < type.min || type.strictMin && value === type.min) || type.max !== undefined && (value > type.max || type.strictMax && value === type.max)) {
        return null;
      }
      var ret = {
        name: name,
        value: value,
        strValue: '' + value + (units ? units : ''),
        units: units,
        bypass: propIsBypass
      };

      // normalise value in pixels
      if (type.unitless || units !== 'px' && units !== 'em') {
        ret.pfValue = value;
      } else {
        ret.pfValue = units === 'px' || !units ? value : this.getEmSizeInPixels() * value;
      }

      // normalise value in ms
      if (units === 'ms' || units === 's') {
        ret.pfValue = units === 'ms' ? value : 1000 * value;
      }

      // normalise value in rad
      if (units === 'deg' || units === 'rad') {
        ret.pfValue = units === 'rad' ? value : deg2rad(value);
      }

      // normalize value in %
      if (units === '%') {
        ret.pfValue = value / 100;
      }
      return ret;
    } else if (type.propList) {
      var props = [];
      var propsStr = '' + value;
      if (propsStr === 'none') ; else {
        // go over each prop

        var propsSplit = propsStr.split(/\s*,\s*|\s+/);
        for (var _i2 = 0; _i2 < propsSplit.length; _i2++) {
          var propName = propsSplit[_i2].trim();
          if (self.properties[propName]) {
            props.push(propName);
          } else {
            warn('`' + propName + '` is not a valid property name');
          }
        }
        if (props.length === 0) {
          return null;
        }
      }
      return {
        name: name,
        value: props,
        strValue: props.length === 0 ? 'none' : props.join(' '),
        bypass: propIsBypass
      };
    } else if (type.color) {
      var tuple = color2tuple(value);
      if (!tuple) {
        return null;
      }
      return {
        name: name,
        value: tuple,
        pfValue: tuple,
        strValue: 'rgb(' + tuple[0] + ',' + tuple[1] + ',' + tuple[2] + ')',
        // n.b. no spaces b/c of multiple support
        bypass: propIsBypass
      };
    } else if (type.regex || type.regexes) {
      // first check enums
      if (type.enums) {
        var enumProp = checkEnums();
        if (enumProp) {
          return enumProp;
        }
      }
      var regexes = type.regexes ? type.regexes : [type.regex];
      for (var _i3 = 0; _i3 < regexes.length; _i3++) {
        var regex = new RegExp(regexes[_i3]); // make a regex from the type string
        var m = regex.exec(value);
        if (m) {
          // regex matches
          return {
            name: name,
            value: type.singleRegexMatchValue ? m[1] : m,
            strValue: '' + value,
            bypass: propIsBypass
          };
        }
      }
      return null; // didn't match any
    } else if (type.string) {
      // just return
      return {
        name: name,
        value: '' + value,
        strValue: '' + value,
        bypass: propIsBypass
      };
    } else if (type.enums) {
      // check enums last because it's a combo type in others
      return checkEnums();
    } else {
      return null; // not a type we can handle
    }
  };

  var Style = function Style(cy) {
    if (!(this instanceof Style)) {
      return new Style(cy);
    }
    if (!core(cy)) {
      error('A style must have a core reference');
      return;
    }
    this._private = {
      cy: cy,
      coreStyle: {}
    };
    this.length = 0;
    this.resetToDefault();
  };
  var styfn = Style.prototype;
  styfn.instanceString = function () {
    return 'style';
  };

  // remove all contexts
  styfn.clear = function () {
    var _p = this._private;
    var cy = _p.cy;
    var eles = cy.elements();
    for (var i = 0; i < this.length; i++) {
      this[i] = undefined;
    }
    this.length = 0;
    _p.contextStyles = {};
    _p.propDiffs = {};
    this.cleanElements(eles, true);
    eles.forEach(function (ele) {
      var ele_p = ele[0]._private;
      ele_p.styleDirty = true;
      ele_p.appliedInitStyle = false;
    });
    return this; // chaining
  };

  styfn.resetToDefault = function () {
    this.clear();
    this.addDefaultStylesheet();
    return this;
  };

  // builds a style object for the 'core' selector
  styfn.core = function (propName) {
    return this._private.coreStyle[propName] || this.getDefaultProperty(propName);
  };

  // create a new context from the specified selector string and switch to that context
  styfn.selector = function (selectorStr) {
    // 'core' is a special case and does not need a selector
    var selector = selectorStr === 'core' ? null : new Selector(selectorStr);
    var i = this.length++; // new context means new index
    this[i] = {
      selector: selector,
      properties: [],
      mappedProperties: [],
      index: i
    };
    return this; // chaining
  };

  // add one or many css rules to the current context
  styfn.css = function () {
    var self = this;
    var args = arguments;
    if (args.length === 1) {
      var map = args[0];
      for (var i = 0; i < self.properties.length; i++) {
        var prop = self.properties[i];
        var mapVal = map[prop.name];
        if (mapVal === undefined) {
          mapVal = map[dash2camel(prop.name)];
        }
        if (mapVal !== undefined) {
          this.cssRule(prop.name, mapVal);
        }
      }
    } else if (args.length === 2) {
      this.cssRule(args[0], args[1]);
    }

    // do nothing if args are invalid

    return this; // chaining
  };

  styfn.style = styfn.css;

  // add a single css rule to the current context
  styfn.cssRule = function (name, value) {
    // name-value pair
    var property = this.parse(name, value);

    // add property to current context if valid
    if (property) {
      var i = this.length - 1;
      this[i].properties.push(property);
      this[i].properties[property.name] = property; // allow access by name as well

      if (property.name.match(/pie-(\d+)-background-size/) && property.value) {
        this._private.hasPie = true;
      }
      if (property.mapped) {
        this[i].mappedProperties.push(property);
      }

      // add to core style if necessary
      var currentSelectorIsCore = !this[i].selector;
      if (currentSelectorIsCore) {
        this._private.coreStyle[property.name] = property;
      }
    }
    return this; // chaining
  };

  styfn.append = function (style) {
    if (stylesheet(style)) {
      style.appendToStyle(this);
    } else if (array(style)) {
      this.appendFromJson(style);
    } else if (string(style)) {
      this.appendFromString(style);
    } // you probably wouldn't want to append a Style, since you'd duplicate the default parts

    return this;
  };

  // static function
  Style.fromJson = function (cy, json) {
    var style = new Style(cy);
    style.fromJson(json);
    return style;
  };
  Style.fromString = function (cy, string) {
    return new Style(cy).fromString(string);
  };
  [styfn$8, styfn$7, styfn$6, styfn$5, styfn$4, styfn$3, styfn$2, styfn$1].forEach(function (props) {
    extend(styfn, props);
  });
  Style.types = styfn.types;
  Style.properties = styfn.properties;
  Style.propertyGroups = styfn.propertyGroups;
  Style.propertyGroupNames = styfn.propertyGroupNames;
  Style.propertyGroupKeys = styfn.propertyGroupKeys;

  var corefn$2 = {
    style: function style(newStyle) {
      if (newStyle) {
        var s = this.setStyle(newStyle);
        s.update();
      }
      return this._private.style;
    },
    setStyle: function setStyle(style) {
      var _p = this._private;
      if (stylesheet(style)) {
        _p.style = style.generateStyle(this);
      } else if (array(style)) {
        _p.style = Style.fromJson(this, style);
      } else if (string(style)) {
        _p.style = Style.fromString(this, style);
      } else {
        _p.style = Style(this);
      }
      return _p.style;
    },
    // e.g. cy.data() changed => recalc ele mappers
    updateStyle: function updateStyle() {
      this.mutableElements().updateStyle(); // just send to all eles
    }
  };

  var defaultSelectionType = 'single';
  var corefn$1 = {
    autolock: function autolock(bool) {
      if (bool !== undefined) {
        this._private.autolock = bool ? true : false;
      } else {
        return this._private.autolock;
      }
      return this; // chaining
    },

    autoungrabify: function autoungrabify(bool) {
      if (bool !== undefined) {
        this._private.autoungrabify = bool ? true : false;
      } else {
        return this._private.autoungrabify;
      }
      return this; // chaining
    },

    autounselectify: function autounselectify(bool) {
      if (bool !== undefined) {
        this._private.autounselectify = bool ? true : false;
      } else {
        return this._private.autounselectify;
      }
      return this; // chaining
    },

    selectionType: function selectionType(selType) {
      var _p = this._private;
      if (_p.selectionType == null) {
        _p.selectionType = defaultSelectionType;
      }
      if (selType !== undefined) {
        if (selType === 'additive' || selType === 'single') {
          _p.selectionType = selType;
        }
      } else {
        return _p.selectionType;
      }
      return this;
    },
    panningEnabled: function panningEnabled(bool) {
      if (bool !== undefined) {
        this._private.panningEnabled = bool ? true : false;
      } else {
        return this._private.panningEnabled;
      }
      return this; // chaining
    },

    userPanningEnabled: function userPanningEnabled(bool) {
      if (bool !== undefined) {
        this._private.userPanningEnabled = bool ? true : false;
      } else {
        return this._private.userPanningEnabled;
      }
      return this; // chaining
    },

    zoomingEnabled: function zoomingEnabled(bool) {
      if (bool !== undefined) {
        this._private.zoomingEnabled = bool ? true : false;
      } else {
        return this._private.zoomingEnabled;
      }
      return this; // chaining
    },

    userZoomingEnabled: function userZoomingEnabled(bool) {
      if (bool !== undefined) {
        this._private.userZoomingEnabled = bool ? true : false;
      } else {
        return this._private.userZoomingEnabled;
      }
      return this; // chaining
    },

    boxSelectionEnabled: function boxSelectionEnabled(bool) {
      if (bool !== undefined) {
        this._private.boxSelectionEnabled = bool ? true : false;
      } else {
        return this._private.boxSelectionEnabled;
      }
      return this; // chaining
    },

    pan: function pan() {
      var args = arguments;
      var pan = this._private.pan;
      var dim, val, dims, x, y;
      switch (args.length) {
        case 0:
          // .pan()
          return pan;
        case 1:
          if (string(args[0])) {
            // .pan('x')
            dim = args[0];
            return pan[dim];
          } else if (plainObject(args[0])) {
            // .pan({ x: 0, y: 100 })
            if (!this._private.panningEnabled) {
              return this;
            }
            dims = args[0];
            x = dims.x;
            y = dims.y;
            if (number$1(x)) {
              pan.x = x;
            }
            if (number$1(y)) {
              pan.y = y;
            }
            this.emit('pan viewport');
          }
          break;
        case 2:
          // .pan('x', 100)
          if (!this._private.panningEnabled) {
            return this;
          }
          dim = args[0];
          val = args[1];
          if ((dim === 'x' || dim === 'y') && number$1(val)) {
            pan[dim] = val;
          }
          this.emit('pan viewport');
          break;
        // invalid
      }

      this.notify('viewport');
      return this; // chaining
    },

    panBy: function panBy(arg0, arg1) {
      var args = arguments;
      var pan = this._private.pan;
      var dim, val, dims, x, y;
      if (!this._private.panningEnabled) {
        return this;
      }
      switch (args.length) {
        case 1:
          if (plainObject(arg0)) {
            // .panBy({ x: 0, y: 100 })
            dims = args[0];
            x = dims.x;
            y = dims.y;
            if (number$1(x)) {
              pan.x += x;
            }
            if (number$1(y)) {
              pan.y += y;
            }
            this.emit('pan viewport');
          }
          break;
        case 2:
          // .panBy('x', 100)
          dim = arg0;
          val = arg1;
          if ((dim === 'x' || dim === 'y') && number$1(val)) {
            pan[dim] += val;
          }
          this.emit('pan viewport');
          break;
        // invalid
      }

      this.notify('viewport');
      return this; // chaining
    },

    fit: function fit(elements, padding) {
      var viewportState = this.getFitViewport(elements, padding);
      if (viewportState) {
        var _p = this._private;
        _p.zoom = viewportState.zoom;
        _p.pan = viewportState.pan;
        this.emit('pan zoom viewport');
        this.notify('viewport');
      }
      return this; // chaining
    },

    getFitViewport: function getFitViewport(elements, padding) {
      if (number$1(elements) && padding === undefined) {
        // elements is optional
        padding = elements;
        elements = undefined;
      }
      if (!this._private.panningEnabled || !this._private.zoomingEnabled) {
        return;
      }
      var bb;
      if (string(elements)) {
        var sel = elements;
        elements = this.$(sel);
      } else if (boundingBox(elements)) {
        // assume bb
        var bbe = elements;
        bb = {
          x1: bbe.x1,
          y1: bbe.y1,
          x2: bbe.x2,
          y2: bbe.y2
        };
        bb.w = bb.x2 - bb.x1;
        bb.h = bb.y2 - bb.y1;
      } else if (!elementOrCollection(elements)) {
        elements = this.mutableElements();
      }
      if (elementOrCollection(elements) && elements.empty()) {
        return;
      } // can't fit to nothing

      bb = bb || elements.boundingBox();
      var w = this.width();
      var h = this.height();
      var zoom;
      padding = number$1(padding) ? padding : 0;
      if (!isNaN(w) && !isNaN(h) && w > 0 && h > 0 && !isNaN(bb.w) && !isNaN(bb.h) && bb.w > 0 && bb.h > 0) {
        zoom = Math.min((w - 2 * padding) / bb.w, (h - 2 * padding) / bb.h);

        // crop zoom
        zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom;
        zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom;
        var pan = {
          // now pan to middle
          x: (w - zoom * (bb.x1 + bb.x2)) / 2,
          y: (h - zoom * (bb.y1 + bb.y2)) / 2
        };
        return {
          zoom: zoom,
          pan: pan
        };
      }
      return;
    },
    zoomRange: function zoomRange(min, max) {
      var _p = this._private;
      if (max == null) {
        var opts = min;
        min = opts.min;
        max = opts.max;
      }
      if (number$1(min) && number$1(max) && min <= max) {
        _p.minZoom = min;
        _p.maxZoom = max;
      } else if (number$1(min) && max === undefined && min <= _p.maxZoom) {
        _p.minZoom = min;
      } else if (number$1(max) && min === undefined && max >= _p.minZoom) {
        _p.maxZoom = max;
      }
      return this;
    },
    minZoom: function minZoom(zoom) {
      if (zoom === undefined) {
        return this._private.minZoom;
      } else {
        return this.zoomRange({
          min: zoom
        });
      }
    },
    maxZoom: function maxZoom(zoom) {
      if (zoom === undefined) {
        return this._private.maxZoom;
      } else {
        return this.zoomRange({
          max: zoom
        });
      }
    },
    getZoomedViewport: function getZoomedViewport(params) {
      var _p = this._private;
      var currentPan = _p.pan;
      var currentZoom = _p.zoom;
      var pos; // in rendered px
      var zoom;
      var bail = false;
      if (!_p.zoomingEnabled) {
        // zooming disabled
        bail = true;
      }
      if (number$1(params)) {
        // then set the zoom
        zoom = params;
      } else if (plainObject(params)) {
        // then zoom about a point
        zoom = params.level;
        if (params.position != null) {
          pos = modelToRenderedPosition(params.position, currentZoom, currentPan);
        } else if (params.renderedPosition != null) {
          pos = params.renderedPosition;
        }
        if (pos != null && !_p.panningEnabled) {
          // panning disabled
          bail = true;
        }
      }

      // crop zoom
      zoom = zoom > _p.maxZoom ? _p.maxZoom : zoom;
      zoom = zoom < _p.minZoom ? _p.minZoom : zoom;

      // can't zoom with invalid params
      if (bail || !number$1(zoom) || zoom === currentZoom || pos != null && (!number$1(pos.x) || !number$1(pos.y))) {
        return null;
      }
      if (pos != null) {
        // set zoom about position
        var pan1 = currentPan;
        var zoom1 = currentZoom;
        var zoom2 = zoom;
        var pan2 = {
          x: -zoom2 / zoom1 * (pos.x - pan1.x) + pos.x,
          y: -zoom2 / zoom1 * (pos.y - pan1.y) + pos.y
        };
        return {
          zoomed: true,
          panned: true,
          zoom: zoom2,
          pan: pan2
        };
      } else {
        // just set the zoom
        return {
          zoomed: true,
          panned: false,
          zoom: zoom,
          pan: currentPan
        };
      }
    },
    zoom: function zoom(params) {
      if (params === undefined) {
        // get
        return this._private.zoom;
      } else {
        // set
        var vp = this.getZoomedViewport(params);
        var _p = this._private;
        if (vp == null || !vp.zoomed) {
          return this;
        }
        _p.zoom = vp.zoom;
        if (vp.panned) {
          _p.pan.x = vp.pan.x;
          _p.pan.y = vp.pan.y;
        }
        this.emit('zoom' + (vp.panned ? ' pan' : '') + ' viewport');
        this.notify('viewport');
        return this; // chaining
      }
    },

    viewport: function viewport(opts) {
      var _p = this._private;
      var zoomDefd = true;
      var panDefd = true;
      var events = []; // to trigger
      var zoomFailed = false;
      var panFailed = false;
      if (!opts) {
        return this;
      }
      if (!number$1(opts.zoom)) {
        zoomDefd = false;
      }
      if (!plainObject(opts.pan)) {
        panDefd = false;
      }
      if (!zoomDefd && !panDefd) {
        return this;
      }
      if (zoomDefd) {
        var z = opts.zoom;
        if (z < _p.minZoom || z > _p.maxZoom || !_p.zoomingEnabled) {
          zoomFailed = true;
        } else {
          _p.zoom = z;
          events.push('zoom');
        }
      }
      if (panDefd && (!zoomFailed || !opts.cancelOnFailedZoom) && _p.panningEnabled) {
        var p = opts.pan;
        if (number$1(p.x)) {
          _p.pan.x = p.x;
          panFailed = false;
        }
        if (number$1(p.y)) {
          _p.pan.y = p.y;
          panFailed = false;
        }
        if (!panFailed) {
          events.push('pan');
        }
      }
      if (events.length > 0) {
        events.push('viewport');
        this.emit(events.join(' '));
        this.notify('viewport');
      }
      return this; // chaining
    },

    center: function center(elements) {
      var pan = this.getCenterPan(elements);
      if (pan) {
        this._private.pan = pan;
        this.emit('pan viewport');
        this.notify('viewport');
      }
      return this; // chaining
    },

    getCenterPan: function getCenterPan(elements, zoom) {
      if (!this._private.panningEnabled) {
        return;
      }
      if (string(elements)) {
        var selector = elements;
        elements = this.mutableElements().filter(selector);
      } else if (!elementOrCollection(elements)) {
        elements = this.mutableElements();
      }
      if (elements.length === 0) {
        return;
      } // can't centre pan to nothing

      var bb = elements.boundingBox();
      var w = this.width();
      var h = this.height();
      zoom = zoom === undefined ? this._private.zoom : zoom;
      var pan = {
        // middle
        x: (w - zoom * (bb.x1 + bb.x2)) / 2,
        y: (h - zoom * (bb.y1 + bb.y2)) / 2
      };
      return pan;
    },
    reset: function reset() {
      if (!this._private.panningEnabled || !this._private.zoomingEnabled) {
        return this;
      }
      this.viewport({
        pan: {
          x: 0,
          y: 0
        },
        zoom: 1
      });
      return this; // chaining
    },

    invalidateSize: function invalidateSize() {
      this._private.sizeCache = null;
    },
    size: function size() {
      var _p = this._private;
      var container = _p.container;
      var cy = this;
      return _p.sizeCache = _p.sizeCache || (container ? function () {
        var style = cy.window().getComputedStyle(container);
        var val = function val(name) {
          return parseFloat(style.getPropertyValue(name));
        };
        return {
          width: container.clientWidth - val('padding-left') - val('padding-right'),
          height: container.clientHeight - val('padding-top') - val('padding-bottom')
        };
      }() : {
        // fallback if no container (not 0 b/c can be used for dividing etc)
        width: 1,
        height: 1
      });
    },
    width: function width() {
      return this.size().width;
    },
    height: function height() {
      return this.size().height;
    },
    extent: function extent() {
      var pan = this._private.pan;
      var zoom = this._private.zoom;
      var rb = this.renderedExtent();
      var b = {
        x1: (rb.x1 - pan.x) / zoom,
        x2: (rb.x2 - pan.x) / zoom,
        y1: (rb.y1 - pan.y) / zoom,
        y2: (rb.y2 - pan.y) / zoom
      };
      b.w = b.x2 - b.x1;
      b.h = b.y2 - b.y1;
      return b;
    },
    renderedExtent: function renderedExtent() {
      var width = this.width();
      var height = this.height();
      return {
        x1: 0,
        y1: 0,
        x2: width,
        y2: height,
        w: width,
        h: height
      };
    },
    multiClickDebounceTime: function multiClickDebounceTime(_int) {
      if (_int) this._private.multiClickDebounceTime = _int;else return this._private.multiClickDebounceTime;
      return this; // chaining
    }
  };

  // aliases
  corefn$1.centre = corefn$1.center;

  // backwards compatibility
  corefn$1.autolockNodes = corefn$1.autolock;
  corefn$1.autoungrabifyNodes = corefn$1.autoungrabify;

  var fn = {
    data: define.data({
      field: 'data',
      bindingEvent: 'data',
      allowBinding: true,
      allowSetting: true,
      settingEvent: 'data',
      settingTriggersEvent: true,
      triggerFnName: 'trigger',
      allowGetting: true,
      updateStyle: true
    }),
    removeData: define.removeData({
      field: 'data',
      event: 'data',
      triggerFnName: 'trigger',
      triggerEvent: true,
      updateStyle: true
    }),
    scratch: define.data({
      field: 'scratch',
      bindingEvent: 'scratch',
      allowBinding: true,
      allowSetting: true,
      settingEvent: 'scratch',
      settingTriggersEvent: true,
      triggerFnName: 'trigger',
      allowGetting: true,
      updateStyle: true
    }),
    removeScratch: define.removeData({
      field: 'scratch',
      event: 'scratch',
      triggerFnName: 'trigger',
      triggerEvent: true,
      updateStyle: true
    })
  };

  // aliases
  fn.attr = fn.data;
  fn.removeAttr = fn.removeData;

  var Core = function Core(opts) {
    var cy = this;
    opts = extend({}, opts);
    var container = opts.container;

    // allow for passing a wrapped jquery object
    // e.g. cytoscape({ container: $('#cy') })
    if (container && !htmlElement(container) && htmlElement(container[0])) {
      container = container[0];
    }
    var reg = container ? container._cyreg : null; // e.g. already registered some info (e.g. readies) via jquery
    reg = reg || {};
    if (reg && reg.cy) {
      reg.cy.destroy();
      reg = {}; // old instance => replace reg completely
    }

    var readies = reg.readies = reg.readies || [];
    if (container) {
      container._cyreg = reg;
    } // make sure container assoc'd reg points to this cy
    reg.cy = cy;
    var head = _window !== undefined && container !== undefined && !opts.headless;
    var options = opts;
    options.layout = extend({
      name: head ? 'grid' : 'null'
    }, options.layout);
    options.renderer = extend({
      name: head ? 'canvas' : 'null'
    }, options.renderer);
    var defVal = function defVal(def, val, altVal) {
      if (val !== undefined) {
        return val;
      } else if (altVal !== undefined) {
        return altVal;
      } else {
        return def;
      }
    };
    var _p = this._private = {
      container: container,
      // html dom ele container
      ready: false,
      // whether ready has been triggered
      options: options,
      // cached options
      elements: new Collection(this),
      // elements in the graph
      listeners: [],
      // list of listeners
      aniEles: new Collection(this),
      // elements being animated
      data: options.data || {},
      // data for the core
      scratch: {},
      // scratch object for core
      layout: null,
      renderer: null,
      destroyed: false,
      // whether destroy was called
      notificationsEnabled: true,
      // whether notifications are sent to the renderer
      minZoom: 1e-50,
      maxZoom: 1e50,
      zoomingEnabled: defVal(true, options.zoomingEnabled),
      userZoomingEnabled: defVal(true, options.userZoomingEnabled),
      panningEnabled: defVal(true, options.panningEnabled),
      userPanningEnabled: defVal(true, options.userPanningEnabled),
      boxSelectionEnabled: defVal(true, options.boxSelectionEnabled),
      autolock: defVal(false, options.autolock, options.autolockNodes),
      autoungrabify: defVal(false, options.autoungrabify, options.autoungrabifyNodes),
      autounselectify: defVal(false, options.autounselectify),
      styleEnabled: options.styleEnabled === undefined ? head : options.styleEnabled,
      zoom: number$1(options.zoom) ? options.zoom : 1,
      pan: {
        x: plainObject(options.pan) && number$1(options.pan.x) ? options.pan.x : 0,
        y: plainObject(options.pan) && number$1(options.pan.y) ? options.pan.y : 0
      },
      animation: {
        // object for currently-running animations
        current: [],
        queue: []
      },
      hasCompoundNodes: false,
      multiClickDebounceTime: defVal(250, options.multiClickDebounceTime)
    };
    this.createEmitter();

    // set selection type
    this.selectionType(options.selectionType);

    // init zoom bounds
    this.zoomRange({
      min: options.minZoom,
      max: options.maxZoom
    });
    var loadExtData = function loadExtData(extData, next) {
      var anyIsPromise = extData.some(promise);
      if (anyIsPromise) {
        return Promise$1.all(extData).then(next); // load all data asynchronously, then exec rest of init
      } else {
        next(extData); // exec synchronously for convenience
      }
    };

    // start with the default stylesheet so we have something before loading an external stylesheet
    if (_p.styleEnabled) {
      cy.setStyle([]);
    }

    // create the renderer
    var rendererOptions = extend({}, options, options.renderer); // allow rendering hints in top level options
    cy.initRenderer(rendererOptions);
    var setElesAndLayout = function setElesAndLayout(elements, onload, ondone) {
      cy.notifications(false);

      // remove old elements
      var oldEles = cy.mutableElements();
      if (oldEles.length > 0) {
        oldEles.remove();
      }
      if (elements != null) {
        if (plainObject(elements) || array(elements)) {
          cy.add(elements);
        }
      }
      cy.one('layoutready', function (e) {
        cy.notifications(true);
        cy.emit(e); // we missed this event by turning notifications off, so pass it on

        cy.one('load', onload);
        cy.emitAndNotify('load');
      }).one('layoutstop', function () {
        cy.one('done', ondone);
        cy.emit('done');
      });
      var layoutOpts = extend({}, cy._private.options.layout);
      layoutOpts.eles = cy.elements();
      cy.layout(layoutOpts).run();
    };
    loadExtData([options.style, options.elements], function (thens) {
      var initStyle = thens[0];
      var initEles = thens[1];

      // init style
      if (_p.styleEnabled) {
        cy.style().append(initStyle);
      }

      // initial load
      setElesAndLayout(initEles, function () {
        // onready
        cy.startAnimationLoop();
        _p.ready = true;

        // if a ready callback is specified as an option, the bind it
        if (fn$6(options.ready)) {
          cy.on('ready', options.ready);
        }

        // bind all the ready handlers registered before creating this instance
        for (var i = 0; i < readies.length; i++) {
          var fn = readies[i];
          cy.on('ready', fn);
        }
        if (reg) {
          reg.readies = [];
        } // 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

        cy.emit('ready');
      }, options.done);
    });
  };
  var corefn = Core.prototype; // short alias

  extend(corefn, {
    instanceString: function instanceString() {
      return 'core';
    },
    isReady: function isReady() {
      return this._private.ready;
    },
    destroyed: function destroyed() {
      return this._private.destroyed;
    },
    ready: function ready(fn) {
      if (this.isReady()) {
        this.emitter().emit('ready', [], fn); // just calls fn as though triggered via ready event
      } else {
        this.on('ready', fn);
      }
      return this;
    },
    destroy: function destroy() {
      var cy = this;
      if (cy.destroyed()) return;
      cy.stopAnimationLoop();
      cy.destroyRenderer();
      this.emit('destroy');
      cy._private.destroyed = true;
      return cy;
    },
    hasElementWithId: function hasElementWithId(id) {
      return this._private.elements.hasElementWithId(id);
    },
    getElementById: function getElementById(id) {
      return this._private.elements.getElementById(id);
    },
    hasCompoundNodes: function hasCompoundNodes() {
      return this._private.hasCompoundNodes;
    },
    headless: function headless() {
      return this._private.renderer.isHeadless();
    },
    styleEnabled: function styleEnabled() {
      return this._private.styleEnabled;
    },
    addToPool: function addToPool(eles) {
      this._private.elements.merge(eles);
      return this; // chaining
    },

    removeFromPool: function removeFromPool(eles) {
      this._private.elements.unmerge(eles);
      return this;
    },
    container: function container() {
      return this._private.container || null;
    },
    window: function window() {
      var container = this._private.container;
      if (container == null) return _window;
      var ownerDocument = this._private.container.ownerDocument;
      if (ownerDocument === undefined || ownerDocument == null) {
        return _window;
      }
      return ownerDocument.defaultView || _window;
    },
    mount: function mount(container) {
      if (container == null) {
        return;
      }
      var cy = this;
      var _p = cy._private;
      var options = _p.options;
      if (!htmlElement(container) && htmlElement(container[0])) {
        container = container[0];
      }
      cy.stopAnimationLoop();
      cy.destroyRenderer();
      _p.container = container;
      _p.styleEnabled = true;
      cy.invalidateSize();
      cy.initRenderer(extend({}, options, options.renderer, {
        // allow custom renderer name to be re-used, otherwise use canvas
        name: options.renderer.name === 'null' ? 'canvas' : options.renderer.name
      }));
      cy.startAnimationLoop();
      cy.style(options.style);
      cy.emit('mount');
      return cy;
    },
    unmount: function unmount() {
      var cy = this;
      cy.stopAnimationLoop();
      cy.destroyRenderer();
      cy.initRenderer({
        name: 'null'
      });
      cy.emit('unmount');
      return cy;
    },
    options: function options() {
      return copy(this._private.options);
    },
    json: function json(obj) {
      var cy = this;
      var _p = cy._private;
      var eles = cy.mutableElements();
      var getFreshRef = function getFreshRef(ele) {
        return cy.getElementById(ele.id());
      };
      if (plainObject(obj)) {
        // set

        cy.startBatch();
        if (obj.elements) {
          var idInJson = {};
          var updateEles = function updateEles(jsons, gr) {
            var toAdd = [];
            var toMod = [];
            for (var i = 0; i < jsons.length; i++) {
              var json = jsons[i];
              if (!json.data.id) {
                warn('cy.json() cannot handle elements without an ID attribute');
                continue;
              }
              var id = '' + json.data.id; // id must be string
              var ele = cy.getElementById(id);
              idInJson[id] = true;
              if (ele.length !== 0) {
                // existing element should be updated
                toMod.push({
                  ele: ele,
                  json: json
                });
              } else {
                // otherwise should be added
                if (gr) {
                  json.group = gr;
                  toAdd.push(json);
                } else {
                  toAdd.push(json);
                }
              }
            }
            cy.add(toAdd);
            for (var _i = 0; _i < toMod.length; _i++) {
              var _toMod$_i = toMod[_i],
                _ele = _toMod$_i.ele,
                _json = _toMod$_i.json;
              _ele.json(_json);
            }
          };
          if (array(obj.elements)) {
            // elements: []
            updateEles(obj.elements);
          } else {
            // elements: { nodes: [], edges: [] }
            var grs = ['nodes', 'edges'];
            for (var i = 0; i < grs.length; i++) {
              var gr = grs[i];
              var elements = obj.elements[gr];
              if (array(elements)) {
                updateEles(elements, gr);
              }
            }
          }
          var parentsToRemove = cy.collection();
          eles.filter(function (ele) {
            return !idInJson[ele.id()];
          }).forEach(function (ele) {
            if (ele.isParent()) {
              parentsToRemove.merge(ele);
            } else {
              ele.remove();
            }
          });

          // so that children are not removed w/parent
          parentsToRemove.forEach(function (ele) {
            return ele.children().move({
              parent: null
            });
          });

          // intermediate parents may be moved by prior line, so make sure we remove by fresh refs
          parentsToRemove.forEach(function (ele) {
            return getFreshRef(ele).remove();
          });
        }
        if (obj.style) {
          cy.style(obj.style);
        }
        if (obj.zoom != null && obj.zoom !== _p.zoom) {
          cy.zoom(obj.zoom);
        }
        if (obj.pan) {
          if (obj.pan.x !== _p.pan.x || obj.pan.y !== _p.pan.y) {
            cy.pan(obj.pan);
          }
        }
        if (obj.data) {
          cy.data(obj.data);
        }
        var fields = ['minZoom', 'maxZoom', 'zoomingEnabled', 'userZoomingEnabled', 'panningEnabled', 'userPanningEnabled', 'boxSelectionEnabled', 'autolock', 'autoungrabify', 'autounselectify', 'multiClickDebounceTime'];
        for (var _i2 = 0; _i2 < fields.length; _i2++) {
          var f = fields[_i2];
          if (obj[f] != null) {
            cy[f](obj[f]);
          }
        }
        cy.endBatch();
        return this; // chaining
      } else {
        // get
        var flat = !!obj;
        var json = {};
        if (flat) {
          json.elements = this.elements().map(function (ele) {
            return ele.json();
          });
        } else {
          json.elements = {};
          eles.forEach(function (ele) {
            var group = ele.group();
            if (!json.elements[group]) {
              json.elements[group] = [];
            }
            json.elements[group].push(ele.json());
          });
        }
        if (this._private.styleEnabled) {
          json.style = cy.style().json();
        }
        json.data = copy(cy.data());
        var options = _p.options;
        json.zoomingEnabled = _p.zoomingEnabled;
        json.userZoomingEnabled = _p.userZoomingEnabled;
        json.zoom = _p.zoom;
        json.minZoom = _p.minZoom;
        json.maxZoom = _p.maxZoom;
        json.panningEnabled = _p.panningEnabled;
        json.userPanningEnabled = _p.userPanningEnabled;
        json.pan = copy(_p.pan);
        json.boxSelectionEnabled = _p.boxSelectionEnabled;
        json.renderer = copy(options.renderer);
        json.hideEdgesOnViewport = options.hideEdgesOnViewport;
        json.textureOnViewport = options.textureOnViewport;
        json.wheelSensitivity = options.wheelSensitivity;
        json.motionBlur = options.motionBlur;
        json.multiClickDebounceTime = options.multiClickDebounceTime;
        return json;
      }
    }
  });
  corefn.$id = corefn.getElementById;
  [corefn$9, corefn$8, elesfn, corefn$7, corefn$6, corefn$5, corefn$4, corefn$3, corefn$2, corefn$1, fn].forEach(function (props) {
    extend(corefn, props);
  });

  /* eslint-disable no-unused-vars */
  var defaults$7 = {
    fit: true,
    // whether to fit the viewport to the graph
    directed: false,
    // whether the tree is directed downwards (or edges can point in any direction if false)
    padding: 30,
    // padding on fit
    circle: false,
    // put depths in concentric circles if true, put depths top down if false
    grid: false,
    // whether to create an even grid into which the DAG is placed (circle:false only)
    spacingFactor: 1.75,
    // positive spacing factor, larger => more space between nodes (N.B. n/a if causes overlap)
    boundingBox: undefined,
    // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
    avoidOverlap: true,
    // prevents node overlap, may overflow boundingBox if not enough space
    nodeDimensionsIncludeLabels: false,
    // Excludes the label when calculating node bounding boxes for the layout algorithm
    roots: undefined,
    // the roots of the trees
    depthSort: undefined,
    // a sorting function to order nodes at equal depth. e.g. function(a, b){ return a.data('weight') - b.data('weight') }
    animate: false,
    // whether to transition the node positions
    animationDuration: 500,
    // duration of animation in ms if enabled
    animationEasing: undefined,
    // easing of animation if enabled,
    animateFilter: function animateFilter(node, i) {
      return true;
    },
    // 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
    ready: undefined,
    // callback on layoutready
    stop: undefined,
    // callback on layoutstop
    transform: function transform(node, position) {
      return position;
    } // transform a given node position. Useful for changing flow direction in discrete layouts
  };

  var deprecatedOptionDefaults = {
    maximal: false,
    // whether to shift nodes down their natural BFS depths in order to avoid upwards edges (DAGS only); setting acyclic to true sets maximal to true also
    acyclic: false // whether the tree is acyclic and thus a node could be shifted (due to the maximal option) multiple times without causing an infinite loop; setting to true sets maximal to true also; if you are uncertain whether a tree is acyclic, set to false to avoid potential infinite loops
  };

  /* eslint-enable */

  var getInfo = function getInfo(ele) {
    return ele.scratch('breadthfirst');
  };
  var setInfo = function setInfo(ele, obj) {
    return ele.scratch('breadthfirst', obj);
  };
  function BreadthFirstLayout(options) {
    this.options = extend({}, defaults$7, deprecatedOptionDefaults, options);
  }
  BreadthFirstLayout.prototype.run = function () {
    var params = this.options;
    var options = params;
    var cy = params.cy;
    var eles = options.eles;
    var nodes = eles.nodes().filter(function (n) {
      return !n.isParent();
    });
    var graph = eles;
    var directed = options.directed;
    var maximal = options.acyclic || options.maximal || options.maximalAdjustments > 0; // maximalAdjustments for compat. w/ old code; also, setting acyclic to true sets maximal to true

    var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {
      x1: 0,
      y1: 0,
      w: cy.width(),
      h: cy.height()
    });
    var roots;
    if (elementOrCollection(options.roots)) {
      roots = options.roots;
    } else if (array(options.roots)) {
      var rootsArray = [];
      for (var i = 0; i < options.roots.length; i++) {
        var id = options.roots[i];
        var ele = cy.getElementById(id);
        rootsArray.push(ele);
      }
      roots = cy.collection(rootsArray);
    } else if (string(options.roots)) {
      roots = cy.$(options.roots);
    } else {
      if (directed) {
        roots = nodes.roots();
      } else {
        var components = eles.components();
        roots = cy.collection();
        var _loop = function _loop(_i) {
          var comp = components[_i];
          var maxDegree = comp.maxDegree(false);
          var compRoots = comp.filter(function (ele) {
            return ele.degree(false) === maxDegree;
          });
          roots = roots.add(compRoots);
        };
        for (var _i = 0; _i < components.length; _i++) {
          _loop(_i);
        }
      }
    }
    var depths = [];
    var foundByBfs = {};
    var addToDepth = function addToDepth(ele, d) {
      if (depths[d] == null) {
        depths[d] = [];
      }
      var i = depths[d].length;
      depths[d].push(ele);
      setInfo(ele, {
        index: i,
        depth: d
      });
    };
    var changeDepth = function changeDepth(ele, newDepth) {
      var _getInfo = getInfo(ele),
        depth = _getInfo.depth,
        index = _getInfo.index;
      depths[depth][index] = null;
      addToDepth(ele, newDepth);
    };

    // find the depths of the nodes
    graph.bfs({
      roots: roots,
      directed: options.directed,
      visit: function visit(node, edge, pNode, i, depth) {
        var ele = node[0];
        var id = ele.id();
        addToDepth(ele, depth);
        foundByBfs[id] = true;
      }
    });

    // check for nodes not found by bfs
    var orphanNodes = [];
    for (var _i2 = 0; _i2 < nodes.length; _i2++) {
      var _ele = nodes[_i2];
      if (foundByBfs[_ele.id()]) {
        continue;
      } else {
        orphanNodes.push(_ele);
      }
    }

    // assign the nodes a depth and index

    var assignDepthsAt = function assignDepthsAt(i) {
      var eles = depths[i];
      for (var j = 0; j < eles.length; j++) {
        var _ele2 = eles[j];
        if (_ele2 == null) {
          eles.splice(j, 1);
          j--;
          continue;
        }
        setInfo(_ele2, {
          depth: i,
          index: j
        });
      }
    };
    var assignDepths = function assignDepths() {
      for (var _i3 = 0; _i3 < depths.length; _i3++) {
        assignDepthsAt(_i3);
      }
    };
    var adjustMaximally = function adjustMaximally(ele, shifted) {
      var eInfo = getInfo(ele);
      var incomers = ele.incomers().filter(function (el) {
        return el.isNode() && eles.has(el);
      });
      var maxDepth = -1;
      var id = ele.id();
      for (var k = 0; k < incomers.length; k++) {
        var incmr = incomers[k];
        var iInfo = getInfo(incmr);
        maxDepth = Math.max(maxDepth, iInfo.depth);
      }
      if (eInfo.depth <= maxDepth) {
        if (!options.acyclic && shifted[id]) {
          return null;
        }
        var newDepth = maxDepth + 1;
        changeDepth(ele, newDepth);
        shifted[id] = newDepth;
        return true;
      }
      return false;
    };

    // for the directed case, try to make the edges all go down (i.e. depth i => depth i + 1)
    if (directed && maximal) {
      var Q = [];
      var shifted = {};
      var enqueue = function enqueue(n) {
        return Q.push(n);
      };
      var dequeue = function dequeue() {
        return Q.shift();
      };
      nodes.forEach(function (n) {
        return Q.push(n);
      });
      while (Q.length > 0) {
        var _ele3 = dequeue();
        var didShift = adjustMaximally(_ele3, shifted);
        if (didShift) {
          _ele3.outgoers().filter(function (el) {
            return el.isNode() && eles.has(el);
          }).forEach(enqueue);
        } else if (didShift === null) {
          warn('Detected double maximal shift for node `' + _ele3.id() + '`.  Bailing maximal adjustment due to cycle.  Use `options.maximal: true` only on DAGs.');
          break; // exit on failure
        }
      }
    }

    assignDepths(); // clear holes

    // find min distance we need to leave between nodes
    var minDistance = 0;
    if (options.avoidOverlap) {
      for (var _i4 = 0; _i4 < nodes.length; _i4++) {
        var n = nodes[_i4];
        var nbb = n.layoutDimensions(options);
        var w = nbb.w;
        var h = nbb.h;
        minDistance = Math.max(minDistance, w, h);
      }
    }

    // get the weighted percent for an element based on its connectivity to other levels
    var cachedWeightedPercent = {};
    var getWeightedPercent = function getWeightedPercent(ele) {
      if (cachedWeightedPercent[ele.id()]) {
        return cachedWeightedPercent[ele.id()];
      }
      var eleDepth = getInfo(ele).depth;
      var neighbors = ele.neighborhood();
      var percent = 0;
      var samples = 0;
      for (var _i5 = 0; _i5 < neighbors.length; _i5++) {
        var neighbor = neighbors[_i5];
        if (neighbor.isEdge() || neighbor.isParent() || !nodes.has(neighbor)) {
          continue;
        }
        var bf = getInfo(neighbor);
        if (bf == null) {
          continue;
        }
        var index = bf.index;
        var depth = bf.depth;

        // unassigned neighbours shouldn't affect the ordering
        if (index == null || depth == null) {
          continue;
        }
        var nDepth = depths[depth].length;
        if (depth < eleDepth) {
          // only get influenced by elements above
          percent += index / nDepth;
          samples++;
        }
      }
      samples = Math.max(1, samples);
      percent = percent / samples;
      if (samples === 0) {
        // put lone nodes at the start
        percent = 0;
      }
      cachedWeightedPercent[ele.id()] = percent;
      return percent;
    };

    // rearrange the indices in each depth level based on connectivity

    var sortFn = function sortFn(a, b) {
      var apct = getWeightedPercent(a);
      var bpct = getWeightedPercent(b);
      var diff = apct - bpct;
      if (diff === 0) {
        return ascending(a.id(), b.id()); // make sure sort doesn't have don't-care comparisons
      } else {
        return diff;
      }
    };
    if (options.depthSort !== undefined) {
      sortFn = options.depthSort;
    }

    // sort each level to make connected nodes closer
    for (var _i6 = 0; _i6 < depths.length; _i6++) {
      depths[_i6].sort(sortFn);
      assignDepthsAt(_i6);
    }

    // assign orphan nodes to a new top-level depth
    var orphanDepth = [];
    for (var _i7 = 0; _i7 < orphanNodes.length; _i7++) {
      orphanDepth.push(orphanNodes[_i7]);
    }
    depths.unshift(orphanDepth);
    assignDepths();
    var biggestDepthSize = 0;
    for (var _i8 = 0; _i8 < depths.length; _i8++) {
      biggestDepthSize = Math.max(depths[_i8].length, biggestDepthSize);
    }
    var center = {
      x: bb.x1 + bb.w / 2,
      y: bb.x1 + bb.h / 2
    };
    var maxDepthSize = depths.reduce(function (max, eles) {
      return Math.max(max, eles.length);
    }, 0);
    var getPosition = function getPosition(ele) {
      var _getInfo2 = getInfo(ele),
        depth = _getInfo2.depth,
        index = _getInfo2.index;
      var depthSize = depths[depth].length;
      var distanceX = Math.max(bb.w / ((options.grid ? maxDepthSize : depthSize) + 1), minDistance);
      var distanceY = Math.max(bb.h / (depths.length + 1), minDistance);
      var radiusStepSize = Math.min(bb.w / 2 / depths.length, bb.h / 2 / depths.length);
      radiusStepSize = Math.max(radiusStepSize, minDistance);
      if (!options.circle) {
        var epos = {
          x: center.x + (index + 1 - (depthSize + 1) / 2) * distanceX,
          y: (depth + 1) * distanceY
        };
        return epos;
      } else {
        var radius = radiusStepSize * depth + radiusStepSize - (depths.length > 0 && depths[0].length <= 3 ? radiusStepSize / 2 : 0);
        var theta = 2 * Math.PI / depths[depth].length * index;
        if (depth === 0 && depths[0].length === 1) {
          radius = 1;
        }
        return {
          x: center.x + radius * Math.cos(theta),
          y: center.y + radius * Math.sin(theta)
        };
      }
    };
    eles.nodes().layoutPositions(this, options, getPosition);
    return this; // chaining
  };

  var defaults$6 = {
    fit: true,
    // whether to fit the viewport to the graph
    padding: 30,
    // the padding on fit
    boundingBox: undefined,
    // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
    avoidOverlap: true,
    // prevents node overlap, may overflow boundingBox and radius if not enough space
    nodeDimensionsIncludeLabels: false,
    // Excludes the label when calculating node bounding boxes for the layout algorithm
    spacingFactor: undefined,
    // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up
    radius: undefined,
    // the radius of the circle
    startAngle: 3 / 2 * Math.PI,
    // where nodes start in radians
    sweep: undefined,
    // how many radians should be between the first and last node (defaults to full circle)
    clockwise: true,
    // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false)
    sort: undefined,
    // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') }
    animate: false,
    // whether to transition the node positions
    animationDuration: 500,
    // duration of animation in ms if enabled
    animationEasing: undefined,
    // easing of animation if enabled
    animateFilter: function animateFilter(node, i) {
      return true;
    },
    // 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
    ready: undefined,
    // callback on layoutready
    stop: undefined,
    // callback on layoutstop
    transform: function transform(node, position) {
      return position;
    } // transform a given node position. Useful for changing flow direction in discrete layouts 
  };

  function CircleLayout(options) {
    this.options = extend({}, defaults$6, options);
  }
  CircleLayout.prototype.run = function () {
    var params = this.options;
    var options = params;
    var cy = params.cy;
    var eles = options.eles;
    var clockwise = options.counterclockwise !== undefined ? !options.counterclockwise : options.clockwise;
    var nodes = eles.nodes().not(':parent');
    if (options.sort) {
      nodes = nodes.sort(options.sort);
    }
    var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {
      x1: 0,
      y1: 0,
      w: cy.width(),
      h: cy.height()
    });
    var center = {
      x: bb.x1 + bb.w / 2,
      y: bb.y1 + bb.h / 2
    };
    var sweep = options.sweep === undefined ? 2 * Math.PI - 2 * Math.PI / nodes.length : options.sweep;
    var dTheta = sweep / Math.max(1, nodes.length - 1);
    var r;
    var minDistance = 0;
    for (var i = 0; i < nodes.length; i++) {
      var n = nodes[i];
      var nbb = n.layoutDimensions(options);
      var w = nbb.w;
      var h = nbb.h;
      minDistance = Math.max(minDistance, w, h);
    }
    if (number$1(options.radius)) {
      r = options.radius;
    } else if (nodes.length <= 1) {
      r = 0;
    } else {
      r = Math.min(bb.h, bb.w) / 2 - minDistance;
    }

    // calculate the radius
    if (nodes.length > 1 && options.avoidOverlap) {
      // but only if more than one node (can't overlap)
      minDistance *= 1.75; // just to have some nice spacing

      var dcos = Math.cos(dTheta) - Math.cos(0);
      var dsin = Math.sin(dTheta) - Math.sin(0);
      var rMin = Math.sqrt(minDistance * minDistance / (dcos * dcos + dsin * dsin)); // s.t. no nodes overlapping
      r = Math.max(rMin, r);
    }
    var getPos = function getPos(ele, i) {
      var theta = options.startAngle + i * dTheta * (clockwise ? 1 : -1);
      var rx = r * Math.cos(theta);
      var ry = r * Math.sin(theta);
      var pos = {
        x: center.x + rx,
        y: center.y + ry
      };
      return pos;
    };
    eles.nodes().layoutPositions(this, options, getPos);
    return this; // chaining
  };

  var defaults$5 = {
    fit: true,
    // whether to fit the viewport to the graph
    padding: 30,
    // the padding on fit
    startAngle: 3 / 2 * Math.PI,
    // where nodes start in radians
    sweep: undefined,
    // how many radians should be between the first and last node (defaults to full circle)
    clockwise: true,
    // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false)
    equidistant: false,
    // whether levels have an equal radial distance betwen them, may cause bounding box overflow
    minNodeSpacing: 10,
    // min spacing between outside of nodes (used for radius adjustment)
    boundingBox: undefined,
    // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
    avoidOverlap: true,
    // prevents node overlap, may overflow boundingBox if not enough space
    nodeDimensionsIncludeLabels: false,
    // Excludes the label when calculating node bounding boxes for the layout algorithm
    height: undefined,
    // height of layout area (overrides container height)
    width: undefined,
    // width of layout area (overrides container width)
    spacingFactor: undefined,
    // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up
    concentric: function concentric(node) {
      // returns numeric value for each node, placing higher nodes in levels towards the centre
      return node.degree();
    },
    levelWidth: function levelWidth(nodes) {
      // the variation of concentric values in each level
      return nodes.maxDegree() / 4;
    },
    animate: false,
    // whether to transition the node positions
    animationDuration: 500,
    // duration of animation in ms if enabled
    animationEasing: undefined,
    // easing of animation if enabled
    animateFilter: function animateFilter(node, i) {
      return true;
    },
    // 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
    ready: undefined,
    // callback on layoutready
    stop: undefined,
    // callback on layoutstop
    transform: function transform(node, position) {
      return position;
    } // transform a given node position. Useful for changing flow direction in discrete layouts
  };

  function ConcentricLayout(options) {
    this.options = extend({}, defaults$5, options);
  }
  ConcentricLayout.prototype.run = function () {
    var params = this.options;
    var options = params;
    var clockwise = options.counterclockwise !== undefined ? !options.counterclockwise : options.clockwise;
    var cy = params.cy;
    var eles = options.eles;
    var nodes = eles.nodes().not(':parent');
    var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {
      x1: 0,
      y1: 0,
      w: cy.width(),
      h: cy.height()
    });
    var center = {
      x: bb.x1 + bb.w / 2,
      y: bb.y1 + bb.h / 2
    };
    var nodeValues = []; // { node, value }
    var maxNodeSize = 0;
    for (var i = 0; i < nodes.length; i++) {
      var node = nodes[i];
      var value = void 0;

      // calculate the node value
      value = options.concentric(node);
      nodeValues.push({
        value: value,
        node: node
      });

      // for style mapping
      node._private.scratch.concentric = value;
    }

    // in case we used the `concentric` in style
    nodes.updateStyle();

    // calculate max size now based on potentially updated mappers
    for (var _i = 0; _i < nodes.length; _i++) {
      var _node = nodes[_i];
      var nbb = _node.layoutDimensions(options);
      maxNodeSize = Math.max(maxNodeSize, nbb.w, nbb.h);
    }

    // sort node values in descreasing order
    nodeValues.sort(function (a, b) {
      return b.value - a.value;
    });
    var levelWidth = options.levelWidth(nodes);

    // put the values into levels
    var levels = [[]];
    var currentLevel = levels[0];
    for (var _i2 = 0; _i2 < nodeValues.length; _i2++) {
      var val = nodeValues[_i2];
      if (currentLevel.length > 0) {
        var diff = Math.abs(currentLevel[0].value - val.value);
        if (diff >= levelWidth) {
          currentLevel = [];
          levels.push(currentLevel);
        }
      }
      currentLevel.push(val);
    }

    // create positions from levels

    var minDist = maxNodeSize + options.minNodeSpacing; // min dist between nodes

    if (!options.avoidOverlap) {
      // then strictly constrain to bb
      var firstLvlHasMulti = levels.length > 0 && levels[0].length > 1;
      var maxR = Math.min(bb.w, bb.h) / 2 - minDist;
      var rStep = maxR / (levels.length + firstLvlHasMulti ? 1 : 0);
      minDist = Math.min(minDist, rStep);
    }

    // find the metrics for each level
    var r = 0;
    for (var _i3 = 0; _i3 < levels.length; _i3++) {
      var level = levels[_i3];
      var sweep = options.sweep === undefined ? 2 * Math.PI - 2 * Math.PI / level.length : options.sweep;
      var dTheta = level.dTheta = sweep / Math.max(1, level.length - 1);

      // calculate the radius
      if (level.length > 1 && options.avoidOverlap) {
        // but only if more than one node (can't overlap)
        var dcos = Math.cos(dTheta) - Math.cos(0);
        var dsin = Math.sin(dTheta) - Math.sin(0);
        var rMin = Math.sqrt(minDist * minDist / (dcos * dcos + dsin * dsin)); // s.t. no nodes overlapping

        r = Math.max(rMin, r);
      }
      level.r = r;
      r += minDist;
    }
    if (options.equidistant) {
      var rDeltaMax = 0;
      var _r = 0;
      for (var _i4 = 0; _i4 < levels.length; _i4++) {
        var _level = levels[_i4];
        var rDelta = _level.r - _r;
        rDeltaMax = Math.max(rDeltaMax, rDelta);
      }
      _r = 0;
      for (var _i5 = 0; _i5 < levels.length; _i5++) {
        var _level2 = levels[_i5];
        if (_i5 === 0) {
          _r = _level2.r;
        }
        _level2.r = _r;
        _r += rDeltaMax;
      }
    }

    // calculate the node positions
    var pos = {}; // id => position
    for (var _i6 = 0; _i6 < levels.length; _i6++) {
      var _level3 = levels[_i6];
      var _dTheta = _level3.dTheta;
      var _r2 = _level3.r;
      for (var j = 0; j < _level3.length; j++) {
        var _val = _level3[j];
        var theta = options.startAngle + (clockwise ? 1 : -1) * _dTheta * j;
        var p = {
          x: center.x + _r2 * Math.cos(theta),
          y: center.y + _r2 * Math.sin(theta)
        };
        pos[_val.node.id()] = p;
      }
    }

    // position the nodes
    eles.nodes().layoutPositions(this, options, function (ele) {
      var id = ele.id();
      return pos[id];
    });
    return this; // chaining
  };

  /*
  The CoSE layout was written by Gerardo Huck.
  https://www.linkedin.com/in/gerardohuck/

  Based on the following article:
  http://dl.acm.org/citation.cfm?id=1498047

  Modifications tracked on Github.
  */
  var DEBUG;

  /**
   * @brief :  default layout options
   */
  var defaults$4 = {
    // Called on `layoutready`
    ready: function ready() {},
    // Called on `layoutstop`
    stop: function stop() {},
    // Whether to animate while running the layout
    // true : Animate continuously as the layout is running
    // false : Just show the end result
    // 'end' : Animate with the end result, from the initial positions to the end positions
    animate: true,
    // Easing of the animation for animate:'end'
    animationEasing: undefined,
    // The duration of the animation for animate:'end'
    animationDuration: undefined,
    // 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
    animateFilter: function animateFilter(node, i) {
      return true;
    },
    // The layout animates only after this many milliseconds for animate:true
    // (prevents flashing on fast runs)
    animationThreshold: 250,
    // Number of iterations between consecutive screen positions update
    refresh: 20,
    // Whether to fit the network view after when done
    fit: true,
    // Padding on fit
    padding: 30,
    // Constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
    boundingBox: undefined,
    // Excludes the label when calculating node bounding boxes for the layout algorithm
    nodeDimensionsIncludeLabels: false,
    // Randomize the initial positions of the nodes (true) or use existing positions (false)
    randomize: false,
    // Extra spacing between components in non-compound graphs
    componentSpacing: 40,
    // Node repulsion (non overlapping) multiplier
    nodeRepulsion: function nodeRepulsion(node) {
      return 2048;
    },
    // Node repulsion (overlapping) multiplier
    nodeOverlap: 4,
    // Ideal edge (non nested) length
    idealEdgeLength: function idealEdgeLength(edge) {
      return 32;
    },
    // Divisor to compute edge forces
    edgeElasticity: function edgeElasticity(edge) {
      return 32;
    },
    // Nesting factor (multiplier) to compute ideal edge length for nested edges
    nestingFactor: 1.2,
    // Gravity force (constant)
    gravity: 1,
    // Maximum number of iterations to perform
    numIter: 1000,
    // Initial temperature (maximum node displacement)
    initialTemp: 1000,
    // Cooling factor (how the temperature is reduced between consecutive iterations
    coolingFactor: 0.99,
    // Lower temperature threshold (below this point the layout will end)
    minTemp: 1.0
  };

  /**
   * @brief       : constructor
   * @arg options : object containing layout options
   */
  function CoseLayout(options) {
    this.options = extend({}, defaults$4, options);
    this.options.layout = this;

    // Exclude any edge that has a source or target node that is not in the set of passed-in nodes
    var nodes = this.options.eles.nodes();
    var edges = this.options.eles.edges();
    var notEdges = edges.filter(function (e) {
      var sourceId = e.source().data('id');
      var targetId = e.target().data('id');
      var hasSource = nodes.some(function (n) {
        return n.data('id') === sourceId;
      });
      var hasTarget = nodes.some(function (n) {
        return n.data('id') === targetId;
      });
      return !hasSource || !hasTarget;
    });
    this.options.eles = this.options.eles.not(notEdges);
  }

  /**
   * @brief : runs the layout
   */
  CoseLayout.prototype.run = function () {
    var options = this.options;
    var cy = options.cy;
    var layout = this;
    layout.stopped = false;
    if (options.animate === true || options.animate === false) {
      layout.emit({
        type: 'layoutstart',
        layout: layout
      });
    }

    // Set DEBUG - Global variable
    if (true === options.debug) {
      DEBUG = true;
    } else {
      DEBUG = false;
    }

    // Initialize layout info
    var layoutInfo = createLayoutInfo(cy, layout, options);

    // Show LayoutInfo contents if debugging
    if (DEBUG) {
      printLayoutInfo(layoutInfo);
    }

    // If required, randomize node positions
    if (options.randomize) {
      randomizePositions(layoutInfo);
    }
    var startTime = performanceNow();
    var refresh = function refresh() {
      refreshPositions(layoutInfo, cy, options);

      // Fit the graph if necessary
      if (true === options.fit) {
        cy.fit(options.padding);
      }
    };
    var mainLoop = function mainLoop(i) {
      if (layout.stopped || i >= options.numIter) {
        // logDebug("Layout manually stopped. Stopping computation in step " + i);
        return false;
      }

      // Do one step in the phisical simulation
      step(layoutInfo, options);

      // Update temperature
      layoutInfo.temperature = layoutInfo.temperature * options.coolingFactor;
      // logDebug("New temperature: " + layoutInfo.temperature);

      if (layoutInfo.temperature < options.minTemp) {
        // logDebug("Temperature drop below minimum threshold. Stopping computation in step " + i);
        return false;
      }
      return true;
    };
    var done = function done() {
      if (options.animate === true || options.animate === false) {
        refresh();

        // Layout has finished
        layout.one('layoutstop', options.stop);
        layout.emit({
          type: 'layoutstop',
          layout: layout
        });
      } else {
        var nodes = options.eles.nodes();
        var getScaledPos = getScaleInBoundsFn(layoutInfo, options, nodes);
        nodes.layoutPositions(layout, options, getScaledPos);
      }
    };
    var i = 0;
    var loopRet = true;
    if (options.animate === true) {
      var frame = function frame() {
        var f = 0;
        while (loopRet && f < options.refresh) {
          loopRet = mainLoop(i);
          i++;
          f++;
        }
        if (!loopRet) {
          // it's done
          separateComponents(layoutInfo, options);
          done();
        } else {
          var now = performanceNow();
          if (now - startTime >= options.animationThreshold) {
            refresh();
          }
          requestAnimationFrame(frame);
        }
      };
      frame();
    } else {
      while (loopRet) {
        loopRet = mainLoop(i);
        i++;
      }
      separateComponents(layoutInfo, options);
      done();
    }
    return this; // chaining
  };

  /**
   * @brief : called on continuous layouts to stop them before they finish
   */
  CoseLayout.prototype.stop = function () {
    this.stopped = true;
    if (this.thread) {
      this.thread.stop();
    }
    this.emit('layoutstop');
    return this; // chaining
  };

  CoseLayout.prototype.destroy = function () {
    if (this.thread) {
      this.thread.stop();
    }
    return this; // chaining
  };

  /**
   * @brief     : Creates an object which is contains all the data
   *              used in the layout process
   * @arg cy    : cytoscape.js object
   * @return    : layoutInfo object initialized
   */
  var createLayoutInfo = function createLayoutInfo(cy, layout, options) {
    // Shortcut
    var edges = options.eles.edges();
    var nodes = options.eles.nodes();
    var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {
      x1: 0,
      y1: 0,
      w: cy.width(),
      h: cy.height()
    });
    var layoutInfo = {
      isCompound: cy.hasCompoundNodes(),
      layoutNodes: [],
      idToIndex: {},
      nodeSize: nodes.size(),
      graphSet: [],
      indexToGraph: [],
      layoutEdges: [],
      edgeSize: edges.size(),
      temperature: options.initialTemp,
      clientWidth: bb.w,
      clientHeight: bb.h,
      boundingBox: bb
    };
    var components = options.eles.components();
    var id2cmptId = {};
    for (var i = 0; i < components.length; i++) {
      var component = components[i];
      for (var j = 0; j < component.length; j++) {
        var node = component[j];
        id2cmptId[node.id()] = i;
      }
    }

    // Iterate over all nodes, creating layout nodes
    for (var i = 0; i < layoutInfo.nodeSize; i++) {
      var n = nodes[i];
      var nbb = n.layoutDimensions(options);
      var tempNode = {};
      tempNode.isLocked = n.locked();
      tempNode.id = n.data('id');
      tempNode.parentId = n.data('parent');
      tempNode.cmptId = id2cmptId[n.id()];
      tempNode.children = [];
      tempNode.positionX = n.position('x');
      tempNode.positionY = n.position('y');
      tempNode.offsetX = 0;
      tempNode.offsetY = 0;
      tempNode.height = nbb.w;
      tempNode.width = nbb.h;
      tempNode.maxX = tempNode.positionX + tempNode.width / 2;
      tempNode.minX = tempNode.positionX - tempNode.width / 2;
      tempNode.maxY = tempNode.positionY + tempNode.height / 2;
      tempNode.minY = tempNode.positionY - tempNode.height / 2;
      tempNode.padLeft = parseFloat(n.style('padding'));
      tempNode.padRight = parseFloat(n.style('padding'));
      tempNode.padTop = parseFloat(n.style('padding'));
      tempNode.padBottom = parseFloat(n.style('padding'));

      // forces
      tempNode.nodeRepulsion = fn$6(options.nodeRepulsion) ? options.nodeRepulsion(n) : options.nodeRepulsion;

      // Add new node
      layoutInfo.layoutNodes.push(tempNode);
      // Add entry to id-index map
      layoutInfo.idToIndex[tempNode.id] = i;
    }

    // Inline implementation of a queue, used for traversing the graph in BFS order
    var queue = [];
    var start = 0; // Points to the start the queue
    var end = -1; // Points to the end of the queue

    var tempGraph = [];

    // Second pass to add child information and
    // initialize queue for hierarchical traversal
    for (var i = 0; i < layoutInfo.nodeSize; i++) {
      var n = layoutInfo.layoutNodes[i];
      var p_id = n.parentId;
      // Check if node n has a parent node
      if (null != p_id) {
        // Add node Id to parent's list of children
        layoutInfo.layoutNodes[layoutInfo.idToIndex[p_id]].children.push(n.id);
      } else {
        // If a node doesn't have a parent, then it's in the root graph
        queue[++end] = n.id;
        tempGraph.push(n.id);
      }
    }

    // Add root graph to graphSet
    layoutInfo.graphSet.push(tempGraph);

    // Traverse the graph, level by level,
    while (start <= end) {
      // Get the node to visit and remove it from queue
      var node_id = queue[start++];
      var node_ix = layoutInfo.idToIndex[node_id];
      var node = layoutInfo.layoutNodes[node_ix];
      var children = node.children;
      if (children.length > 0) {
        // Add children nodes as a new graph to graph set
        layoutInfo.graphSet.push(children);
        // Add children to que queue to be visited
        for (var i = 0; i < children.length; i++) {
          queue[++end] = children[i];
        }
      }
    }

    // Create indexToGraph map
    for (var i = 0; i < layoutInfo.graphSet.length; i++) {
      var graph = layoutInfo.graphSet[i];
      for (var j = 0; j < graph.length; j++) {
        var index = layoutInfo.idToIndex[graph[j]];
        layoutInfo.indexToGraph[index] = i;
      }
    }

    // Iterate over all edges, creating Layout Edges
    for (var i = 0; i < layoutInfo.edgeSize; i++) {
      var e = edges[i];
      var tempEdge = {};
      tempEdge.id = e.data('id');
      tempEdge.sourceId = e.data('source');
      tempEdge.targetId = e.data('target');

      // Compute ideal length
      var idealLength = fn$6(options.idealEdgeLength) ? options.idealEdgeLength(e) : options.idealEdgeLength;
      var elasticity = fn$6(options.edgeElasticity) ? options.edgeElasticity(e) : options.edgeElasticity;

      // Check if it's an inter graph edge
      var sourceIx = layoutInfo.idToIndex[tempEdge.sourceId];
      var targetIx = layoutInfo.idToIndex[tempEdge.targetId];
      var sourceGraph = layoutInfo.indexToGraph[sourceIx];
      var targetGraph = layoutInfo.indexToGraph[targetIx];
      if (sourceGraph != targetGraph) {
        // Find lowest common graph ancestor
        var lca = findLCA(tempEdge.sourceId, tempEdge.targetId, layoutInfo);

        // Compute sum of node depths, relative to lca graph
        var lcaGraph = layoutInfo.graphSet[lca];
        var depth = 0;

        // Source depth
        var tempNode = layoutInfo.layoutNodes[sourceIx];
        while (-1 === lcaGraph.indexOf(tempNode.id)) {
          tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]];
          depth++;
        }

        // Target depth
        tempNode = layoutInfo.layoutNodes[targetIx];
        while (-1 === lcaGraph.indexOf(tempNode.id)) {
          tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]];
          depth++;
        }

        // logDebug('LCA of nodes ' + tempEdge.sourceId + ' and ' + tempEdge.targetId +
        //  ". Index: " + lca + " Contents: " + lcaGraph.toString() +
        //  ". Depth: " + depth);

        // Update idealLength
        idealLength *= depth * options.nestingFactor;
      }
      tempEdge.idealLength = idealLength;
      tempEdge.elasticity = elasticity;
      layoutInfo.layoutEdges.push(tempEdge);
    }

    // Finally, return layoutInfo object
    return layoutInfo;
  };

  /**
   * @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
   *
   */
  var findLCA = function findLCA(node1, node2, layoutInfo) {
    // Find their common ancester, starting from the root graph
    var res = findLCA_aux(node1, node2, 0, layoutInfo);
    if (2 > res.count) {
      // If aux function couldn't find the common ancester,
      // then it is the root graph
      return 0;
    } else {
      return res.graph;
    }
  };

  /**
   * @brief          : Auxiliary function used for LCA computation
   *
   * @arg node1      : node1's ID
   * @arg node2      : node2's ID
   * @arg graphIx    : subgraph index
   * @arg layoutInfo : layoutInfo object
   *
   * @return         : object of the form {count: X, graph: Y}, where:
   *                   X is the number of ancestors (max: 2) found in
   *                   graphIx (and it's subgraphs),
   *                   Y is the graph index of the lowest graph containing
   *                   all X nodes
   */
  var findLCA_aux = function findLCA_aux(node1, node2, graphIx, layoutInfo) {
    var graph = layoutInfo.graphSet[graphIx];
    // If both nodes belongs to graphIx
    if (-1 < graph.indexOf(node1) && -1 < graph.indexOf(node2)) {
      return {
        count: 2,
        graph: graphIx
      };
    }

    // Make recursive calls for all subgraphs
    var c = 0;
    for (var i = 0; i < graph.length; i++) {
      var nodeId = graph[i];
      var nodeIx = layoutInfo.idToIndex[nodeId];
      var children = layoutInfo.layoutNodes[nodeIx].children;

      // If the node has no child, skip it
      if (0 === children.length) {
        continue;
      }
      var childGraphIx = layoutInfo.indexToGraph[layoutInfo.idToIndex[children[0]]];
      var result = findLCA_aux(node1, node2, childGraphIx, layoutInfo);
      if (0 === result.count) {
        // Neither node1 nor node2 are present in this subgraph
        continue;
      } else if (1 === result.count) {
        // One of (node1, node2) is present in this subgraph
        c++;
        if (2 === c) {
          // We've already found both nodes, no need to keep searching
          break;
        }
      } else {
        // Both nodes are present in this subgraph
        return result;
      }
    }
    return {
      count: c,
      graph: graphIx
    };
  };

  /**
   * @brief: printsLayoutInfo into js console
   *         Only used for debbuging
   */
var printLayoutInfo; 

  /**
   * @brief : Randomizes the position of all nodes
   */
  var randomizePositions = function randomizePositions(layoutInfo, cy) {
    var width = layoutInfo.clientWidth;
    var height = layoutInfo.clientHeight;
    for (var i = 0; i < layoutInfo.nodeSize; i++) {
      var n = layoutInfo.layoutNodes[i];

      // No need to randomize compound nodes or locked nodes
      if (0 === n.children.length && !n.isLocked) {
        n.positionX = Math.random() * width;
        n.positionY = Math.random() * height;
      }
    }
  };
  var getScaleInBoundsFn = function getScaleInBoundsFn(layoutInfo, options, nodes) {
    var bb = layoutInfo.boundingBox;
    var coseBB = {
      x1: Infinity,
      x2: -Infinity,
      y1: Infinity,
      y2: -Infinity
    };
    if (options.boundingBox) {
      nodes.forEach(function (node) {
        var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[node.data('id')]];
        coseBB.x1 = Math.min(coseBB.x1, lnode.positionX);
        coseBB.x2 = Math.max(coseBB.x2, lnode.positionX);
        coseBB.y1 = Math.min(coseBB.y1, lnode.positionY);
        coseBB.y2 = Math.max(coseBB.y2, lnode.positionY);
      });
      coseBB.w = coseBB.x2 - coseBB.x1;
      coseBB.h = coseBB.y2 - coseBB.y1;
    }
    return function (ele, i) {
      var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[ele.data('id')]];
      if (options.boundingBox) {
        // then add extra bounding box constraint
        var pctX = (lnode.positionX - coseBB.x1) / coseBB.w;
        var pctY = (lnode.positionY - coseBB.y1) / coseBB.h;
        return {
          x: bb.x1 + pctX * bb.w,
          y: bb.y1 + pctY * bb.h
        };
      } else {
        return {
          x: lnode.positionX,
          y: lnode.positionY
        };
      }
    };
  };

  /**
   * @brief          : Updates the positions of nodes in the network
   * @arg layoutInfo : LayoutInfo object
   * @arg cy         : Cytoscape object
   * @arg options    : Layout options
   */
  var refreshPositions = function refreshPositions(layoutInfo, cy, options) {
    // var s = 'Refreshing positions';
    // logDebug(s);

    var layout = options.layout;
    var nodes = options.eles.nodes();
    var getScaledPos = getScaleInBoundsFn(layoutInfo, options, nodes);
    nodes.positions(getScaledPos);

    // Trigger layoutReady only on first call
    if (true !== layoutInfo.ready) {
      // s = 'Triggering layoutready';
      // logDebug(s);
      layoutInfo.ready = true;
      layout.one('layoutready', options.ready);
      layout.emit({
        type: 'layoutready',
        layout: this
      });
    }
  };

  /**
   * @brief : Logs a debug message in JS console, if DEBUG is ON
   */
  // var logDebug = function(text) {
  //   if (DEBUG) {
  //     console.debug(text);
  //   }
  // };

  /**
   * @brief          : Performs one iteration of the physical simulation
   * @arg layoutInfo : LayoutInfo object already initialized
   * @arg cy         : Cytoscape object
   * @arg options    : Layout options
   */
  var step = function step(layoutInfo, options, _step) {
    // var s = "\n\n###############################";
    // s += "\nSTEP: " + step;
    // s += "\n###############################\n";
    // logDebug(s);

    // Calculate node repulsions
    calculateNodeForces(layoutInfo, options);
    // Calculate edge forces
    calculateEdgeForces(layoutInfo);
    // Calculate gravity forces
    calculateGravityForces(layoutInfo, options);
    // Propagate forces from parent to child
    propagateForces(layoutInfo);
    // Update positions based on calculated forces
    updatePositions(layoutInfo);
  };

  /**
   * @brief : Computes the node repulsion forces
   */
  var calculateNodeForces = function calculateNodeForces(layoutInfo, options) {
    // Go through each of the graphs in graphSet
    // Nodes only repel each other if they belong to the same graph
    // var s = 'calculateNodeForces';
    // logDebug(s);
    for (var i = 0; i < layoutInfo.graphSet.length; i++) {
      var graph = layoutInfo.graphSet[i];
      var numNodes = graph.length;

      // s = "Set: " + graph.toString();
      // logDebug(s);

      // Now get all the pairs of nodes
      // Only get each pair once, (A, B) = (B, A)
      for (var j = 0; j < numNodes; j++) {
        var node1 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]];
        for (var k = j + 1; k < numNodes; k++) {
          var node2 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[k]]];
          nodeRepulsion(node1, node2, layoutInfo, options);
        }
      }
    }
  };
  var randomDistance = function randomDistance(max) {
    return -max + 2 * max * Math.random();
  };

  /**
   * @brief : Compute the node repulsion forces between a pair of nodes
   */
  var nodeRepulsion = function nodeRepulsion(node1, node2, layoutInfo, options) {
    // var s = "Node repulsion. Node1: " + node1.id + " Node2: " + node2.id;

    var cmptId1 = node1.cmptId;
    var cmptId2 = node2.cmptId;
    if (cmptId1 !== cmptId2 && !layoutInfo.isCompound) {
      return;
    }

    // Get direction of line connecting both node centers
    var directionX = node2.positionX - node1.positionX;
    var directionY = node2.positionY - node1.positionY;
    var maxRandDist = 1;
    // s += "\ndirectionX: " + directionX + ", directionY: " + directionY;

    // If both centers are the same, apply a random force
    if (0 === directionX && 0 === directionY) {
      directionX = randomDistance(maxRandDist);
      directionY = randomDistance(maxRandDist);
    }
    var overlap = nodesOverlap(node1, node2, directionX, directionY);
    if (overlap > 0) {
      // s += "\nNodes DO overlap.";
      // s += "\nOverlap: " + overlap;
      // If nodes overlap, repulsion force is proportional
      // to the overlap
      var force = options.nodeOverlap * overlap;

      // Compute the module and components of the force vector
      var distance = Math.sqrt(directionX * directionX + directionY * directionY);
      // s += "\nDistance: " + distance;
      var forceX = force * directionX / distance;
      var forceY = force * directionY / distance;
    } else {
      // s += "\nNodes do NOT overlap.";
      // If there's no overlap, force is inversely proportional
      // to squared distance

      // Get clipping points for both nodes
      var point1 = findClippingPoint(node1, directionX, directionY);
      var point2 = findClippingPoint(node2, -1 * directionX, -1 * directionY);

      // Use clipping points to compute distance
      var distanceX = point2.x - point1.x;
      var distanceY = point2.y - point1.y;
      var distanceSqr = distanceX * distanceX + distanceY * distanceY;
      var distance = Math.sqrt(distanceSqr);
      // s += "\nDistance: " + distance;

      // Compute the module and components of the force vector
      var force = (node1.nodeRepulsion + node2.nodeRepulsion) / distanceSqr;
      var forceX = force * distanceX / distance;
      var forceY = force * distanceY / distance;
    }

    // Apply force
    if (!node1.isLocked) {
      node1.offsetX -= forceX;
      node1.offsetY -= forceY;
    }
    if (!node2.isLocked) {
      node2.offsetX += forceX;
      node2.offsetY += forceY;
    }

    // s += "\nForceX: " + forceX + " ForceY: " + forceY;
    // logDebug(s);

    return;
  };

  /**
   * @brief  : Determines whether two nodes overlap or not
   * @return : Amount of overlapping (0 => no overlap)
   */
  var nodesOverlap = function nodesOverlap(node1, node2, dX, dY) {
    if (dX > 0) {
      var overlapX = node1.maxX - node2.minX;
    } else {
      var overlapX = node2.maxX - node1.minX;
    }
    if (dY > 0) {
      var overlapY = node1.maxY - node2.minY;
    } else {
      var overlapY = node2.maxY - node1.minY;
    }
    if (overlapX >= 0 && overlapY >= 0) {
      return Math.sqrt(overlapX * overlapX + overlapY * overlapY);
    } else {
      return 0;
    }
  };

  /**
   * @brief : Finds the point in which an edge (direction dX, dY) intersects
   *          the rectangular bounding box of it's source/target node
   */
  var findClippingPoint = function findClippingPoint(node, dX, dY) {
    // Shorcuts
    var X = node.positionX;
    var Y = node.positionY;
    var H = node.height || 1;
    var W = node.width || 1;
    var dirSlope = dY / dX;
    var nodeSlope = H / W;

    // var s = 'Computing clipping point of node ' + node.id +
    //   " . Height:  " + H + ", Width: " + W +
    //   "\nDirection " + dX + ", " + dY;
    //
    // Compute intersection
    var res = {};

    // Case: Vertical direction (up)
    if (0 === dX && 0 < dY) {
      res.x = X;
      // s += "\nUp direction";
      res.y = Y + H / 2;
      return res;
    }

    // Case: Vertical direction (down)
    if (0 === dX && 0 > dY) {
      res.x = X;
      res.y = Y + H / 2;
      // s += "\nDown direction";

      return res;
    }

    // Case: Intersects the right border
    if (0 < dX && -1 * nodeSlope <= dirSlope && dirSlope <= nodeSlope) {
      res.x = X + W / 2;
      res.y = Y + W * dY / 2 / dX;
      // s += "\nRightborder";

      return res;
    }

    // Case: Intersects the left border
    if (0 > dX && -1 * nodeSlope <= dirSlope && dirSlope <= nodeSlope) {
      res.x = X - W / 2;
      res.y = Y - W * dY / 2 / dX;
      // s += "\nLeftborder";

      return res;
    }

    // Case: Intersects the top border
    if (0 < dY && (dirSlope <= -1 * nodeSlope || dirSlope >= nodeSlope)) {
      res.x = X + H * dX / 2 / dY;
      res.y = Y + H / 2;
      // s += "\nTop border";

      return res;
    }

    // Case: Intersects the bottom border
    if (0 > dY && (dirSlope <= -1 * nodeSlope || dirSlope >= nodeSlope)) {
      res.x = X - H * dX / 2 / dY;
      res.y = Y - H / 2;
      // s += "\nBottom border";

      return res;
    }

    // s += "\nClipping point found at " + res.x + ", " + res.y;
    // logDebug(s);
    return res;
  };

  /**
   * @brief : Calculates all edge forces
   */
  var calculateEdgeForces = function calculateEdgeForces(layoutInfo, options) {
    // Iterate over all edges
    for (var i = 0; i < layoutInfo.edgeSize; i++) {
      // Get edge, source & target nodes
      var edge = layoutInfo.layoutEdges[i];
      var sourceIx = layoutInfo.idToIndex[edge.sourceId];
      var source = layoutInfo.layoutNodes[sourceIx];
      var targetIx = layoutInfo.idToIndex[edge.targetId];
      var target = layoutInfo.layoutNodes[targetIx];

      // Get direction of line connecting both node centers
      var directionX = target.positionX - source.positionX;
      var directionY = target.positionY - source.positionY;

      // If both centers are the same, do nothing.
      // A random force has already been applied as node repulsion
      if (0 === directionX && 0 === directionY) {
        continue;
      }

      // Get clipping points for both nodes
      var point1 = findClippingPoint(source, directionX, directionY);
      var point2 = findClippingPoint(target, -1 * directionX, -1 * directionY);
      var lx = point2.x - point1.x;
      var ly = point2.y - point1.y;
      var l = Math.sqrt(lx * lx + ly * ly);
      var force = Math.pow(edge.idealLength - l, 2) / edge.elasticity;
      if (0 !== l) {
        var forceX = force * lx / l;
        var forceY = force * ly / l;
      } else {
        var forceX = 0;
        var forceY = 0;
      }

      // Add this force to target and source nodes
      if (!source.isLocked) {
        source.offsetX += forceX;
        source.offsetY += forceY;
      }
      if (!target.isLocked) {
        target.offsetX -= forceX;
        target.offsetY -= forceY;
      }

      // var s = 'Edge force between nodes ' + source.id + ' and ' + target.id;
      // s += "\nDistance: " + l + " Force: (" + forceX + ", " + forceY + ")";
      // logDebug(s);
    }
  };

  /**
   * @brief : Computes gravity forces for all nodes
   */
  var calculateGravityForces = function calculateGravityForces(layoutInfo, options) {
    if (options.gravity === 0) {
      return;
    }
    var distThreshold = 1;

    // var s = 'calculateGravityForces';
    // logDebug(s);
    for (var i = 0; i < layoutInfo.graphSet.length; i++) {
      var graph = layoutInfo.graphSet[i];
      var numNodes = graph.length;

      // s = "Set: " + graph.toString();
      // logDebug(s);

      // Compute graph center
      if (0 === i) {
        var centerX = layoutInfo.clientHeight / 2;
        var centerY = layoutInfo.clientWidth / 2;
      } else {
        // Get Parent node for this graph, and use its position as center
        var temp = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[0]]];
        var parent = layoutInfo.layoutNodes[layoutInfo.idToIndex[temp.parentId]];
        var centerX = parent.positionX;
        var centerY = parent.positionY;
      }
      // s = "Center found at: " + centerX + ", " + centerY;
      // logDebug(s);

      // Apply force to all nodes in graph
      for (var j = 0; j < numNodes; j++) {
        var node = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]];
        // s = "Node: " + node.id;

        if (node.isLocked) {
          continue;
        }
        var dx = centerX - node.positionX;
        var dy = centerY - node.positionY;
        var d = Math.sqrt(dx * dx + dy * dy);
        if (d > distThreshold) {
          var fx = options.gravity * dx / d;
          var fy = options.gravity * dy / d;
          node.offsetX += fx;
          node.offsetY += fy;
          // s += ": Applied force: " + fx + ", " + fy;
        }
        // logDebug(s);
      }
    }
  };

  /**
   * @brief          : This function propagates the existing offsets from
   *                   parent nodes to its descendents.
   * @arg layoutInfo : layoutInfo Object
   * @arg cy         : cytoscape Object
   * @arg options    : Layout options
   */
  var propagateForces = function propagateForces(layoutInfo, options) {
    // Inline implementation of a queue, used for traversing the graph in BFS order
    var queue = [];
    var start = 0; // Points to the start the queue
    var end = -1; // Points to the end of the queue

    // logDebug('propagateForces');

    // Start by visiting the nodes in the root graph
    queue.push.apply(queue, layoutInfo.graphSet[0]);
    end += layoutInfo.graphSet[0].length;

    // Traverse the graph, level by level,
    while (start <= end) {
      // Get the node to visit and remove it from queue
      var nodeId = queue[start++];
      var nodeIndex = layoutInfo.idToIndex[nodeId];
      var node = layoutInfo.layoutNodes[nodeIndex];
      var children = node.children;

      // We only need to process the node if it's compound
      if (0 < children.length && !node.isLocked) {
        var offX = node.offsetX;
        var offY = node.offsetY;

        // var s = "Propagating offset from parent node : " + node.id +
        //   ". OffsetX: " + offX + ". OffsetY: " + offY;
        // s += "\n Children: " + children.toString();
        // logDebug(s);

        for (var i = 0; i < children.length; i++) {
          var childNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[children[i]]];
          // Propagate offset
          childNode.offsetX += offX;
          childNode.offsetY += offY;
          // Add children to queue to be visited
          queue[++end] = children[i];
        }

        // Reset parent offsets
        node.offsetX = 0;
        node.offsetY = 0;
      }
    }
  };

  /**
   * @brief : Updates the layout model positions, based on
   *          the accumulated forces
   */
  var updatePositions = function updatePositions(layoutInfo, options) {
    // var s = 'Updating positions';
    // logDebug(s);

    // Reset boundaries for compound nodes
    for (var i = 0; i < layoutInfo.nodeSize; i++) {
      var n = layoutInfo.layoutNodes[i];
      if (0 < n.children.length) {
        // logDebug("Resetting boundaries of compound node: " + n.id);
        n.maxX = undefined;
        n.minX = undefined;
        n.maxY = undefined;
        n.minY = undefined;
      }
    }
    for (var i = 0; i < layoutInfo.nodeSize; i++) {
      var n = layoutInfo.layoutNodes[i];
      if (0 < n.children.length || n.isLocked) {
        // No need to set compound or locked node position
        // logDebug("Skipping position update of node: " + n.id);
        continue;
      }
      // s = "Node: " + n.id + " Previous position: (" +
      // n.positionX + ", " + n.positionY + ").";

      // Limit displacement in order to improve stability
      var tempForce = limitForce(n.offsetX, n.offsetY, layoutInfo.temperature);
      n.positionX += tempForce.x;
      n.positionY += tempForce.y;
      n.offsetX = 0;
      n.offsetY = 0;
      n.minX = n.positionX - n.width;
      n.maxX = n.positionX + n.width;
      n.minY = n.positionY - n.height;
      n.maxY = n.positionY + n.height;
      // s += " New Position: (" + n.positionX + ", " + n.positionY + ").";
      // logDebug(s);

      // Update ancestry boudaries
      updateAncestryBoundaries(n, layoutInfo);
    }

    // Update size, position of compund nodes
    for (var i = 0; i < layoutInfo.nodeSize; i++) {
      var n = layoutInfo.layoutNodes[i];
      if (0 < n.children.length && !n.isLocked) {
        n.positionX = (n.maxX + n.minX) / 2;
        n.positionY = (n.maxY + n.minY) / 2;
        n.width = n.maxX - n.minX;
        n.height = n.maxY - n.minY;
        // s = "Updating position, size of compound node " + n.id;
        // s += "\nPositionX: " + n.positionX + ", PositionY: " + n.positionY;
        // s += "\nWidth: " + n.width + ", Height: " + n.height;
        // logDebug(s);
      }
    }
  };

  /**
   * @brief : Limits a force (forceX, forceY) to be not
   *          greater (in modulo) than max.
   8          Preserves force direction.
    */
  var limitForce = function limitForce(forceX, forceY, max) {
    // var s = "Limiting force: (" + forceX + ", " + forceY + "). Max: " + max;
    var force = Math.sqrt(forceX * forceX + forceY * forceY);
    if (force > max) {
      var res = {
        x: max * forceX / force,
        y: max * forceY / force
      };
    } else {
      var res = {
        x: forceX,
        y: forceY
      };
    }

    // s += ".\nResult: (" + res.x + ", " + res.y + ")";
    // logDebug(s);

    return res;
  };

  /**
   * @brief : Function used for keeping track of compound node
   *          sizes, since they should bound all their subnodes.
   */
  var updateAncestryBoundaries = function updateAncestryBoundaries(node, layoutInfo) {
    // var s = "Propagating new position/size of node " + node.id;
    var parentId = node.parentId;
    if (null == parentId) {
      // If there's no parent, we are done
      // s += ". No parent node.";
      // logDebug(s);
      return;
    }

    // Get Parent Node
    var p = layoutInfo.layoutNodes[layoutInfo.idToIndex[parentId]];
    var flag = false;

    // MaxX
    if (null == p.maxX || node.maxX + p.padRight > p.maxX) {
      p.maxX = node.maxX + p.padRight;
      flag = true;
      // s += "\nNew maxX for parent node " + p.id + ": " + p.maxX;
    }

    // MinX
    if (null == p.minX || node.minX - p.padLeft < p.minX) {
      p.minX = node.minX - p.padLeft;
      flag = true;
      // s += "\nNew minX for parent node " + p.id + ": " + p.minX;
    }

    // MaxY
    if (null == p.maxY || node.maxY + p.padBottom > p.maxY) {
      p.maxY = node.maxY + p.padBottom;
      flag = true;
      // s += "\nNew maxY for parent node " + p.id + ": " + p.maxY;
    }

    // MinY
    if (null == p.minY || node.minY - p.padTop < p.minY) {
      p.minY = node.minY - p.padTop;
      flag = true;
      // s += "\nNew minY for parent node " + p.id + ": " + p.minY;
    }

    // If updated boundaries, propagate changes upward
    if (flag) {
      // logDebug(s);
      return updateAncestryBoundaries(p, layoutInfo);
    }

    // s += ". No changes in boundaries/position of parent node " + p.id;
    // logDebug(s);
    return;
  };
  var separateComponents = function separateComponents(layoutInfo, options) {
    var nodes = layoutInfo.layoutNodes;
    var components = [];
    for (var i = 0; i < nodes.length; i++) {
      var node = nodes[i];
      var cid = node.cmptId;
      var component = components[cid] = components[cid] || [];
      component.push(node);
    }
    var totalA = 0;
    for (var i = 0; i < components.length; i++) {
      var c = components[i];
      if (!c) {
        continue;
      }
      c.x1 = Infinity;
      c.x2 = -Infinity;
      c.y1 = Infinity;
      c.y2 = -Infinity;
      for (var j = 0; j < c.length; j++) {
        var n = c[j];
        c.x1 = Math.min(c.x1, n.positionX - n.width / 2);
        c.x2 = Math.max(c.x2, n.positionX + n.width / 2);
        c.y1 = Math.min(c.y1, n.positionY - n.height / 2);
        c.y2 = Math.max(c.y2, n.positionY + n.height / 2);
      }
      c.w = c.x2 - c.x1;
      c.h = c.y2 - c.y1;
      totalA += c.w * c.h;
    }
    components.sort(function (c1, c2) {
      return c2.w * c2.h - c1.w * c1.h;
    });
    var x = 0;
    var y = 0;
    var usedW = 0;
    var rowH = 0;
    var maxRowW = Math.sqrt(totalA) * layoutInfo.clientWidth / layoutInfo.clientHeight;
    for (var i = 0; i < components.length; i++) {
      var c = components[i];
      if (!c) {
        continue;
      }
      for (var j = 0; j < c.length; j++) {
        var n = c[j];
        if (!n.isLocked) {
          n.positionX += x - c.x1;
          n.positionY += y - c.y1;
        }
      }
      x += c.w + options.componentSpacing;
      usedW += c.w + options.componentSpacing;
      rowH = Math.max(rowH, c.h);
      if (usedW > maxRowW) {
        y += rowH + options.componentSpacing;
        x = 0;
        usedW = 0;
        rowH = 0;
      }
    }
  };

  var defaults$3 = {
    fit: true,
    // whether to fit the viewport to the graph
    padding: 30,
    // padding used on fit
    boundingBox: undefined,
    // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
    avoidOverlap: true,
    // prevents node overlap, may overflow boundingBox if not enough space
    avoidOverlapPadding: 10,
    // extra spacing around nodes when avoidOverlap: true
    nodeDimensionsIncludeLabels: false,
    // Excludes the label when calculating node bounding boxes for the layout algorithm
    spacingFactor: undefined,
    // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up
    condense: false,
    // uses all available space on false, uses minimal space on true
    rows: undefined,
    // force num of rows in the grid
    cols: undefined,
    // force num of columns in the grid
    position: function position(node) {},
    // returns { row, col } for element
    sort: undefined,
    // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') }
    animate: false,
    // whether to transition the node positions
    animationDuration: 500,
    // duration of animation in ms if enabled
    animationEasing: undefined,
    // easing of animation if enabled
    animateFilter: function animateFilter(node, i) {
      return true;
    },
    // 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
    ready: undefined,
    // callback on layoutready
    stop: undefined,
    // callback on layoutstop
    transform: function transform(node, position) {
      return position;
    } // transform a given node position. Useful for changing flow direction in discrete layouts 
  };

  function GridLayout(options) {
    this.options = extend({}, defaults$3, options);
  }
  GridLayout.prototype.run = function () {
    var params = this.options;
    var options = params;
    var cy = params.cy;
    var eles = options.eles;
    var nodes = eles.nodes().not(':parent');
    if (options.sort) {
      nodes = nodes.sort(options.sort);
    }
    var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {
      x1: 0,
      y1: 0,
      w: cy.width(),
      h: cy.height()
    });
    if (bb.h === 0 || bb.w === 0) {
      eles.nodes().layoutPositions(this, options, function (ele) {
        return {
          x: bb.x1,
          y: bb.y1
        };
      });
    } else {
      // width/height * splits^2 = cells where splits is number of times to split width
      var cells = nodes.size();
      var splits = Math.sqrt(cells * bb.h / bb.w);
      var rows = Math.round(splits);
      var cols = Math.round(bb.w / bb.h * splits);
      var small = function small(val) {
        if (val == null) {
          return Math.min(rows, cols);
        } else {
          var min = Math.min(rows, cols);
          if (min == rows) {
            rows = val;
          } else {
            cols = val;
          }
        }
      };
      var large = function large(val) {
        if (val == null) {
          return Math.max(rows, cols);
        } else {
          var max = Math.max(rows, cols);
          if (max == rows) {
            rows = val;
          } else {
            cols = val;
          }
        }
      };
      var oRows = options.rows;
      var oCols = options.cols != null ? options.cols : options.columns;

      // if rows or columns were set in options, use those values
      if (oRows != null && oCols != null) {
        rows = oRows;
        cols = oCols;
      } else if (oRows != null && oCols == null) {
        rows = oRows;
        cols = Math.ceil(cells / rows);
      } else if (oRows == null && oCols != null) {
        cols = oCols;
        rows = Math.ceil(cells / cols);
      }

      // otherwise use the automatic values and adjust accordingly

      // if rounding was up, see if we can reduce rows or columns
      else if (cols * rows > cells) {
        var sm = small();
        var lg = large();

        // reducing the small side takes away the most cells, so try it first
        if ((sm - 1) * lg >= cells) {
          small(sm - 1);
        } else if ((lg - 1) * sm >= cells) {
          large(lg - 1);
        }
      } else {
        // if rounding was too low, add rows or columns
        while (cols * rows < cells) {
          var _sm = small();
          var _lg = large();

          // try to add to larger side first (adds less in multiplication)
          if ((_lg + 1) * _sm >= cells) {
            large(_lg + 1);
          } else {
            small(_sm + 1);
          }
        }
      }
      var cellWidth = bb.w / cols;
      var cellHeight = bb.h / rows;
      if (options.condense) {
        cellWidth = 0;
        cellHeight = 0;
      }
      if (options.avoidOverlap) {
        for (var i = 0; i < nodes.length; i++) {
          var node = nodes[i];
          var pos = node._private.position;
          if (pos.x == null || pos.y == null) {
            // for bb
            pos.x = 0;
            pos.y = 0;
          }
          var nbb = node.layoutDimensions(options);
          var p = options.avoidOverlapPadding;
          var w = nbb.w + p;
          var h = nbb.h + p;
          cellWidth = Math.max(cellWidth, w);
          cellHeight = Math.max(cellHeight, h);
        }
      }
      var cellUsed = {}; // e.g. 'c-0-2' => true

      var used = function used(row, col) {
        return cellUsed['c-' + row + '-' + col] ? true : false;
      };
      var use = function use(row, col) {
        cellUsed['c-' + row + '-' + col] = true;
      };

      // to keep track of current cell position
      var row = 0;
      var col = 0;
      var moveToNextCell = function moveToNextCell() {
        col++;
        if (col >= cols) {
          col = 0;
          row++;
        }
      };

      // get a cache of all the manual positions
      var id2manPos = {};
      for (var _i = 0; _i < nodes.length; _i++) {
        var _node = nodes[_i];
        var rcPos = options.position(_node);
        if (rcPos && (rcPos.row !== undefined || rcPos.col !== undefined)) {
          // must have at least row or col def'd
          var _pos = {
            row: rcPos.row,
            col: rcPos.col
          };
          if (_pos.col === undefined) {
            // find unused col
            _pos.col = 0;
            while (used(_pos.row, _pos.col)) {
              _pos.col++;
            }
          } else if (_pos.row === undefined) {
            // find unused row
            _pos.row = 0;
            while (used(_pos.row, _pos.col)) {
              _pos.row++;
            }
          }
          id2manPos[_node.id()] = _pos;
          use(_pos.row, _pos.col);
        }
      }
      var getPos = function getPos(element, i) {
        var x, y;
        if (element.locked() || element.isParent()) {
          return false;
        }

        // see if we have a manual position set
        var rcPos = id2manPos[element.id()];
        if (rcPos) {
          x = rcPos.col * cellWidth + cellWidth / 2 + bb.x1;
          y = rcPos.row * cellHeight + cellHeight / 2 + bb.y1;
        } else {
          // otherwise set automatically

          while (used(row, col)) {
            moveToNextCell();
          }
          x = col * cellWidth + cellWidth / 2 + bb.x1;
          y = row * cellHeight + cellHeight / 2 + bb.y1;
          use(row, col);
          moveToNextCell();
        }
        return {
          x: x,
          y: y
        };
      };
      nodes.layoutPositions(this, options, getPos);
    }
    return this; // chaining
  };

  // default layout options
  var defaults$2 = {
    ready: function ready() {},
    // on layoutready
    stop: function stop() {} // on layoutstop
  };

  // constructor
  // options : object containing layout options
  function NullLayout(options) {
    this.options = extend({}, defaults$2, options);
  }

  // runs the layout
  NullLayout.prototype.run = function () {
    var options = this.options;
    var eles = options.eles; // elements to consider in the layout
    var layout = this;

    // cy is automatically populated for us in the constructor
    // (disable eslint for next line as this serves as example layout code to external developers)
    // eslint-disable-next-line no-unused-vars
    options.cy;
    layout.emit('layoutstart');

    // puts all nodes at (0, 0)
    // n.b. most layouts would use layoutPositions(), instead of positions() and manual events
    eles.nodes().positions(function () {
      return {
        x: 0,
        y: 0
      };
    });

    // trigger layoutready when each node has had its position set at least once
    layout.one('layoutready', options.ready);
    layout.emit('layoutready');

    // trigger layoutstop when the layout stops (e.g. finishes)
    layout.one('layoutstop', options.stop);
    layout.emit('layoutstop');
    return this; // chaining
  };

  // called on continuous layouts to stop them before they finish
  NullLayout.prototype.stop = function () {
    return this; // chaining
  };

  var defaults$1 = {
    positions: undefined,
    // map of (node id) => (position obj); or function(node){ return somPos; }
    zoom: undefined,
    // the zoom level to set (prob want fit = false if set)
    pan: undefined,
    // the pan level to set (prob want fit = false if set)
    fit: true,
    // whether to fit to viewport
    padding: 30,
    // padding on fit
    spacingFactor: undefined,
    // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up
    animate: false,
    // whether to transition the node positions
    animationDuration: 500,
    // duration of animation in ms if enabled
    animationEasing: undefined,
    // easing of animation if enabled
    animateFilter: function animateFilter(node, i) {
      return true;
    },
    // 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
    ready: undefined,
    // callback on layoutready
    stop: undefined,
    // callback on layoutstop
    transform: function transform(node, position) {
      return position;
    } // transform a given node position. Useful for changing flow direction in discrete layouts
  };

  function PresetLayout(options) {
    this.options = extend({}, defaults$1, options);
  }
  PresetLayout.prototype.run = function () {
    var options = this.options;
    var eles = options.eles;
    var nodes = eles.nodes();
    var posIsFn = fn$6(options.positions);
    function getPosition(node) {
      if (options.positions == null) {
        return copyPosition(node.position());
      }
      if (posIsFn) {
        return options.positions(node);
      }
      var pos = options.positions[node._private.data.id];
      if (pos == null) {
        return null;
      }
      return pos;
    }
    nodes.layoutPositions(this, options, function (node, i) {
      var position = getPosition(node);
      if (node.locked() || position == null) {
        return false;
      }
      return position;
    });
    return this; // chaining
  };

  var defaults = {
    fit: true,
    // whether to fit to viewport
    padding: 30,
    // fit padding
    boundingBox: undefined,
    // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
    animate: false,
    // whether to transition the node positions
    animationDuration: 500,
    // duration of animation in ms if enabled
    animationEasing: undefined,
    // easing of animation if enabled
    animateFilter: function animateFilter(node, i) {
      return true;
    },
    // 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
    ready: undefined,
    // callback on layoutready
    stop: undefined,
    // callback on layoutstop
    transform: function transform(node, position) {
      return position;
    } // transform a given node position. Useful for changing flow direction in discrete layouts 
  };

  function RandomLayout(options) {
    this.options = extend({}, defaults, options);
  }
  RandomLayout.prototype.run = function () {
    var options = this.options;
    var cy = options.cy;
    var eles = options.eles;
    var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {
      x1: 0,
      y1: 0,
      w: cy.width(),
      h: cy.height()
    });
    var getPos = function getPos(node, i) {
      return {
        x: bb.x1 + Math.round(Math.random() * bb.w),
        y: bb.y1 + Math.round(Math.random() * bb.h)
      };
    };
    eles.nodes().layoutPositions(this, options, getPos);
    return this; // chaining
  };

  var layout = [{
    name: 'breadthfirst',
    impl: BreadthFirstLayout
  }, {
    name: 'circle',
    impl: CircleLayout
  }, {
    name: 'concentric',
    impl: ConcentricLayout
  }, {
    name: 'cose',
    impl: CoseLayout
  }, {
    name: 'grid',
    impl: GridLayout
  }, {
    name: 'null',
    impl: NullLayout
  }, {
    name: 'preset',
    impl: PresetLayout
  }, {
    name: 'random',
    impl: RandomLayout
  }];

  function NullRenderer(options) {
    this.options = options;
    this.notifications = 0; // for testing
  }

  var noop = function noop() {};
  var throwImgErr = function throwImgErr() {
    throw new Error('A headless instance can not render images');
  };
  NullRenderer.prototype = {
    recalculateRenderedStyle: noop,
    notify: function notify() {
      this.notifications++;
    },
    init: noop,
    isHeadless: function isHeadless() {
      return true;
    },
    png: throwImgErr,
    jpg: throwImgErr
  };

  var BRp$f = {};
  BRp$f.arrowShapeWidth = 0.3;
  BRp$f.registerArrowShapes = function () {
    var arrowShapes = this.arrowShapes = {};
    var renderer = this;

    // Contract for arrow shapes:
    // 0, 0 is arrow tip
    // (0, 1) is direction towards node
    // (1, 0) is right
    //
    // functional api:
    // collide: check x, y in shape
    // roughCollide: called before collide, no false negatives
    // draw: draw
    // spacing: dist(arrowTip, nodeBoundary)
    // gap: dist(edgeTip, nodeBoundary), edgeTip may != arrowTip

    var bbCollide = function bbCollide(x, y, size, angle, translation, edgeWidth, padding) {
      var x1 = translation.x - size / 2 - padding;
      var x2 = translation.x + size / 2 + padding;
      var y1 = translation.y - size / 2 - padding;
      var y2 = translation.y + size / 2 + padding;
      var inside = x1 <= x && x <= x2 && y1 <= y && y <= y2;
      return inside;
    };
    var transform = function transform(x, y, size, angle, translation) {
      var xRotated = x * Math.cos(angle) - y * Math.sin(angle);
      var yRotated = x * Math.sin(angle) + y * Math.cos(angle);
      var xScaled = xRotated * size;
      var yScaled = yRotated * size;
      var xTranslated = xScaled + translation.x;
      var yTranslated = yScaled + translation.y;
      return {
        x: xTranslated,
        y: yTranslated
      };
    };
    var transformPoints = function transformPoints(pts, size, angle, translation) {
      var retPts = [];
      for (var i = 0; i < pts.length; i += 2) {
        var x = pts[i];
        var y = pts[i + 1];
        retPts.push(transform(x, y, size, angle, translation));
      }
      return retPts;
    };
    var pointsToArr = function pointsToArr(pts) {
      var ret = [];
      for (var i = 0; i < pts.length; i++) {
        var p = pts[i];
        ret.push(p.x, p.y);
      }
      return ret;
    };
    var standardGap = function standardGap(edge) {
      return edge.pstyle('width').pfValue * edge.pstyle('arrow-scale').pfValue * 2;
    };
    var defineArrowShape = function defineArrowShape(name, defn) {
      if (string(defn)) {
        defn = arrowShapes[defn];
      }
      arrowShapes[name] = extend({
        name: name,
        points: [-0.15, -0.3, 0.15, -0.3, 0.15, 0.3, -0.15, 0.3],
        collide: function collide(x, y, size, angle, translation, padding) {
          var points = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation));
          var inside = pointInsidePolygonPoints(x, y, points);
          return inside;
        },
        roughCollide: bbCollide,
        draw: function draw(context, size, angle, translation) {
          var points = transformPoints(this.points, size, angle, translation);
          renderer.arrowShapeImpl('polygon')(context, points);
        },
        spacing: function spacing(edge) {
          return 0;
        },
        gap: standardGap
      }, defn);
    };
    defineArrowShape('none', {
      collide: falsify,
      roughCollide: falsify,
      draw: noop$1,
      spacing: zeroify,
      gap: zeroify
    });
    defineArrowShape('triangle', {
      points: [-0.15, -0.3, 0, 0, 0.15, -0.3]
    });
    defineArrowShape('arrow', 'triangle');
    defineArrowShape('triangle-backcurve', {
      points: arrowShapes['triangle'].points,
      controlPoint: [0, -0.15],
      roughCollide: bbCollide,
      draw: function draw(context, size, angle, translation, edgeWidth) {
        var ptsTrans = transformPoints(this.points, size, angle, translation);
        var ctrlPt = this.controlPoint;
        var ctrlPtTrans = transform(ctrlPt[0], ctrlPt[1], size, angle, translation);
        renderer.arrowShapeImpl(this.name)(context, ptsTrans, ctrlPtTrans);
      },
      gap: function gap(edge) {
        return standardGap(edge) * 0.8;
      }
    });
    defineArrowShape('triangle-tee', {
      points: [0, 0, 0.15, -0.3, -0.15, -0.3, 0, 0],
      pointsTee: [-0.15, -0.4, -0.15, -0.5, 0.15, -0.5, 0.15, -0.4],
      collide: function collide(x, y, size, angle, translation, edgeWidth, padding) {
        var triPts = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation));
        var teePts = pointsToArr(transformPoints(this.pointsTee, size + 2 * padding, angle, translation));
        var inside = pointInsidePolygonPoints(x, y, triPts) || pointInsidePolygonPoints(x, y, teePts);
        return inside;
      },
      draw: function draw(context, size, angle, translation, edgeWidth) {
        var triPts = transformPoints(this.points, size, angle, translation);
        var teePts = transformPoints(this.pointsTee, size, angle, translation);
        renderer.arrowShapeImpl(this.name)(context, triPts, teePts);
      }
    });
    defineArrowShape('circle-triangle', {
      radius: 0.15,
      pointsTr: [0, -0.15, 0.15, -0.45, -0.15, -0.45, 0, -0.15],
      collide: function collide(x, y, size, angle, translation, edgeWidth, padding) {
        var t = translation;
        var circleInside = Math.pow(t.x - x, 2) + Math.pow(t.y - y, 2) <= Math.pow((size + 2 * padding) * this.radius, 2);
        var triPts = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation));
        return pointInsidePolygonPoints(x, y, triPts) || circleInside;
      },
      draw: function draw(context, size, angle, translation, edgeWidth) {
        var triPts = transformPoints(this.pointsTr, size, angle, translation);
        renderer.arrowShapeImpl(this.name)(context, triPts, translation.x, translation.y, this.radius * size);
      },
      spacing: function spacing(edge) {
        return renderer.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.radius;
      }
    });
    defineArrowShape('triangle-cross', {
      points: [0, 0, 0.15, -0.3, -0.15, -0.3, 0, 0],
      baseCrossLinePts: [-0.15, -0.4,
      // first half of the rectangle
      -0.15, -0.4, 0.15, -0.4,
      // second half of the rectangle
      0.15, -0.4],
      crossLinePts: function crossLinePts(size, edgeWidth) {
        // shift points so that the distance between the cross points matches edge width
        var p = this.baseCrossLinePts.slice();
        var shiftFactor = edgeWidth / size;
        var y0 = 3;
        var y1 = 5;
        p[y0] = p[y0] - shiftFactor;
        p[y1] = p[y1] - shiftFactor;
        return p;
      },
      collide: function collide(x, y, size, angle, translation, edgeWidth, padding) {
        var triPts = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation));
        var teePts = pointsToArr(transformPoints(this.crossLinePts(size, edgeWidth), size + 2 * padding, angle, translation));
        var inside = pointInsidePolygonPoints(x, y, triPts) || pointInsidePolygonPoints(x, y, teePts);
        return inside;
      },
      draw: function draw(context, size, angle, translation, edgeWidth) {
        var triPts = transformPoints(this.points, size, angle, translation);
        var crossLinePts = transformPoints(this.crossLinePts(size, edgeWidth), size, angle, translation);
        renderer.arrowShapeImpl(this.name)(context, triPts, crossLinePts);
      }
    });
    defineArrowShape('vee', {
      points: [-0.15, -0.3, 0, 0, 0.15, -0.3, 0, -0.15],
      gap: function gap(edge) {
        return standardGap(edge) * 0.525;
      }
    });
    defineArrowShape('circle', {
      radius: 0.15,
      collide: function collide(x, y, size, angle, translation, edgeWidth, padding) {
        var t = translation;
        var inside = Math.pow(t.x - x, 2) + Math.pow(t.y - y, 2) <= Math.pow((size + 2 * padding) * this.radius, 2);
        return inside;
      },
      draw: function draw(context, size, angle, translation, edgeWidth) {
        renderer.arrowShapeImpl(this.name)(context, translation.x, translation.y, this.radius * size);
      },
      spacing: function spacing(edge) {
        return renderer.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.radius;
      }
    });
    defineArrowShape('tee', {
      points: [-0.15, 0, -0.15, -0.1, 0.15, -0.1, 0.15, 0],
      spacing: function spacing(edge) {
        return 1;
      },
      gap: function gap(edge) {
        return 1;
      }
    });
    defineArrowShape('square', {
      points: [-0.15, 0.00, 0.15, 0.00, 0.15, -0.3, -0.15, -0.3]
    });
    defineArrowShape('diamond', {
      points: [-0.15, -0.15, 0, -0.3, 0.15, -0.15, 0, 0],
      gap: function gap(edge) {
        return edge.pstyle('width').pfValue * edge.pstyle('arrow-scale').value;
      }
    });
    defineArrowShape('chevron', {
      points: [0, 0, -0.15, -0.15, -0.1, -0.2, 0, -0.1, 0.1, -0.2, 0.15, -0.15],
      gap: function gap(edge) {
        return 0.95 * edge.pstyle('width').pfValue * edge.pstyle('arrow-scale').value;
      }
    });
  };

  var BRp$e = {};

  // Project mouse
  BRp$e.projectIntoViewport = function (clientX, clientY) {
    var cy = this.cy;
    var offsets = this.findContainerClientCoords();
    var offsetLeft = offsets[0];
    var offsetTop = offsets[1];
    var scale = offsets[4];
    var pan = cy.pan();
    var zoom = cy.zoom();
    var x = ((clientX - offsetLeft) / scale - pan.x) / zoom;
    var y = ((clientY - offsetTop) / scale - pan.y) / zoom;
    return [x, y];
  };
  BRp$e.findContainerClientCoords = function () {
    if (this.containerBB) {
      return this.containerBB;
    }
    var container = this.container;
    var rect = container.getBoundingClientRect();
    var style = this.cy.window().getComputedStyle(container);
    var styleValue = function styleValue(name) {
      return parseFloat(style.getPropertyValue(name));
    };
    var padding = {
      left: styleValue('padding-left'),
      right: styleValue('padding-right'),
      top: styleValue('padding-top'),
      bottom: styleValue('padding-bottom')
    };
    var border = {
      left: styleValue('border-left-width'),
      right: styleValue('border-right-width'),
      top: styleValue('border-top-width'),
      bottom: styleValue('border-bottom-width')
    };
    var clientWidth = container.clientWidth;
    var clientHeight = container.clientHeight;
    var paddingHor = padding.left + padding.right;
    var paddingVer = padding.top + padding.bottom;
    var borderHor = border.left + border.right;
    var scale = rect.width / (clientWidth + borderHor);
    var unscaledW = clientWidth - paddingHor;
    var unscaledH = clientHeight - paddingVer;
    var left = rect.left + padding.left + border.left;
    var top = rect.top + padding.top + border.top;
    return this.containerBB = [left, top, unscaledW, unscaledH, scale];
  };
  BRp$e.invalidateContainerClientCoordsCache = function () {
    this.containerBB = null;
  };
  BRp$e.findNearestElement = function (x, y, interactiveElementsOnly, isTouch) {
    return this.findNearestElements(x, y, interactiveElementsOnly, isTouch)[0];
  };
  BRp$e.findNearestElements = function (x, y, interactiveElementsOnly, isTouch) {
    var self = this;
    var r = this;
    var eles = r.getCachedZSortedEles();
    var near = []; // 1 node max, 1 edge max
    var zoom = r.cy.zoom();
    var hasCompounds = r.cy.hasCompoundNodes();
    var edgeThreshold = (isTouch ? 24 : 8) / zoom;
    var nodeThreshold = (isTouch ? 8 : 2) / zoom;
    var labelThreshold = (isTouch ? 8 : 2) / zoom;
    var minSqDist = Infinity;
    var nearEdge;
    var nearNode;
    if (interactiveElementsOnly) {
      eles = eles.interactive;
    }
    function addEle(ele, sqDist) {
      if (ele.isNode()) {
        if (nearNode) {
          return; // can't replace node
        } else {
          nearNode = ele;
          near.push(ele);
        }
      }
      if (ele.isEdge() && (sqDist == null || sqDist < minSqDist)) {
        if (nearEdge) {
          // then replace existing edge
          // can replace only if same z-index
          if (nearEdge.pstyle('z-compound-depth').value === ele.pstyle('z-compound-depth').value && nearEdge.pstyle('z-compound-depth').value === ele.pstyle('z-compound-depth').value) {
            for (var i = 0; i < near.length; i++) {
              if (near[i].isEdge()) {
                near[i] = ele;
                nearEdge = ele;
                minSqDist = sqDist != null ? sqDist : minSqDist;
                break;
              }
            }
          }
        } else {
          near.push(ele);
          nearEdge = ele;
          minSqDist = sqDist != null ? sqDist : minSqDist;
        }
      }
    }
    function checkNode(node) {
      var width = node.outerWidth() + 2 * nodeThreshold;
      var height = node.outerHeight() + 2 * nodeThreshold;
      var hw = width / 2;
      var hh = height / 2;
      var pos = node.position();
      if (pos.x - hw <= x && x <= pos.x + hw // bb check x
      && pos.y - hh <= y && y <= pos.y + hh // bb check y
      ) {
        var shape = r.nodeShapes[self.getNodeShape(node)];
        if (shape.checkPoint(x, y, 0, width, height, pos.x, pos.y)) {
          addEle(node, 0);
          return true;
        }
      }
    }
    function checkEdge(edge) {
      var _p = edge._private;
      var rs = _p.rscratch;
      var styleWidth = edge.pstyle('width').pfValue;
      var scale = edge.pstyle('arrow-scale').value;
      var width = styleWidth / 2 + edgeThreshold; // more like a distance radius from centre
      var widthSq = width * width;
      var width2 = width * 2;
      var src = _p.source;
      var tgt = _p.target;
      var sqDist;
      if (rs.edgeType === 'segments' || rs.edgeType === 'straight' || rs.edgeType === 'haystack') {
        var pts = rs.allpts;
        for (var i = 0; i + 3 < pts.length; i += 2) {
          if (inLineVicinity(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3], width2) && widthSq > (sqDist = sqdistToFiniteLine(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3]))) {
            addEle(edge, sqDist);
            return true;
          }
        }
      } else if (rs.edgeType === 'bezier' || rs.edgeType === 'multibezier' || rs.edgeType === 'self' || rs.edgeType === 'compound') {
        var pts = rs.allpts;
        for (var i = 0; i + 5 < rs.allpts.length; i += 4) {
          if (inBezierVicinity(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3], pts[i + 4], pts[i + 5], width2) && widthSq > (sqDist = sqdistToQuadraticBezier(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3], pts[i + 4], pts[i + 5]))) {
            addEle(edge, sqDist);
            return true;
          }
        }
      }

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

      var src = src || _p.source;
      var tgt = tgt || _p.target;
      var arSize = self.getArrowWidth(styleWidth, scale);
      var arrows = [{
        name: 'source',
        x: rs.arrowStartX,
        y: rs.arrowStartY,
        angle: rs.srcArrowAngle
      }, {
        name: 'target',
        x: rs.arrowEndX,
        y: rs.arrowEndY,
        angle: rs.tgtArrowAngle
      }, {
        name: 'mid-source',
        x: rs.midX,
        y: rs.midY,
        angle: rs.midsrcArrowAngle
      }, {
        name: 'mid-target',
        x: rs.midX,
        y: rs.midY,
        angle: rs.midtgtArrowAngle
      }];
      for (var i = 0; i < arrows.length; i++) {
        var ar = arrows[i];
        var shape = r.arrowShapes[edge.pstyle(ar.name + '-arrow-shape').value];
        var edgeWidth = edge.pstyle('width').pfValue;
        if (shape.roughCollide(x, y, arSize, ar.angle, {
          x: ar.x,
          y: ar.y
        }, edgeWidth, edgeThreshold) && shape.collide(x, y, arSize, ar.angle, {
          x: ar.x,
          y: ar.y
        }, edgeWidth, edgeThreshold)) {
          addEle(edge);
          return true;
        }
      }

      // for compound graphs, hitting edge may actually want a connected node instead (b/c edge may have greater z-index precedence)
      if (hasCompounds && near.length > 0) {
        checkNode(src);
        checkNode(tgt);
      }
    }
    function preprop(obj, name, pre) {
      return getPrefixedProperty(obj, name, pre);
    }
    function checkLabel(ele, prefix) {
      var _p = ele._private;
      var th = labelThreshold;
      var prefixDash;
      if (prefix) {
        prefixDash = prefix + '-';
      } else {
        prefixDash = '';
      }
      ele.boundingBox();
      var bb = _p.labelBounds[prefix || 'main'];
      var text = ele.pstyle(prefixDash + 'label').value;
      var eventsEnabled = ele.pstyle('text-events').strValue === 'yes';
      if (!eventsEnabled || !text) {
        return;
      }
      var lx = preprop(_p.rscratch, 'labelX', prefix);
      var ly = preprop(_p.rscratch, 'labelY', prefix);
      var theta = preprop(_p.rscratch, 'labelAngle', prefix);
      var ox = ele.pstyle(prefixDash + 'text-margin-x').pfValue;
      var oy = ele.pstyle(prefixDash + 'text-margin-y').pfValue;
      var lx1 = bb.x1 - th - ox; // (-ox, -oy) as bb already includes margin
      var lx2 = bb.x2 + th - ox; // and rotation is about (lx, ly)
      var ly1 = bb.y1 - th - oy;
      var ly2 = bb.y2 + th - oy;
      if (theta) {
        var cos = Math.cos(theta);
        var sin = Math.sin(theta);
        var rotate = function rotate(x, y) {
          x = x - lx;
          y = y - ly;
          return {
            x: x * cos - y * sin + lx,
            y: x * sin + y * cos + ly
          };
        };
        var px1y1 = rotate(lx1, ly1);
        var px1y2 = rotate(lx1, ly2);
        var px2y1 = rotate(lx2, ly1);
        var px2y2 = rotate(lx2, ly2);
        var points = [
        // with the margin added after the rotation is applied
        px1y1.x + ox, px1y1.y + oy, px2y1.x + ox, px2y1.y + oy, px2y2.x + ox, px2y2.y + oy, px1y2.x + ox, px1y2.y + oy];
        if (pointInsidePolygonPoints(x, y, points)) {
          addEle(ele);
          return true;
        }
      } else {
        // do a cheaper bb check
        if (inBoundingBox(bb, x, y)) {
          addEle(ele);
          return true;
        }
      }
    }
    for (var i = eles.length - 1; i >= 0; i--) {
      // reverse order for precedence
      var ele = eles[i];
      if (ele.isNode()) {
        checkNode(ele) || checkLabel(ele);
      } else {
        // then edge
        checkEdge(ele) || checkLabel(ele) || checkLabel(ele, 'source') || checkLabel(ele, 'target');
      }
    }
    return near;
  };

  // 'Give me everything from this box'
  BRp$e.getAllInBox = function (x1, y1, x2, y2) {
    var eles = this.getCachedZSortedEles().interactive;
    var box = [];
    var x1c = Math.min(x1, x2);
    var x2c = Math.max(x1, x2);
    var y1c = Math.min(y1, y2);
    var y2c = Math.max(y1, y2);
    x1 = x1c;
    x2 = x2c;
    y1 = y1c;
    y2 = y2c;
    var boxBb = makeBoundingBox({
      x1: x1,
      y1: y1,
      x2: x2,
      y2: y2
    });
    for (var e = 0; e < eles.length; e++) {
      var ele = eles[e];
      if (ele.isNode()) {
        var node = ele;
        var nodeBb = node.boundingBox({
          includeNodes: true,
          includeEdges: false,
          includeLabels: false
        });
        if (boundingBoxesIntersect(boxBb, nodeBb) && !boundingBoxInBoundingBox(nodeBb, boxBb)) {
          box.push(node);
        }
      } else {
        var edge = ele;
        var _p = edge._private;
        var rs = _p.rscratch;
        if (rs.startX != null && rs.startY != null && !inBoundingBox(boxBb, rs.startX, rs.startY)) {
          continue;
        }
        if (rs.endX != null && rs.endY != null && !inBoundingBox(boxBb, rs.endX, rs.endY)) {
          continue;
        }
        if (rs.edgeType === 'bezier' || rs.edgeType === 'multibezier' || rs.edgeType === 'self' || rs.edgeType === 'compound' || rs.edgeType === 'segments' || rs.edgeType === 'haystack') {
          var pts = _p.rstyle.bezierPts || _p.rstyle.linePts || _p.rstyle.haystackPts;
          var allInside = true;
          for (var i = 0; i < pts.length; i++) {
            if (!pointInBoundingBox(boxBb, pts[i])) {
              allInside = false;
              break;
            }
          }
          if (allInside) {
            box.push(edge);
          }
        } else if (rs.edgeType === 'haystack' || rs.edgeType === 'straight') {
          box.push(edge);
        }
      }
    }
    return box;
  };

  var BRp$d = {};
  BRp$d.calculateArrowAngles = function (edge) {
    var rs = edge._private.rscratch;
    var isHaystack = rs.edgeType === 'haystack';
    var isBezier = rs.edgeType === 'bezier';
    var isMultibezier = rs.edgeType === 'multibezier';
    var isSegments = rs.edgeType === 'segments';
    var isCompound = rs.edgeType === 'compound';
    var isSelf = rs.edgeType === 'self';

    // Displacement gives direction for arrowhead orientation
    var dispX, dispY;
    var startX, startY, endX, endY, midX, midY;
    if (isHaystack) {
      startX = rs.haystackPts[0];
      startY = rs.haystackPts[1];
      endX = rs.haystackPts[2];
      endY = rs.haystackPts[3];
    } else {
      startX = rs.arrowStartX;
      startY = rs.arrowStartY;
      endX = rs.arrowEndX;
      endY = rs.arrowEndY;
    }
    midX = rs.midX;
    midY = rs.midY;

    // source
    //

    if (isSegments) {
      dispX = startX - rs.segpts[0];
      dispY = startY - rs.segpts[1];
    } else if (isMultibezier || isCompound || isSelf || isBezier) {
      var pts = rs.allpts;
      var bX = qbezierAt(pts[0], pts[2], pts[4], 0.1);
      var bY = qbezierAt(pts[1], pts[3], pts[5], 0.1);
      dispX = startX - bX;
      dispY = startY - bY;
    } else {
      dispX = startX - midX;
      dispY = startY - midY;
    }
    rs.srcArrowAngle = getAngleFromDisp(dispX, dispY);

    // mid target
    //

    var midX = rs.midX;
    var midY = rs.midY;
    if (isHaystack) {
      midX = (startX + endX) / 2;
      midY = (startY + endY) / 2;
    }
    dispX = endX - startX;
    dispY = endY - startY;
    if (isSegments) {
      var pts = rs.allpts;
      if (pts.length / 2 % 2 === 0) {
        var i2 = pts.length / 2;
        var i1 = i2 - 2;
        dispX = pts[i2] - pts[i1];
        dispY = pts[i2 + 1] - pts[i1 + 1];
      } else {
        var i2 = pts.length / 2 - 1;
        var i1 = i2 - 2;
        var i3 = i2 + 2;
        dispX = pts[i2] - pts[i1];
        dispY = pts[i2 + 1] - pts[i1 + 1];
      }
    } else if (isMultibezier || isCompound || isSelf) {
      var pts = rs.allpts;
      var cpts = rs.ctrlpts;
      var bp0x, bp0y;
      var bp1x, bp1y;
      if (cpts.length / 2 % 2 === 0) {
        var p0 = pts.length / 2 - 1; // startpt
        var ic = p0 + 2;
        var p1 = ic + 2;
        bp0x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.0);
        bp0y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.0);
        bp1x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.0001);
        bp1y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.0001);
      } else {
        var ic = pts.length / 2 - 1; // ctrpt
        var p0 = ic - 2; // startpt
        var p1 = ic + 2; // endpt

        bp0x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.4999);
        bp0y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.4999);
        bp1x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.5);
        bp1y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.5);
      }
      dispX = bp1x - bp0x;
      dispY = bp1y - bp0y;
    }
    rs.midtgtArrowAngle = getAngleFromDisp(dispX, dispY);
    rs.midDispX = dispX;
    rs.midDispY = dispY;

    // mid source
    //

    dispX *= -1;
    dispY *= -1;
    if (isSegments) {
      var pts = rs.allpts;
      if (pts.length / 2 % 2 === 0) ; else {
        var i2 = pts.length / 2 - 1;
        var i3 = i2 + 2;
        dispX = -(pts[i3] - pts[i2]);
        dispY = -(pts[i3 + 1] - pts[i2 + 1]);
      }
    }
    rs.midsrcArrowAngle = getAngleFromDisp(dispX, dispY);

    // target
    //

    if (isSegments) {
      dispX = endX - rs.segpts[rs.segpts.length - 2];
      dispY = endY - rs.segpts[rs.segpts.length - 1];
    } else if (isMultibezier || isCompound || isSelf || isBezier) {
      var pts = rs.allpts;
      var l = pts.length;
      var bX = qbezierAt(pts[l - 6], pts[l - 4], pts[l - 2], 0.9);
      var bY = qbezierAt(pts[l - 5], pts[l - 3], pts[l - 1], 0.9);
      dispX = endX - bX;
      dispY = endY - bY;
    } else {
      dispX = endX - midX;
      dispY = endY - midY;
    }
    rs.tgtArrowAngle = getAngleFromDisp(dispX, dispY);
  };
  BRp$d.getArrowWidth = BRp$d.getArrowHeight = function (edgeWidth, scale) {
    var cache = this.arrowWidthCache = this.arrowWidthCache || {};
    var cachedVal = cache[edgeWidth + ', ' + scale];
    if (cachedVal) {
      return cachedVal;
    }
    cachedVal = Math.max(Math.pow(edgeWidth * 13.37, 0.9), 29) * scale;
    cache[edgeWidth + ', ' + scale] = cachedVal;
    return cachedVal;
  };

  var BRp$c = {};
  BRp$c.findMidptPtsEtc = function (edge, pairInfo) {
    var posPts = pairInfo.posPts,
      intersectionPts = pairInfo.intersectionPts,
      vectorNormInverse = pairInfo.vectorNormInverse;
    var midptPts;

    // n.b. assumes all edges in bezier bundle have same endpoints specified
    var srcManEndpt = edge.pstyle('source-endpoint');
    var tgtManEndpt = edge.pstyle('target-endpoint');
    var haveManualEndPts = srcManEndpt.units != null && tgtManEndpt.units != null;
    var recalcVectorNormInverse = function recalcVectorNormInverse(x1, y1, x2, y2) {
      var dy = y2 - y1;
      var dx = x2 - x1;
      var l = Math.sqrt(dx * dx + dy * dy);
      return {
        x: -dy / l,
        y: dx / l
      };
    };
    var edgeDistances = edge.pstyle('edge-distances').value;
    switch (edgeDistances) {
      case 'node-position':
        midptPts = posPts;
        break;
      case 'intersection':
        midptPts = intersectionPts;
        break;
      case 'endpoints':
        {
          if (haveManualEndPts) {
            var _this$manualEndptToPx = this.manualEndptToPx(edge.source()[0], srcManEndpt),
              _this$manualEndptToPx2 = _slicedToArray(_this$manualEndptToPx, 2),
              x1 = _this$manualEndptToPx2[0],
              y1 = _this$manualEndptToPx2[1];
            var _this$manualEndptToPx3 = this.manualEndptToPx(edge.target()[0], tgtManEndpt),
              _this$manualEndptToPx4 = _slicedToArray(_this$manualEndptToPx3, 2),
              x2 = _this$manualEndptToPx4[0],
              y2 = _this$manualEndptToPx4[1];
            var endPts = {
              x1: x1,
              y1: y1,
              x2: x2,
              y2: y2
            };
            vectorNormInverse = recalcVectorNormInverse(x1, y1, x2, y2);
            midptPts = endPts;
          } else {
            warn("Edge ".concat(edge.id(), " has edge-distances:endpoints specified without manual endpoints specified via source-endpoint and target-endpoint.  Falling back on edge-distances:intersection (default)."));
            midptPts = intersectionPts; // back to default
          }

          break;
        }
    }
    return {
      midptPts: midptPts,
      vectorNormInverse: vectorNormInverse
    };
  };
  BRp$c.findHaystackPoints = function (edges) {
    for (var i = 0; i < edges.length; i++) {
      var edge = edges[i];
      var _p = edge._private;
      var rs = _p.rscratch;
      if (!rs.haystack) {
        var angle = Math.random() * 2 * Math.PI;
        rs.source = {
          x: Math.cos(angle),
          y: Math.sin(angle)
        };
        angle = Math.random() * 2 * Math.PI;
        rs.target = {
          x: Math.cos(angle),
          y: Math.sin(angle)
        };
      }
      var src = _p.source;
      var tgt = _p.target;
      var srcPos = src.position();
      var tgtPos = tgt.position();
      var srcW = src.width();
      var tgtW = tgt.width();
      var srcH = src.height();
      var tgtH = tgt.height();
      var radius = edge.pstyle('haystack-radius').value;
      var halfRadius = radius / 2; // b/c have to half width/height

      rs.haystackPts = rs.allpts = [rs.source.x * srcW * halfRadius + srcPos.x, rs.source.y * srcH * halfRadius + srcPos.y, rs.target.x * tgtW * halfRadius + tgtPos.x, rs.target.y * tgtH * halfRadius + tgtPos.y];
      rs.midX = (rs.allpts[0] + rs.allpts[2]) / 2;
      rs.midY = (rs.allpts[1] + rs.allpts[3]) / 2;

      // always override as haystack in case set to different type previously
      rs.edgeType = 'haystack';
      rs.haystack = true;
      this.storeEdgeProjections(edge);
      this.calculateArrowAngles(edge);
      this.recalculateEdgeLabelProjections(edge);
      this.calculateLabelAngles(edge);
    }
  };
  BRp$c.findSegmentsPoints = function (edge, pairInfo) {
    // Segments (multiple straight lines)

    var rs = edge._private.rscratch;
    var segmentWs = edge.pstyle('segment-weights');
    var segmentDs = edge.pstyle('segment-distances');
    var segmentsN = Math.min(segmentWs.pfValue.length, segmentDs.pfValue.length);
    rs.edgeType = 'segments';
    rs.segpts = [];
    for (var s = 0; s < segmentsN; s++) {
      var w = segmentWs.pfValue[s];
      var d = segmentDs.pfValue[s];
      var w1 = 1 - w;
      var w2 = w;
      var _this$findMidptPtsEtc = this.findMidptPtsEtc(edge, pairInfo),
        midptPts = _this$findMidptPtsEtc.midptPts,
        vectorNormInverse = _this$findMidptPtsEtc.vectorNormInverse;
      var adjustedMidpt = {
        x: midptPts.x1 * w1 + midptPts.x2 * w2,
        y: midptPts.y1 * w1 + midptPts.y2 * w2
      };
      rs.segpts.push(adjustedMidpt.x + vectorNormInverse.x * d, adjustedMidpt.y + vectorNormInverse.y * d);
    }
  };
  BRp$c.findLoopPoints = function (edge, pairInfo, i, edgeIsUnbundled) {
    // Self-edge

    var rs = edge._private.rscratch;
    var dirCounts = pairInfo.dirCounts,
      srcPos = pairInfo.srcPos;
    var ctrlptDists = edge.pstyle('control-point-distances');
    var ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[0] : undefined;
    var loopDir = edge.pstyle('loop-direction').pfValue;
    var loopSwp = edge.pstyle('loop-sweep').pfValue;
    var stepSize = edge.pstyle('control-point-step-size').pfValue;
    rs.edgeType = 'self';
    var j = i;
    var loopDist = stepSize;
    if (edgeIsUnbundled) {
      j = 0;
      loopDist = ctrlptDist;
    }
    var loopAngle = loopDir - Math.PI / 2;
    var outAngle = loopAngle - loopSwp / 2;
    var inAngle = loopAngle + loopSwp / 2;

    // increase by step size for overlapping loops, keyed on direction and sweep values
    var dc = String(loopDir + '_' + loopSwp);
    j = dirCounts[dc] === undefined ? dirCounts[dc] = 0 : ++dirCounts[dc];
    rs.ctrlpts = [srcPos.x + Math.cos(outAngle) * 1.4 * loopDist * (j / 3 + 1), srcPos.y + Math.sin(outAngle) * 1.4 * loopDist * (j / 3 + 1), srcPos.x + Math.cos(inAngle) * 1.4 * loopDist * (j / 3 + 1), srcPos.y + Math.sin(inAngle) * 1.4 * loopDist * (j / 3 + 1)];
  };
  BRp$c.findCompoundLoopPoints = function (edge, pairInfo, i, edgeIsUnbundled) {
    // Compound edge

    var rs = edge._private.rscratch;
    rs.edgeType = 'compound';
    var srcPos = pairInfo.srcPos,
      tgtPos = pairInfo.tgtPos,
      srcW = pairInfo.srcW,
      srcH = pairInfo.srcH,
      tgtW = pairInfo.tgtW,
      tgtH = pairInfo.tgtH;
    var stepSize = edge.pstyle('control-point-step-size').pfValue;
    var ctrlptDists = edge.pstyle('control-point-distances');
    var ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[0] : undefined;
    var j = i;
    var loopDist = stepSize;
    if (edgeIsUnbundled) {
      j = 0;
      loopDist = ctrlptDist;
    }
    var loopW = 50;
    var loopaPos = {
      x: srcPos.x - srcW / 2,
      y: srcPos.y - srcH / 2
    };
    var loopbPos = {
      x: tgtPos.x - tgtW / 2,
      y: tgtPos.y - tgtH / 2
    };
    var loopPos = {
      x: Math.min(loopaPos.x, loopbPos.x),
      y: Math.min(loopaPos.y, loopbPos.y)
    };

    // avoids cases with impossible beziers
    var minCompoundStretch = 0.5;
    var compoundStretchA = Math.max(minCompoundStretch, Math.log(srcW * 0.01));
    var compoundStretchB = Math.max(minCompoundStretch, Math.log(tgtW * 0.01));
    rs.ctrlpts = [loopPos.x, loopPos.y - (1 + Math.pow(loopW, 1.12) / 100) * loopDist * (j / 3 + 1) * compoundStretchA, loopPos.x - (1 + Math.pow(loopW, 1.12) / 100) * loopDist * (j / 3 + 1) * compoundStretchB, loopPos.y];
  };
  BRp$c.findStraightEdgePoints = function (edge) {
    // Straight edge within bundle

    edge._private.rscratch.edgeType = 'straight';
  };
  BRp$c.findBezierPoints = function (edge, pairInfo, i, edgeIsUnbundled, edgeIsSwapped) {
    var rs = edge._private.rscratch;
    var stepSize = edge.pstyle('control-point-step-size').pfValue;
    var ctrlptDists = edge.pstyle('control-point-distances');
    var ctrlptWs = edge.pstyle('control-point-weights');
    var bezierN = ctrlptDists && ctrlptWs ? Math.min(ctrlptDists.value.length, ctrlptWs.value.length) : 1;
    var ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[0] : undefined;
    var ctrlptWeight = ctrlptWs.value[0];

    // (Multi)bezier

    var multi = edgeIsUnbundled;
    rs.edgeType = multi ? 'multibezier' : 'bezier';
    rs.ctrlpts = [];
    for (var b = 0; b < bezierN; b++) {
      var normctrlptDist = (0.5 - pairInfo.eles.length / 2 + i) * stepSize * (edgeIsSwapped ? -1 : 1);
      var manctrlptDist = void 0;
      var sign = signum(normctrlptDist);
      if (multi) {
        ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[b] : stepSize; // fall back on step size
        ctrlptWeight = ctrlptWs.value[b];
      }
      if (edgeIsUnbundled) {
        // multi or single unbundled
        manctrlptDist = ctrlptDist;
      } else {
        manctrlptDist = ctrlptDist !== undefined ? sign * ctrlptDist : undefined;
      }
      var distanceFromMidpoint = manctrlptDist !== undefined ? manctrlptDist : normctrlptDist;
      var w1 = 1 - ctrlptWeight;
      var w2 = ctrlptWeight;
      var _this$findMidptPtsEtc2 = this.findMidptPtsEtc(edge, pairInfo),
        midptPts = _this$findMidptPtsEtc2.midptPts,
        vectorNormInverse = _this$findMidptPtsEtc2.vectorNormInverse;
      var adjustedMidpt = {
        x: midptPts.x1 * w1 + midptPts.x2 * w2,
        y: midptPts.y1 * w1 + midptPts.y2 * w2
      };
      rs.ctrlpts.push(adjustedMidpt.x + vectorNormInverse.x * distanceFromMidpoint, adjustedMidpt.y + vectorNormInverse.y * distanceFromMidpoint);
    }
  };
  BRp$c.findTaxiPoints = function (edge, pairInfo) {
    // Taxicab geometry with two turns maximum

    var rs = edge._private.rscratch;
    rs.edgeType = 'segments';
    var VERTICAL = 'vertical';
    var HORIZONTAL = 'horizontal';
    var LEFTWARD = 'leftward';
    var RIGHTWARD = 'rightward';
    var DOWNWARD = 'downward';
    var UPWARD = 'upward';
    var AUTO = 'auto';
    var posPts = pairInfo.posPts,
      srcW = pairInfo.srcW,
      srcH = pairInfo.srcH,
      tgtW = pairInfo.tgtW,
      tgtH = pairInfo.tgtH;
    var edgeDistances = edge.pstyle('edge-distances').value;
    var dIncludesNodeBody = edgeDistances !== 'node-position';
    var taxiDir = edge.pstyle('taxi-direction').value;
    var rawTaxiDir = taxiDir; // unprocessed value
    var taxiTurn = edge.pstyle('taxi-turn');
    var turnIsPercent = taxiTurn.units === '%';
    var taxiTurnPfVal = taxiTurn.pfValue;
    var turnIsNegative = taxiTurnPfVal < 0; // i.e. from target side
    var minD = edge.pstyle('taxi-turn-min-distance').pfValue;
    var dw = dIncludesNodeBody ? (srcW + tgtW) / 2 : 0;
    var dh = dIncludesNodeBody ? (srcH + tgtH) / 2 : 0;
    var pdx = posPts.x2 - posPts.x1;
    var pdy = posPts.y2 - posPts.y1;

    // take away the effective w/h from the magnitude of the delta value
    var subDWH = function subDWH(dxy, dwh) {
      if (dxy > 0) {
        return Math.max(dxy - dwh, 0);
      } else {
        return Math.min(dxy + dwh, 0);
      }
    };
    var dx = subDWH(pdx, dw);
    var dy = subDWH(pdy, dh);
    var isExplicitDir = false;
    if (rawTaxiDir === AUTO) {
      taxiDir = Math.abs(dx) > Math.abs(dy) ? HORIZONTAL : VERTICAL;
    } else if (rawTaxiDir === UPWARD || rawTaxiDir === DOWNWARD) {
      taxiDir = VERTICAL;
      isExplicitDir = true;
    } else if (rawTaxiDir === LEFTWARD || rawTaxiDir === RIGHTWARD) {
      taxiDir = HORIZONTAL;
      isExplicitDir = true;
    }
    var isVert = taxiDir === VERTICAL;
    var l = isVert ? dy : dx;
    var pl = isVert ? pdy : pdx;
    var sgnL = signum(pl);
    var forcedDir = false;
    if (!(isExplicitDir && (turnIsPercent || turnIsNegative)) // forcing in this case would cause weird growing in the opposite direction
    && (rawTaxiDir === DOWNWARD && pl < 0 || rawTaxiDir === UPWARD && pl > 0 || rawTaxiDir === LEFTWARD && pl > 0 || rawTaxiDir === RIGHTWARD && pl < 0)) {
      sgnL *= -1;
      l = sgnL * Math.abs(l);
      forcedDir = true;
    }
    var d;
    if (turnIsPercent) {
      var p = taxiTurnPfVal < 0 ? 1 + taxiTurnPfVal : taxiTurnPfVal;
      d = p * l;
    } else {
      var k = taxiTurnPfVal < 0 ? l : 0;
      d = k + taxiTurnPfVal * sgnL;
    }
    var getIsTooClose = function getIsTooClose(d) {
      return Math.abs(d) < minD || Math.abs(d) >= Math.abs(l);
    };
    var isTooCloseSrc = getIsTooClose(d);
    var isTooCloseTgt = getIsTooClose(Math.abs(l) - Math.abs(d));
    var isTooClose = isTooCloseSrc || isTooCloseTgt;
    if (isTooClose && !forcedDir) {
      // non-ideal routing
      if (isVert) {
        // vertical fallbacks
        var lShapeInsideSrc = Math.abs(pl) <= srcH / 2;
        var lShapeInsideTgt = Math.abs(pdx) <= tgtW / 2;
        if (lShapeInsideSrc) {
          // horizontal Z-shape (direction not respected)
          var x = (posPts.x1 + posPts.x2) / 2;
          var y1 = posPts.y1,
            y2 = posPts.y2;
          rs.segpts = [x, y1, x, y2];
        } else if (lShapeInsideTgt) {
          // vertical Z-shape (distance not respected)
          var y = (posPts.y1 + posPts.y2) / 2;
          var x1 = posPts.x1,
            x2 = posPts.x2;
          rs.segpts = [x1, y, x2, y];
        } else {
          // L-shape fallback (turn distance not respected, but works well with tree siblings)
          rs.segpts = [posPts.x1, posPts.y2];
        }
      } else {
        // horizontal fallbacks
        var _lShapeInsideSrc = Math.abs(pl) <= srcW / 2;
        var _lShapeInsideTgt = Math.abs(pdy) <= tgtH / 2;
        if (_lShapeInsideSrc) {
          // vertical Z-shape (direction not respected)
          var _y = (posPts.y1 + posPts.y2) / 2;
          var _x = posPts.x1,
            _x2 = posPts.x2;
          rs.segpts = [_x, _y, _x2, _y];
        } else if (_lShapeInsideTgt) {
          // horizontal Z-shape (turn distance not respected)
          var _x3 = (posPts.x1 + posPts.x2) / 2;
          var _y2 = posPts.y1,
            _y3 = posPts.y2;
          rs.segpts = [_x3, _y2, _x3, _y3];
        } else {
          // L-shape (turn distance not respected, but works well for tree siblings)
          rs.segpts = [posPts.x2, posPts.y1];
        }
      }
    } else {
      // ideal routing
      if (isVert) {
        var _y4 = posPts.y1 + d + (dIncludesNodeBody ? srcH / 2 * sgnL : 0);
        var _x4 = posPts.x1,
          _x5 = posPts.x2;
        rs.segpts = [_x4, _y4, _x5, _y4];
      } else {
        // horizontal
        var _x6 = posPts.x1 + d + (dIncludesNodeBody ? srcW / 2 * sgnL : 0);
        var _y5 = posPts.y1,
          _y6 = posPts.y2;
        rs.segpts = [_x6, _y5, _x6, _y6];
      }
    }
  };
  BRp$c.tryToCorrectInvalidPoints = function (edge, pairInfo) {
    var rs = edge._private.rscratch;

    // can only correct beziers for now...
    if (rs.edgeType === 'bezier') {
      var srcPos = pairInfo.srcPos,
        tgtPos = pairInfo.tgtPos,
        srcW = pairInfo.srcW,
        srcH = pairInfo.srcH,
        tgtW = pairInfo.tgtW,
        tgtH = pairInfo.tgtH,
        srcShape = pairInfo.srcShape,
        tgtShape = pairInfo.tgtShape;
      var badStart = !number$1(rs.startX) || !number$1(rs.startY);
      var badAStart = !number$1(rs.arrowStartX) || !number$1(rs.arrowStartY);
      var badEnd = !number$1(rs.endX) || !number$1(rs.endY);
      var badAEnd = !number$1(rs.arrowEndX) || !number$1(rs.arrowEndY);
      var minCpADistFactor = 3;
      var arrowW = this.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.arrowShapeWidth;
      var minCpADist = minCpADistFactor * arrowW;
      var startACpDist = dist({
        x: rs.ctrlpts[0],
        y: rs.ctrlpts[1]
      }, {
        x: rs.startX,
        y: rs.startY
      });
      var closeStartACp = startACpDist < minCpADist;
      var endACpDist = dist({
        x: rs.ctrlpts[0],
        y: rs.ctrlpts[1]
      }, {
        x: rs.endX,
        y: rs.endY
      });
      var closeEndACp = endACpDist < minCpADist;
      var overlapping = false;
      if (badStart || badAStart || closeStartACp) {
        overlapping = true;

        // project control point along line from src centre to outside the src shape
        // (otherwise intersection will yield nothing)
        var cpD = {
          // delta
          x: rs.ctrlpts[0] - srcPos.x,
          y: rs.ctrlpts[1] - srcPos.y
        };
        var cpL = Math.sqrt(cpD.x * cpD.x + cpD.y * cpD.y); // length of line
        var cpM = {
          // normalised delta
          x: cpD.x / cpL,
          y: cpD.y / cpL
        };
        var radius = Math.max(srcW, srcH);
        var cpProj = {
          // *2 radius guarantees outside shape
          x: rs.ctrlpts[0] + cpM.x * 2 * radius,
          y: rs.ctrlpts[1] + cpM.y * 2 * radius
        };
        var srcCtrlPtIntn = srcShape.intersectLine(srcPos.x, srcPos.y, srcW, srcH, cpProj.x, cpProj.y, 0);
        if (closeStartACp) {
          rs.ctrlpts[0] = rs.ctrlpts[0] + cpM.x * (minCpADist - startACpDist);
          rs.ctrlpts[1] = rs.ctrlpts[1] + cpM.y * (minCpADist - startACpDist);
        } else {
          rs.ctrlpts[0] = srcCtrlPtIntn[0] + cpM.x * minCpADist;
          rs.ctrlpts[1] = srcCtrlPtIntn[1] + cpM.y * minCpADist;
        }
      }
      if (badEnd || badAEnd || closeEndACp) {
        overlapping = true;

        // project control point along line from tgt centre to outside the tgt shape
        // (otherwise intersection will yield nothing)
        var _cpD = {
          // delta
          x: rs.ctrlpts[0] - tgtPos.x,
          y: rs.ctrlpts[1] - tgtPos.y
        };
        var _cpL = Math.sqrt(_cpD.x * _cpD.x + _cpD.y * _cpD.y); // length of line
        var _cpM = {
          // normalised delta
          x: _cpD.x / _cpL,
          y: _cpD.y / _cpL
        };
        var _radius = Math.max(srcW, srcH);
        var _cpProj = {
          // *2 radius guarantees outside shape
          x: rs.ctrlpts[0] + _cpM.x * 2 * _radius,
          y: rs.ctrlpts[1] + _cpM.y * 2 * _radius
        };
        var tgtCtrlPtIntn = tgtShape.intersectLine(tgtPos.x, tgtPos.y, tgtW, tgtH, _cpProj.x, _cpProj.y, 0);
        if (closeEndACp) {
          rs.ctrlpts[0] = rs.ctrlpts[0] + _cpM.x * (minCpADist - endACpDist);
          rs.ctrlpts[1] = rs.ctrlpts[1] + _cpM.y * (minCpADist - endACpDist);
        } else {
          rs.ctrlpts[0] = tgtCtrlPtIntn[0] + _cpM.x * minCpADist;
          rs.ctrlpts[1] = tgtCtrlPtIntn[1] + _cpM.y * minCpADist;
        }
      }
      if (overlapping) {
        // recalc endpts
        this.findEndpoints(edge);
      }
    }
  };
  BRp$c.storeAllpts = function (edge) {
    var rs = edge._private.rscratch;
    if (rs.edgeType === 'multibezier' || rs.edgeType === 'bezier' || rs.edgeType === 'self' || rs.edgeType === 'compound') {
      rs.allpts = [];
      rs.allpts.push(rs.startX, rs.startY);
      for (var b = 0; b + 1 < rs.ctrlpts.length; b += 2) {
        // ctrl pt itself
        rs.allpts.push(rs.ctrlpts[b], rs.ctrlpts[b + 1]);

        // the midpt between ctrlpts as intermediate destination pts
        if (b + 3 < rs.ctrlpts.length) {
          rs.allpts.push((rs.ctrlpts[b] + rs.ctrlpts[b + 2]) / 2, (rs.ctrlpts[b + 1] + rs.ctrlpts[b + 3]) / 2);
        }
      }
      rs.allpts.push(rs.endX, rs.endY);
      var m, mt;
      if (rs.ctrlpts.length / 2 % 2 === 0) {
        m = rs.allpts.length / 2 - 1;
        rs.midX = rs.allpts[m];
        rs.midY = rs.allpts[m + 1];
      } else {
        m = rs.allpts.length / 2 - 3;
        mt = 0.5;
        rs.midX = qbezierAt(rs.allpts[m], rs.allpts[m + 2], rs.allpts[m + 4], mt);
        rs.midY = qbezierAt(rs.allpts[m + 1], rs.allpts[m + 3], rs.allpts[m + 5], mt);
      }
    } else if (rs.edgeType === 'straight') {
      // need to calc these after endpts
      rs.allpts = [rs.startX, rs.startY, rs.endX, rs.endY];

      // default midpt for labels etc
      rs.midX = (rs.startX + rs.endX + rs.arrowStartX + rs.arrowEndX) / 4;
      rs.midY = (rs.startY + rs.endY + rs.arrowStartY + rs.arrowEndY) / 4;
    } else if (rs.edgeType === 'segments') {
      rs.allpts = [];
      rs.allpts.push(rs.startX, rs.startY);
      rs.allpts.push.apply(rs.allpts, rs.segpts);
      rs.allpts.push(rs.endX, rs.endY);
      if (rs.segpts.length % 4 === 0) {
        var i2 = rs.segpts.length / 2;
        var i1 = i2 - 2;
        rs.midX = (rs.segpts[i1] + rs.segpts[i2]) / 2;
        rs.midY = (rs.segpts[i1 + 1] + rs.segpts[i2 + 1]) / 2;
      } else {
        var _i = rs.segpts.length / 2 - 1;
        rs.midX = rs.segpts[_i];
        rs.midY = rs.segpts[_i + 1];
      }
    }
  };
  BRp$c.checkForInvalidEdgeWarning = function (edge) {
    var rs = edge[0]._private.rscratch;
    if (rs.nodesOverlap || number$1(rs.startX) && number$1(rs.startY) && number$1(rs.endX) && number$1(rs.endY)) {
      rs.loggedErr = false;
    } else {
      if (!rs.loggedErr) {
        rs.loggedErr = true;
        warn('Edge `' + edge.id() + '` has invalid endpoints and so it is impossible to draw.  Adjust your edge style (e.g. control points) accordingly or use an alternative edge type.  This is expected behaviour when the source node and the target node overlap.');
      }
    }
  };
  BRp$c.findEdgeControlPoints = function (edges) {
    var _this = this;
    if (!edges || edges.length === 0) {
      return;
    }
    var r = this;
    var cy = r.cy;
    var hasCompounds = cy.hasCompoundNodes();
    var hashTable = {
      map: new Map$2(),
      get: function get(pairId) {
        var map2 = this.map.get(pairId[0]);
        if (map2 != null) {
          return map2.get(pairId[1]);
        } else {
          return null;
        }
      },
      set: function set(pairId, val) {
        var map2 = this.map.get(pairId[0]);
        if (map2 == null) {
          map2 = new Map$2();
          this.map.set(pairId[0], map2);
        }
        map2.set(pairId[1], val);
      }
    };
    var pairIds = [];
    var haystackEdges = [];

    // create a table of edge (src, tgt) => list of edges between them
    for (var i = 0; i < edges.length; i++) {
      var edge = edges[i];
      var _p = edge._private;
      var curveStyle = edge.pstyle('curve-style').value;

      // ignore edges who are not to be displayed
      // they shouldn't take up space
      if (edge.removed() || !edge.takesUpSpace()) {
        continue;
      }
      if (curveStyle === 'haystack') {
        haystackEdges.push(edge);
        continue;
      }
      var edgeIsUnbundled = curveStyle === 'unbundled-bezier' || curveStyle === 'segments' || curveStyle === 'straight' || curveStyle === 'straight-triangle' || curveStyle === 'taxi';
      var edgeIsBezier = curveStyle === 'unbundled-bezier' || curveStyle === 'bezier';
      var src = _p.source;
      var tgt = _p.target;
      var srcIndex = src.poolIndex();
      var tgtIndex = tgt.poolIndex();
      var pairId = [srcIndex, tgtIndex].sort();
      var tableEntry = hashTable.get(pairId);
      if (tableEntry == null) {
        tableEntry = {
          eles: []
        };
        hashTable.set(pairId, tableEntry);
        pairIds.push(pairId);
      }
      tableEntry.eles.push(edge);
      if (edgeIsUnbundled) {
        tableEntry.hasUnbundled = true;
      }
      if (edgeIsBezier) {
        tableEntry.hasBezier = true;
      }
    }

    // for each pair (src, tgt), create the ctrl pts
    // Nested for loop is OK; total number of iterations for both loops = edgeCount
    var _loop = function _loop(p) {
      var pairId = pairIds[p];
      var pairInfo = hashTable.get(pairId);
      var swappedpairInfo = void 0;
      if (!pairInfo.hasUnbundled) {
        var pllEdges = pairInfo.eles[0].parallelEdges().filter(function (e) {
          return e.isBundledBezier();
        });
        clearArray(pairInfo.eles);
        pllEdges.forEach(function (edge) {
          return pairInfo.eles.push(edge);
        });

        // for each pair id, the edges should be sorted by index
        pairInfo.eles.sort(function (edge1, edge2) {
          return edge1.poolIndex() - edge2.poolIndex();
        });
      }
      var firstEdge = pairInfo.eles[0];
      var src = firstEdge.source();
      var tgt = firstEdge.target();

      // make sure src/tgt distinction is consistent w.r.t. pairId
      if (src.poolIndex() > tgt.poolIndex()) {
        var temp = src;
        src = tgt;
        tgt = temp;
      }
      var srcPos = pairInfo.srcPos = src.position();
      var tgtPos = pairInfo.tgtPos = tgt.position();
      var srcW = pairInfo.srcW = src.outerWidth();
      var srcH = pairInfo.srcH = src.outerHeight();
      var tgtW = pairInfo.tgtW = tgt.outerWidth();
      var tgtH = pairInfo.tgtH = tgt.outerHeight();
      var srcShape = pairInfo.srcShape = r.nodeShapes[_this.getNodeShape(src)];
      var tgtShape = pairInfo.tgtShape = r.nodeShapes[_this.getNodeShape(tgt)];
      pairInfo.dirCounts = {
        'north': 0,
        'west': 0,
        'south': 0,
        'east': 0,
        'northwest': 0,
        'southwest': 0,
        'northeast': 0,
        'southeast': 0
      };
      for (var _i2 = 0; _i2 < pairInfo.eles.length; _i2++) {
        var _edge = pairInfo.eles[_i2];
        var rs = _edge[0]._private.rscratch;
        var _curveStyle = _edge.pstyle('curve-style').value;
        var _edgeIsUnbundled = _curveStyle === 'unbundled-bezier' || _curveStyle === 'segments' || _curveStyle === 'taxi';

        // whether the normalised pair order is the reverse of the edge's src-tgt order
        var edgeIsSwapped = !src.same(_edge.source());
        if (!pairInfo.calculatedIntersection && src !== tgt && (pairInfo.hasBezier || pairInfo.hasUnbundled)) {
          pairInfo.calculatedIntersection = true;

          // pt outside src shape to calc distance/displacement from src to tgt
          var srcOutside = srcShape.intersectLine(srcPos.x, srcPos.y, srcW, srcH, tgtPos.x, tgtPos.y, 0);
          var srcIntn = pairInfo.srcIntn = srcOutside;

          // pt outside tgt shape to calc distance/displacement from src to tgt
          var tgtOutside = tgtShape.intersectLine(tgtPos.x, tgtPos.y, tgtW, tgtH, srcPos.x, srcPos.y, 0);
          var tgtIntn = pairInfo.tgtIntn = tgtOutside;
          var intersectionPts = pairInfo.intersectionPts = {
            x1: srcOutside[0],
            x2: tgtOutside[0],
            y1: srcOutside[1],
            y2: tgtOutside[1]
          };
          var posPts = pairInfo.posPts = {
            x1: srcPos.x,
            x2: tgtPos.x,
            y1: srcPos.y,
            y2: tgtPos.y
          };
          var dy = tgtOutside[1] - srcOutside[1];
          var dx = tgtOutside[0] - srcOutside[0];
          var l = Math.sqrt(dx * dx + dy * dy);
          var vector = pairInfo.vector = {
            x: dx,
            y: dy
          };
          var vectorNorm = pairInfo.vectorNorm = {
            x: vector.x / l,
            y: vector.y / l
          };
          var vectorNormInverse = {
            x: -vectorNorm.y,
            y: vectorNorm.x
          };

          // if node shapes overlap, then no ctrl pts to draw
          pairInfo.nodesOverlap = !number$1(l) || tgtShape.checkPoint(srcOutside[0], srcOutside[1], 0, tgtW, tgtH, tgtPos.x, tgtPos.y) || srcShape.checkPoint(tgtOutside[0], tgtOutside[1], 0, srcW, srcH, srcPos.x, srcPos.y);
          pairInfo.vectorNormInverse = vectorNormInverse;
          swappedpairInfo = {
            nodesOverlap: pairInfo.nodesOverlap,
            dirCounts: pairInfo.dirCounts,
            calculatedIntersection: true,
            hasBezier: pairInfo.hasBezier,
            hasUnbundled: pairInfo.hasUnbundled,
            eles: pairInfo.eles,
            srcPos: tgtPos,
            tgtPos: srcPos,
            srcW: tgtW,
            srcH: tgtH,
            tgtW: srcW,
            tgtH: srcH,
            srcIntn: tgtIntn,
            tgtIntn: srcIntn,
            srcShape: tgtShape,
            tgtShape: srcShape,
            posPts: {
              x1: posPts.x2,
              y1: posPts.y2,
              x2: posPts.x1,
              y2: posPts.y1
            },
            intersectionPts: {
              x1: intersectionPts.x2,
              y1: intersectionPts.y2,
              x2: intersectionPts.x1,
              y2: intersectionPts.y1
            },
            vector: {
              x: -vector.x,
              y: -vector.y
            },
            vectorNorm: {
              x: -vectorNorm.x,
              y: -vectorNorm.y
            },
            vectorNormInverse: {
              x: -vectorNormInverse.x,
              y: -vectorNormInverse.y
            }
          };
        }
        var passedPairInfo = edgeIsSwapped ? swappedpairInfo : pairInfo;
        rs.nodesOverlap = passedPairInfo.nodesOverlap;
        rs.srcIntn = passedPairInfo.srcIntn;
        rs.tgtIntn = passedPairInfo.tgtIntn;
        if (hasCompounds && (src.isParent() || src.isChild() || tgt.isParent() || tgt.isChild()) && (src.parents().anySame(tgt) || tgt.parents().anySame(src) || src.same(tgt) && src.isParent())) {
          _this.findCompoundLoopPoints(_edge, passedPairInfo, _i2, _edgeIsUnbundled);
        } else if (src === tgt) {
          _this.findLoopPoints(_edge, passedPairInfo, _i2, _edgeIsUnbundled);
        } else if (_curveStyle === 'segments') {
          _this.findSegmentsPoints(_edge, passedPairInfo);
        } else if (_curveStyle === 'taxi') {
          _this.findTaxiPoints(_edge, passedPairInfo);
        } else if (_curveStyle === 'straight' || !_edgeIsUnbundled && pairInfo.eles.length % 2 === 1 && _i2 === Math.floor(pairInfo.eles.length / 2)) {
          _this.findStraightEdgePoints(_edge);
        } else {
          _this.findBezierPoints(_edge, passedPairInfo, _i2, _edgeIsUnbundled, edgeIsSwapped);
        }
        _this.findEndpoints(_edge);
        _this.tryToCorrectInvalidPoints(_edge, passedPairInfo);
        _this.checkForInvalidEdgeWarning(_edge);
        _this.storeAllpts(_edge);
        _this.storeEdgeProjections(_edge);
        _this.calculateArrowAngles(_edge);
        _this.recalculateEdgeLabelProjections(_edge);
        _this.calculateLabelAngles(_edge);
      } // for pair edges
    };
    for (var p = 0; p < pairIds.length; p++) {
      _loop(p);
    } // for pair ids

    // haystacks avoid the expense of pairInfo stuff (intersections etc.)
    this.findHaystackPoints(haystackEdges);
  };
  function getPts(pts) {
    var retPts = [];
    if (pts == null) {
      return;
    }
    for (var i = 0; i < pts.length; i += 2) {
      var x = pts[i];
      var y = pts[i + 1];
      retPts.push({
        x: x,
        y: y
      });
    }
    return retPts;
  }
  BRp$c.getSegmentPoints = function (edge) {
    var rs = edge[0]._private.rscratch;
    var type = rs.edgeType;
    if (type === 'segments') {
      this.recalculateRenderedStyle(edge);
      return getPts(rs.segpts);
    }
  };
  BRp$c.getControlPoints = function (edge) {
    var rs = edge[0]._private.rscratch;
    var type = rs.edgeType;
    if (type === 'bezier' || type === 'multibezier' || type === 'self' || type === 'compound') {
      this.recalculateRenderedStyle(edge);
      return getPts(rs.ctrlpts);
    }
  };
  BRp$c.getEdgeMidpoint = function (edge) {
    var rs = edge[0]._private.rscratch;
    this.recalculateRenderedStyle(edge);
    return {
      x: rs.midX,
      y: rs.midY
    };
  };

  var BRp$b = {};
  BRp$b.manualEndptToPx = function (node, prop) {
    var r = this;
    var npos = node.position();
    var w = node.outerWidth();
    var h = node.outerHeight();
    if (prop.value.length === 2) {
      var p = [prop.pfValue[0], prop.pfValue[1]];
      if (prop.units[0] === '%') {
        p[0] = p[0] * w;
      }
      if (prop.units[1] === '%') {
        p[1] = p[1] * h;
      }
      p[0] += npos.x;
      p[1] += npos.y;
      return p;
    } else {
      var angle = prop.pfValue[0];
      angle = -Math.PI / 2 + angle; // start at 12 o'clock

      var l = 2 * Math.max(w, h);
      var _p = [npos.x + Math.cos(angle) * l, npos.y + Math.sin(angle) * l];
      return r.nodeShapes[this.getNodeShape(node)].intersectLine(npos.x, npos.y, w, h, _p[0], _p[1], 0);
    }
  };
  BRp$b.findEndpoints = function (edge) {
    var r = this;
    var intersect;
    var source = edge.source()[0];
    var target = edge.target()[0];
    var srcPos = source.position();
    var tgtPos = target.position();
    var tgtArShape = edge.pstyle('target-arrow-shape').value;
    var srcArShape = edge.pstyle('source-arrow-shape').value;
    var tgtDist = edge.pstyle('target-distance-from-node').pfValue;
    var srcDist = edge.pstyle('source-distance-from-node').pfValue;
    var curveStyle = edge.pstyle('curve-style').value;
    var rs = edge._private.rscratch;
    var et = rs.edgeType;
    var taxi = curveStyle === 'taxi';
    var self = et === 'self' || et === 'compound';
    var bezier = et === 'bezier' || et === 'multibezier' || self;
    var multi = et !== 'bezier';
    var lines = et === 'straight' || et === 'segments';
    var segments = et === 'segments';
    var hasEndpts = bezier || multi || lines;
    var overrideEndpts = self || taxi;
    var srcManEndpt = edge.pstyle('source-endpoint');
    var srcManEndptVal = overrideEndpts ? 'outside-to-node' : srcManEndpt.value;
    var tgtManEndpt = edge.pstyle('target-endpoint');
    var tgtManEndptVal = overrideEndpts ? 'outside-to-node' : tgtManEndpt.value;
    rs.srcManEndpt = srcManEndpt;
    rs.tgtManEndpt = tgtManEndpt;
    var p1; // last known point of edge on target side
    var p2; // last known point of edge on source side

    var p1_i; // point to intersect with target shape
    var p2_i; // point to intersect with source shape

    if (bezier) {
      var cpStart = [rs.ctrlpts[0], rs.ctrlpts[1]];
      var cpEnd = multi ? [rs.ctrlpts[rs.ctrlpts.length - 2], rs.ctrlpts[rs.ctrlpts.length - 1]] : cpStart;
      p1 = cpEnd;
      p2 = cpStart;
    } else if (lines) {
      var srcArrowFromPt = !segments ? [tgtPos.x, tgtPos.y] : rs.segpts.slice(0, 2);
      var tgtArrowFromPt = !segments ? [srcPos.x, srcPos.y] : rs.segpts.slice(rs.segpts.length - 2);
      p1 = tgtArrowFromPt;
      p2 = srcArrowFromPt;
    }
    if (tgtManEndptVal === 'inside-to-node') {
      intersect = [tgtPos.x, tgtPos.y];
    } else if (tgtManEndpt.units) {
      intersect = this.manualEndptToPx(target, tgtManEndpt);
    } else if (tgtManEndptVal === 'outside-to-line') {
      intersect = rs.tgtIntn; // use cached value from ctrlpt calc
    } else {
      if (tgtManEndptVal === 'outside-to-node' || tgtManEndptVal === 'outside-to-node-or-label') {
        p1_i = p1;
      } else if (tgtManEndptVal === 'outside-to-line' || tgtManEndptVal === 'outside-to-line-or-label') {
        p1_i = [srcPos.x, srcPos.y];
      }
      intersect = r.nodeShapes[this.getNodeShape(target)].intersectLine(tgtPos.x, tgtPos.y, target.outerWidth(), target.outerHeight(), p1_i[0], p1_i[1], 0);
      if (tgtManEndptVal === 'outside-to-node-or-label' || tgtManEndptVal === 'outside-to-line-or-label') {
        var trs = target._private.rscratch;
        var lw = trs.labelWidth;
        var lh = trs.labelHeight;
        var lx = trs.labelX;
        var ly = trs.labelY;
        var lw2 = lw / 2;
        var lh2 = lh / 2;
        var va = target.pstyle('text-valign').value;
        if (va === 'top') {
          ly -= lh2;
        } else if (va === 'bottom') {
          ly += lh2;
        }
        var ha = target.pstyle('text-halign').value;
        if (ha === 'left') {
          lx -= lw2;
        } else if (ha === 'right') {
          lx += lw2;
        }
        var labelIntersect = polygonIntersectLine(p1_i[0], p1_i[1], [lx - lw2, ly - lh2, lx + lw2, ly - lh2, lx + lw2, ly + lh2, lx - lw2, ly + lh2], tgtPos.x, tgtPos.y);
        if (labelIntersect.length > 0) {
          var refPt = srcPos;
          var intSqdist = sqdist(refPt, array2point(intersect));
          var labIntSqdist = sqdist(refPt, array2point(labelIntersect));
          var minSqDist = intSqdist;
          if (labIntSqdist < intSqdist) {
            intersect = labelIntersect;
            minSqDist = labIntSqdist;
          }
          if (labelIntersect.length > 2) {
            var labInt2SqDist = sqdist(refPt, {
              x: labelIntersect[2],
              y: labelIntersect[3]
            });
            if (labInt2SqDist < minSqDist) {
              intersect = [labelIntersect[2], labelIntersect[3]];
            }
          }
        }
      }
    }
    var arrowEnd = shortenIntersection(intersect, p1, r.arrowShapes[tgtArShape].spacing(edge) + tgtDist);
    var edgeEnd = shortenIntersection(intersect, p1, r.arrowShapes[tgtArShape].gap(edge) + tgtDist);
    rs.endX = edgeEnd[0];
    rs.endY = edgeEnd[1];
    rs.arrowEndX = arrowEnd[0];
    rs.arrowEndY = arrowEnd[1];
    if (srcManEndptVal === 'inside-to-node') {
      intersect = [srcPos.x, srcPos.y];
    } else if (srcManEndpt.units) {
      intersect = this.manualEndptToPx(source, srcManEndpt);
    } else if (srcManEndptVal === 'outside-to-line') {
      intersect = rs.srcIntn; // use cached value from ctrlpt calc
    } else {
      if (srcManEndptVal === 'outside-to-node' || srcManEndptVal === 'outside-to-node-or-label') {
        p2_i = p2;
      } else if (srcManEndptVal === 'outside-to-line' || srcManEndptVal === 'outside-to-line-or-label') {
        p2_i = [tgtPos.x, tgtPos.y];
      }
      intersect = r.nodeShapes[this.getNodeShape(source)].intersectLine(srcPos.x, srcPos.y, source.outerWidth(), source.outerHeight(), p2_i[0], p2_i[1], 0);
      if (srcManEndptVal === 'outside-to-node-or-label' || srcManEndptVal === 'outside-to-line-or-label') {
        var srs = source._private.rscratch;
        var _lw = srs.labelWidth;
        var _lh = srs.labelHeight;
        var _lx = srs.labelX;
        var _ly = srs.labelY;
        var _lw2 = _lw / 2;
        var _lh2 = _lh / 2;
        var _va = source.pstyle('text-valign').value;
        if (_va === 'top') {
          _ly -= _lh2;
        } else if (_va === 'bottom') {
          _ly += _lh2;
        }
        var _ha = source.pstyle('text-halign').value;
        if (_ha === 'left') {
          _lx -= _lw2;
        } else if (_ha === 'right') {
          _lx += _lw2;
        }
        var _labelIntersect = polygonIntersectLine(p2_i[0], p2_i[1], [_lx - _lw2, _ly - _lh2, _lx + _lw2, _ly - _lh2, _lx + _lw2, _ly + _lh2, _lx - _lw2, _ly + _lh2], srcPos.x, srcPos.y);
        if (_labelIntersect.length > 0) {
          var _refPt = tgtPos;
          var _intSqdist = sqdist(_refPt, array2point(intersect));
          var _labIntSqdist = sqdist(_refPt, array2point(_labelIntersect));
          var _minSqDist = _intSqdist;
          if (_labIntSqdist < _intSqdist) {
            intersect = [_labelIntersect[0], _labelIntersect[1]];
            _minSqDist = _labIntSqdist;
          }
          if (_labelIntersect.length > 2) {
            var _labInt2SqDist = sqdist(_refPt, {
              x: _labelIntersect[2],
              y: _labelIntersect[3]
            });
            if (_labInt2SqDist < _minSqDist) {
              intersect = [_labelIntersect[2], _labelIntersect[3]];
            }
          }
        }
      }
    }
    var arrowStart = shortenIntersection(intersect, p2, r.arrowShapes[srcArShape].spacing(edge) + srcDist);
    var edgeStart = shortenIntersection(intersect, p2, r.arrowShapes[srcArShape].gap(edge) + srcDist);
    rs.startX = edgeStart[0];
    rs.startY = edgeStart[1];
    rs.arrowStartX = arrowStart[0];
    rs.arrowStartY = arrowStart[1];
    if (hasEndpts) {
      if (!number$1(rs.startX) || !number$1(rs.startY) || !number$1(rs.endX) || !number$1(rs.endY)) {
        rs.badLine = true;
      } else {
        rs.badLine = false;
      }
    }
  };
  BRp$b.getSourceEndpoint = function (edge) {
    var rs = edge[0]._private.rscratch;
    this.recalculateRenderedStyle(edge);
    switch (rs.edgeType) {
      case 'haystack':
        return {
          x: rs.haystackPts[0],
          y: rs.haystackPts[1]
        };
      default:
        return {
          x: rs.arrowStartX,
          y: rs.arrowStartY
        };
    }
  };
  BRp$b.getTargetEndpoint = function (edge) {
    var rs = edge[0]._private.rscratch;
    this.recalculateRenderedStyle(edge);
    switch (rs.edgeType) {
      case 'haystack':
        return {
          x: rs.haystackPts[2],
          y: rs.haystackPts[3]
        };
      default:
        return {
          x: rs.arrowEndX,
          y: rs.arrowEndY
        };
    }
  };

  var BRp$a = {};
  function pushBezierPts(r, edge, pts) {
    var qbezierAt$1 = function qbezierAt$1(p1, p2, p3, t) {
      return qbezierAt(p1, p2, p3, t);
    };
    var _p = edge._private;
    var bpts = _p.rstyle.bezierPts;
    for (var i = 0; i < r.bezierProjPcts.length; i++) {
      var p = r.bezierProjPcts[i];
      bpts.push({
        x: qbezierAt$1(pts[0], pts[2], pts[4], p),
        y: qbezierAt$1(pts[1], pts[3], pts[5], p)
      });
    }
  }
  BRp$a.storeEdgeProjections = function (edge) {
    var _p = edge._private;
    var rs = _p.rscratch;
    var et = rs.edgeType;

    // clear the cached points state
    _p.rstyle.bezierPts = null;
    _p.rstyle.linePts = null;
    _p.rstyle.haystackPts = null;
    if (et === 'multibezier' || et === 'bezier' || et === 'self' || et === 'compound') {
      _p.rstyle.bezierPts = [];
      for (var i = 0; i + 5 < rs.allpts.length; i += 4) {
        pushBezierPts(this, edge, rs.allpts.slice(i, i + 6));
      }
    } else if (et === 'segments') {
      var lpts = _p.rstyle.linePts = [];
      for (var i = 0; i + 1 < rs.allpts.length; i += 2) {
        lpts.push({
          x: rs.allpts[i],
          y: rs.allpts[i + 1]
        });
      }
    } else if (et === 'haystack') {
      var hpts = rs.haystackPts;
      _p.rstyle.haystackPts = [{
        x: hpts[0],
        y: hpts[1]
      }, {
        x: hpts[2],
        y: hpts[3]
      }];
    }
    _p.rstyle.arrowWidth = this.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.arrowShapeWidth;
  };
  BRp$a.recalculateEdgeProjections = function (edges) {
    this.findEdgeControlPoints(edges);
  };

  /* global document */

  var BRp$9 = {};
  BRp$9.recalculateNodeLabelProjection = function (node) {
    var content = node.pstyle('label').strValue;
    if (emptyString(content)) {
      return;
    }
    var textX, textY;
    var _p = node._private;
    var nodeWidth = node.width();
    var nodeHeight = node.height();
    var padding = node.padding();
    var nodePos = node.position();
    var textHalign = node.pstyle('text-halign').strValue;
    var textValign = node.pstyle('text-valign').strValue;
    var rs = _p.rscratch;
    var rstyle = _p.rstyle;
    switch (textHalign) {
      case 'left':
        textX = nodePos.x - nodeWidth / 2 - padding;
        break;
      case 'right':
        textX = nodePos.x + nodeWidth / 2 + padding;
        break;
      default:
        // e.g. center
        textX = nodePos.x;
    }
    switch (textValign) {
      case 'top':
        textY = nodePos.y - nodeHeight / 2 - padding;
        break;
      case 'bottom':
        textY = nodePos.y + nodeHeight / 2 + padding;
        break;
      default:
        // e.g. middle
        textY = nodePos.y;
    }
    rs.labelX = textX;
    rs.labelY = textY;
    rstyle.labelX = textX;
    rstyle.labelY = textY;
    this.calculateLabelAngles(node);
    this.applyLabelDimensions(node);
  };
  var lineAngleFromDelta = function lineAngleFromDelta(dx, dy) {
    var angle = Math.atan(dy / dx);
    if (dx === 0 && angle < 0) {
      angle = angle * -1;
    }
    return angle;
  };
  var lineAngle = function lineAngle(p0, p1) {
    var dx = p1.x - p0.x;
    var dy = p1.y - p0.y;
    return lineAngleFromDelta(dx, dy);
  };
  var bezierAngle = function bezierAngle(p0, p1, p2, t) {
    var t0 = bound(0, t - 0.001, 1);
    var t1 = bound(0, t + 0.001, 1);
    var lp0 = qbezierPtAt(p0, p1, p2, t0);
    var lp1 = qbezierPtAt(p0, p1, p2, t1);
    return lineAngle(lp0, lp1);
  };
  BRp$9.recalculateEdgeLabelProjections = function (edge) {
    var p;
    var _p = edge._private;
    var rs = _p.rscratch;
    var r = this;
    var content = {
      mid: edge.pstyle('label').strValue,
      source: edge.pstyle('source-label').strValue,
      target: edge.pstyle('target-label').strValue
    };
    if (content.mid || content.source || content.target) ; else {
      return; // no labels => no calcs
    }

    // add center point to style so bounding box calculations can use it
    //
    p = {
      x: rs.midX,
      y: rs.midY
    };
    var setRs = function setRs(propName, prefix, value) {
      setPrefixedProperty(_p.rscratch, propName, prefix, value);
      setPrefixedProperty(_p.rstyle, propName, prefix, value);
    };
    setRs('labelX', null, p.x);
    setRs('labelY', null, p.y);
    var midAngle = lineAngleFromDelta(rs.midDispX, rs.midDispY);
    setRs('labelAutoAngle', null, midAngle);
    var createControlPointInfo = function createControlPointInfo() {
      if (createControlPointInfo.cache) {
        return createControlPointInfo.cache;
      } // use cache so only 1x per edge

      var ctrlpts = [];

      // store each ctrlpt info init
      for (var i = 0; i + 5 < rs.allpts.length; i += 4) {
        var p0 = {
          x: rs.allpts[i],
          y: rs.allpts[i + 1]
        };
        var p1 = {
          x: rs.allpts[i + 2],
          y: rs.allpts[i + 3]
        }; // ctrlpt
        var p2 = {
          x: rs.allpts[i + 4],
          y: rs.allpts[i + 5]
        };
        ctrlpts.push({
          p0: p0,
          p1: p1,
          p2: p2,
          startDist: 0,
          length: 0,
          segments: []
        });
      }
      var bpts = _p.rstyle.bezierPts;
      var nProjs = r.bezierProjPcts.length;
      function addSegment(cp, p0, p1, t0, t1) {
        var length = dist(p0, p1);
        var prevSegment = cp.segments[cp.segments.length - 1];
        var segment = {
          p0: p0,
          p1: p1,
          t0: t0,
          t1: t1,
          startDist: prevSegment ? prevSegment.startDist + prevSegment.length : 0,
          length: length
        };
        cp.segments.push(segment);
        cp.length += length;
      }

      // update each ctrlpt with segment info
      for (var _i = 0; _i < ctrlpts.length; _i++) {
        var cp = ctrlpts[_i];
        var prevCp = ctrlpts[_i - 1];
        if (prevCp) {
          cp.startDist = prevCp.startDist + prevCp.length;
        }
        addSegment(cp, cp.p0, bpts[_i * nProjs], 0, r.bezierProjPcts[0]); // first

        for (var j = 0; j < nProjs - 1; j++) {
          addSegment(cp, bpts[_i * nProjs + j], bpts[_i * nProjs + j + 1], r.bezierProjPcts[j], r.bezierProjPcts[j + 1]);
        }
        addSegment(cp, bpts[_i * nProjs + nProjs - 1], cp.p2, r.bezierProjPcts[nProjs - 1], 1); // last
      }

      return createControlPointInfo.cache = ctrlpts;
    };
    var calculateEndProjection = function calculateEndProjection(prefix) {
      var angle;
      var isSrc = prefix === 'source';
      if (!content[prefix]) {
        return;
      }
      var offset = edge.pstyle(prefix + '-text-offset').pfValue;
      switch (rs.edgeType) {
        case 'self':
        case 'compound':
        case 'bezier':
        case 'multibezier':
          {
            var cps = createControlPointInfo();
            var selected;
            var startDist = 0;
            var totalDist = 0;

            // find the segment we're on
            for (var i = 0; i < cps.length; i++) {
              var _cp = cps[isSrc ? i : cps.length - 1 - i];
              for (var j = 0; j < _cp.segments.length; j++) {
                var _seg = _cp.segments[isSrc ? j : _cp.segments.length - 1 - j];
                var lastSeg = i === cps.length - 1 && j === _cp.segments.length - 1;
                startDist = totalDist;
                totalDist += _seg.length;
                if (totalDist >= offset || lastSeg) {
                  selected = {
                    cp: _cp,
                    segment: _seg
                  };
                  break;
                }
              }
              if (selected) {
                break;
              }
            }
            var cp = selected.cp;
            var seg = selected.segment;
            var tSegment = (offset - startDist) / seg.length;
            var segDt = seg.t1 - seg.t0;
            var t = isSrc ? seg.t0 + segDt * tSegment : seg.t1 - segDt * tSegment;
            t = bound(0, t, 1);
            p = qbezierPtAt(cp.p0, cp.p1, cp.p2, t);
            angle = bezierAngle(cp.p0, cp.p1, cp.p2, t);
            break;
          }
        case 'straight':
        case 'segments':
        case 'haystack':
          {
            var d = 0,
              di,
              d0;
            var p0, p1;
            var l = rs.allpts.length;
            for (var _i2 = 0; _i2 + 3 < l; _i2 += 2) {
              if (isSrc) {
                p0 = {
                  x: rs.allpts[_i2],
                  y: rs.allpts[_i2 + 1]
                };
                p1 = {
                  x: rs.allpts[_i2 + 2],
                  y: rs.allpts[_i2 + 3]
                };
              } else {
                p0 = {
                  x: rs.allpts[l - 2 - _i2],
                  y: rs.allpts[l - 1 - _i2]
                };
                p1 = {
                  x: rs.allpts[l - 4 - _i2],
                  y: rs.allpts[l - 3 - _i2]
                };
              }
              di = dist(p0, p1);
              d0 = d;
              d += di;
              if (d >= offset) {
                break;
              }
            }
            var pD = offset - d0;
            var _t = pD / di;
            _t = bound(0, _t, 1);
            p = lineAt(p0, p1, _t);
            angle = lineAngle(p0, p1);
            break;
          }
      }
      setRs('labelX', prefix, p.x);
      setRs('labelY', prefix, p.y);
      setRs('labelAutoAngle', prefix, angle);
    };
    calculateEndProjection('source');
    calculateEndProjection('target');
    this.applyLabelDimensions(edge);
  };
  BRp$9.applyLabelDimensions = function (ele) {
    this.applyPrefixedLabelDimensions(ele);
    if (ele.isEdge()) {
      this.applyPrefixedLabelDimensions(ele, 'source');
      this.applyPrefixedLabelDimensions(ele, 'target');
    }
  };
  BRp$9.applyPrefixedLabelDimensions = function (ele, prefix) {
    var _p = ele._private;
    var text = this.getLabelText(ele, prefix);
    var labelDims = this.calculateLabelDimensions(ele, text);
    var lineHeight = ele.pstyle('line-height').pfValue;
    var textWrap = ele.pstyle('text-wrap').strValue;
    var lines = getPrefixedProperty(_p.rscratch, 'labelWrapCachedLines', prefix) || [];
    var numLines = textWrap !== 'wrap' ? 1 : Math.max(lines.length, 1);
    var normPerLineHeight = labelDims.height / numLines;
    var labelLineHeight = normPerLineHeight * lineHeight;
    var width = labelDims.width;
    var height = labelDims.height + (numLines - 1) * (lineHeight - 1) * normPerLineHeight;
    setPrefixedProperty(_p.rstyle, 'labelWidth', prefix, width);
    setPrefixedProperty(_p.rscratch, 'labelWidth', prefix, width);
    setPrefixedProperty(_p.rstyle, 'labelHeight', prefix, height);
    setPrefixedProperty(_p.rscratch, 'labelHeight', prefix, height);
    setPrefixedProperty(_p.rscratch, 'labelLineHeight', prefix, labelLineHeight);
  };
  BRp$9.getLabelText = function (ele, prefix) {
    var _p = ele._private;
    var pfd = prefix ? prefix + '-' : '';
    var text = ele.pstyle(pfd + 'label').strValue;
    var textTransform = ele.pstyle('text-transform').value;
    var rscratch = function rscratch(propName, value) {
      if (value) {
        setPrefixedProperty(_p.rscratch, propName, prefix, value);
        return value;
      } else {
        return getPrefixedProperty(_p.rscratch, propName, prefix);
      }
    };

    // for empty text, skip all processing
    if (!text) {
      return '';
    }
    if (textTransform == 'none') ; else if (textTransform == 'uppercase') {
      text = text.toUpperCase();
    } else if (textTransform == 'lowercase') {
      text = text.toLowerCase();
    }
    var wrapStyle = ele.pstyle('text-wrap').value;
    if (wrapStyle === 'wrap') {
      var labelKey = rscratch('labelKey');

      // save recalc if the label is the same as before
      if (labelKey != null && rscratch('labelWrapKey') === labelKey) {
        return rscratch('labelWrapCachedText');
      }
      var zwsp = "\u200B";
      var lines = text.split('\n');
      var maxW = ele.pstyle('text-max-width').pfValue;
      var overflow = ele.pstyle('text-overflow-wrap').value;
      var overflowAny = overflow === 'anywhere';
      var wrappedLines = [];
      var wordsRegex = /[\s\u200b]+/;
      var wordSeparator = overflowAny ? '' : ' ';
      for (var l = 0; l < lines.length; l++) {
        var line = lines[l];
        var lineDims = this.calculateLabelDimensions(ele, line);
        var lineW = lineDims.width;
        if (overflowAny) {
          var processedLine = line.split('').join(zwsp);
          line = processedLine;
        }
        if (lineW > maxW) {
          // line is too long
          var words = line.split(wordsRegex);
          var subline = '';
          for (var w = 0; w < words.length; w++) {
            var word = words[w];
            var testLine = subline.length === 0 ? word : subline + wordSeparator + word;
            var testDims = this.calculateLabelDimensions(ele, testLine);
            var testW = testDims.width;
            if (testW <= maxW) {
              // word fits on current line
              subline += word + wordSeparator;
            } else {
              // word starts new line
              if (subline) {
                wrappedLines.push(subline);
              }
              subline = word + wordSeparator;
            }
          }

          // if there's remaining text, put it in a wrapped line
          if (!subline.match(/^[\s\u200b]+$/)) {
            wrappedLines.push(subline);
          }
        } else {
          // line is already short enough
          wrappedLines.push(line);
        }
      } // for

      rscratch('labelWrapCachedLines', wrappedLines);
      text = rscratch('labelWrapCachedText', wrappedLines.join('\n'));
      rscratch('labelWrapKey', labelKey);
    } else if (wrapStyle === 'ellipsis') {
      var _maxW = ele.pstyle('text-max-width').pfValue;
      var ellipsized = '';
      var ellipsis = "\u2026";
      var incLastCh = false;
      if (this.calculateLabelDimensions(ele, text).width < _maxW) {
        // the label already fits
        return text;
      }
      for (var i = 0; i < text.length; i++) {
        var widthWithNextCh = this.calculateLabelDimensions(ele, ellipsized + text[i] + ellipsis).width;
        if (widthWithNextCh > _maxW) {
          break;
        }
        ellipsized += text[i];
        if (i === text.length - 1) {
          incLastCh = true;
        }
      }
      if (!incLastCh) {
        ellipsized += ellipsis;
      }
      return ellipsized;
    } // if ellipsize

    return text;
  };
  BRp$9.getLabelJustification = function (ele) {
    var justification = ele.pstyle('text-justification').strValue;
    var textHalign = ele.pstyle('text-halign').strValue;
    if (justification === 'auto') {
      if (ele.isNode()) {
        switch (textHalign) {
          case 'left':
            return 'right';
          case 'right':
            return 'left';
          default:
            return 'center';
        }
      } else {
        return 'center';
      }
    } else {
      return justification;
    }
  };
  BRp$9.calculateLabelDimensions = function (ele, text) {
    var r = this;
    var cacheKey = hashString(text, ele._private.labelDimsKey);
    var cache = r.labelDimCache || (r.labelDimCache = []);
    var existingVal = cache[cacheKey];
    if (existingVal != null) {
      return existingVal;
    }
    var padding = 0; // add padding around text dims, as the measurement isn't that accurate
    var fStyle = ele.pstyle('font-style').strValue;
    var size = ele.pstyle('font-size').pfValue;
    var family = ele.pstyle('font-family').strValue;
    var weight = ele.pstyle('font-weight').strValue;
    var canvas = this.labelCalcCanvas;
    var c2d = this.labelCalcCanvasContext;
    if (!canvas) {
      canvas = this.labelCalcCanvas = document.createElement('canvas');
      c2d = this.labelCalcCanvasContext = canvas.getContext('2d');
      var ds = canvas.style;
      ds.position = 'absolute';
      ds.left = '-9999px';
      ds.top = '-9999px';
      ds.zIndex = '-1';
      ds.visibility = 'hidden';
      ds.pointerEvents = 'none';
    }
    c2d.font = "".concat(fStyle, " ").concat(weight, " ").concat(size, "px ").concat(family);
    var width = 0;
    var height = 0;
    var lines = text.split('\n');
    for (var i = 0; i < lines.length; i++) {
      var line = lines[i];
      var metrics = c2d.measureText(line);
      var w = Math.ceil(metrics.width);
      var h = size;
      width = Math.max(w, width);
      height += h;
    }
    width += padding;
    height += padding;
    return cache[cacheKey] = {
      width: width,
      height: height
    };
  };
  BRp$9.calculateLabelAngle = function (ele, prefix) {
    var _p = ele._private;
    var rs = _p.rscratch;
    var isEdge = ele.isEdge();
    var prefixDash = prefix ? prefix + '-' : '';
    var rot = ele.pstyle(prefixDash + 'text-rotation');
    var rotStr = rot.strValue;
    if (rotStr === 'none') {
      return 0;
    } else if (isEdge && rotStr === 'autorotate') {
      return rs.labelAutoAngle;
    } else if (rotStr === 'autorotate') {
      return 0;
    } else {
      return rot.pfValue;
    }
  };
  BRp$9.calculateLabelAngles = function (ele) {
    var r = this;
    var isEdge = ele.isEdge();
    var _p = ele._private;
    var rs = _p.rscratch;
    rs.labelAngle = r.calculateLabelAngle(ele);
    if (isEdge) {
      rs.sourceLabelAngle = r.calculateLabelAngle(ele, 'source');
      rs.targetLabelAngle = r.calculateLabelAngle(ele, 'target');
    }
  };

  var BRp$8 = {};
  var TOO_SMALL_CUT_RECT = 28;
  var warnedCutRect = false;
  BRp$8.getNodeShape = function (node) {
    var r = this;
    var shape = node.pstyle('shape').value;
    if (shape === 'cutrectangle' && (node.width() < TOO_SMALL_CUT_RECT || node.height() < TOO_SMALL_CUT_RECT)) {
      if (!warnedCutRect) {
        warn('The `cutrectangle` node shape can not be used at small sizes so `rectangle` is used instead');
        warnedCutRect = true;
      }
      return 'rectangle';
    }
    if (node.isParent()) {
      if (shape === 'rectangle' || shape === 'roundrectangle' || shape === 'round-rectangle' || shape === 'cutrectangle' || shape === 'cut-rectangle' || shape === 'barrel') {
        return shape;
      } else {
        return 'rectangle';
      }
    }
    if (shape === 'polygon') {
      var points = node.pstyle('shape-polygon-points').value;
      return r.nodeShapes.makePolygon(points).name;
    }
    return shape;
  };

  var BRp$7 = {};
  BRp$7.registerCalculationListeners = function () {
    var cy = this.cy;
    var elesToUpdate = cy.collection();
    var r = this;
    var enqueue = function enqueue(eles) {
      var dirtyStyleCaches = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      elesToUpdate.merge(eles);
      if (dirtyStyleCaches) {
        for (var i = 0; i < eles.length; i++) {
          var ele = eles[i];
          var _p = ele._private;
          var rstyle = _p.rstyle;
          rstyle.clean = false;
          rstyle.cleanConnected = false;
        }
      }
    };
    r.binder(cy).on('bounds.* dirty.*', function onDirtyBounds(e) {
      var ele = e.target;
      enqueue(ele);
    }).on('style.* background.*', function onDirtyStyle(e) {
      var ele = e.target;
      enqueue(ele, false);
    });
    var updateEleCalcs = function updateEleCalcs(willDraw) {
      if (willDraw) {
        var fns = r.onUpdateEleCalcsFns;

        // because we need to have up-to-date style (e.g. stylesheet mappers)
        // before calculating rendered style (and pstyle might not be called yet)
        elesToUpdate.cleanStyle();
        for (var i = 0; i < elesToUpdate.length; i++) {
          var ele = elesToUpdate[i];
          var rstyle = ele._private.rstyle;
          if (ele.isNode() && !rstyle.cleanConnected) {
            enqueue(ele.connectedEdges());
            rstyle.cleanConnected = true;
          }
        }
        if (fns) {
          for (var _i = 0; _i < fns.length; _i++) {
            var fn = fns[_i];
            fn(willDraw, elesToUpdate);
          }
        }
        r.recalculateRenderedStyle(elesToUpdate);
        elesToUpdate = cy.collection();
      }
    };
    r.flushRenderedStyleQueue = function () {
      updateEleCalcs(true);
    };
    r.beforeRender(updateEleCalcs, r.beforeRenderPriorities.eleCalcs);
  };
  BRp$7.onUpdateEleCalcs = function (fn) {
    var fns = this.onUpdateEleCalcsFns = this.onUpdateEleCalcsFns || [];
    fns.push(fn);
  };
  BRp$7.recalculateRenderedStyle = function (eles, useCache) {
    var isCleanConnected = function isCleanConnected(ele) {
      return ele._private.rstyle.cleanConnected;
    };
    var edges = [];
    var nodes = [];

    // the renderer can't be used for calcs when destroyed, e.g. ele.boundingBox()
    if (this.destroyed) {
      return;
    }

    // use cache by default for perf
    if (useCache === undefined) {
      useCache = true;
    }
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      var _p = ele._private;
      var rstyle = _p.rstyle;

      // an edge may be implicitly dirty b/c of one of its connected nodes
      // (and a request for recalc may come in between frames)
      if (ele.isEdge() && (!isCleanConnected(ele.source()) || !isCleanConnected(ele.target()))) {
        rstyle.clean = false;
      }

      // only update if dirty and in graph
      if (useCache && rstyle.clean || ele.removed()) {
        continue;
      }

      // only update if not display: none
      if (ele.pstyle('display').value === 'none') {
        continue;
      }
      if (_p.group === 'nodes') {
        nodes.push(ele);
      } else {
        // edges
        edges.push(ele);
      }
      rstyle.clean = true;
    }

    // update node data from projections
    for (var _i2 = 0; _i2 < nodes.length; _i2++) {
      var _ele = nodes[_i2];
      var _p2 = _ele._private;
      var _rstyle = _p2.rstyle;
      var pos = _ele.position();
      this.recalculateNodeLabelProjection(_ele);
      _rstyle.nodeX = pos.x;
      _rstyle.nodeY = pos.y;
      _rstyle.nodeW = _ele.pstyle('width').pfValue;
      _rstyle.nodeH = _ele.pstyle('height').pfValue;
    }
    this.recalculateEdgeProjections(edges);

    // update edge data from projections
    for (var _i3 = 0; _i3 < edges.length; _i3++) {
      var _ele2 = edges[_i3];
      var _p3 = _ele2._private;
      var _rstyle2 = _p3.rstyle;
      var rs = _p3.rscratch;

      // update rstyle positions
      _rstyle2.srcX = rs.arrowStartX;
      _rstyle2.srcY = rs.arrowStartY;
      _rstyle2.tgtX = rs.arrowEndX;
      _rstyle2.tgtY = rs.arrowEndY;
      _rstyle2.midX = rs.midX;
      _rstyle2.midY = rs.midY;
      _rstyle2.labelAngle = rs.labelAngle;
      _rstyle2.sourceLabelAngle = rs.sourceLabelAngle;
      _rstyle2.targetLabelAngle = rs.targetLabelAngle;
    }
  };

  var BRp$6 = {};
  BRp$6.updateCachedGrabbedEles = function () {
    var eles = this.cachedZSortedEles;
    if (!eles) {
      // just let this be recalculated on the next z sort tick
      return;
    }
    eles.drag = [];
    eles.nondrag = [];
    var grabTargets = [];
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      var rs = ele._private.rscratch;
      if (ele.grabbed() && !ele.isParent()) {
        grabTargets.push(ele);
      } else if (rs.inDragLayer) {
        eles.drag.push(ele);
      } else {
        eles.nondrag.push(ele);
      }
    }

    // put the grab target nodes last so it's on top of its neighbourhood
    for (var i = 0; i < grabTargets.length; i++) {
      var ele = grabTargets[i];
      eles.drag.push(ele);
    }
  };
  BRp$6.invalidateCachedZSortedEles = function () {
    this.cachedZSortedEles = null;
  };
  BRp$6.getCachedZSortedEles = function (forceRecalc) {
    if (forceRecalc || !this.cachedZSortedEles) {
      var eles = this.cy.mutableElements().toArray();
      eles.sort(zIndexSort);
      eles.interactive = eles.filter(function (ele) {
        return ele.interactive();
      });
      this.cachedZSortedEles = eles;
      this.updateCachedGrabbedEles();
    } else {
      eles = this.cachedZSortedEles;
    }
    return eles;
  };

  var BRp$5 = {};
  [BRp$e, BRp$d, BRp$c, BRp$b, BRp$a, BRp$9, BRp$8, BRp$7, BRp$6].forEach(function (props) {
    extend(BRp$5, props);
  });

  var BRp$4 = {};
  BRp$4.getCachedImage = function (url, crossOrigin, onLoad) {
    var r = this;
    var imageCache = r.imageCache = r.imageCache || {};
    var cache = imageCache[url];
    if (cache) {
      if (!cache.image.complete) {
        cache.image.addEventListener('load', onLoad);
      }
      return cache.image;
    } else {
      cache = imageCache[url] = imageCache[url] || {};
      var image = cache.image = new Image(); // eslint-disable-line no-undef

      image.addEventListener('load', onLoad);
      image.addEventListener('error', function () {
        image.error = true;
      });

      // #1582 safari doesn't load data uris with crossOrigin properly
      // https://bugs.webkit.org/show_bug.cgi?id=123978
      var dataUriPrefix = 'data:';
      var isDataUri = url.substring(0, dataUriPrefix.length).toLowerCase() === dataUriPrefix;
      if (!isDataUri) {
        // if crossorigin is 'null'(stringified), then manually set it to null 
        crossOrigin = crossOrigin === 'null' ? null : crossOrigin;
        image.crossOrigin = crossOrigin; // prevent tainted canvas
      }

      image.src = url;
      return image;
    }
  };

  var BRp$3 = {};

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

  BRp$3.registerBinding = function (target, event, handler, useCapture) {
    // eslint-disable-line no-unused-vars
    var args = Array.prototype.slice.apply(arguments, [1]); // copy
    var b = this.binder(target);
    return b.on.apply(b, args);
  };
  BRp$3.binder = function (tgt) {
    var r = this;
    var containerWindow = r.cy.window();
    var tgtIsDom = tgt === containerWindow || tgt === containerWindow.document || tgt === containerWindow.document.body || domElement(tgt);
    if (r.supportsPassiveEvents == null) {
      // from https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection
      var supportsPassive = false;
      try {
        var opts = Object.defineProperty({}, 'passive', {
          get: function get() {
            supportsPassive = true;
            return true;
          }
        });
        containerWindow.addEventListener('test', null, opts);
      } catch (err) {
        // not supported
      }
      r.supportsPassiveEvents = supportsPassive;
    }
    var on = function on(event, handler, useCapture) {
      var args = Array.prototype.slice.call(arguments);
      if (tgtIsDom && r.supportsPassiveEvents) {
        // replace useCapture w/ opts obj
        args[2] = {
          capture: useCapture != null ? useCapture : false,
          passive: false,
          once: false
        };
      }
      r.bindings.push({
        target: tgt,
        args: args
      });
      (tgt.addEventListener || tgt.on).apply(tgt, args);
      return this;
    };
    return {
      on: on,
      addEventListener: on,
      addListener: on,
      bind: on
    };
  };
  BRp$3.nodeIsDraggable = function (node) {
    return node && node.isNode() && !node.locked() && node.grabbable();
  };
  BRp$3.nodeIsGrabbable = function (node) {
    return this.nodeIsDraggable(node) && node.interactive();
  };
  BRp$3.load = function () {
    var r = this;
    var containerWindow = r.cy.window();
    var isSelected = function isSelected(ele) {
      return ele.selected();
    };
    var triggerEvents = function triggerEvents(target, names, e, position) {
      if (target == null) {
        target = r.cy;
      }
      for (var i = 0; i < names.length; i++) {
        var name = names[i];
        target.emit({
          originalEvent: e,
          type: name,
          position: position
        });
      }
    };
    var isMultSelKeyDown = function isMultSelKeyDown(e) {
      return e.shiftKey || e.metaKey || e.ctrlKey; // maybe e.altKey
    };

    var allowPanningPassthrough = function allowPanningPassthrough(down, downs) {
      var allowPassthrough = true;
      if (r.cy.hasCompoundNodes() && down && down.pannable()) {
        // a grabbable compound node below the ele => no passthrough panning
        for (var i = 0; downs && i < downs.length; i++) {
          var down = downs[i];

          //if any parent node in event hierarchy isn't pannable, reject passthrough
          if (down.isNode() && down.isParent() && !down.pannable()) {
            allowPassthrough = false;
            break;
          }
        }
      } else {
        allowPassthrough = true;
      }
      return allowPassthrough;
    };
    var setGrabbed = function setGrabbed(ele) {
      ele[0]._private.grabbed = true;
    };
    var setFreed = function setFreed(ele) {
      ele[0]._private.grabbed = false;
    };
    var setInDragLayer = function setInDragLayer(ele) {
      ele[0]._private.rscratch.inDragLayer = true;
    };
    var setOutDragLayer = function setOutDragLayer(ele) {
      ele[0]._private.rscratch.inDragLayer = false;
    };
    var setGrabTarget = function setGrabTarget(ele) {
      ele[0]._private.rscratch.isGrabTarget = true;
    };
    var removeGrabTarget = function removeGrabTarget(ele) {
      ele[0]._private.rscratch.isGrabTarget = false;
    };
    var addToDragList = function addToDragList(ele, opts) {
      var list = opts.addToList;
      var listHasEle = list.has(ele);
      if (!listHasEle && ele.grabbable() && !ele.locked()) {
        list.merge(ele);
        setGrabbed(ele);
      }
    };

    // helper function to determine which child nodes and inner edges
    // of a compound node to be dragged as well as the grabbed and selected nodes
    var addDescendantsToDrag = function addDescendantsToDrag(node, opts) {
      if (!node.cy().hasCompoundNodes()) {
        return;
      }
      if (opts.inDragLayer == null && opts.addToList == null) {
        return;
      } // nothing to do

      var innerNodes = node.descendants();
      if (opts.inDragLayer) {
        innerNodes.forEach(setInDragLayer);
        innerNodes.connectedEdges().forEach(setInDragLayer);
      }
      if (opts.addToList) {
        addToDragList(innerNodes, opts);
      }
    };

    // adds the given nodes and its neighbourhood to the drag layer
    var addNodesToDrag = function addNodesToDrag(nodes, opts) {
      opts = opts || {};
      var hasCompoundNodes = nodes.cy().hasCompoundNodes();
      if (opts.inDragLayer) {
        nodes.forEach(setInDragLayer);
        nodes.neighborhood().stdFilter(function (ele) {
          return !hasCompoundNodes || ele.isEdge();
        }).forEach(setInDragLayer);
      }
      if (opts.addToList) {
        nodes.forEach(function (ele) {
          addToDragList(ele, opts);
        });
      }
      addDescendantsToDrag(nodes, opts); // always add to drag

      // also add nodes and edges related to the topmost ancestor
      updateAncestorsInDragLayer(nodes, {
        inDragLayer: opts.inDragLayer
      });
      r.updateCachedGrabbedEles();
    };
    var addNodeToDrag = addNodesToDrag;
    var freeDraggedElements = function freeDraggedElements(grabbedEles) {
      if (!grabbedEles) {
        return;
      }

      // just go over all elements rather than doing a bunch of (possibly expensive) traversals
      r.getCachedZSortedEles().forEach(function (ele) {
        setFreed(ele);
        setOutDragLayer(ele);
        removeGrabTarget(ele);
      });
      r.updateCachedGrabbedEles();
    };

    // helper function to determine which ancestor nodes and edges should go
    // to the drag layer (or should be removed from drag layer).
    var updateAncestorsInDragLayer = function updateAncestorsInDragLayer(node, opts) {
      if (opts.inDragLayer == null && opts.addToList == null) {
        return;
      } // nothing to do

      if (!node.cy().hasCompoundNodes()) {
        return;
      }

      // find top-level parent
      var parent = node.ancestors().orphans();

      // no parent node: no nodes to add to the drag layer
      if (parent.same(node)) {
        return;
      }
      var nodes = parent.descendants().spawnSelf().merge(parent).unmerge(node).unmerge(node.descendants());
      var edges = nodes.connectedEdges();
      if (opts.inDragLayer) {
        edges.forEach(setInDragLayer);
        nodes.forEach(setInDragLayer);
      }
      if (opts.addToList) {
        nodes.forEach(function (ele) {
          addToDragList(ele, opts);
        });
      }
    };
    var blurActiveDomElement = function blurActiveDomElement() {
      if (document.activeElement != null && document.activeElement.blur != null) {
        document.activeElement.blur();
      }
    };
    var haveMutationsApi = typeof MutationObserver !== 'undefined';
    var haveResizeObserverApi = typeof ResizeObserver !== 'undefined';

    // watch for when the cy container is removed from the dom
    if (haveMutationsApi) {
      r.removeObserver = new MutationObserver(function (mutns) {
        // eslint-disable-line no-undef
        for (var i = 0; i < mutns.length; i++) {
          var mutn = mutns[i];
          var rNodes = mutn.removedNodes;
          if (rNodes) {
            for (var j = 0; j < rNodes.length; j++) {
              var rNode = rNodes[j];
              if (rNode === r.container) {
                r.destroy();
                break;
              }
            }
          }
        }
      });
      if (r.container.parentNode) {
        r.removeObserver.observe(r.container.parentNode, {
          childList: true
        });
      }
    } else {
      r.registerBinding(r.container, 'DOMNodeRemoved', function (e) {
        // eslint-disable-line no-unused-vars
        r.destroy();
      });
    }
    var onResize = debounce_1(function () {
      r.cy.resize();
    }, 100);
    if (haveMutationsApi) {
      r.styleObserver = new MutationObserver(onResize); // eslint-disable-line no-undef

      r.styleObserver.observe(r.container, {
        attributes: true
      });
    }

    // auto resize
    r.registerBinding(containerWindow, 'resize', onResize); // eslint-disable-line no-undef

    if (haveResizeObserverApi) {
      r.resizeObserver = new ResizeObserver(onResize); // eslint-disable-line no-undef

      r.resizeObserver.observe(r.container);
    }
    var forEachUp = function forEachUp(domEle, fn) {
      while (domEle != null) {
        fn(domEle);
        domEle = domEle.parentNode;
      }
    };
    var invalidateCoords = function invalidateCoords() {
      r.invalidateContainerClientCoordsCache();
    };
    forEachUp(r.container, function (domEle) {
      r.registerBinding(domEle, 'transitionend', invalidateCoords);
      r.registerBinding(domEle, 'animationend', invalidateCoords);
      r.registerBinding(domEle, 'scroll', invalidateCoords);
    });

    // stop right click menu from appearing on cy
    r.registerBinding(r.container, 'contextmenu', function (e) {
      e.preventDefault();
    });
    var inBoxSelection = function inBoxSelection() {
      return r.selection[4] !== 0;
    };
    var eventInContainer = function eventInContainer(e) {
      // save cycles if mouse events aren't to be captured
      var containerPageCoords = r.findContainerClientCoords();
      var x = containerPageCoords[0];
      var y = containerPageCoords[1];
      var width = containerPageCoords[2];
      var height = containerPageCoords[3];
      var positions = e.touches ? e.touches : [e];
      var atLeastOnePosInside = false;
      for (var i = 0; i < positions.length; i++) {
        var p = positions[i];
        if (x <= p.clientX && p.clientX <= x + width && y <= p.clientY && p.clientY <= y + height) {
          atLeastOnePosInside = true;
          break;
        }
      }
      if (!atLeastOnePosInside) {
        return false;
      }
      var container = r.container;
      var target = e.target;
      var tParent = target.parentNode;
      var containerIsTarget = false;
      while (tParent) {
        if (tParent === container) {
          containerIsTarget = true;
          break;
        }
        tParent = tParent.parentNode;
      }
      if (!containerIsTarget) {
        return false;
      } // if target is outisde cy container, then this event is not for us

      return true;
    };

    // Primary key
    r.registerBinding(r.container, 'mousedown', function mousedownHandler(e) {
      if (!eventInContainer(e)) {
        return;
      }
      e.preventDefault();
      blurActiveDomElement();
      r.hoverData.capture = true;
      r.hoverData.which = e.which;
      var cy = r.cy;
      var gpos = [e.clientX, e.clientY];
      var pos = r.projectIntoViewport(gpos[0], gpos[1]);
      var select = r.selection;
      var nears = r.findNearestElements(pos[0], pos[1], true, false);
      var near = nears[0];
      var draggedElements = r.dragData.possibleDragElements;
      r.hoverData.mdownPos = pos;
      r.hoverData.mdownGPos = gpos;
      var checkForTaphold = function checkForTaphold() {
        r.hoverData.tapholdCancelled = false;
        clearTimeout(r.hoverData.tapholdTimeout);
        r.hoverData.tapholdTimeout = setTimeout(function () {
          if (r.hoverData.tapholdCancelled) {
            return;
          } else {
            var ele = r.hoverData.down;
            if (ele) {
              ele.emit({
                originalEvent: e,
                type: 'taphold',
                position: {
                  x: pos[0],
                  y: pos[1]
                }
              });
            } else {
              cy.emit({
                originalEvent: e,
                type: 'taphold',
                position: {
                  x: pos[0],
                  y: pos[1]
                }
              });
            }
          }
        }, r.tapholdDuration);
      };

      // Right click button
      if (e.which == 3) {
        r.hoverData.cxtStarted = true;
        var cxtEvt = {
          originalEvent: e,
          type: 'cxttapstart',
          position: {
            x: pos[0],
            y: pos[1]
          }
        };
        if (near) {
          near.activate();
          near.emit(cxtEvt);
          r.hoverData.down = near;
        } else {
          cy.emit(cxtEvt);
        }
        r.hoverData.downTime = new Date().getTime();
        r.hoverData.cxtDragged = false;

        // Primary button
      } else if (e.which == 1) {
        if (near) {
          near.activate();
        }

        // Element dragging
        {
          // If something is under the cursor and it is draggable, prepare to grab it
          if (near != null) {
            if (r.nodeIsGrabbable(near)) {
              var makeEvent = function makeEvent(type) {
                return {
                  originalEvent: e,
                  type: type,
                  position: {
                    x: pos[0],
                    y: pos[1]
                  }
                };
              };
              var triggerGrab = function triggerGrab(ele) {
                ele.emit(makeEvent('grab'));
              };
              setGrabTarget(near);
              if (!near.selected()) {
                draggedElements = r.dragData.possibleDragElements = cy.collection();
                addNodeToDrag(near, {
                  addToList: draggedElements
                });
                near.emit(makeEvent('grabon')).emit(makeEvent('grab'));
              } else {
                draggedElements = r.dragData.possibleDragElements = cy.collection();
                var selectedNodes = cy.$(function (ele) {
                  return ele.isNode() && ele.selected() && r.nodeIsGrabbable(ele);
                });
                addNodesToDrag(selectedNodes, {
                  addToList: draggedElements
                });
                near.emit(makeEvent('grabon'));
                selectedNodes.forEach(triggerGrab);
              }
              r.redrawHint('eles', true);
              r.redrawHint('drag', true);
            }
          }
          r.hoverData.down = near;
          r.hoverData.downs = nears;
          r.hoverData.downTime = new Date().getTime();
        }
        triggerEvents(near, ['mousedown', 'tapstart', 'vmousedown'], e, {
          x: pos[0],
          y: pos[1]
        });
        if (near == null) {
          select[4] = 1;
          r.data.bgActivePosistion = {
            x: pos[0],
            y: pos[1]
          };
          r.redrawHint('select', true);
          r.redraw();
        } else if (near.pannable()) {
          select[4] = 1; // for future pan
        }

        checkForTaphold();
      }

      // Initialize selection box coordinates
      select[0] = select[2] = pos[0];
      select[1] = select[3] = pos[1];
    }, false);
    r.registerBinding(containerWindow, 'mousemove', function mousemoveHandler(e) {
      // eslint-disable-line no-undef
      var capture = r.hoverData.capture;
      if (!capture && !eventInContainer(e)) {
        return;
      }
      var preventDefault = false;
      var cy = r.cy;
      var zoom = cy.zoom();
      var gpos = [e.clientX, e.clientY];
      var pos = r.projectIntoViewport(gpos[0], gpos[1]);
      var mdownPos = r.hoverData.mdownPos;
      var mdownGPos = r.hoverData.mdownGPos;
      var select = r.selection;
      var near = null;
      if (!r.hoverData.draggingEles && !r.hoverData.dragging && !r.hoverData.selecting) {
        near = r.findNearestElement(pos[0], pos[1], true, false);
      }
      var last = r.hoverData.last;
      var down = r.hoverData.down;
      var disp = [pos[0] - select[2], pos[1] - select[3]];
      var draggedElements = r.dragData.possibleDragElements;
      var isOverThresholdDrag;
      if (mdownGPos) {
        var dx = gpos[0] - mdownGPos[0];
        var dx2 = dx * dx;
        var dy = gpos[1] - mdownGPos[1];
        var dy2 = dy * dy;
        var dist2 = dx2 + dy2;
        r.hoverData.isOverThresholdDrag = isOverThresholdDrag = dist2 >= r.desktopTapThreshold2;
      }
      var multSelKeyDown = isMultSelKeyDown(e);
      if (isOverThresholdDrag) {
        r.hoverData.tapholdCancelled = true;
      }
      var updateDragDelta = function updateDragDelta() {
        var dragDelta = r.hoverData.dragDelta = r.hoverData.dragDelta || [];
        if (dragDelta.length === 0) {
          dragDelta.push(disp[0]);
          dragDelta.push(disp[1]);
        } else {
          dragDelta[0] += disp[0];
          dragDelta[1] += disp[1];
        }
      };
      preventDefault = true;
      triggerEvents(near, ['mousemove', 'vmousemove', 'tapdrag'], e, {
        x: pos[0],
        y: pos[1]
      });
      var goIntoBoxMode = function goIntoBoxMode() {
        r.data.bgActivePosistion = undefined;
        if (!r.hoverData.selecting) {
          cy.emit({
            originalEvent: e,
            type: 'boxstart',
            position: {
              x: pos[0],
              y: pos[1]
            }
          });
        }
        select[4] = 1;
        r.hoverData.selecting = true;
        r.redrawHint('select', true);
        r.redraw();
      };

      // trigger context drag if rmouse down
      if (r.hoverData.which === 3) {
        // but only if over threshold
        if (isOverThresholdDrag) {
          var cxtEvt = {
            originalEvent: e,
            type: 'cxtdrag',
            position: {
              x: pos[0],
              y: pos[1]
            }
          };
          if (down) {
            down.emit(cxtEvt);
          } else {
            cy.emit(cxtEvt);
          }
          r.hoverData.cxtDragged = true;
          if (!r.hoverData.cxtOver || near !== r.hoverData.cxtOver) {
            if (r.hoverData.cxtOver) {
              r.hoverData.cxtOver.emit({
                originalEvent: e,
                type: 'cxtdragout',
                position: {
                  x: pos[0],
                  y: pos[1]
                }
              });
            }
            r.hoverData.cxtOver = near;
            if (near) {
              near.emit({
                originalEvent: e,
                type: 'cxtdragover',
                position: {
                  x: pos[0],
                  y: pos[1]
                }
              });
            }
          }
        }

        // Check if we are drag panning the entire graph
      } else if (r.hoverData.dragging) {
        preventDefault = true;
        if (cy.panningEnabled() && cy.userPanningEnabled()) {
          var deltaP;
          if (r.hoverData.justStartedPan) {
            var mdPos = r.hoverData.mdownPos;
            deltaP = {
              x: (pos[0] - mdPos[0]) * zoom,
              y: (pos[1] - mdPos[1]) * zoom
            };
            r.hoverData.justStartedPan = false;
          } else {
            deltaP = {
              x: disp[0] * zoom,
              y: disp[1] * zoom
            };
          }
          cy.panBy(deltaP);
          cy.emit('dragpan');
          r.hoverData.dragged = true;
        }

        // Needs reproject due to pan changing viewport
        pos = r.projectIntoViewport(e.clientX, e.clientY);

        // Checks primary button down & out of time & mouse not moved much
      } else if (select[4] == 1 && (down == null || down.pannable())) {
        if (isOverThresholdDrag) {
          if (!r.hoverData.dragging && cy.boxSelectionEnabled() && (multSelKeyDown || !cy.panningEnabled() || !cy.userPanningEnabled())) {
            goIntoBoxMode();
          } else if (!r.hoverData.selecting && cy.panningEnabled() && cy.userPanningEnabled()) {
            var allowPassthrough = allowPanningPassthrough(down, r.hoverData.downs);
            if (allowPassthrough) {
              r.hoverData.dragging = true;
              r.hoverData.justStartedPan = true;
              select[4] = 0;
              r.data.bgActivePosistion = array2point(mdownPos);
              r.redrawHint('select', true);
              r.redraw();
            }
          }
          if (down && down.pannable() && down.active()) {
            down.unactivate();
          }
        }
      } else {
        if (down && down.pannable() && down.active()) {
          down.unactivate();
        }
        if ((!down || !down.grabbed()) && near != last) {
          if (last) {
            triggerEvents(last, ['mouseout', 'tapdragout'], e, {
              x: pos[0],
              y: pos[1]
            });
          }
          if (near) {
            triggerEvents(near, ['mouseover', 'tapdragover'], e, {
              x: pos[0],
              y: pos[1]
            });
          }
          r.hoverData.last = near;
        }
        if (down) {
          if (isOverThresholdDrag) {
            // then we can take action

            if (cy.boxSelectionEnabled() && multSelKeyDown) {
              // then selection overrides
              if (down && down.grabbed()) {
                freeDraggedElements(draggedElements);
                down.emit('freeon');
                draggedElements.emit('free');
                if (r.dragData.didDrag) {
                  down.emit('dragfreeon');
                  draggedElements.emit('dragfree');
                }
              }
              goIntoBoxMode();
            } else if (down && down.grabbed() && r.nodeIsDraggable(down)) {
              // drag node
              var justStartedDrag = !r.dragData.didDrag;
              if (justStartedDrag) {
                r.redrawHint('eles', true);
              }
              r.dragData.didDrag = true; // indicate that we actually did drag the node

              // now, add the elements to the drag layer if not done already
              if (!r.hoverData.draggingEles) {
                addNodesToDrag(draggedElements, {
                  inDragLayer: true
                });
              }
              var totalShift = {
                x: 0,
                y: 0
              };
              if (number$1(disp[0]) && number$1(disp[1])) {
                totalShift.x += disp[0];
                totalShift.y += disp[1];
                if (justStartedDrag) {
                  var dragDelta = r.hoverData.dragDelta;
                  if (dragDelta && number$1(dragDelta[0]) && number$1(dragDelta[1])) {
                    totalShift.x += dragDelta[0];
                    totalShift.y += dragDelta[1];
                  }
                }
              }
              r.hoverData.draggingEles = true;
              draggedElements.silentShift(totalShift).emit('position drag');
              r.redrawHint('drag', true);
              r.redraw();
            }
          } else {
            // otherwise save drag delta for when we actually start dragging so the relative grab pos is constant
            updateDragDelta();
          }
        }

        // prevent the dragging from triggering text selection on the page
        preventDefault = true;
      }
      select[2] = pos[0];
      select[3] = pos[1];
      if (preventDefault) {
        if (e.stopPropagation) e.stopPropagation();
        if (e.preventDefault) e.preventDefault();
        return false;
      }
    }, false);
    var clickTimeout, didDoubleClick, prevClickTimeStamp;
    r.registerBinding(containerWindow, 'mouseup', function mouseupHandler(e) {
      // eslint-disable-line no-undef
      var capture = r.hoverData.capture;
      if (!capture) {
        return;
      }
      r.hoverData.capture = false;
      var cy = r.cy;
      var pos = r.projectIntoViewport(e.clientX, e.clientY);
      var select = r.selection;
      var near = r.findNearestElement(pos[0], pos[1], true, false);
      var draggedElements = r.dragData.possibleDragElements;
      var down = r.hoverData.down;
      var multSelKeyDown = isMultSelKeyDown(e);
      if (r.data.bgActivePosistion) {
        r.redrawHint('select', true);
        r.redraw();
      }
      r.hoverData.tapholdCancelled = true;
      r.data.bgActivePosistion = undefined; // not active bg now

      if (down) {
        down.unactivate();
      }
      if (r.hoverData.which === 3) {
        var cxtEvt = {
          originalEvent: e,
          type: 'cxttapend',
          position: {
            x: pos[0],
            y: pos[1]
          }
        };
        if (down) {
          down.emit(cxtEvt);
        } else {
          cy.emit(cxtEvt);
        }
        if (!r.hoverData.cxtDragged) {
          var cxtTap = {
            originalEvent: e,
            type: 'cxttap',
            position: {
              x: pos[0],
              y: pos[1]
            }
          };
          if (down) {
            down.emit(cxtTap);
          } else {
            cy.emit(cxtTap);
          }
        }
        r.hoverData.cxtDragged = false;
        r.hoverData.which = null;
      } else if (r.hoverData.which === 1) {
        triggerEvents(near, ['mouseup', 'tapend', 'vmouseup'], e, {
          x: pos[0],
          y: pos[1]
        });
        if (!r.dragData.didDrag &&
        // didn't move a node around
        !r.hoverData.dragged &&
        // didn't pan
        !r.hoverData.selecting &&
        // not box selection
        !r.hoverData.isOverThresholdDrag // didn't move too much
        ) {
          triggerEvents(down, ["click", "tap", "vclick"], e, {
            x: pos[0],
            y: pos[1]
          });
          didDoubleClick = false;
          if (e.timeStamp - prevClickTimeStamp <= cy.multiClickDebounceTime()) {
            clickTimeout && clearTimeout(clickTimeout);
            didDoubleClick = true;
            prevClickTimeStamp = null;
            triggerEvents(down, ["dblclick", "dbltap", "vdblclick"], e, {
              x: pos[0],
              y: pos[1]
            });
          } else {
            clickTimeout = setTimeout(function () {
              if (didDoubleClick) return;
              triggerEvents(down, ["oneclick", "onetap", "voneclick"], e, {
                x: pos[0],
                y: pos[1]
              });
            }, cy.multiClickDebounceTime());
            prevClickTimeStamp = e.timeStamp;
          }
        }

        // Deselect all elements if nothing is currently under the mouse cursor and we aren't dragging something
        if (down == null // not mousedown on node
        && !r.dragData.didDrag // didn't move the node around
        && !r.hoverData.selecting // not box selection
        && !r.hoverData.dragged // didn't pan
        && !isMultSelKeyDown(e)) {
          cy.$(isSelected).unselect(['tapunselect']);
          if (draggedElements.length > 0) {
            r.redrawHint('eles', true);
          }
          r.dragData.possibleDragElements = draggedElements = cy.collection();
        }

        // Single selection
        if (near == down && !r.dragData.didDrag && !r.hoverData.selecting) {
          if (near != null && near._private.selectable) {
            if (r.hoverData.dragging) ; else if (cy.selectionType() === 'additive' || multSelKeyDown) {
              if (near.selected()) {
                near.unselect(['tapunselect']);
              } else {
                near.select(['tapselect']);
              }
            } else {
              if (!multSelKeyDown) {
                cy.$(isSelected).unmerge(near).unselect(['tapunselect']);
                near.select(['tapselect']);
              }
            }
            r.redrawHint('eles', true);
          }
        }
        if (r.hoverData.selecting) {
          var box = cy.collection(r.getAllInBox(select[0], select[1], select[2], select[3]));
          r.redrawHint('select', true);
          if (box.length > 0) {
            r.redrawHint('eles', true);
          }
          cy.emit({
            type: 'boxend',
            originalEvent: e,
            position: {
              x: pos[0],
              y: pos[1]
            }
          });
          var eleWouldBeSelected = function eleWouldBeSelected(ele) {
            return ele.selectable() && !ele.selected();
          };
          if (cy.selectionType() === 'additive') {
            box.emit('box').stdFilter(eleWouldBeSelected).select().emit('boxselect');
          } else {
            if (!multSelKeyDown) {
              cy.$(isSelected).unmerge(box).unselect();
            }
            box.emit('box').stdFilter(eleWouldBeSelected).select().emit('boxselect');
          }

          // always need redraw in case eles unselectable
          r.redraw();
        }

        // Cancel drag pan
        if (r.hoverData.dragging) {
          r.hoverData.dragging = false;
          r.redrawHint('select', true);
          r.redrawHint('eles', true);
          r.redraw();
        }
        if (!select[4]) {
          r.redrawHint('drag', true);
          r.redrawHint('eles', true);
          var downWasGrabbed = down && down.grabbed();
          freeDraggedElements(draggedElements);
          if (downWasGrabbed) {
            down.emit('freeon');
            draggedElements.emit('free');
            if (r.dragData.didDrag) {
              down.emit('dragfreeon');
              draggedElements.emit('dragfree');
            }
          }
        }
      } // else not right mouse

      select[4] = 0;
      r.hoverData.down = null;
      r.hoverData.cxtStarted = false;
      r.hoverData.draggingEles = false;
      r.hoverData.selecting = false;
      r.hoverData.isOverThresholdDrag = false;
      r.dragData.didDrag = false;
      r.hoverData.dragged = false;
      r.hoverData.dragDelta = [];
      r.hoverData.mdownPos = null;
      r.hoverData.mdownGPos = null;
    }, false);
    var wheelHandler = function wheelHandler(e) {
      if (r.scrollingPage) {
        return;
      } // while scrolling, ignore wheel-to-zoom

      var cy = r.cy;
      var zoom = cy.zoom();
      var pan = cy.pan();
      var pos = r.projectIntoViewport(e.clientX, e.clientY);
      var rpos = [pos[0] * zoom + pan.x, pos[1] * zoom + pan.y];
      if (r.hoverData.draggingEles || r.hoverData.dragging || r.hoverData.cxtStarted || inBoxSelection()) {
        // if pan dragging or cxt dragging, wheel movements make no zoom
        e.preventDefault();
        return;
      }
      if (cy.panningEnabled() && cy.userPanningEnabled() && cy.zoomingEnabled() && cy.userZoomingEnabled()) {
        e.preventDefault();
        r.data.wheelZooming = true;
        clearTimeout(r.data.wheelTimeout);
        r.data.wheelTimeout = setTimeout(function () {
          r.data.wheelZooming = false;
          r.redrawHint('eles', true);
          r.redraw();
        }, 150);
        var diff;
        if (e.deltaY != null) {
          diff = e.deltaY / -250;
        } else if (e.wheelDeltaY != null) {
          diff = e.wheelDeltaY / 1000;
        } else {
          diff = e.wheelDelta / 1000;
        }
        diff = diff * r.wheelSensitivity;
        var needsWheelFix = e.deltaMode === 1;
        if (needsWheelFix) {
          // fixes slow wheel events on ff/linux and ff/windows
          diff *= 33;
        }
        var newZoom = cy.zoom() * Math.pow(10, diff);
        if (e.type === 'gesturechange') {
          newZoom = r.gestureStartZoom * e.scale;
        }
        cy.zoom({
          level: newZoom,
          renderedPosition: {
            x: rpos[0],
            y: rpos[1]
          }
        });
        cy.emit(e.type === 'gesturechange' ? 'pinchzoom' : 'scrollzoom');
      }
    };

    // Functions to help with whether mouse wheel should trigger zooming
    // --
    r.registerBinding(r.container, 'wheel', wheelHandler, true);

    // disable nonstandard wheel events
    // r.registerBinding(r.container, 'mousewheel', wheelHandler, true);
    // r.registerBinding(r.container, 'DOMMouseScroll', wheelHandler, true);
    // r.registerBinding(r.container, 'MozMousePixelScroll', wheelHandler, true); // older firefox

    r.registerBinding(containerWindow, 'scroll', function scrollHandler(e) {
      // eslint-disable-line no-unused-vars
      r.scrollingPage = true;
      clearTimeout(r.scrollingPageTimeout);
      r.scrollingPageTimeout = setTimeout(function () {
        r.scrollingPage = false;
      }, 250);
    }, true);

    // desktop safari pinch to zoom start
    r.registerBinding(r.container, 'gesturestart', function gestureStartHandler(e) {
      r.gestureStartZoom = r.cy.zoom();
      if (!r.hasTouchStarted) {
        // don't affect touch devices like iphone
        e.preventDefault();
      }
    }, true);
    r.registerBinding(r.container, 'gesturechange', function (e) {
      if (!r.hasTouchStarted) {
        // don't affect touch devices like iphone
        wheelHandler(e);
      }
    }, true);

    // Functions to help with handling mouseout/mouseover on the Cytoscape container
    // Handle mouseout on Cytoscape container
    r.registerBinding(r.container, 'mouseout', function mouseOutHandler(e) {
      var pos = r.projectIntoViewport(e.clientX, e.clientY);
      r.cy.emit({
        originalEvent: e,
        type: 'mouseout',
        position: {
          x: pos[0],
          y: pos[1]
        }
      });
    }, false);
    r.registerBinding(r.container, 'mouseover', function mouseOverHandler(e) {
      var pos = r.projectIntoViewport(e.clientX, e.clientY);
      r.cy.emit({
        originalEvent: e,
        type: 'mouseover',
        position: {
          x: pos[0],
          y: pos[1]
        }
      });
    }, false);
    var f1x1, f1y1, f2x1, f2y1; // starting points for pinch-to-zoom
    var distance1, distance1Sq; // initial distance between finger 1 and finger 2 for pinch-to-zoom
    var center1, modelCenter1; // center point on start pinch to zoom
    var offsetLeft, offsetTop;
    var containerWidth, containerHeight;
    var twoFingersStartInside;
    var distance = function distance(x1, y1, x2, y2) {
      return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
    };
    var distanceSq = function distanceSq(x1, y1, x2, y2) {
      return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
    };
    var touchstartHandler;
    r.registerBinding(r.container, 'touchstart', touchstartHandler = function touchstartHandler(e) {
      r.hasTouchStarted = true;
      if (!eventInContainer(e)) {
        return;
      }
      blurActiveDomElement();
      r.touchData.capture = true;
      r.data.bgActivePosistion = undefined;
      var cy = r.cy;
      var now = r.touchData.now;
      var earlier = r.touchData.earlier;
      if (e.touches[0]) {
        var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);
        now[0] = pos[0];
        now[1] = pos[1];
      }
      if (e.touches[1]) {
        var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY);
        now[2] = pos[0];
        now[3] = pos[1];
      }
      if (e.touches[2]) {
        var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY);
        now[4] = pos[0];
        now[5] = pos[1];
      }

      // record starting points for pinch-to-zoom
      if (e.touches[1]) {
        r.touchData.singleTouchMoved = true;
        freeDraggedElements(r.dragData.touchDragEles);
        var offsets = r.findContainerClientCoords();
        offsetLeft = offsets[0];
        offsetTop = offsets[1];
        containerWidth = offsets[2];
        containerHeight = offsets[3];
        f1x1 = e.touches[0].clientX - offsetLeft;
        f1y1 = e.touches[0].clientY - offsetTop;
        f2x1 = e.touches[1].clientX - offsetLeft;
        f2y1 = e.touches[1].clientY - offsetTop;
        twoFingersStartInside = 0 <= f1x1 && f1x1 <= containerWidth && 0 <= f2x1 && f2x1 <= containerWidth && 0 <= f1y1 && f1y1 <= containerHeight && 0 <= f2y1 && f2y1 <= containerHeight;
        var pan = cy.pan();
        var zoom = cy.zoom();
        distance1 = distance(f1x1, f1y1, f2x1, f2y1);
        distance1Sq = distanceSq(f1x1, f1y1, f2x1, f2y1);
        center1 = [(f1x1 + f2x1) / 2, (f1y1 + f2y1) / 2];
        modelCenter1 = [(center1[0] - pan.x) / zoom, (center1[1] - pan.y) / zoom];

        // consider context tap
        var cxtDistThreshold = 200;
        var cxtDistThresholdSq = cxtDistThreshold * cxtDistThreshold;
        if (distance1Sq < cxtDistThresholdSq && !e.touches[2]) {
          var near1 = r.findNearestElement(now[0], now[1], true, true);
          var near2 = r.findNearestElement(now[2], now[3], true, true);
          if (near1 && near1.isNode()) {
            near1.activate().emit({
              originalEvent: e,
              type: 'cxttapstart',
              position: {
                x: now[0],
                y: now[1]
              }
            });
            r.touchData.start = near1;
          } else if (near2 && near2.isNode()) {
            near2.activate().emit({
              originalEvent: e,
              type: 'cxttapstart',
              position: {
                x: now[0],
                y: now[1]
              }
            });
            r.touchData.start = near2;
          } else {
            cy.emit({
              originalEvent: e,
              type: 'cxttapstart',
              position: {
                x: now[0],
                y: now[1]
              }
            });
          }
          if (r.touchData.start) {
            r.touchData.start._private.grabbed = false;
          }
          r.touchData.cxt = true;
          r.touchData.cxtDragged = false;
          r.data.bgActivePosistion = undefined;
          r.redraw();
          return;
        }
      }
      if (e.touches[2]) {
        // ignore

        // safari on ios pans the page otherwise (normally you should be able to preventdefault on touchmove...)
        if (cy.boxSelectionEnabled()) {
          e.preventDefault();
        }
      } else if (e.touches[1]) ; else if (e.touches[0]) {
        var nears = r.findNearestElements(now[0], now[1], true, true);
        var near = nears[0];
        if (near != null) {
          near.activate();
          r.touchData.start = near;
          r.touchData.starts = nears;
          if (r.nodeIsGrabbable(near)) {
            var draggedEles = r.dragData.touchDragEles = cy.collection();
            var selectedNodes = null;
            r.redrawHint('eles', true);
            r.redrawHint('drag', true);
            if (near.selected()) {
              // reset drag elements, since near will be added again

              selectedNodes = cy.$(function (ele) {
                return ele.selected() && r.nodeIsGrabbable(ele);
              });
              addNodesToDrag(selectedNodes, {
                addToList: draggedEles
              });
            } else {
              addNodeToDrag(near, {
                addToList: draggedEles
              });
            }
            setGrabTarget(near);
            var makeEvent = function makeEvent(type) {
              return {
                originalEvent: e,
                type: type,
                position: {
                  x: now[0],
                  y: now[1]
                }
              };
            };
            near.emit(makeEvent('grabon'));
            if (selectedNodes) {
              selectedNodes.forEach(function (n) {
                n.emit(makeEvent('grab'));
              });
            } else {
              near.emit(makeEvent('grab'));
            }
          }
        }
        triggerEvents(near, ['touchstart', 'tapstart', 'vmousedown'], e, {
          x: now[0],
          y: now[1]
        });
        if (near == null) {
          r.data.bgActivePosistion = {
            x: pos[0],
            y: pos[1]
          };
          r.redrawHint('select', true);
          r.redraw();
        }

        // Tap, taphold
        // -----

        r.touchData.singleTouchMoved = false;
        r.touchData.singleTouchStartTime = +new Date();
        clearTimeout(r.touchData.tapholdTimeout);
        r.touchData.tapholdTimeout = setTimeout(function () {
          if (r.touchData.singleTouchMoved === false && !r.pinching // if pinching, then taphold unselect shouldn't take effect
          && !r.touchData.selecting // box selection shouldn't allow taphold through
          ) {
            triggerEvents(r.touchData.start, ['taphold'], e, {
              x: now[0],
              y: now[1]
            });
          }
        }, r.tapholdDuration);
      }
      if (e.touches.length >= 1) {
        var sPos = r.touchData.startPosition = [null, null, null, null, null, null];
        for (var i = 0; i < now.length; i++) {
          sPos[i] = earlier[i] = now[i];
        }
        var touch0 = e.touches[0];
        r.touchData.startGPosition = [touch0.clientX, touch0.clientY];
      }
    }, false);
    var touchmoveHandler;
    r.registerBinding(window, 'touchmove', touchmoveHandler = function touchmoveHandler(e) {
      // eslint-disable-line no-undef
      var capture = r.touchData.capture;
      if (!capture && !eventInContainer(e)) {
        return;
      }
      var select = r.selection;
      var cy = r.cy;
      var now = r.touchData.now;
      var earlier = r.touchData.earlier;
      var zoom = cy.zoom();
      if (e.touches[0]) {
        var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);
        now[0] = pos[0];
        now[1] = pos[1];
      }
      if (e.touches[1]) {
        var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY);
        now[2] = pos[0];
        now[3] = pos[1];
      }
      if (e.touches[2]) {
        var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY);
        now[4] = pos[0];
        now[5] = pos[1];
      }
      var startGPos = r.touchData.startGPosition;
      var isOverThresholdDrag;
      if (capture && e.touches[0] && startGPos) {
        var disp = [];
        for (var j = 0; j < now.length; j++) {
          disp[j] = now[j] - earlier[j];
        }
        var dx = e.touches[0].clientX - startGPos[0];
        var dx2 = dx * dx;
        var dy = e.touches[0].clientY - startGPos[1];
        var dy2 = dy * dy;
        var dist2 = dx2 + dy2;
        isOverThresholdDrag = dist2 >= r.touchTapThreshold2;
      }

      // context swipe cancelling
      if (capture && r.touchData.cxt) {
        e.preventDefault();
        var f1x2 = e.touches[0].clientX - offsetLeft,
          f1y2 = e.touches[0].clientY - offsetTop;
        var f2x2 = e.touches[1].clientX - offsetLeft,
          f2y2 = e.touches[1].clientY - offsetTop;
        // var distance2 = distance( f1x2, f1y2, f2x2, f2y2 );
        var distance2Sq = distanceSq(f1x2, f1y2, f2x2, f2y2);
        var factorSq = distance2Sq / distance1Sq;
        var distThreshold = 150;
        var distThresholdSq = distThreshold * distThreshold;
        var factorThreshold = 1.5;
        var factorThresholdSq = factorThreshold * factorThreshold;

        // cancel ctx gestures if the distance b/t the fingers increases
        if (factorSq >= factorThresholdSq || distance2Sq >= distThresholdSq) {
          r.touchData.cxt = false;
          r.data.bgActivePosistion = undefined;
          r.redrawHint('select', true);
          var cxtEvt = {
            originalEvent: e,
            type: 'cxttapend',
            position: {
              x: now[0],
              y: now[1]
            }
          };
          if (r.touchData.start) {
            r.touchData.start.unactivate().emit(cxtEvt);
            r.touchData.start = null;
          } else {
            cy.emit(cxtEvt);
          }
        }
      }

      // context swipe
      if (capture && r.touchData.cxt) {
        var cxtEvt = {
          originalEvent: e,
          type: 'cxtdrag',
          position: {
            x: now[0],
            y: now[1]
          }
        };
        r.data.bgActivePosistion = undefined;
        r.redrawHint('select', true);
        if (r.touchData.start) {
          r.touchData.start.emit(cxtEvt);
        } else {
          cy.emit(cxtEvt);
        }
        if (r.touchData.start) {
          r.touchData.start._private.grabbed = false;
        }
        r.touchData.cxtDragged = true;
        var near = r.findNearestElement(now[0], now[1], true, true);
        if (!r.touchData.cxtOver || near !== r.touchData.cxtOver) {
          if (r.touchData.cxtOver) {
            r.touchData.cxtOver.emit({
              originalEvent: e,
              type: 'cxtdragout',
              position: {
                x: now[0],
                y: now[1]
              }
            });
          }
          r.touchData.cxtOver = near;
          if (near) {
            near.emit({
              originalEvent: e,
              type: 'cxtdragover',
              position: {
                x: now[0],
                y: now[1]
              }
            });
          }
        }

        // box selection
      } else if (capture && e.touches[2] && cy.boxSelectionEnabled()) {
        e.preventDefault();
        r.data.bgActivePosistion = undefined;
        this.lastThreeTouch = +new Date();
        if (!r.touchData.selecting) {
          cy.emit({
            originalEvent: e,
            type: 'boxstart',
            position: {
              x: now[0],
              y: now[1]
            }
          });
        }
        r.touchData.selecting = true;
        r.touchData.didSelect = true;
        select[4] = 1;
        if (!select || select.length === 0 || select[0] === undefined) {
          select[0] = (now[0] + now[2] + now[4]) / 3;
          select[1] = (now[1] + now[3] + now[5]) / 3;
          select[2] = (now[0] + now[2] + now[4]) / 3 + 1;
          select[3] = (now[1] + now[3] + now[5]) / 3 + 1;
        } else {
          select[2] = (now[0] + now[2] + now[4]) / 3;
          select[3] = (now[1] + now[3] + now[5]) / 3;
        }
        r.redrawHint('select', true);
        r.redraw();

        // pinch to zoom
      } else if (capture && e.touches[1] && !r.touchData.didSelect // don't allow box selection to degrade to pinch-to-zoom
      && cy.zoomingEnabled() && cy.panningEnabled() && cy.userZoomingEnabled() && cy.userPanningEnabled()) {
        // two fingers => pinch to zoom
        e.preventDefault();
        r.data.bgActivePosistion = undefined;
        r.redrawHint('select', true);
        var draggedEles = r.dragData.touchDragEles;
        if (draggedEles) {
          r.redrawHint('drag', true);
          for (var i = 0; i < draggedEles.length; i++) {
            var de_p = draggedEles[i]._private;
            de_p.grabbed = false;
            de_p.rscratch.inDragLayer = false;
          }
        }
        var _start = r.touchData.start;

        // (x2, y2) for fingers 1 and 2
        var f1x2 = e.touches[0].clientX - offsetLeft,
          f1y2 = e.touches[0].clientY - offsetTop;
        var f2x2 = e.touches[1].clientX - offsetLeft,
          f2y2 = e.touches[1].clientY - offsetTop;
        var distance2 = distance(f1x2, f1y2, f2x2, f2y2);
        // var distance2Sq = distanceSq( f1x2, f1y2, f2x2, f2y2 );
        // var factor = Math.sqrt( distance2Sq ) / Math.sqrt( distance1Sq );
        var factor = distance2 / distance1;
        if (twoFingersStartInside) {
          // delta finger1
          var df1x = f1x2 - f1x1;
          var df1y = f1y2 - f1y1;

          // delta finger 2
          var df2x = f2x2 - f2x1;
          var df2y = f2y2 - f2y1;

          // translation is the normalised vector of the two fingers movement
          // i.e. so pinching cancels out and moving together pans
          var tx = (df1x + df2x) / 2;
          var ty = (df1y + df2y) / 2;

          // now calculate the zoom
          var zoom1 = cy.zoom();
          var zoom2 = zoom1 * factor;
          var pan1 = cy.pan();

          // the model center point converted to the current rendered pos
          var ctrx = modelCenter1[0] * zoom1 + pan1.x;
          var ctry = modelCenter1[1] * zoom1 + pan1.y;
          var pan2 = {
            x: -zoom2 / zoom1 * (ctrx - pan1.x - tx) + ctrx,
            y: -zoom2 / zoom1 * (ctry - pan1.y - ty) + ctry
          };

          // remove dragged eles
          if (_start && _start.active()) {
            var draggedEles = r.dragData.touchDragEles;
            freeDraggedElements(draggedEles);
            r.redrawHint('drag', true);
            r.redrawHint('eles', true);
            _start.unactivate().emit('freeon');
            draggedEles.emit('free');
            if (r.dragData.didDrag) {
              _start.emit('dragfreeon');
              draggedEles.emit('dragfree');
            }
          }
          cy.viewport({
            zoom: zoom2,
            pan: pan2,
            cancelOnFailedZoom: true
          });
          cy.emit('pinchzoom');
          distance1 = distance2;
          f1x1 = f1x2;
          f1y1 = f1y2;
          f2x1 = f2x2;
          f2y1 = f2y2;
          r.pinching = true;
        }

        // Re-project
        if (e.touches[0]) {
          var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);
          now[0] = pos[0];
          now[1] = pos[1];
        }
        if (e.touches[1]) {
          var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY);
          now[2] = pos[0];
          now[3] = pos[1];
        }
        if (e.touches[2]) {
          var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY);
          now[4] = pos[0];
          now[5] = pos[1];
        }
      } else if (e.touches[0] && !r.touchData.didSelect // don't allow box selection to degrade to single finger events like panning
      ) {
        var start = r.touchData.start;
        var last = r.touchData.last;
        var near;
        if (!r.hoverData.draggingEles && !r.swipePanning) {
          near = r.findNearestElement(now[0], now[1], true, true);
        }
        if (capture && start != null) {
          e.preventDefault();
        }

        // dragging nodes
        if (capture && start != null && r.nodeIsDraggable(start)) {
          if (isOverThresholdDrag) {
            // then dragging can happen
            var draggedEles = r.dragData.touchDragEles;
            var justStartedDrag = !r.dragData.didDrag;
            if (justStartedDrag) {
              addNodesToDrag(draggedEles, {
                inDragLayer: true
              });
            }
            r.dragData.didDrag = true;
            var totalShift = {
              x: 0,
              y: 0
            };
            if (number$1(disp[0]) && number$1(disp[1])) {
              totalShift.x += disp[0];
              totalShift.y += disp[1];
              if (justStartedDrag) {
                r.redrawHint('eles', true);
                var dragDelta = r.touchData.dragDelta;
                if (dragDelta && number$1(dragDelta[0]) && number$1(dragDelta[1])) {
                  totalShift.x += dragDelta[0];
                  totalShift.y += dragDelta[1];
                }
              }
            }
            r.hoverData.draggingEles = true;
            draggedEles.silentShift(totalShift).emit('position drag');
            r.redrawHint('drag', true);
            if (r.touchData.startPosition[0] == earlier[0] && r.touchData.startPosition[1] == earlier[1]) {
              r.redrawHint('eles', true);
            }
            r.redraw();
          } else {
            // otherwise keep track of drag delta for later
            var dragDelta = r.touchData.dragDelta = r.touchData.dragDelta || [];
            if (dragDelta.length === 0) {
              dragDelta.push(disp[0]);
              dragDelta.push(disp[1]);
            } else {
              dragDelta[0] += disp[0];
              dragDelta[1] += disp[1];
            }
          }
        }

        // touchmove
        {
          triggerEvents(start || near, ['touchmove', 'tapdrag', 'vmousemove'], e, {
            x: now[0],
            y: now[1]
          });
          if ((!start || !start.grabbed()) && near != last) {
            if (last) {
              last.emit({
                originalEvent: e,
                type: 'tapdragout',
                position: {
                  x: now[0],
                  y: now[1]
                }
              });
            }
            if (near) {
              near.emit({
                originalEvent: e,
                type: 'tapdragover',
                position: {
                  x: now[0],
                  y: now[1]
                }
              });
            }
          }
          r.touchData.last = near;
        }

        // check to cancel taphold
        if (capture) {
          for (var i = 0; i < now.length; i++) {
            if (now[i] && r.touchData.startPosition[i] && isOverThresholdDrag) {
              r.touchData.singleTouchMoved = true;
            }
          }
        }

        // panning
        if (capture && (start == null || start.pannable()) && cy.panningEnabled() && cy.userPanningEnabled()) {
          var allowPassthrough = allowPanningPassthrough(start, r.touchData.starts);
          if (allowPassthrough) {
            e.preventDefault();
            if (!r.data.bgActivePosistion) {
              r.data.bgActivePosistion = array2point(r.touchData.startPosition);
            }
            if (r.swipePanning) {
              cy.panBy({
                x: disp[0] * zoom,
                y: disp[1] * zoom
              });
              cy.emit('dragpan');
            } else if (isOverThresholdDrag) {
              r.swipePanning = true;
              cy.panBy({
                x: dx * zoom,
                y: dy * zoom
              });
              cy.emit('dragpan');
              if (start) {
                start.unactivate();
                r.redrawHint('select', true);
                r.touchData.start = null;
              }
            }
          }

          // Re-project
          var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);
          now[0] = pos[0];
          now[1] = pos[1];
        }
      }
      for (var j = 0; j < now.length; j++) {
        earlier[j] = now[j];
      }

      // the active bg indicator should be removed when making a swipe that is neither for dragging nodes or panning
      if (capture && e.touches.length > 0 && !r.hoverData.draggingEles && !r.swipePanning && r.data.bgActivePosistion != null) {
        r.data.bgActivePosistion = undefined;
        r.redrawHint('select', true);
        r.redraw();
      }
    }, false);
    var touchcancelHandler;
    r.registerBinding(containerWindow, 'touchcancel', touchcancelHandler = function touchcancelHandler(e) {
      // eslint-disable-line no-unused-vars
      var start = r.touchData.start;
      r.touchData.capture = false;
      if (start) {
        start.unactivate();
      }
    });
    var touchendHandler, didDoubleTouch, touchTimeout, prevTouchTimeStamp;
    r.registerBinding(containerWindow, 'touchend', touchendHandler = function touchendHandler(e) {
      // eslint-disable-line no-unused-vars
      var start = r.touchData.start;
      var capture = r.touchData.capture;
      if (capture) {
        if (e.touches.length === 0) {
          r.touchData.capture = false;
        }
        e.preventDefault();
      } else {
        return;
      }
      var select = r.selection;
      r.swipePanning = false;
      r.hoverData.draggingEles = false;
      var cy = r.cy;
      var zoom = cy.zoom();
      var now = r.touchData.now;
      var earlier = r.touchData.earlier;
      if (e.touches[0]) {
        var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);
        now[0] = pos[0];
        now[1] = pos[1];
      }
      if (e.touches[1]) {
        var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY);
        now[2] = pos[0];
        now[3] = pos[1];
      }
      if (e.touches[2]) {
        var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY);
        now[4] = pos[0];
        now[5] = pos[1];
      }
      if (start) {
        start.unactivate();
      }
      var ctxTapend;
      if (r.touchData.cxt) {
        ctxTapend = {
          originalEvent: e,
          type: 'cxttapend',
          position: {
            x: now[0],
            y: now[1]
          }
        };
        if (start) {
          start.emit(ctxTapend);
        } else {
          cy.emit(ctxTapend);
        }
        if (!r.touchData.cxtDragged) {
          var ctxTap = {
            originalEvent: e,
            type: 'cxttap',
            position: {
              x: now[0],
              y: now[1]
            }
          };
          if (start) {
            start.emit(ctxTap);
          } else {
            cy.emit(ctxTap);
          }
        }
        if (r.touchData.start) {
          r.touchData.start._private.grabbed = false;
        }
        r.touchData.cxt = false;
        r.touchData.start = null;
        r.redraw();
        return;
      }

      // no more box selection if we don't have three fingers
      if (!e.touches[2] && cy.boxSelectionEnabled() && r.touchData.selecting) {
        r.touchData.selecting = false;
        var box = cy.collection(r.getAllInBox(select[0], select[1], select[2], select[3]));
        select[0] = undefined;
        select[1] = undefined;
        select[2] = undefined;
        select[3] = undefined;
        select[4] = 0;
        r.redrawHint('select', true);
        cy.emit({
          type: 'boxend',
          originalEvent: e,
          position: {
            x: now[0],
            y: now[1]
          }
        });
        var eleWouldBeSelected = function eleWouldBeSelected(ele) {
          return ele.selectable() && !ele.selected();
        };
        box.emit('box').stdFilter(eleWouldBeSelected).select().emit('boxselect');
        if (box.nonempty()) {
          r.redrawHint('eles', true);
        }
        r.redraw();
      }
      if (start != null) {
        start.unactivate();
      }
      if (e.touches[2]) {
        r.data.bgActivePosistion = undefined;
        r.redrawHint('select', true);
      } else if (e.touches[1]) ; else if (e.touches[0]) ; else if (!e.touches[0]) {
        r.data.bgActivePosistion = undefined;
        r.redrawHint('select', true);
        var draggedEles = r.dragData.touchDragEles;
        if (start != null) {
          var startWasGrabbed = start._private.grabbed;
          freeDraggedElements(draggedEles);
          r.redrawHint('drag', true);
          r.redrawHint('eles', true);
          if (startWasGrabbed) {
            start.emit('freeon');
            draggedEles.emit('free');
            if (r.dragData.didDrag) {
              start.emit('dragfreeon');
              draggedEles.emit('dragfree');
            }
          }
          triggerEvents(start, ['touchend', 'tapend', 'vmouseup', 'tapdragout'], e, {
            x: now[0],
            y: now[1]
          });
          start.unactivate();
          r.touchData.start = null;
        } else {
          var near = r.findNearestElement(now[0], now[1], true, true);
          triggerEvents(near, ['touchend', 'tapend', 'vmouseup', 'tapdragout'], e, {
            x: now[0],
            y: now[1]
          });
        }
        var dx = r.touchData.startPosition[0] - now[0];
        var dx2 = dx * dx;
        var dy = r.touchData.startPosition[1] - now[1];
        var dy2 = dy * dy;
        var dist2 = dx2 + dy2;
        var rdist2 = dist2 * zoom * zoom;

        // Tap event, roughly same as mouse click event for touch
        if (!r.touchData.singleTouchMoved) {
          if (!start) {
            cy.$(':selected').unselect(['tapunselect']);
          }
          triggerEvents(start, ['tap', 'vclick'], e, {
            x: now[0],
            y: now[1]
          });
          didDoubleTouch = false;
          if (e.timeStamp - prevTouchTimeStamp <= cy.multiClickDebounceTime()) {
            touchTimeout && clearTimeout(touchTimeout);
            didDoubleTouch = true;
            prevTouchTimeStamp = null;
            triggerEvents(start, ['dbltap', 'vdblclick'], e, {
              x: now[0],
              y: now[1]
            });
          } else {
            touchTimeout = setTimeout(function () {
              if (didDoubleTouch) return;
              triggerEvents(start, ['onetap', 'voneclick'], e, {
                x: now[0],
                y: now[1]
              });
            }, cy.multiClickDebounceTime());
            prevTouchTimeStamp = e.timeStamp;
          }
        }

        // Prepare to select the currently touched node, only if it hasn't been dragged past a certain distance
        if (start != null && !r.dragData.didDrag // didn't drag nodes around
        && start._private.selectable && rdist2 < r.touchTapThreshold2 && !r.pinching // pinch to zoom should not affect selection
        ) {
          if (cy.selectionType() === 'single') {
            cy.$(isSelected).unmerge(start).unselect(['tapunselect']);
            start.select(['tapselect']);
          } else {
            if (start.selected()) {
              start.unselect(['tapunselect']);
            } else {
              start.select(['tapselect']);
            }
          }
          r.redrawHint('eles', true);
        }
        r.touchData.singleTouchMoved = true;
      }
      for (var j = 0; j < now.length; j++) {
        earlier[j] = now[j];
      }
      r.dragData.didDrag = false; // reset for next touchstart

      if (e.touches.length === 0) {
        r.touchData.dragDelta = [];
        r.touchData.startPosition = [null, null, null, null, null, null];
        r.touchData.startGPosition = null;
        r.touchData.didSelect = false;
      }
      if (e.touches.length < 2) {
        if (e.touches.length === 1) {
          // the old start global pos'n may not be the same finger that remains
          r.touchData.startGPosition = [e.touches[0].clientX, e.touches[0].clientY];
        }
        r.pinching = false;
        r.redrawHint('eles', true);
        r.redraw();
      }

      //r.redraw();
    }, false);

    // fallback compatibility layer for ms pointer events
    if (typeof TouchEvent === 'undefined') {
      var pointers = [];
      var makeTouch = function makeTouch(e) {
        return {
          clientX: e.clientX,
          clientY: e.clientY,
          force: 1,
          identifier: e.pointerId,
          pageX: e.pageX,
          pageY: e.pageY,
          radiusX: e.width / 2,
          radiusY: e.height / 2,
          screenX: e.screenX,
          screenY: e.screenY,
          target: e.target
        };
      };
      var makePointer = function makePointer(e) {
        return {
          event: e,
          touch: makeTouch(e)
        };
      };
      var addPointer = function addPointer(e) {
        pointers.push(makePointer(e));
      };
      var removePointer = function removePointer(e) {
        for (var i = 0; i < pointers.length; i++) {
          var p = pointers[i];
          if (p.event.pointerId === e.pointerId) {
            pointers.splice(i, 1);
            return;
          }
        }
      };
      var updatePointer = function updatePointer(e) {
        var p = pointers.filter(function (p) {
          return p.event.pointerId === e.pointerId;
        })[0];
        p.event = e;
        p.touch = makeTouch(e);
      };
      var addTouchesToEvent = function addTouchesToEvent(e) {
        e.touches = pointers.map(function (p) {
          return p.touch;
        });
      };
      var pointerIsMouse = function pointerIsMouse(e) {
        return e.pointerType === 'mouse' || e.pointerType === 4;
      };
      r.registerBinding(r.container, 'pointerdown', function (e) {
        if (pointerIsMouse(e)) {
          return;
        } // mouse already handled

        e.preventDefault();
        addPointer(e);
        addTouchesToEvent(e);
        touchstartHandler(e);
      });
      r.registerBinding(r.container, 'pointerup', function (e) {
        if (pointerIsMouse(e)) {
          return;
        } // mouse already handled

        removePointer(e);
        addTouchesToEvent(e);
        touchendHandler(e);
      });
      r.registerBinding(r.container, 'pointercancel', function (e) {
        if (pointerIsMouse(e)) {
          return;
        } // mouse already handled

        removePointer(e);
        addTouchesToEvent(e);
        touchcancelHandler(e);
      });
      r.registerBinding(r.container, 'pointermove', function (e) {
        if (pointerIsMouse(e)) {
          return;
        } // mouse already handled

        e.preventDefault();
        updatePointer(e);
        addTouchesToEvent(e);
        touchmoveHandler(e);
      });
    }
  };

  var BRp$2 = {};
  BRp$2.generatePolygon = function (name, points) {
    return this.nodeShapes[name] = {
      renderer: this,
      name: name,
      points: points,
      draw: function draw(context, centerX, centerY, width, height) {
        this.renderer.nodeShapeImpl('polygon', context, centerX, centerY, width, height, this.points);
      },
      intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) {
        return polygonIntersectLine(x, y, this.points, nodeX, nodeY, width / 2, height / 2, padding);
      },
      checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) {
        return pointInsidePolygon(x, y, this.points, centerX, centerY, width, height, [0, -1], padding);
      }
    };
  };
  BRp$2.generateEllipse = function () {
    return this.nodeShapes['ellipse'] = {
      renderer: this,
      name: 'ellipse',
      draw: function draw(context, centerX, centerY, width, height) {
        this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height);
      },
      intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) {
        return intersectLineEllipse(x, y, nodeX, nodeY, width / 2 + padding, height / 2 + padding);
      },
      checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) {
        return checkInEllipse(x, y, width, height, centerX, centerY, padding);
      }
    };
  };
  BRp$2.generateRoundPolygon = function (name, points) {
    // Pre-compute control points
    // Since these points depend on the radius length (which in turns depend on the width/height of the node) we will only pre-compute
    // the unit vectors.
    // For simplicity the layout will be:
    // [ p0, UnitVectorP0P1, p1, UniVectorP1P2, ..., pn, UnitVectorPnP0 ]
    var allPoints = new Array(points.length * 2);
    for (var i = 0; i < points.length / 2; i++) {
      var sourceIndex = i * 2;
      var destIndex = void 0;
      if (i < points.length / 2 - 1) {
        destIndex = (i + 1) * 2;
      } else {
        destIndex = 0;
      }
      allPoints[i * 4] = points[sourceIndex];
      allPoints[i * 4 + 1] = points[sourceIndex + 1];
      var xDest = points[destIndex] - points[sourceIndex];
      var yDest = points[destIndex + 1] - points[sourceIndex + 1];
      var norm = Math.sqrt(xDest * xDest + yDest * yDest);
      allPoints[i * 4 + 2] = xDest / norm;
      allPoints[i * 4 + 3] = yDest / norm;
    }
    return this.nodeShapes[name] = {
      renderer: this,
      name: name,
      points: allPoints,
      draw: function draw(context, centerX, centerY, width, height) {
        this.renderer.nodeShapeImpl('round-polygon', context, centerX, centerY, width, height, this.points);
      },
      intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) {
        return roundPolygonIntersectLine(x, y, this.points, nodeX, nodeY, width, height);
      },
      checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) {
        return pointInsideRoundPolygon(x, y, this.points, centerX, centerY, width, height);
      }
    };
  };
  BRp$2.generateRoundRectangle = function () {
    return this.nodeShapes['round-rectangle'] = this.nodeShapes['roundrectangle'] = {
      renderer: this,
      name: 'round-rectangle',
      points: generateUnitNgonPointsFitToSquare(4, 0),
      draw: function draw(context, centerX, centerY, width, height) {
        this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height);
      },
      intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) {
        return roundRectangleIntersectLine(x, y, nodeX, nodeY, width, height, padding);
      },
      checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) {
        var cornerRadius = getRoundRectangleRadius(width, height);
        var diam = cornerRadius * 2;

        // Check hBox
        if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - diam, [0, -1], padding)) {
          return true;
        }

        // Check vBox
        if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - diam, height, [0, -1], padding)) {
          return true;
        }

        // Check top left quarter circle
        if (checkInEllipse(x, y, diam, diam, centerX - width / 2 + cornerRadius, centerY - height / 2 + cornerRadius, padding)) {
          return true;
        }

        // Check top right quarter circle
        if (checkInEllipse(x, y, diam, diam, centerX + width / 2 - cornerRadius, centerY - height / 2 + cornerRadius, padding)) {
          return true;
        }

        // Check bottom right quarter circle
        if (checkInEllipse(x, y, diam, diam, centerX + width / 2 - cornerRadius, centerY + height / 2 - cornerRadius, padding)) {
          return true;
        }

        // Check bottom left quarter circle
        if (checkInEllipse(x, y, diam, diam, centerX - width / 2 + cornerRadius, centerY + height / 2 - cornerRadius, padding)) {
          return true;
        }
        return false;
      }
    };
  };
  BRp$2.generateCutRectangle = function () {
    return this.nodeShapes['cut-rectangle'] = this.nodeShapes['cutrectangle'] = {
      renderer: this,
      name: 'cut-rectangle',
      cornerLength: getCutRectangleCornerLength(),
      points: generateUnitNgonPointsFitToSquare(4, 0),
      draw: function draw(context, centerX, centerY, width, height) {
        this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height);
      },
      generateCutTrianglePts: function generateCutTrianglePts(width, height, centerX, centerY) {
        var cl = this.cornerLength;
        var hh = height / 2;
        var hw = width / 2;
        var xBegin = centerX - hw;
        var xEnd = centerX + hw;
        var yBegin = centerY - hh;
        var yEnd = centerY + hh;

        // points are in clockwise order, inner (imaginary) triangle pt on [4, 5]
        return {
          topLeft: [xBegin, yBegin + cl, xBegin + cl, yBegin, xBegin + cl, yBegin + cl],
          topRight: [xEnd - cl, yBegin, xEnd, yBegin + cl, xEnd - cl, yBegin + cl],
          bottomRight: [xEnd, yEnd - cl, xEnd - cl, yEnd, xEnd - cl, yEnd - cl],
          bottomLeft: [xBegin + cl, yEnd, xBegin, yEnd - cl, xBegin + cl, yEnd - cl]
        };
      },
      intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) {
        var cPts = this.generateCutTrianglePts(width + 2 * padding, height + 2 * padding, nodeX, nodeY);
        var pts = [].concat.apply([], [cPts.topLeft.splice(0, 4), cPts.topRight.splice(0, 4), cPts.bottomRight.splice(0, 4), cPts.bottomLeft.splice(0, 4)]);
        return polygonIntersectLine(x, y, pts, nodeX, nodeY);
      },
      checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) {
        // Check hBox
        if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - 2 * this.cornerLength, [0, -1], padding)) {
          return true;
        }

        // Check vBox
        if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - 2 * this.cornerLength, height, [0, -1], padding)) {
          return true;
        }
        var cutTrianglePts = this.generateCutTrianglePts(width, height, centerX, centerY);
        return pointInsidePolygonPoints(x, y, cutTrianglePts.topLeft) || pointInsidePolygonPoints(x, y, cutTrianglePts.topRight) || pointInsidePolygonPoints(x, y, cutTrianglePts.bottomRight) || pointInsidePolygonPoints(x, y, cutTrianglePts.bottomLeft);
      }
    };
  };
  BRp$2.generateBarrel = function () {
    return this.nodeShapes['barrel'] = {
      renderer: this,
      name: 'barrel',
      points: generateUnitNgonPointsFitToSquare(4, 0),
      draw: function draw(context, centerX, centerY, width, height) {
        this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height);
      },
      intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) {
        // use two fixed t values for the bezier curve approximation

        var t0 = 0.15;
        var t1 = 0.5;
        var t2 = 0.85;
        var bPts = this.generateBarrelBezierPts(width + 2 * padding, height + 2 * padding, nodeX, nodeY);
        var approximateBarrelCurvePts = function approximateBarrelCurvePts(pts) {
          // approximate curve pts based on the two t values
          var m0 = qbezierPtAt({
            x: pts[0],
            y: pts[1]
          }, {
            x: pts[2],
            y: pts[3]
          }, {
            x: pts[4],
            y: pts[5]
          }, t0);
          var m1 = qbezierPtAt({
            x: pts[0],
            y: pts[1]
          }, {
            x: pts[2],
            y: pts[3]
          }, {
            x: pts[4],
            y: pts[5]
          }, t1);
          var m2 = qbezierPtAt({
            x: pts[0],
            y: pts[1]
          }, {
            x: pts[2],
            y: pts[3]
          }, {
            x: pts[4],
            y: pts[5]
          }, t2);
          return [pts[0], pts[1], m0.x, m0.y, m1.x, m1.y, m2.x, m2.y, pts[4], pts[5]];
        };
        var pts = [].concat(approximateBarrelCurvePts(bPts.topLeft), approximateBarrelCurvePts(bPts.topRight), approximateBarrelCurvePts(bPts.bottomRight), approximateBarrelCurvePts(bPts.bottomLeft));
        return polygonIntersectLine(x, y, pts, nodeX, nodeY);
      },
      generateBarrelBezierPts: function generateBarrelBezierPts(width, height, centerX, centerY) {
        var hh = height / 2;
        var hw = width / 2;
        var xBegin = centerX - hw;
        var xEnd = centerX + hw;
        var yBegin = centerY - hh;
        var yEnd = centerY + hh;
        var curveConstants = getBarrelCurveConstants(width, height);
        var hOffset = curveConstants.heightOffset;
        var wOffset = curveConstants.widthOffset;
        var ctrlPtXOffset = curveConstants.ctrlPtOffsetPct * width;

        // points are in clockwise order, inner (imaginary) control pt on [4, 5]
        var pts = {
          topLeft: [xBegin, yBegin + hOffset, xBegin + ctrlPtXOffset, yBegin, xBegin + wOffset, yBegin],
          topRight: [xEnd - wOffset, yBegin, xEnd - ctrlPtXOffset, yBegin, xEnd, yBegin + hOffset],
          bottomRight: [xEnd, yEnd - hOffset, xEnd - ctrlPtXOffset, yEnd, xEnd - wOffset, yEnd],
          bottomLeft: [xBegin + wOffset, yEnd, xBegin + ctrlPtXOffset, yEnd, xBegin, yEnd - hOffset]
        };
        pts.topLeft.isTop = true;
        pts.topRight.isTop = true;
        pts.bottomLeft.isBottom = true;
        pts.bottomRight.isBottom = true;
        return pts;
      },
      checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) {
        var curveConstants = getBarrelCurveConstants(width, height);
        var hOffset = curveConstants.heightOffset;
        var wOffset = curveConstants.widthOffset;

        // Check hBox
        if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - 2 * hOffset, [0, -1], padding)) {
          return true;
        }

        // Check vBox
        if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - 2 * wOffset, height, [0, -1], padding)) {
          return true;
        }
        var barrelCurvePts = this.generateBarrelBezierPts(width, height, centerX, centerY);
        var getCurveT = function getCurveT(x, y, curvePts) {
          var x0 = curvePts[4];
          var x1 = curvePts[2];
          var x2 = curvePts[0];
          var y0 = curvePts[5];
          // var y1 = curvePts[ 3 ];
          var y2 = curvePts[1];
          var xMin = Math.min(x0, x2);
          var xMax = Math.max(x0, x2);
          var yMin = Math.min(y0, y2);
          var yMax = Math.max(y0, y2);
          if (xMin <= x && x <= xMax && yMin <= y && y <= yMax) {
            var coeff = bezierPtsToQuadCoeff(x0, x1, x2);
            var roots = solveQuadratic(coeff[0], coeff[1], coeff[2], x);
            var validRoots = roots.filter(function (r) {
              return 0 <= r && r <= 1;
            });
            if (validRoots.length > 0) {
              return validRoots[0];
            }
          }
          return null;
        };
        var curveRegions = Object.keys(barrelCurvePts);
        for (var i = 0; i < curveRegions.length; i++) {
          var corner = curveRegions[i];
          var cornerPts = barrelCurvePts[corner];
          var t = getCurveT(x, y, cornerPts);
          if (t == null) {
            continue;
          }
          var y0 = cornerPts[5];
          var y1 = cornerPts[3];
          var y2 = cornerPts[1];
          var bezY = qbezierAt(y0, y1, y2, t);
          if (cornerPts.isTop && bezY <= y) {
            return true;
          }
          if (cornerPts.isBottom && y <= bezY) {
            return true;
          }
        }
        return false;
      }
    };
  };
  BRp$2.generateBottomRoundrectangle = function () {
    return this.nodeShapes['bottom-round-rectangle'] = this.nodeShapes['bottomroundrectangle'] = {
      renderer: this,
      name: 'bottom-round-rectangle',
      points: generateUnitNgonPointsFitToSquare(4, 0),
      draw: function draw(context, centerX, centerY, width, height) {
        this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height);
      },
      intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding) {
        var topStartX = nodeX - (width / 2 + padding);
        var topStartY = nodeY - (height / 2 + padding);
        var topEndY = topStartY;
        var topEndX = nodeX + (width / 2 + padding);
        var topIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false);
        if (topIntersections.length > 0) {
          return topIntersections;
        }
        return roundRectangleIntersectLine(x, y, nodeX, nodeY, width, height, padding);
      },
      checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY) {
        var cornerRadius = getRoundRectangleRadius(width, height);
        var diam = 2 * cornerRadius;

        // Check hBox
        if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - diam, [0, -1], padding)) {
          return true;
        }

        // Check vBox
        if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - diam, height, [0, -1], padding)) {
          return true;
        }

        // check non-rounded top side
        var outerWidth = width / 2 + 2 * padding;
        var outerHeight = height / 2 + 2 * padding;
        var points = [centerX - outerWidth, centerY - outerHeight, centerX - outerWidth, centerY, centerX + outerWidth, centerY, centerX + outerWidth, centerY - outerHeight];
        if (pointInsidePolygonPoints(x, y, points)) {
          return true;
        }

        // Check bottom right quarter circle
        if (checkInEllipse(x, y, diam, diam, centerX + width / 2 - cornerRadius, centerY + height / 2 - cornerRadius, padding)) {
          return true;
        }

        // Check bottom left quarter circle
        if (checkInEllipse(x, y, diam, diam, centerX - width / 2 + cornerRadius, centerY + height / 2 - cornerRadius, padding)) {
          return true;
        }
        return false;
      }
    };
  };
  BRp$2.registerNodeShapes = function () {
    var nodeShapes = this.nodeShapes = {};
    var renderer = this;
    this.generateEllipse();
    this.generatePolygon('triangle', generateUnitNgonPointsFitToSquare(3, 0));
    this.generateRoundPolygon('round-triangle', generateUnitNgonPointsFitToSquare(3, 0));
    this.generatePolygon('rectangle', generateUnitNgonPointsFitToSquare(4, 0));
    nodeShapes['square'] = nodeShapes['rectangle'];
    this.generateRoundRectangle();
    this.generateCutRectangle();
    this.generateBarrel();
    this.generateBottomRoundrectangle();
    {
      var diamondPoints = [0, 1, 1, 0, 0, -1, -1, 0];
      this.generatePolygon('diamond', diamondPoints);
      this.generateRoundPolygon('round-diamond', diamondPoints);
    }
    this.generatePolygon('pentagon', generateUnitNgonPointsFitToSquare(5, 0));
    this.generateRoundPolygon('round-pentagon', generateUnitNgonPointsFitToSquare(5, 0));
    this.generatePolygon('hexagon', generateUnitNgonPointsFitToSquare(6, 0));
    this.generateRoundPolygon('round-hexagon', generateUnitNgonPointsFitToSquare(6, 0));
    this.generatePolygon('heptagon', generateUnitNgonPointsFitToSquare(7, 0));
    this.generateRoundPolygon('round-heptagon', generateUnitNgonPointsFitToSquare(7, 0));
    this.generatePolygon('octagon', generateUnitNgonPointsFitToSquare(8, 0));
    this.generateRoundPolygon('round-octagon', generateUnitNgonPointsFitToSquare(8, 0));
    var star5Points = new Array(20);
    {
      var outerPoints = generateUnitNgonPoints(5, 0);
      var innerPoints = generateUnitNgonPoints(5, Math.PI / 5);

      // Outer radius is 1; inner radius of star is smaller
      var innerRadius = 0.5 * (3 - Math.sqrt(5));
      innerRadius *= 1.57;
      for (var i = 0; i < innerPoints.length / 2; i++) {
        innerPoints[i * 2] *= innerRadius;
        innerPoints[i * 2 + 1] *= innerRadius;
      }
      for (var i = 0; i < 20 / 4; i++) {
        star5Points[i * 4] = outerPoints[i * 2];
        star5Points[i * 4 + 1] = outerPoints[i * 2 + 1];
        star5Points[i * 4 + 2] = innerPoints[i * 2];
        star5Points[i * 4 + 3] = innerPoints[i * 2 + 1];
      }
    }
    star5Points = fitPolygonToSquare(star5Points);
    this.generatePolygon('star', star5Points);
    this.generatePolygon('vee', [-1, -1, 0, -0.333, 1, -1, 0, 1]);
    this.generatePolygon('rhomboid', [-1, -1, 0.333, -1, 1, 1, -0.333, 1]);
    this.generatePolygon('right-rhomboid', [-0.333, -1, 1, -1, 0.333, 1, -1, 1]);
    this.nodeShapes['concavehexagon'] = this.generatePolygon('concave-hexagon', [-1, -0.95, -0.75, 0, -1, 0.95, 1, 0.95, 0.75, 0, 1, -0.95]);
    {
      var tagPoints = [-1, -1, 0.25, -1, 1, 0, 0.25, 1, -1, 1];
      this.generatePolygon('tag', tagPoints);
      this.generateRoundPolygon('round-tag', tagPoints);
    }
    nodeShapes.makePolygon = function (points) {
      // use caching on user-specified polygons so they are as fast as native shapes

      var key = points.join('$');
      var name = 'polygon-' + key;
      var shape;
      if (shape = this[name]) {
        // got cached shape
        return shape;
      }

      // create and cache new shape
      return renderer.generatePolygon(name, points);
    };
  };

  var BRp$1 = {};
  BRp$1.timeToRender = function () {
    return this.redrawTotalTime / this.redrawCount;
  };
  BRp$1.redraw = function (options) {
    options = options || staticEmptyObject();
    var r = this;
    if (r.averageRedrawTime === undefined) {
      r.averageRedrawTime = 0;
    }
    if (r.lastRedrawTime === undefined) {
      r.lastRedrawTime = 0;
    }
    if (r.lastDrawTime === undefined) {
      r.lastDrawTime = 0;
    }
    r.requestedFrame = true;
    r.renderOptions = options;
  };
  BRp$1.beforeRender = function (fn, priority) {
    // the renderer can't add tick callbacks when destroyed
    if (this.destroyed) {
      return;
    }
    if (priority == null) {
      error('Priority is not optional for beforeRender');
    }
    var cbs = this.beforeRenderCallbacks;
    cbs.push({
      fn: fn,
      priority: priority
    });

    // higher priority callbacks executed first
    cbs.sort(function (a, b) {
      return b.priority - a.priority;
    });
  };
  var beforeRenderCallbacks = function beforeRenderCallbacks(r, willDraw, startTime) {
    var cbs = r.beforeRenderCallbacks;
    for (var i = 0; i < cbs.length; i++) {
      cbs[i].fn(willDraw, startTime);
    }
  };
  BRp$1.startRenderLoop = function () {
    var r = this;
    var cy = r.cy;
    if (r.renderLoopStarted) {
      return;
    } else {
      r.renderLoopStarted = true;
    }
    var renderFn = function renderFn(requestTime) {
      if (r.destroyed) {
        return;
      }
      if (cy.batching()) ; else if (r.requestedFrame && !r.skipFrame) {
        beforeRenderCallbacks(r, true, requestTime);
        var startTime = performanceNow();
        r.render(r.renderOptions);
        var endTime = r.lastDrawTime = performanceNow();
        if (r.averageRedrawTime === undefined) {
          r.averageRedrawTime = endTime - startTime;
        }
        if (r.redrawCount === undefined) {
          r.redrawCount = 0;
        }
        r.redrawCount++;
        if (r.redrawTotalTime === undefined) {
          r.redrawTotalTime = 0;
        }
        var duration = endTime - startTime;
        r.redrawTotalTime += duration;
        r.lastRedrawTime = duration;

        // use a weighted average with a bias from the previous average so we don't spike so easily
        r.averageRedrawTime = r.averageRedrawTime / 2 + duration / 2;
        r.requestedFrame = false;
      } else {
        beforeRenderCallbacks(r, false, requestTime);
      }
      r.skipFrame = false;
      requestAnimationFrame(renderFn);
    };
    requestAnimationFrame(renderFn);
  };

  var BaseRenderer = function BaseRenderer(options) {
    this.init(options);
  };
  var BR = BaseRenderer;
  var BRp = BR.prototype;
  BRp.clientFunctions = ['redrawHint', 'render', 'renderTo', 'matchCanvasSize', 'nodeShapeImpl', 'arrowShapeImpl'];
  BRp.init = function (options) {
    var r = this;
    r.options = options;
    r.cy = options.cy;
    var ctr = r.container = options.cy.container();
    var containerWindow = r.cy.window();

    // prepend a stylesheet in the head such that
    if (containerWindow) {
      var document = containerWindow.document;
      var head = document.head;
      var stylesheetId = '__________cytoscape_stylesheet';
      var className = '__________cytoscape_container';
      var stylesheetAlreadyExists = document.getElementById(stylesheetId) != null;
      if (ctr.className.indexOf(className) < 0) {
        ctr.className = (ctr.className || '') + ' ' + className;
      }
      if (!stylesheetAlreadyExists) {
        var stylesheet = document.createElement('style');
        stylesheet.id = stylesheetId;
        stylesheet.textContent = '.' + className + ' { position: relative; }';
        head.insertBefore(stylesheet, head.children[0]); // first so lowest priority
      }

      var computedStyle = containerWindow.getComputedStyle(ctr);
      var position = computedStyle.getPropertyValue('position');
      if (position === 'static') {
        warn('A Cytoscape container has style position:static and so can not use UI extensions properly');
      }
    }
    r.selection = [undefined, undefined, undefined, undefined, 0]; // Coordinates for selection box, plus enabled flag

    r.bezierProjPcts = [0.05, 0.225, 0.4, 0.5, 0.6, 0.775, 0.95];

    //--Pointer-related data
    r.hoverData = {
      down: null,
      last: null,
      downTime: null,
      triggerMode: null,
      dragging: false,
      initialPan: [null, null],
      capture: false
    };
    r.dragData = {
      possibleDragElements: []
    };
    r.touchData = {
      start: null,
      capture: false,
      // These 3 fields related to tap, taphold events
      startPosition: [null, null, null, null, null, null],
      singleTouchStartTime: null,
      singleTouchMoved: true,
      now: [null, null, null, null, null, null],
      earlier: [null, null, null, null, null, null]
    };
    r.redraws = 0;
    r.showFps = options.showFps;
    r.debug = options.debug;
    r.hideEdgesOnViewport = options.hideEdgesOnViewport;
    r.textureOnViewport = options.textureOnViewport;
    r.wheelSensitivity = options.wheelSensitivity;
    r.motionBlurEnabled = options.motionBlur; // on by default
    r.forcedPixelRatio = number$1(options.pixelRatio) ? options.pixelRatio : null;
    r.motionBlur = options.motionBlur; // for initial kick off
    r.motionBlurOpacity = options.motionBlurOpacity;
    r.motionBlurTransparency = 1 - r.motionBlurOpacity;
    r.motionBlurPxRatio = 1;
    r.mbPxRBlurry = 1; //0.8;
    r.minMbLowQualFrames = 4;
    r.fullQualityMb = false;
    r.clearedForMotionBlur = [];
    r.desktopTapThreshold = options.desktopTapThreshold;
    r.desktopTapThreshold2 = options.desktopTapThreshold * options.desktopTapThreshold;
    r.touchTapThreshold = options.touchTapThreshold;
    r.touchTapThreshold2 = options.touchTapThreshold * options.touchTapThreshold;
    r.tapholdDuration = 500;
    r.bindings = [];
    r.beforeRenderCallbacks = [];
    r.beforeRenderPriorities = {
      // higher priority execs before lower one
      animations: 400,
      eleCalcs: 300,
      eleTxrDeq: 200,
      lyrTxrDeq: 150,
      lyrTxrSkip: 100
    };
    r.registerNodeShapes();
    r.registerArrowShapes();
    r.registerCalculationListeners();
  };
  BRp.notify = function (eventName, eles) {
    var r = this;
    var cy = r.cy;

    // the renderer can't be notified after it's destroyed
    if (this.destroyed) {
      return;
    }
    if (eventName === 'init') {
      r.load();
      return;
    }
    if (eventName === 'destroy') {
      r.destroy();
      return;
    }
    if (eventName === 'add' || eventName === 'remove' || eventName === 'move' && cy.hasCompoundNodes() || eventName === 'load' || eventName === 'zorder' || eventName === 'mount') {
      r.invalidateCachedZSortedEles();
    }
    if (eventName === 'viewport') {
      r.redrawHint('select', true);
    }
    if (eventName === 'load' || eventName === 'resize' || eventName === 'mount') {
      r.invalidateContainerClientCoordsCache();
      r.matchCanvasSize(r.container);
    }
    r.redrawHint('eles', true);
    r.redrawHint('drag', true);
    this.startRenderLoop();
    this.redraw();
  };
  BRp.destroy = function () {
    var r = this;
    r.destroyed = true;
    r.cy.stopAnimationLoop();
    for (var i = 0; i < r.bindings.length; i++) {
      var binding = r.bindings[i];
      var b = binding;
      var tgt = b.target;
      (tgt.off || tgt.removeEventListener).apply(tgt, b.args);
    }
    r.bindings = [];
    r.beforeRenderCallbacks = [];
    r.onUpdateEleCalcsFns = [];
    if (r.removeObserver) {
      r.removeObserver.disconnect();
    }
    if (r.styleObserver) {
      r.styleObserver.disconnect();
    }
    if (r.resizeObserver) {
      r.resizeObserver.disconnect();
    }
    if (r.labelCalcDiv) {
      try {
        document.body.removeChild(r.labelCalcDiv); // eslint-disable-line no-undef
      } catch (e) {
        // ie10 issue #1014
      }
    }
  };
  BRp.isHeadless = function () {
    return false;
  };
  [BRp$f, BRp$5, BRp$4, BRp$3, BRp$2, BRp$1].forEach(function (props) {
    extend(BRp, props);
  });

  var fullFpsTime = 1000 / 60; // assume 60 frames per second

  var defs = {
    setupDequeueing: function setupDequeueing(opts) {
      return function setupDequeueingImpl() {
        var self = this;
        var r = this.renderer;
        if (self.dequeueingSetup) {
          return;
        } else {
          self.dequeueingSetup = true;
        }
        var queueRedraw = debounce_1(function () {
          r.redrawHint('eles', true);
          r.redrawHint('drag', true);
          r.redraw();
        }, opts.deqRedrawThreshold);
        var dequeue = function dequeue(willDraw, frameStartTime) {
          var startTime = performanceNow();
          var avgRenderTime = r.averageRedrawTime;
          var renderTime = r.lastRedrawTime;
          var deqd = [];
          var extent = r.cy.extent();
          var pixelRatio = r.getPixelRatio();

          // if we aren't in a tick that causes a draw, then the rendered style
          // queue won't automatically be flushed before dequeueing starts
          if (!willDraw) {
            r.flushRenderedStyleQueue();
          }
          while (true) {
            // eslint-disable-line no-constant-condition
            var now = performanceNow();
            var duration = now - startTime;
            var frameDuration = now - frameStartTime;
            if (renderTime < fullFpsTime) {
              // if we're rendering faster than the ideal fps, then do dequeueing
              // during all of the remaining frame time

              var timeAvailable = fullFpsTime - (willDraw ? avgRenderTime : 0);
              if (frameDuration >= opts.deqFastCost * timeAvailable) {
                break;
              }
            } else {
              if (willDraw) {
                if (duration >= opts.deqCost * renderTime || duration >= opts.deqAvgCost * avgRenderTime) {
                  break;
                }
              } else if (frameDuration >= opts.deqNoDrawCost * fullFpsTime) {
                break;
              }
            }
            var thisDeqd = opts.deq(self, pixelRatio, extent);
            if (thisDeqd.length > 0) {
              for (var i = 0; i < thisDeqd.length; i++) {
                deqd.push(thisDeqd[i]);
              }
            } else {
              break;
            }
          }

          // callbacks on dequeue
          if (deqd.length > 0) {
            opts.onDeqd(self, deqd);
            if (!willDraw && opts.shouldRedraw(self, deqd, pixelRatio, extent)) {
              queueRedraw();
            }
          }
        };
        var priority = opts.priority || noop$1;
        r.beforeRender(dequeue, priority(self));
      };
    }
  };

  // Allows lookups for (ele, lvl) => cache.
  // Uses keys so elements may share the same cache.
  var ElementTextureCacheLookup = /*#__PURE__*/function () {
    function ElementTextureCacheLookup(getKey) {
      var doesEleInvalidateKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : falsify;
      _classCallCheck(this, ElementTextureCacheLookup);
      this.idsByKey = new Map$2();
      this.keyForId = new Map$2();
      this.cachesByLvl = new Map$2();
      this.lvls = [];
      this.getKey = getKey;
      this.doesEleInvalidateKey = doesEleInvalidateKey;
    }
    _createClass(ElementTextureCacheLookup, [{
      key: "getIdsFor",
      value: function getIdsFor(key) {
        if (key == null) {
          error("Can not get id list for null key");
        }
        var idsByKey = this.idsByKey;
        var ids = this.idsByKey.get(key);
        if (!ids) {
          ids = new Set$1();
          idsByKey.set(key, ids);
        }
        return ids;
      }
    }, {
      key: "addIdForKey",
      value: function addIdForKey(key, id) {
        if (key != null) {
          this.getIdsFor(key).add(id);
        }
      }
    }, {
      key: "deleteIdForKey",
      value: function deleteIdForKey(key, id) {
        if (key != null) {
          this.getIdsFor(key)["delete"](id);
        }
      }
    }, {
      key: "getNumberOfIdsForKey",
      value: function getNumberOfIdsForKey(key) {
        if (key == null) {
          return 0;
        } else {
          return this.getIdsFor(key).size;
        }
      }
    }, {
      key: "updateKeyMappingFor",
      value: function updateKeyMappingFor(ele) {
        var id = ele.id();
        var prevKey = this.keyForId.get(id);
        var currKey = this.getKey(ele);
        this.deleteIdForKey(prevKey, id);
        this.addIdForKey(currKey, id);
        this.keyForId.set(id, currKey);
      }
    }, {
      key: "deleteKeyMappingFor",
      value: function deleteKeyMappingFor(ele) {
        var id = ele.id();
        var prevKey = this.keyForId.get(id);
        this.deleteIdForKey(prevKey, id);
        this.keyForId["delete"](id);
      }
    }, {
      key: "keyHasChangedFor",
      value: function keyHasChangedFor(ele) {
        var id = ele.id();
        var prevKey = this.keyForId.get(id);
        var newKey = this.getKey(ele);
        return prevKey !== newKey;
      }
    }, {
      key: "isInvalid",
      value: function isInvalid(ele) {
        return this.keyHasChangedFor(ele) || this.doesEleInvalidateKey(ele);
      }
    }, {
      key: "getCachesAt",
      value: function getCachesAt(lvl) {
        var cachesByLvl = this.cachesByLvl,
          lvls = this.lvls;
        var caches = cachesByLvl.get(lvl);
        if (!caches) {
          caches = new Map$2();
          cachesByLvl.set(lvl, caches);
          lvls.push(lvl);
        }
        return caches;
      }
    }, {
      key: "getCache",
      value: function getCache(key, lvl) {
        return this.getCachesAt(lvl).get(key);
      }
    }, {
      key: "get",
      value: function get(ele, lvl) {
        var key = this.getKey(ele);
        var cache = this.getCache(key, lvl);

        // getting for an element may need to add to the id list b/c eles can share keys
        if (cache != null) {
          this.updateKeyMappingFor(ele);
        }
        return cache;
      }
    }, {
      key: "getForCachedKey",
      value: function getForCachedKey(ele, lvl) {
        var key = this.keyForId.get(ele.id()); // n.b. use cached key, not newly computed key
        var cache = this.getCache(key, lvl);
        return cache;
      }
    }, {
      key: "hasCache",
      value: function hasCache(key, lvl) {
        return this.getCachesAt(lvl).has(key);
      }
    }, {
      key: "has",
      value: function has(ele, lvl) {
        var key = this.getKey(ele);
        return this.hasCache(key, lvl);
      }
    }, {
      key: "setCache",
      value: function setCache(key, lvl, cache) {
        cache.key = key;
        this.getCachesAt(lvl).set(key, cache);
      }
    }, {
      key: "set",
      value: function set(ele, lvl, cache) {
        var key = this.getKey(ele);
        this.setCache(key, lvl, cache);
        this.updateKeyMappingFor(ele);
      }
    }, {
      key: "deleteCache",
      value: function deleteCache(key, lvl) {
        this.getCachesAt(lvl)["delete"](key);
      }
    }, {
      key: "delete",
      value: function _delete(ele, lvl) {
        var key = this.getKey(ele);
        this.deleteCache(key, lvl);
      }
    }, {
      key: "invalidateKey",
      value: function invalidateKey(key) {
        var _this = this;
        this.lvls.forEach(function (lvl) {
          return _this.deleteCache(key, lvl);
        });
      }

      // returns true if no other eles reference the invalidated cache (n.b. other eles may need the cache with the same key)
    }, {
      key: "invalidate",
      value: function invalidate(ele) {
        var id = ele.id();
        var key = this.keyForId.get(id); // n.b. use stored key rather than current (potential key)

        this.deleteKeyMappingFor(ele);
        var entireKeyInvalidated = this.doesEleInvalidateKey(ele);
        if (entireKeyInvalidated) {
          // clear mapping for current key
          this.invalidateKey(key);
        }
        return entireKeyInvalidated || this.getNumberOfIdsForKey(key) === 0;
      }
    }]);
    return ElementTextureCacheLookup;
  }();

  var minTxrH = 25; // the size of the texture cache for small height eles (special case)
  var txrStepH = 50; // the min size of the regular cache, and the size it increases with each step up
  var minLvl$1 = -4; // when scaling smaller than that we don't need to re-render
  var maxLvl$1 = 3; // when larger than this scale just render directly (caching is not helpful)
  var maxZoom$1 = 7.99; // beyond this zoom level, layered textures are not used
  var eleTxrSpacing = 8; // spacing between elements on textures to avoid blitting overlaps
  var defTxrWidth = 1024; // default/minimum texture width
  var maxTxrW = 1024; // the maximum width of a texture
  var maxTxrH = 1024; // the maximum height of a texture
  var minUtility = 0.2; // if usage of texture is less than this, it is retired
  var maxFullness = 0.8; // fullness of texture after which queue removal is checked
  var maxFullnessChecks = 10; // dequeued after this many checks
  var deqCost$1 = 0.15; // % of add'l rendering cost allowed for dequeuing ele caches each frame
  var deqAvgCost$1 = 0.1; // % of add'l rendering cost compared to average overall redraw time
  var deqNoDrawCost$1 = 0.9; // % of avg frame time that can be used for dequeueing when not drawing
  var deqFastCost$1 = 0.9; // % of frame time to be used when >60fps
  var deqRedrawThreshold$1 = 100; // time to batch redraws together from dequeueing to allow more dequeueing calcs to happen in the meanwhile
  var maxDeqSize$1 = 1; // number of eles to dequeue and render at higher texture in each batch

  var getTxrReasons = {
    dequeue: 'dequeue',
    downscale: 'downscale',
    highQuality: 'highQuality'
  };
  var initDefaults = defaults$g({
    getKey: null,
    doesEleInvalidateKey: falsify,
    drawElement: null,
    getBoundingBox: null,
    getRotationPoint: null,
    getRotationOffset: null,
    isVisible: trueify,
    allowEdgeTxrCaching: true,
    allowParentTxrCaching: true
  });
  var ElementTextureCache = function ElementTextureCache(renderer, initOptions) {
    var self = this;
    self.renderer = renderer;
    self.onDequeues = [];
    var opts = initDefaults(initOptions);
    extend(self, opts);
    self.lookup = new ElementTextureCacheLookup(opts.getKey, opts.doesEleInvalidateKey);
    self.setupDequeueing();
  };
  var ETCp = ElementTextureCache.prototype;
  ETCp.reasons = getTxrReasons;

  // the list of textures in which new subtextures for elements can be placed
  ETCp.getTextureQueue = function (txrH) {
    var self = this;
    self.eleImgCaches = self.eleImgCaches || {};
    return self.eleImgCaches[txrH] = self.eleImgCaches[txrH] || [];
  };

  // the list of usused textures which can be recycled (in use in texture queue)
  ETCp.getRetiredTextureQueue = function (txrH) {
    var self = this;
    var rtxtrQs = self.eleImgCaches.retired = self.eleImgCaches.retired || {};
    var rtxtrQ = rtxtrQs[txrH] = rtxtrQs[txrH] || [];
    return rtxtrQ;
  };

  // queue of element draw requests at different scale levels
  ETCp.getElementQueue = function () {
    var self = this;
    var q = self.eleCacheQueue = self.eleCacheQueue || new heap(function (a, b) {
      return b.reqs - a.reqs;
    });
    return q;
  };

  // queue of element draw requests at different scale levels (element id lookup)
  ETCp.getElementKeyToQueue = function () {
    var self = this;
    var k2q = self.eleKeyToCacheQueue = self.eleKeyToCacheQueue || {};
    return k2q;
  };
  ETCp.getElement = function (ele, bb, pxRatio, lvl, reason) {
    var self = this;
    var r = this.renderer;
    var zoom = r.cy.zoom();
    var lookup = this.lookup;
    if (!bb || bb.w === 0 || bb.h === 0 || isNaN(bb.w) || isNaN(bb.h) || !ele.visible() || ele.removed()) {
      return null;
    }
    if (!self.allowEdgeTxrCaching && ele.isEdge() || !self.allowParentTxrCaching && ele.isParent()) {
      return null;
    }
    if (lvl == null) {
      lvl = Math.ceil(log2(zoom * pxRatio));
    }
    if (lvl < minLvl$1) {
      lvl = minLvl$1;
    } else if (zoom >= maxZoom$1 || lvl > maxLvl$1) {
      return null;
    }
    var scale = Math.pow(2, lvl);
    var eleScaledH = bb.h * scale;
    var eleScaledW = bb.w * scale;
    var scaledLabelShown = r.eleTextBiggerThanMin(ele, scale);
    if (!this.isVisible(ele, scaledLabelShown)) {
      return null;
    }
    var eleCache = lookup.get(ele, lvl);

    // if this get was on an unused/invalidated cache, then restore the texture usage metric
    if (eleCache && eleCache.invalidated) {
      eleCache.invalidated = false;
      eleCache.texture.invalidatedWidth -= eleCache.width;
    }
    if (eleCache) {
      return eleCache;
    }
    var txrH; // which texture height this ele belongs to

    if (eleScaledH <= minTxrH) {
      txrH = minTxrH;
    } else if (eleScaledH <= txrStepH) {
      txrH = txrStepH;
    } else {
      txrH = Math.ceil(eleScaledH / txrStepH) * txrStepH;
    }
    if (eleScaledH > maxTxrH || eleScaledW > maxTxrW) {
      return null; // caching large elements is not efficient
    }

    var txrQ = self.getTextureQueue(txrH);

    // first try the second last one in case it has space at the end
    var txr = txrQ[txrQ.length - 2];
    var addNewTxr = function addNewTxr() {
      return self.recycleTexture(txrH, eleScaledW) || self.addTexture(txrH, eleScaledW);
    };

    // try the last one if there is no second last one
    if (!txr) {
      txr = txrQ[txrQ.length - 1];
    }

    // if the last one doesn't exist, we need a first one
    if (!txr) {
      txr = addNewTxr();
    }

    // if there's no room in the current texture, we need a new one
    if (txr.width - txr.usedWidth < eleScaledW) {
      txr = addNewTxr();
    }
    var scalableFrom = function scalableFrom(otherCache) {
      return otherCache && otherCache.scaledLabelShown === scaledLabelShown;
    };
    var deqing = reason && reason === getTxrReasons.dequeue;
    var highQualityReq = reason && reason === getTxrReasons.highQuality;
    var downscaleReq = reason && reason === getTxrReasons.downscale;
    var higherCache; // the nearest cache with a higher level
    for (var l = lvl + 1; l <= maxLvl$1; l++) {
      var c = lookup.get(ele, l);
      if (c) {
        higherCache = c;
        break;
      }
    }
    var oneUpCache = higherCache && higherCache.level === lvl + 1 ? higherCache : null;
    var downscale = function downscale() {
      txr.context.drawImage(oneUpCache.texture.canvas, oneUpCache.x, 0, oneUpCache.width, oneUpCache.height, txr.usedWidth, 0, eleScaledW, eleScaledH);
    };

    // reset ele area in texture
    txr.context.setTransform(1, 0, 0, 1, 0, 0);
    txr.context.clearRect(txr.usedWidth, 0, eleScaledW, txrH);
    if (scalableFrom(oneUpCache)) {
      // then we can relatively cheaply rescale the existing image w/o rerendering
      downscale();
    } else if (scalableFrom(higherCache)) {
      // then use the higher cache for now and queue the next level down
      // to cheaply scale towards the smaller level

      if (highQualityReq) {
        for (var _l = higherCache.level; _l > lvl; _l--) {
          oneUpCache = self.getElement(ele, bb, pxRatio, _l, getTxrReasons.downscale);
        }
        downscale();
      } else {
        self.queueElement(ele, higherCache.level - 1);
        return higherCache;
      }
    } else {
      var lowerCache; // the nearest cache with a lower level
      if (!deqing && !highQualityReq && !downscaleReq) {
        for (var _l2 = lvl - 1; _l2 >= minLvl$1; _l2--) {
          var _c = lookup.get(ele, _l2);
          if (_c) {
            lowerCache = _c;
            break;
          }
        }
      }
      if (scalableFrom(lowerCache)) {
        // then use the lower quality cache for now and queue the better one for later

        self.queueElement(ele, lvl);
        return lowerCache;
      }
      txr.context.translate(txr.usedWidth, 0);
      txr.context.scale(scale, scale);
      this.drawElement(txr.context, ele, bb, scaledLabelShown, false);
      txr.context.scale(1 / scale, 1 / scale);
      txr.context.translate(-txr.usedWidth, 0);
    }
    eleCache = {
      x: txr.usedWidth,
      texture: txr,
      level: lvl,
      scale: scale,
      width: eleScaledW,
      height: eleScaledH,
      scaledLabelShown: scaledLabelShown
    };
    txr.usedWidth += Math.ceil(eleScaledW + eleTxrSpacing);
    txr.eleCaches.push(eleCache);
    lookup.set(ele, lvl, eleCache);
    self.checkTextureFullness(txr);
    return eleCache;
  };
  ETCp.invalidateElements = function (eles) {
    for (var i = 0; i < eles.length; i++) {
      this.invalidateElement(eles[i]);
    }
  };
  ETCp.invalidateElement = function (ele) {
    var self = this;
    var lookup = self.lookup;
    var caches = [];
    var invalid = lookup.isInvalid(ele);
    if (!invalid) {
      return; // override the invalidation request if the element key has not changed
    }

    for (var lvl = minLvl$1; lvl <= maxLvl$1; lvl++) {
      var cache = lookup.getForCachedKey(ele, lvl);
      if (cache) {
        caches.push(cache);
      }
    }
    var noOtherElesUseCache = lookup.invalidate(ele);
    if (noOtherElesUseCache) {
      for (var i = 0; i < caches.length; i++) {
        var _cache = caches[i];
        var txr = _cache.texture;

        // remove space from the texture it belongs to
        txr.invalidatedWidth += _cache.width;

        // mark the cache as invalidated
        _cache.invalidated = true;

        // retire the texture if its utility is low
        self.checkTextureUtility(txr);
      }
    }

    // remove from queue since the old req was for the old state
    self.removeFromQueue(ele);
  };
  ETCp.checkTextureUtility = function (txr) {
    // invalidate all entries in the cache if the cache size is small
    if (txr.invalidatedWidth >= minUtility * txr.width) {
      this.retireTexture(txr);
    }
  };
  ETCp.checkTextureFullness = function (txr) {
    // if texture has been mostly filled and passed over several times, remove
    // it from the queue so we don't need to waste time looking at it to put new things

    var self = this;
    var txrQ = self.getTextureQueue(txr.height);
    if (txr.usedWidth / txr.width > maxFullness && txr.fullnessChecks >= maxFullnessChecks) {
      removeFromArray(txrQ, txr);
    } else {
      txr.fullnessChecks++;
    }
  };
  ETCp.retireTexture = function (txr) {
    var self = this;
    var txrH = txr.height;
    var txrQ = self.getTextureQueue(txrH);
    var lookup = this.lookup;

    // retire the texture from the active / searchable queue:

    removeFromArray(txrQ, txr);
    txr.retired = true;

    // remove the refs from the eles to the caches:

    var eleCaches = txr.eleCaches;
    for (var i = 0; i < eleCaches.length; i++) {
      var eleCache = eleCaches[i];
      lookup.deleteCache(eleCache.key, eleCache.level);
    }
    clearArray(eleCaches);

    // add the texture to a retired queue so it can be recycled in future:

    var rtxtrQ = self.getRetiredTextureQueue(txrH);
    rtxtrQ.push(txr);
  };
  ETCp.addTexture = function (txrH, minW) {
    var self = this;
    var txrQ = self.getTextureQueue(txrH);
    var txr = {};
    txrQ.push(txr);
    txr.eleCaches = [];
    txr.height = txrH;
    txr.width = Math.max(defTxrWidth, minW);
    txr.usedWidth = 0;
    txr.invalidatedWidth = 0;
    txr.fullnessChecks = 0;
    txr.canvas = self.renderer.makeOffscreenCanvas(txr.width, txr.height);
    txr.context = txr.canvas.getContext('2d');
    return txr;
  };
  ETCp.recycleTexture = function (txrH, minW) {
    var self = this;
    var txrQ = self.getTextureQueue(txrH);
    var rtxtrQ = self.getRetiredTextureQueue(txrH);
    for (var i = 0; i < rtxtrQ.length; i++) {
      var txr = rtxtrQ[i];
      if (txr.width >= minW) {
        txr.retired = false;
        txr.usedWidth = 0;
        txr.invalidatedWidth = 0;
        txr.fullnessChecks = 0;
        clearArray(txr.eleCaches);
        txr.context.setTransform(1, 0, 0, 1, 0, 0);
        txr.context.clearRect(0, 0, txr.width, txr.height);
        removeFromArray(rtxtrQ, txr);
        txrQ.push(txr);
        return txr;
      }
    }
  };
  ETCp.queueElement = function (ele, lvl) {
    var self = this;
    var q = self.getElementQueue();
    var k2q = self.getElementKeyToQueue();
    var key = this.getKey(ele);
    var existingReq = k2q[key];
    if (existingReq) {
      // use the max lvl b/c in between lvls are cheap to make
      existingReq.level = Math.max(existingReq.level, lvl);
      existingReq.eles.merge(ele);
      existingReq.reqs++;
      q.updateItem(existingReq);
    } else {
      var req = {
        eles: ele.spawn().merge(ele),
        level: lvl,
        reqs: 1,
        key: key
      };
      q.push(req);
      k2q[key] = req;
    }
  };
  ETCp.dequeue = function (pxRatio /*, extent*/) {
    var self = this;
    var q = self.getElementQueue();
    var k2q = self.getElementKeyToQueue();
    var dequeued = [];
    var lookup = self.lookup;
    for (var i = 0; i < maxDeqSize$1; i++) {
      if (q.size() > 0) {
        var req = q.pop();
        var key = req.key;
        var ele = req.eles[0]; // all eles have the same key
        var cacheExists = lookup.hasCache(ele, req.level);

        // clear out the key to req lookup
        k2q[key] = null;

        // dequeueing isn't necessary with an existing cache
        if (cacheExists) {
          continue;
        }
        dequeued.push(req);
        var bb = self.getBoundingBox(ele);
        self.getElement(ele, bb, pxRatio, req.level, getTxrReasons.dequeue);
      } else {
        break;
      }
    }
    return dequeued;
  };
  ETCp.removeFromQueue = function (ele) {
    var self = this;
    var q = self.getElementQueue();
    var k2q = self.getElementKeyToQueue();
    var key = this.getKey(ele);
    var req = k2q[key];
    if (req != null) {
      if (req.eles.length === 1) {
        // remove if last ele in the req
        // bring to front of queue
        req.reqs = MAX_INT$1;
        q.updateItem(req);
        q.pop(); // remove from queue

        k2q[key] = null; // remove from lookup map
      } else {
        // otherwise just remove ele from req
        req.eles.unmerge(ele);
      }
    }
  };
  ETCp.onDequeue = function (fn) {
    this.onDequeues.push(fn);
  };
  ETCp.offDequeue = function (fn) {
    removeFromArray(this.onDequeues, fn);
  };
  ETCp.setupDequeueing = defs.setupDequeueing({
    deqRedrawThreshold: deqRedrawThreshold$1,
    deqCost: deqCost$1,
    deqAvgCost: deqAvgCost$1,
    deqNoDrawCost: deqNoDrawCost$1,
    deqFastCost: deqFastCost$1,
    deq: function deq(self, pxRatio, extent) {
      return self.dequeue(pxRatio, extent);
    },
    onDeqd: function onDeqd(self, deqd) {
      for (var i = 0; i < self.onDequeues.length; i++) {
        var fn = self.onDequeues[i];
        fn(deqd);
      }
    },
    shouldRedraw: function shouldRedraw(self, deqd, pxRatio, extent) {
      for (var i = 0; i < deqd.length; i++) {
        var eles = deqd[i].eles;
        for (var j = 0; j < eles.length; j++) {
          var bb = eles[j].boundingBox();
          if (boundingBoxesIntersect(bb, extent)) {
            return true;
          }
        }
      }
      return false;
    },
    priority: function priority(self) {
      return self.renderer.beforeRenderPriorities.eleTxrDeq;
    }
  });

  var defNumLayers = 1; // default number of layers to use
  var minLvl = -4; // when scaling smaller than that we don't need to re-render
  var maxLvl = 2; // when larger than this scale just render directly (caching is not helpful)
  var maxZoom = 3.99; // beyond this zoom level, layered textures are not used
  var deqRedrawThreshold = 50; // time to batch redraws together from dequeueing to allow more dequeueing calcs to happen in the meanwhile
  var refineEleDebounceTime = 50; // time to debounce sharper ele texture updates
  var deqCost = 0.15; // % of add'l rendering cost allowed for dequeuing ele caches each frame
  var deqAvgCost = 0.1; // % of add'l rendering cost compared to average overall redraw time
  var deqNoDrawCost = 0.9; // % of avg frame time that can be used for dequeueing when not drawing
  var deqFastCost = 0.9; // % of frame time to be used when >60fps
  var maxDeqSize = 1; // number of eles to dequeue and render at higher texture in each batch
  var invalidThreshold = 250; // time threshold for disabling b/c of invalidations
  var maxLayerArea = 4000 * 4000; // layers can't be bigger than this
  var useHighQualityEleTxrReqs = true; // whether to use high quality ele txr requests (generally faster and cheaper in the longterm)

  // var log = function(){ console.log.apply( console, arguments ); };

  var LayeredTextureCache = function LayeredTextureCache(renderer) {
    var self = this;
    var r = self.renderer = renderer;
    var cy = r.cy;
    self.layersByLevel = {}; // e.g. 2 => [ layer1, layer2, ..., layerN ]

    self.firstGet = true;
    self.lastInvalidationTime = performanceNow() - 2 * invalidThreshold;
    self.skipping = false;
    self.eleTxrDeqs = cy.collection();
    self.scheduleElementRefinement = debounce_1(function () {
      self.refineElementTextures(self.eleTxrDeqs);
      self.eleTxrDeqs.unmerge(self.eleTxrDeqs);
    }, refineEleDebounceTime);
    r.beforeRender(function (willDraw, now) {
      if (now - self.lastInvalidationTime <= invalidThreshold) {
        self.skipping = true;
      } else {
        self.skipping = false;
      }
    }, r.beforeRenderPriorities.lyrTxrSkip);
    var qSort = function qSort(a, b) {
      return b.reqs - a.reqs;
    };
    self.layersQueue = new heap(qSort);
    self.setupDequeueing();
  };
  var LTCp = LayeredTextureCache.prototype;
  var layerIdPool = 0;
  var MAX_INT = Math.pow(2, 53) - 1;
  LTCp.makeLayer = function (bb, lvl) {
    var scale = Math.pow(2, lvl);
    var w = Math.ceil(bb.w * scale);
    var h = Math.ceil(bb.h * scale);
    var canvas = this.renderer.makeOffscreenCanvas(w, h);
    var layer = {
      id: layerIdPool = ++layerIdPool % MAX_INT,
      bb: bb,
      level: lvl,
      width: w,
      height: h,
      canvas: canvas,
      context: canvas.getContext('2d'),
      eles: [],
      elesQueue: [],
      reqs: 0
    };

    // log('make layer %s with w %s and h %s and lvl %s', layer.id, layer.width, layer.height, layer.level);

    var cxt = layer.context;
    var dx = -layer.bb.x1;
    var dy = -layer.bb.y1;

    // do the transform on creation to save cycles (it's the same for all eles)
    cxt.scale(scale, scale);
    cxt.translate(dx, dy);
    return layer;
  };
  LTCp.getLayers = function (eles, pxRatio, lvl) {
    var self = this;
    var r = self.renderer;
    var cy = r.cy;
    var zoom = cy.zoom();
    var firstGet = self.firstGet;
    self.firstGet = false;

    // log('--\nget layers with %s eles', eles.length);
    //log eles.map(function(ele){ return ele.id() }) );

    if (lvl == null) {
      lvl = Math.ceil(log2(zoom * pxRatio));
      if (lvl < minLvl) {
        lvl = minLvl;
      } else if (zoom >= maxZoom || lvl > maxLvl) {
        return null;
      }
    }
    self.validateLayersElesOrdering(lvl, eles);
    var layersByLvl = self.layersByLevel;
    var scale = Math.pow(2, lvl);
    var layers = layersByLvl[lvl] = layersByLvl[lvl] || [];
    var bb;
    var lvlComplete = self.levelIsComplete(lvl, eles);
    var tmpLayers;
    var checkTempLevels = function checkTempLevels() {
      var canUseAsTmpLvl = function canUseAsTmpLvl(l) {
        self.validateLayersElesOrdering(l, eles);
        if (self.levelIsComplete(l, eles)) {
          tmpLayers = layersByLvl[l];
          return true;
        }
      };
      var checkLvls = function checkLvls(dir) {
        if (tmpLayers) {
          return;
        }
        for (var l = lvl + dir; minLvl <= l && l <= maxLvl; l += dir) {
          if (canUseAsTmpLvl(l)) {
            break;
          }
        }
      };
      checkLvls(+1);
      checkLvls(-1);

      // remove the invalid layers; they will be replaced as needed later in this function
      for (var i = layers.length - 1; i >= 0; i--) {
        var layer = layers[i];
        if (layer.invalid) {
          removeFromArray(layers, layer);
        }
      }
    };
    if (!lvlComplete) {
      // if the current level is incomplete, then use the closest, best quality layerset temporarily
      // and later queue the current layerset so we can get the proper quality level soon

      checkTempLevels();
    } else {
      // log('level complete, using existing layers\n--');
      return layers;
    }
    var getBb = function getBb() {
      if (!bb) {
        bb = makeBoundingBox();
        for (var i = 0; i < eles.length; i++) {
          updateBoundingBox(bb, eles[i].boundingBox());
        }
      }
      return bb;
    };
    var makeLayer = function makeLayer(opts) {
      opts = opts || {};
      var after = opts.after;
      getBb();
      var area = bb.w * scale * (bb.h * scale);
      if (area > maxLayerArea) {
        return null;
      }
      var layer = self.makeLayer(bb, lvl);
      if (after != null) {
        var index = layers.indexOf(after) + 1;
        layers.splice(index, 0, layer);
      } else if (opts.insert === undefined || opts.insert) {
        // no after specified => first layer made so put at start
        layers.unshift(layer);
      }

      // if( tmpLayers ){
      //self.queueLayer( layer );
      // }

      return layer;
    };
    if (self.skipping && !firstGet) {
      // log('skip layers');
      return null;
    }

    // log('do layers');

    var layer = null;
    var maxElesPerLayer = eles.length / defNumLayers;
    var allowLazyQueueing = !firstGet;
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      var rs = ele._private.rscratch;
      var caches = rs.imgLayerCaches = rs.imgLayerCaches || {};

      // log('look at ele', ele.id());

      var existingLayer = caches[lvl];
      if (existingLayer) {
        // reuse layer for later eles
        // log('reuse layer for', ele.id());
        layer = existingLayer;
        continue;
      }
      if (!layer || layer.eles.length >= maxElesPerLayer || !boundingBoxInBoundingBox(layer.bb, ele.boundingBox())) {
        // log('make new layer for ele %s', ele.id());

        layer = makeLayer({
          insert: true,
          after: layer
        });

        // if now layer can be built then we can't use layers at this level
        if (!layer) {
          return null;
        }

        // log('new layer with id %s', layer.id);
      }

      if (tmpLayers || allowLazyQueueing) {
        // log('queue ele %s in layer %s', ele.id(), layer.id);
        self.queueLayer(layer, ele);
      } else {
        // log('draw ele %s in layer %s', ele.id(), layer.id);
        self.drawEleInLayer(layer, ele, lvl, pxRatio);
      }
      layer.eles.push(ele);
      caches[lvl] = layer;
    }

    // log('--');

    if (tmpLayers) {
      // then we only queued the current layerset and can't draw it yet
      return tmpLayers;
    }
    if (allowLazyQueueing) {
      // log('lazy queue level', lvl);
      return null;
    }
    return layers;
  };

  // a layer may want to use an ele cache of a higher level to avoid blurriness
  // so the layer level might not equal the ele level
  LTCp.getEleLevelForLayerLevel = function (lvl, pxRatio) {
    return lvl;
  };
  LTCp.drawEleInLayer = function (layer, ele, lvl, pxRatio) {
    var self = this;
    var r = this.renderer;
    var context = layer.context;
    var bb = ele.boundingBox();
    if (bb.w === 0 || bb.h === 0 || !ele.visible()) {
      return;
    }
    lvl = self.getEleLevelForLayerLevel(lvl, pxRatio);
    {
      r.setImgSmoothing(context, false);
    }
    {
      r.drawCachedElement(context, ele, null, null, lvl, useHighQualityEleTxrReqs);
    }
    {
      r.setImgSmoothing(context, true);
    }
  };
  LTCp.levelIsComplete = function (lvl, eles) {
    var self = this;
    var layers = self.layersByLevel[lvl];
    if (!layers || layers.length === 0) {
      return false;
    }
    var numElesInLayers = 0;
    for (var i = 0; i < layers.length; i++) {
      var layer = layers[i];

      // if there are any eles needed to be drawn yet, the level is not complete
      if (layer.reqs > 0) {
        return false;
      }

      // if the layer is invalid, the level is not complete
      if (layer.invalid) {
        return false;
      }
      numElesInLayers += layer.eles.length;
    }

    // we should have exactly the number of eles passed in to be complete
    if (numElesInLayers !== eles.length) {
      return false;
    }
    return true;
  };
  LTCp.validateLayersElesOrdering = function (lvl, eles) {
    var layers = this.layersByLevel[lvl];
    if (!layers) {
      return;
    }

    // if in a layer the eles are not in the same order, then the layer is invalid
    // (i.e. there is an ele in between the eles in the layer)

    for (var i = 0; i < layers.length; i++) {
      var layer = layers[i];
      var offset = -1;

      // find the offset
      for (var j = 0; j < eles.length; j++) {
        if (layer.eles[0] === eles[j]) {
          offset = j;
          break;
        }
      }
      if (offset < 0) {
        // then the layer has nonexistent elements and is invalid
        this.invalidateLayer(layer);
        continue;
      }

      // the eles in the layer must be in the same continuous order, else the layer is invalid

      var o = offset;
      for (var j = 0; j < layer.eles.length; j++) {
        if (layer.eles[j] !== eles[o + j]) {
          // log('invalidate based on ordering', layer.id);

          this.invalidateLayer(layer);
          break;
        }
      }
    }
  };
  LTCp.updateElementsInLayers = function (eles, update) {
    var self = this;
    var isEles = element(eles[0]);

    // collect udpated elements (cascaded from the layers) and update each
    // layer itself along the way
    for (var i = 0; i < eles.length; i++) {
      var req = isEles ? null : eles[i];
      var ele = isEles ? eles[i] : eles[i].ele;
      var rs = ele._private.rscratch;
      var caches = rs.imgLayerCaches = rs.imgLayerCaches || {};
      for (var l = minLvl; l <= maxLvl; l++) {
        var layer = caches[l];
        if (!layer) {
          continue;
        }

        // if update is a request from the ele cache, then it affects only
        // the matching level
        if (req && self.getEleLevelForLayerLevel(layer.level) !== req.level) {
          continue;
        }
        update(layer, ele, req);
      }
    }
  };
  LTCp.haveLayers = function () {
    var self = this;
    var haveLayers = false;
    for (var l = minLvl; l <= maxLvl; l++) {
      var layers = self.layersByLevel[l];
      if (layers && layers.length > 0) {
        haveLayers = true;
        break;
      }
    }
    return haveLayers;
  };
  LTCp.invalidateElements = function (eles) {
    var self = this;
    if (eles.length === 0) {
      return;
    }
    self.lastInvalidationTime = performanceNow();

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

    if (eles.length === 0 || !self.haveLayers()) {
      return;
    }
    self.updateElementsInLayers(eles, function invalAssocLayers(layer, ele, req) {
      self.invalidateLayer(layer);
    });
  };
  LTCp.invalidateLayer = function (layer) {
    // log('update invalidate layer time');

    this.lastInvalidationTime = performanceNow();
    if (layer.invalid) {
      return;
    } // save cycles

    var lvl = layer.level;
    var eles = layer.eles;
    var layers = this.layersByLevel[lvl];

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

    removeFromArray(layers, layer);
    // layer.eles = [];

    layer.elesQueue = [];
    layer.invalid = true;
    if (layer.replacement) {
      layer.replacement.invalid = true;
    }
    for (var i = 0; i < eles.length; i++) {
      var caches = eles[i]._private.rscratch.imgLayerCaches;
      if (caches) {
        caches[lvl] = null;
      }
    }
  };
  LTCp.refineElementTextures = function (eles) {
    var self = this;

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

    self.updateElementsInLayers(eles, function refineEachEle(layer, ele, req) {
      var rLyr = layer.replacement;
      if (!rLyr) {
        rLyr = layer.replacement = self.makeLayer(layer.bb, layer.level);
        rLyr.replaces = layer;
        rLyr.eles = layer.eles;

        // log('make replacement layer %s for %s with level %s', rLyr.id, layer.id, rLyr.level);
      }

      if (!rLyr.reqs) {
        for (var i = 0; i < rLyr.eles.length; i++) {
          self.queueLayer(rLyr, rLyr.eles[i]);
        }

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

  LTCp.enqueueElementRefinement = function (ele) {
    this.eleTxrDeqs.merge(ele);
    this.scheduleElementRefinement();
  };
  LTCp.queueLayer = function (layer, ele) {
    var self = this;
    var q = self.layersQueue;
    var elesQ = layer.elesQueue;
    var hasId = elesQ.hasId = elesQ.hasId || {};

    // if a layer is going to be replaced, queuing is a waste of time
    if (layer.replacement) {
      return;
    }
    if (ele) {
      if (hasId[ele.id()]) {
        return;
      }
      elesQ.push(ele);
      hasId[ele.id()] = true;
    }
    if (layer.reqs) {
      layer.reqs++;
      q.updateItem(layer);
    } else {
      layer.reqs = 1;
      q.push(layer);
    }
  };
  LTCp.dequeue = function (pxRatio) {
    var self = this;
    var q = self.layersQueue;
    var deqd = [];
    var eleDeqs = 0;
    while (eleDeqs < maxDeqSize) {
      if (q.size() === 0) {
        break;
      }
      var layer = q.peek();

      // if a layer has been or will be replaced, then don't waste time with it
      if (layer.replacement) {
        // log('layer %s in queue skipped b/c it already has a replacement', layer.id);
        q.pop();
        continue;
      }

      // if this is a replacement layer that has been superceded, then forget it
      if (layer.replaces && layer !== layer.replaces.replacement) {
        // log('layer is no longer the most uptodate replacement; dequeued', layer.id)
        q.pop();
        continue;
      }
      if (layer.invalid) {
        // log('replacement layer %s is invalid; dequeued', layer.id);
        q.pop();
        continue;
      }
      var ele = layer.elesQueue.shift();
      if (ele) {
        // log('dequeue layer %s', layer.id);

        self.drawEleInLayer(layer, ele, layer.level, pxRatio);
        eleDeqs++;
      }
      if (deqd.length === 0) {
        // we need only one entry in deqd to queue redrawing etc
        deqd.push(true);
      }

      // if the layer has all its eles done, then remove from the queue
      if (layer.elesQueue.length === 0) {
        q.pop();
        layer.reqs = 0;

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

        // when a replacement layer is dequeued, it replaces the old layer in the level
        if (layer.replaces) {
          self.applyLayerReplacement(layer);
        }
        self.requestRedraw();
      }
    }
    return deqd;
  };
  LTCp.applyLayerReplacement = function (layer) {
    var self = this;
    var layersInLevel = self.layersByLevel[layer.level];
    var replaced = layer.replaces;
    var index = layersInLevel.indexOf(replaced);

    // if the replaced layer is not in the active list for the level, then replacing
    // refs would be a mistake (i.e. overwriting the true active layer)
    if (index < 0 || replaced.invalid) {
      // log('replacement layer would have no effect', layer.id);
      return;
    }
    layersInLevel[index] = layer; // replace level ref

    // replace refs in eles
    for (var i = 0; i < layer.eles.length; i++) {
      var _p = layer.eles[i]._private;
      var cache = _p.imgLayerCaches = _p.imgLayerCaches || {};
      if (cache) {
        cache[layer.level] = layer;
      }
    }

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

    self.requestRedraw();
  };
  LTCp.requestRedraw = debounce_1(function () {
    var r = this.renderer;
    r.redrawHint('eles', true);
    r.redrawHint('drag', true);
    r.redraw();
  }, 100);
  LTCp.setupDequeueing = defs.setupDequeueing({
    deqRedrawThreshold: deqRedrawThreshold,
    deqCost: deqCost,
    deqAvgCost: deqAvgCost,
    deqNoDrawCost: deqNoDrawCost,
    deqFastCost: deqFastCost,
    deq: function deq(self, pxRatio) {
      return self.dequeue(pxRatio);
    },
    onDeqd: noop$1,
    shouldRedraw: trueify,
    priority: function priority(self) {
      return self.renderer.beforeRenderPriorities.lyrTxrDeq;
    }
  });

  var CRp$a = {};
  var impl;
  function polygon(context, points) {
    for (var i = 0; i < points.length; i++) {
      var pt = points[i];
      context.lineTo(pt.x, pt.y);
    }
  }
  function triangleBackcurve(context, points, controlPoint) {
    var firstPt;
    for (var i = 0; i < points.length; i++) {
      var pt = points[i];
      if (i === 0) {
        firstPt = pt;
      }
      context.lineTo(pt.x, pt.y);
    }
    context.quadraticCurveTo(controlPoint.x, controlPoint.y, firstPt.x, firstPt.y);
  }
  function triangleTee(context, trianglePoints, teePoints) {
    if (context.beginPath) {
      context.beginPath();
    }
    var triPts = trianglePoints;
    for (var i = 0; i < triPts.length; i++) {
      var pt = triPts[i];
      context.lineTo(pt.x, pt.y);
    }
    var teePts = teePoints;
    var firstTeePt = teePoints[0];
    context.moveTo(firstTeePt.x, firstTeePt.y);
    for (var i = 1; i < teePts.length; i++) {
      var pt = teePts[i];
      context.lineTo(pt.x, pt.y);
    }
    if (context.closePath) {
      context.closePath();
    }
  }
  function circleTriangle(context, trianglePoints, rx, ry, r) {
    if (context.beginPath) {
      context.beginPath();
    }
    context.arc(rx, ry, r, 0, Math.PI * 2, false);
    var triPts = trianglePoints;
    var firstTrPt = triPts[0];
    context.moveTo(firstTrPt.x, firstTrPt.y);
    for (var i = 0; i < triPts.length; i++) {
      var pt = triPts[i];
      context.lineTo(pt.x, pt.y);
    }
    if (context.closePath) {
      context.closePath();
    }
  }
  function circle(context, rx, ry, r) {
    context.arc(rx, ry, r, 0, Math.PI * 2, false);
  }
  CRp$a.arrowShapeImpl = function (name) {
    return (impl || (impl = {
      'polygon': polygon,
      'triangle-backcurve': triangleBackcurve,
      'triangle-tee': triangleTee,
      'circle-triangle': circleTriangle,
      'triangle-cross': triangleTee,
      'circle': circle
    }))[name];
  };

  var CRp$9 = {};
  CRp$9.drawElement = function (context, ele, shiftToOriginWithBb, showLabel, showOverlay, showOpacity) {
    var r = this;
    if (ele.isNode()) {
      r.drawNode(context, ele, shiftToOriginWithBb, showLabel, showOverlay, showOpacity);
    } else {
      r.drawEdge(context, ele, shiftToOriginWithBb, showLabel, showOverlay, showOpacity);
    }
  };
  CRp$9.drawElementOverlay = function (context, ele) {
    var r = this;
    if (ele.isNode()) {
      r.drawNodeOverlay(context, ele);
    } else {
      r.drawEdgeOverlay(context, ele);
    }
  };
  CRp$9.drawElementUnderlay = function (context, ele) {
    var r = this;
    if (ele.isNode()) {
      r.drawNodeUnderlay(context, ele);
    } else {
      r.drawEdgeUnderlay(context, ele);
    }
  };
  CRp$9.drawCachedElementPortion = function (context, ele, eleTxrCache, pxRatio, lvl, reason, getRotation, getOpacity) {
    var r = this;
    var bb = eleTxrCache.getBoundingBox(ele);
    if (bb.w === 0 || bb.h === 0) {
      return;
    } // ignore zero size case

    var eleCache = eleTxrCache.getElement(ele, bb, pxRatio, lvl, reason);
    if (eleCache != null) {
      var opacity = getOpacity(r, ele);
      if (opacity === 0) {
        return;
      }
      var theta = getRotation(r, ele);
      var x1 = bb.x1,
        y1 = bb.y1,
        w = bb.w,
        h = bb.h;
      var x, y, sx, sy, smooth;
      if (theta !== 0) {
        var rotPt = eleTxrCache.getRotationPoint(ele);
        sx = rotPt.x;
        sy = rotPt.y;
        context.translate(sx, sy);
        context.rotate(theta);
        smooth = r.getImgSmoothing(context);
        if (!smooth) {
          r.setImgSmoothing(context, true);
        }
        var off = eleTxrCache.getRotationOffset(ele);
        x = off.x;
        y = off.y;
      } else {
        x = x1;
        y = y1;
      }
      var oldGlobalAlpha;
      if (opacity !== 1) {
        oldGlobalAlpha = context.globalAlpha;
        context.globalAlpha = oldGlobalAlpha * opacity;
      }
      context.drawImage(eleCache.texture.canvas, eleCache.x, 0, eleCache.width, eleCache.height, x, y, w, h);
      if (opacity !== 1) {
        context.globalAlpha = oldGlobalAlpha;
      }
      if (theta !== 0) {
        context.rotate(-theta);
        context.translate(-sx, -sy);
        if (!smooth) {
          r.setImgSmoothing(context, false);
        }
      }
    } else {
      eleTxrCache.drawElement(context, ele); // direct draw fallback
    }
  };

  var getZeroRotation = function getZeroRotation() {
    return 0;
  };
  var getLabelRotation = function getLabelRotation(r, ele) {
    return r.getTextAngle(ele, null);
  };
  var getSourceLabelRotation = function getSourceLabelRotation(r, ele) {
    return r.getTextAngle(ele, 'source');
  };
  var getTargetLabelRotation = function getTargetLabelRotation(r, ele) {
    return r.getTextAngle(ele, 'target');
  };
  var getOpacity = function getOpacity(r, ele) {
    return ele.effectiveOpacity();
  };
  var getTextOpacity = function getTextOpacity(e, ele) {
    return ele.pstyle('text-opacity').pfValue * ele.effectiveOpacity();
  };
  CRp$9.drawCachedElement = function (context, ele, pxRatio, extent, lvl, requestHighQuality) {
    var r = this;
    var _r$data = r.data,
      eleTxrCache = _r$data.eleTxrCache,
      lblTxrCache = _r$data.lblTxrCache,
      slbTxrCache = _r$data.slbTxrCache,
      tlbTxrCache = _r$data.tlbTxrCache;
    var bb = ele.boundingBox();
    var reason = requestHighQuality === true ? eleTxrCache.reasons.highQuality : null;
    if (bb.w === 0 || bb.h === 0 || !ele.visible()) {
      return;
    }
    if (!extent || boundingBoxesIntersect(bb, extent)) {
      var isEdge = ele.isEdge();
      var badLine = ele.element()._private.rscratch.badLine;
      r.drawElementUnderlay(context, ele);
      r.drawCachedElementPortion(context, ele, eleTxrCache, pxRatio, lvl, reason, getZeroRotation, getOpacity);
      if (!isEdge || !badLine) {
        r.drawCachedElementPortion(context, ele, lblTxrCache, pxRatio, lvl, reason, getLabelRotation, getTextOpacity);
      }
      if (isEdge && !badLine) {
        r.drawCachedElementPortion(context, ele, slbTxrCache, pxRatio, lvl, reason, getSourceLabelRotation, getTextOpacity);
        r.drawCachedElementPortion(context, ele, tlbTxrCache, pxRatio, lvl, reason, getTargetLabelRotation, getTextOpacity);
      }
      r.drawElementOverlay(context, ele);
    }
  };
  CRp$9.drawElements = function (context, eles) {
    var r = this;
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      r.drawElement(context, ele);
    }
  };
  CRp$9.drawCachedElements = function (context, eles, pxRatio, extent) {
    var r = this;
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      r.drawCachedElement(context, ele, pxRatio, extent);
    }
  };
  CRp$9.drawCachedNodes = function (context, eles, pxRatio, extent) {
    var r = this;
    for (var i = 0; i < eles.length; i++) {
      var ele = eles[i];
      if (!ele.isNode()) {
        continue;
      }
      r.drawCachedElement(context, ele, pxRatio, extent);
    }
  };
  CRp$9.drawLayeredElements = function (context, eles, pxRatio, extent) {
    var r = this;
    var layers = r.data.lyrTxrCache.getLayers(eles, pxRatio);
    if (layers) {
      for (var i = 0; i < layers.length; i++) {
        var layer = layers[i];
        var bb = layer.bb;
        if (bb.w === 0 || bb.h === 0) {
          continue;
        }
        context.drawImage(layer.canvas, bb.x1, bb.y1, bb.w, bb.h);
      }
    } else {
      // fall back on plain caching if no layers
      r.drawCachedElements(context, eles, pxRatio, extent);
    }
  };

  /* global Path2D */
  var CRp$8 = {};
  CRp$8.drawEdge = function (context, edge, shiftToOriginWithBb) {
    var drawLabel = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
    var shouldDrawOverlay = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
    var shouldDrawOpacity = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
    var r = this;
    var rs = edge._private.rscratch;
    if (shouldDrawOpacity && !edge.visible()) {
      return;
    }

    // if bezier ctrl pts can not be calculated, then die
    if (rs.badLine || rs.allpts == null || isNaN(rs.allpts[0])) {
      // isNaN in case edge is impossible and browser bugs (e.g. safari)
      return;
    }
    var bb;
    if (shiftToOriginWithBb) {
      bb = shiftToOriginWithBb;
      context.translate(-bb.x1, -bb.y1);
    }
    var opacity = shouldDrawOpacity ? edge.pstyle('opacity').value : 1;
    var lineOpacity = shouldDrawOpacity ? edge.pstyle('line-opacity').value : 1;
    var curveStyle = edge.pstyle('curve-style').value;
    var lineStyle = edge.pstyle('line-style').value;
    var edgeWidth = edge.pstyle('width').pfValue;
    var lineCap = edge.pstyle('line-cap').value;
    var effectiveLineOpacity = opacity * lineOpacity;
    // separate arrow opacity would require arrow-opacity property
    var effectiveArrowOpacity = opacity * lineOpacity;
    var drawLine = function drawLine() {
      var strokeOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : effectiveLineOpacity;
      if (curveStyle === 'straight-triangle') {
        r.eleStrokeStyle(context, edge, strokeOpacity);
        r.drawEdgeTrianglePath(edge, context, rs.allpts);
      } else {
        context.lineWidth = edgeWidth;
        context.lineCap = lineCap;
        r.eleStrokeStyle(context, edge, strokeOpacity);
        r.drawEdgePath(edge, context, rs.allpts, lineStyle);
        context.lineCap = 'butt'; // reset for other drawing functions
      }
    };

    var drawOverlay = function drawOverlay() {
      if (!shouldDrawOverlay) {
        return;
      }
      r.drawEdgeOverlay(context, edge);
    };
    var drawUnderlay = function drawUnderlay() {
      if (!shouldDrawOverlay) {
        return;
      }
      r.drawEdgeUnderlay(context, edge);
    };
    var drawArrows = function drawArrows() {
      var arrowOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : effectiveArrowOpacity;
      r.drawArrowheads(context, edge, arrowOpacity);
    };
    var drawText = function drawText() {
      r.drawElementText(context, edge, null, drawLabel);
    };
    context.lineJoin = 'round';
    var ghost = edge.pstyle('ghost').value === 'yes';
    if (ghost) {
      var gx = edge.pstyle('ghost-offset-x').pfValue;
      var gy = edge.pstyle('ghost-offset-y').pfValue;
      var ghostOpacity = edge.pstyle('ghost-opacity').value;
      var effectiveGhostOpacity = effectiveLineOpacity * ghostOpacity;
      context.translate(gx, gy);
      drawLine(effectiveGhostOpacity);
      drawArrows(effectiveGhostOpacity);
      context.translate(-gx, -gy);
    }
    drawUnderlay();
    drawLine();
    drawArrows();
    drawOverlay();
    drawText();
    if (shiftToOriginWithBb) {
      context.translate(bb.x1, bb.y1);
    }
  };
  var drawEdgeOverlayUnderlay = function drawEdgeOverlayUnderlay(overlayOrUnderlay) {
    if (!['overlay', 'underlay'].includes(overlayOrUnderlay)) {
      throw new Error('Invalid state');
    }
    return function (context, edge) {
      if (!edge.visible()) {
        return;
      }
      var opacity = edge.pstyle("".concat(overlayOrUnderlay, "-opacity")).value;
      if (opacity === 0) {
        return;
      }
      var r = this;
      var usePaths = r.usePaths();
      var rs = edge._private.rscratch;
      var padding = edge.pstyle("".concat(overlayOrUnderlay, "-padding")).pfValue;
      var width = 2 * padding;
      var color = edge.pstyle("".concat(overlayOrUnderlay, "-color")).value;
      context.lineWidth = width;
      if (rs.edgeType === 'self' && !usePaths) {
        context.lineCap = 'butt';
      } else {
        context.lineCap = 'round';
      }
      r.colorStrokeStyle(context, color[0], color[1], color[2], opacity);
      r.drawEdgePath(edge, context, rs.allpts, 'solid');
    };
  };
  CRp$8.drawEdgeOverlay = drawEdgeOverlayUnderlay('overlay');
  CRp$8.drawEdgeUnderlay = drawEdgeOverlayUnderlay('underlay');
  CRp$8.drawEdgePath = function (edge, context, pts, type) {
    var rs = edge._private.rscratch;
    var canvasCxt = context;
    var path;
    var pathCacheHit = false;
    var usePaths = this.usePaths();
    var lineDashPattern = edge.pstyle('line-dash-pattern').pfValue;
    var lineDashOffset = edge.pstyle('line-dash-offset').pfValue;
    if (usePaths) {
      var pathCacheKey = pts.join('$');
      var keyMatches = rs.pathCacheKey && rs.pathCacheKey === pathCacheKey;
      if (keyMatches) {
        path = context = rs.pathCache;
        pathCacheHit = true;
      } else {
        path = context = new Path2D();
        rs.pathCacheKey = pathCacheKey;
        rs.pathCache = path;
      }
    }
    if (canvasCxt.setLineDash) {
      // for very outofdate browsers
      switch (type) {
        case 'dotted':
          canvasCxt.setLineDash([1, 1]);
          break;
        case 'dashed':
          canvasCxt.setLineDash(lineDashPattern);
          canvasCxt.lineDashOffset = lineDashOffset;
          break;
        case 'solid':
          canvasCxt.setLineDash([]);
          break;
      }
    }
    if (!pathCacheHit && !rs.badLine) {
      if (context.beginPath) {
        context.beginPath();
      }
      context.moveTo(pts[0], pts[1]);
      switch (rs.edgeType) {
        case 'bezier':
        case 'self':
        case 'compound':
        case 'multibezier':
          for (var i = 2; i + 3 < pts.length; i += 4) {
            context.quadraticCurveTo(pts[i], pts[i + 1], pts[i + 2], pts[i + 3]);
          }
          break;
        case 'straight':
        case 'segments':
        case 'haystack':
          for (var _i = 2; _i + 1 < pts.length; _i += 2) {
            context.lineTo(pts[_i], pts[_i + 1]);
          }
          break;
      }
    }
    context = canvasCxt;
    if (usePaths) {
      context.stroke(path);
    } else {
      context.stroke();
    }

    // reset any line dashes
    if (context.setLineDash) {
      // for very outofdate browsers
      context.setLineDash([]);
    }
  };
  CRp$8.drawEdgeTrianglePath = function (edge, context, pts) {
    // use line stroke style for triangle fill style
    context.fillStyle = context.strokeStyle;
    var edgeWidth = edge.pstyle('width').pfValue;
    for (var i = 0; i + 1 < pts.length; i += 2) {
      var vector = [pts[i + 2] - pts[i], pts[i + 3] - pts[i + 1]];
      var length = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1]);
      var normal = [vector[1] / length, -vector[0] / length];
      var triangleHead = [normal[0] * edgeWidth / 2, normal[1] * edgeWidth / 2];
      context.beginPath();
      context.moveTo(pts[i] - triangleHead[0], pts[i + 1] - triangleHead[1]);
      context.lineTo(pts[i] + triangleHead[0], pts[i + 1] + triangleHead[1]);
      context.lineTo(pts[i + 2], pts[i + 3]);
      context.closePath();
      context.fill();
    }
  };
  CRp$8.drawArrowheads = function (context, edge, opacity) {
    var rs = edge._private.rscratch;
    var isHaystack = rs.edgeType === 'haystack';
    if (!isHaystack) {
      this.drawArrowhead(context, edge, 'source', rs.arrowStartX, rs.arrowStartY, rs.srcArrowAngle, opacity);
    }
    this.drawArrowhead(context, edge, 'mid-target', rs.midX, rs.midY, rs.midtgtArrowAngle, opacity);
    this.drawArrowhead(context, edge, 'mid-source', rs.midX, rs.midY, rs.midsrcArrowAngle, opacity);
    if (!isHaystack) {
      this.drawArrowhead(context, edge, 'target', rs.arrowEndX, rs.arrowEndY, rs.tgtArrowAngle, opacity);
    }
  };
  CRp$8.drawArrowhead = function (context, edge, prefix, x, y, angle, opacity) {
    if (isNaN(x) || x == null || isNaN(y) || y == null || isNaN(angle) || angle == null) {
      return;
    }
    var self = this;
    var arrowShape = edge.pstyle(prefix + '-arrow-shape').value;
    if (arrowShape === 'none') {
      return;
    }
    var arrowClearFill = edge.pstyle(prefix + '-arrow-fill').value === 'hollow' ? 'both' : 'filled';
    var arrowFill = edge.pstyle(prefix + '-arrow-fill').value;
    var edgeWidth = edge.pstyle('width').pfValue;
    var pArrowWidth = edge.pstyle(prefix + '-arrow-width');
    var arrowWidth = pArrowWidth.value === 'match-line' ? edgeWidth : pArrowWidth.pfValue;
    if (pArrowWidth.units === '%') arrowWidth *= edgeWidth;
    var edgeOpacity = edge.pstyle('opacity').value;
    if (opacity === undefined) {
      opacity = edgeOpacity;
    }
    var gco = context.globalCompositeOperation;
    if (opacity !== 1 || arrowFill === 'hollow') {
      // then extra clear is needed
      context.globalCompositeOperation = 'destination-out';
      self.colorFillStyle(context, 255, 255, 255, 1);
      self.colorStrokeStyle(context, 255, 255, 255, 1);
      self.drawArrowShape(edge, context, arrowClearFill, edgeWidth, arrowShape, arrowWidth, x, y, angle);
      context.globalCompositeOperation = gco;
    } // otherwise, the opaque arrow clears it for free :)

    var color = edge.pstyle(prefix + '-arrow-color').value;
    self.colorFillStyle(context, color[0], color[1], color[2], opacity);
    self.colorStrokeStyle(context, color[0], color[1], color[2], opacity);
    self.drawArrowShape(edge, context, arrowFill, edgeWidth, arrowShape, arrowWidth, x, y, angle);
  };
  CRp$8.drawArrowShape = function (edge, context, fill, edgeWidth, shape, shapeWidth, x, y, angle) {
    var r = this;
    var usePaths = this.usePaths() && shape !== 'triangle-cross';
    var pathCacheHit = false;
    var path;
    var canvasContext = context;
    var translation = {
      x: x,
      y: y
    };
    var scale = edge.pstyle('arrow-scale').value;
    var size = this.getArrowWidth(edgeWidth, scale);
    var shapeImpl = r.arrowShapes[shape];
    if (usePaths) {
      var cache = r.arrowPathCache = r.arrowPathCache || [];
      var key = hashString(shape);
      var cachedPath = cache[key];
      if (cachedPath != null) {
        path = context = cachedPath;
        pathCacheHit = true;
      } else {
        path = context = new Path2D();
        cache[key] = path;
      }
    }
    if (!pathCacheHit) {
      if (context.beginPath) {
        context.beginPath();
      }
      if (usePaths) {
        // store in the path cache with values easily manipulated later
        shapeImpl.draw(context, 1, 0, {
          x: 0,
          y: 0
        }, 1);
      } else {
        shapeImpl.draw(context, size, angle, translation, edgeWidth);
      }
      if (context.closePath) {
        context.closePath();
      }
    }
    context = canvasContext;
    if (usePaths) {
      // set transform to arrow position/orientation
      context.translate(x, y);
      context.rotate(angle);
      context.scale(size, size);
    }
    if (fill === 'filled' || fill === 'both') {
      if (usePaths) {
        context.fill(path);
      } else {
        context.fill();
      }
    }
    if (fill === 'hollow' || fill === 'both') {
      context.lineWidth = shapeWidth / (usePaths ? size : 1);
      context.lineJoin = 'miter';
      if (usePaths) {
        context.stroke(path);
      } else {
        context.stroke();
      }
    }
    if (usePaths) {
      // reset transform by applying inverse
      context.scale(1 / size, 1 / size);
      context.rotate(-angle);
      context.translate(-x, -y);
    }
  };

  var CRp$7 = {};
  CRp$7.safeDrawImage = function (context, img, ix, iy, iw, ih, x, y, w, h) {
    // detect problematic cases for old browsers with bad images (cheaper than try-catch)
    if (iw <= 0 || ih <= 0 || w <= 0 || h <= 0) {
      return;
    }
    try {
      context.drawImage(img, ix, iy, iw, ih, x, y, w, h);
    } catch (e) {
      warn(e);
    }
  };
  CRp$7.drawInscribedImage = function (context, img, node, index, nodeOpacity) {
    var r = this;
    var pos = node.position();
    var nodeX = pos.x;
    var nodeY = pos.y;
    var styleObj = node.cy().style();
    var getIndexedStyle = styleObj.getIndexedStyle.bind(styleObj);
    var fit = getIndexedStyle(node, 'background-fit', 'value', index);
    var repeat = getIndexedStyle(node, 'background-repeat', 'value', index);
    var nodeW = node.width();
    var nodeH = node.height();
    var paddingX2 = node.padding() * 2;
    var nodeTW = nodeW + (getIndexedStyle(node, 'background-width-relative-to', 'value', index) === 'inner' ? 0 : paddingX2);
    var nodeTH = nodeH + (getIndexedStyle(node, 'background-height-relative-to', 'value', index) === 'inner' ? 0 : paddingX2);
    var rs = node._private.rscratch;
    var clip = getIndexedStyle(node, 'background-clip', 'value', index);
    var shouldClip = clip === 'node';
    var imgOpacity = getIndexedStyle(node, 'background-image-opacity', 'value', index) * nodeOpacity;
    var smooth = getIndexedStyle(node, 'background-image-smoothing', 'value', index);
    var imgW = img.width || img.cachedW;
    var imgH = img.height || img.cachedH;

    // workaround for broken browsers like ie
    if (null == imgW || null == imgH) {
      document.body.appendChild(img); // eslint-disable-line no-undef

      imgW = img.cachedW = img.width || img.offsetWidth;
      imgH = img.cachedH = img.height || img.offsetHeight;
      document.body.removeChild(img); // eslint-disable-line no-undef
    }

    var w = imgW;
    var h = imgH;
    if (getIndexedStyle(node, 'background-width', 'value', index) !== 'auto') {
      if (getIndexedStyle(node, 'background-width', 'units', index) === '%') {
        w = getIndexedStyle(node, 'background-width', 'pfValue', index) * nodeTW;
      } else {
        w = getIndexedStyle(node, 'background-width', 'pfValue', index);
      }
    }
    if (getIndexedStyle(node, 'background-height', 'value', index) !== 'auto') {
      if (getIndexedStyle(node, 'background-height', 'units', index) === '%') {
        h = getIndexedStyle(node, 'background-height', 'pfValue', index) * nodeTH;
      } else {
        h = getIndexedStyle(node, 'background-height', 'pfValue', index);
      }
    }
    if (w === 0 || h === 0) {
      return; // no point in drawing empty image (and chrome is broken in this case)
    }

    if (fit === 'contain') {
      var scale = Math.min(nodeTW / w, nodeTH / h);
      w *= scale;
      h *= scale;
    } else if (fit === 'cover') {
      var scale = Math.max(nodeTW / w, nodeTH / h);
      w *= scale;
      h *= scale;
    }
    var x = nodeX - nodeTW / 2; // left
    var posXUnits = getIndexedStyle(node, 'background-position-x', 'units', index);
    var posXPfVal = getIndexedStyle(node, 'background-position-x', 'pfValue', index);
    if (posXUnits === '%') {
      x += (nodeTW - w) * posXPfVal;
    } else {
      x += posXPfVal;
    }
    var offXUnits = getIndexedStyle(node, 'background-offset-x', 'units', index);
    var offXPfVal = getIndexedStyle(node, 'background-offset-x', 'pfValue', index);
    if (offXUnits === '%') {
      x += (nodeTW - w) * offXPfVal;
    } else {
      x += offXPfVal;
    }
    var y = nodeY - nodeTH / 2; // top
    var posYUnits = getIndexedStyle(node, 'background-position-y', 'units', index);
    var posYPfVal = getIndexedStyle(node, 'background-position-y', 'pfValue', index);
    if (posYUnits === '%') {
      y += (nodeTH - h) * posYPfVal;
    } else {
      y += posYPfVal;
    }
    var offYUnits = getIndexedStyle(node, 'background-offset-y', 'units', index);
    var offYPfVal = getIndexedStyle(node, 'background-offset-y', 'pfValue', index);
    if (offYUnits === '%') {
      y += (nodeTH - h) * offYPfVal;
    } else {
      y += offYPfVal;
    }
    if (rs.pathCache) {
      x -= nodeX;
      y -= nodeY;
      nodeX = 0;
      nodeY = 0;
    }
    var gAlpha = context.globalAlpha;
    context.globalAlpha = imgOpacity;
    var smoothingEnabled = r.getImgSmoothing(context);
    var isSmoothingSwitched = false;
    if (smooth === 'no' && smoothingEnabled) {
      r.setImgSmoothing(context, false);
      isSmoothingSwitched = true;
    } else if (smooth === 'yes' && !smoothingEnabled) {
      r.setImgSmoothing(context, true);
      isSmoothingSwitched = true;
    }
    if (repeat === 'no-repeat') {
      if (shouldClip) {
        context.save();
        if (rs.pathCache) {
          context.clip(rs.pathCache);
        } else {
          r.nodeShapes[r.getNodeShape(node)].draw(context, nodeX, nodeY, nodeTW, nodeTH);
          context.clip();
        }
      }
      r.safeDrawImage(context, img, 0, 0, imgW, imgH, x, y, w, h);
      if (shouldClip) {
        context.restore();
      }
    } else {
      var pattern = context.createPattern(img, repeat);
      context.fillStyle = pattern;
      r.nodeShapes[r.getNodeShape(node)].draw(context, nodeX, nodeY, nodeTW, nodeTH);
      context.translate(x, y);
      context.fill();
      context.translate(-x, -y);
    }
    context.globalAlpha = gAlpha;
    if (isSmoothingSwitched) {
      r.setImgSmoothing(context, smoothingEnabled);
    }
  };

  var CRp$6 = {};
  CRp$6.eleTextBiggerThanMin = function (ele, scale) {
    if (!scale) {
      var zoom = ele.cy().zoom();
      var pxRatio = this.getPixelRatio();
      var lvl = Math.ceil(log2(zoom * pxRatio)); // the effective texture level

      scale = Math.pow(2, lvl);
    }
    var computedSize = ele.pstyle('font-size').pfValue * scale;
    var minSize = ele.pstyle('min-zoomed-font-size').pfValue;
    if (computedSize < minSize) {
      return false;
    }
    return true;
  };
  CRp$6.drawElementText = function (context, ele, shiftToOriginWithBb, force, prefix) {
    var useEleOpacity = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
    var r = this;
    if (force == null) {
      if (useEleOpacity && !r.eleTextBiggerThanMin(ele)) {
        return;
      }
    } else if (force === false) {
      return;
    }
    if (ele.isNode()) {
      var label = ele.pstyle('label');
      if (!label || !label.value) {
        return;
      }
      var justification = r.getLabelJustification(ele);
      context.textAlign = justification;
      context.textBaseline = 'bottom';
    } else {
      var badLine = ele.element()._private.rscratch.badLine;
      var _label = ele.pstyle('label');
      var srcLabel = ele.pstyle('source-label');
      var tgtLabel = ele.pstyle('target-label');
      if (badLine || (!_label || !_label.value) && (!srcLabel || !srcLabel.value) && (!tgtLabel || !tgtLabel.value)) {
        return;
      }
      context.textAlign = 'center';
      context.textBaseline = 'bottom';
    }
    var applyRotation = !shiftToOriginWithBb;
    var bb;
    if (shiftToOriginWithBb) {
      bb = shiftToOriginWithBb;
      context.translate(-bb.x1, -bb.y1);
    }
    if (prefix == null) {
      r.drawText(context, ele, null, applyRotation, useEleOpacity);
      if (ele.isEdge()) {
        r.drawText(context, ele, 'source', applyRotation, useEleOpacity);
        r.drawText(context, ele, 'target', applyRotation, useEleOpacity);
      }
    } else {
      r.drawText(context, ele, prefix, applyRotation, useEleOpacity);
    }
    if (shiftToOriginWithBb) {
      context.translate(bb.x1, bb.y1);
    }
  };
  CRp$6.getFontCache = function (context) {
    var cache;
    this.fontCaches = this.fontCaches || [];
    for (var i = 0; i < this.fontCaches.length; i++) {
      cache = this.fontCaches[i];
      if (cache.context === context) {
        return cache;
      }
    }
    cache = {
      context: context
    };
    this.fontCaches.push(cache);
    return cache;
  };

  // set up canvas context with font
  // returns transformed text string
  CRp$6.setupTextStyle = function (context, ele) {
    var useEleOpacity = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
    // Font style
    var labelStyle = ele.pstyle('font-style').strValue;
    var labelSize = ele.pstyle('font-size').pfValue + 'px';
    var labelFamily = ele.pstyle('font-family').strValue;
    var labelWeight = ele.pstyle('font-weight').strValue;
    var opacity = useEleOpacity ? ele.effectiveOpacity() * ele.pstyle('text-opacity').value : 1;
    var outlineOpacity = ele.pstyle('text-outline-opacity').value * opacity;
    var color = ele.pstyle('color').value;
    var outlineColor = ele.pstyle('text-outline-color').value;
    context.font = labelStyle + ' ' + labelWeight + ' ' + labelSize + ' ' + labelFamily;
    context.lineJoin = 'round'; // so text outlines aren't jagged

    this.colorFillStyle(context, color[0], color[1], color[2], opacity);
    this.colorStrokeStyle(context, outlineColor[0], outlineColor[1], outlineColor[2], outlineOpacity);
  };

  // TODO ensure re-used
  function roundRect(ctx, x, y, width, height) {
    var radius = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 5;
    var stroke = arguments.length > 6 ? arguments[6] : undefined;
    ctx.beginPath();
    ctx.moveTo(x + radius, y);
    ctx.lineTo(x + width - radius, y);
    ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
    ctx.lineTo(x + width, y + height - radius);
    ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
    ctx.lineTo(x + radius, y + height);
    ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
    ctx.lineTo(x, y + radius);
    ctx.quadraticCurveTo(x, y, x + radius, y);
    ctx.closePath();
    if (stroke) ctx.stroke();else ctx.fill();
  }
  CRp$6.getTextAngle = function (ele, prefix) {
    var theta;
    var _p = ele._private;
    var rscratch = _p.rscratch;
    var pdash = prefix ? prefix + '-' : '';
    var rotation = ele.pstyle(pdash + 'text-rotation');
    var textAngle = getPrefixedProperty(rscratch, 'labelAngle', prefix);
    if (rotation.strValue === 'autorotate') {
      theta = ele.isEdge() ? textAngle : 0;
    } else if (rotation.strValue === 'none') {
      theta = 0;
    } else {
      theta = rotation.pfValue;
    }
    return theta;
  };
  CRp$6.drawText = function (context, ele, prefix) {
    var applyRotation = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
    var useEleOpacity = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
    var _p = ele._private;
    var rscratch = _p.rscratch;
    var parentOpacity = useEleOpacity ? ele.effectiveOpacity() : 1;
    if (useEleOpacity && (parentOpacity === 0 || ele.pstyle('text-opacity').value === 0)) {
      return;
    }

    // use 'main' as an alias for the main label (i.e. null prefix)
    if (prefix === 'main') {
      prefix = null;
    }
    var textX = getPrefixedProperty(rscratch, 'labelX', prefix);
    var textY = getPrefixedProperty(rscratch, 'labelY', prefix);
    var orgTextX, orgTextY; // used for rotation
    var text = this.getLabelText(ele, prefix);
    if (text != null && text !== '' && !isNaN(textX) && !isNaN(textY)) {
      this.setupTextStyle(context, ele, useEleOpacity);
      var pdash = prefix ? prefix + '-' : '';
      var textW = getPrefixedProperty(rscratch, 'labelWidth', prefix);
      var textH = getPrefixedProperty(rscratch, 'labelHeight', prefix);
      var marginX = ele.pstyle(pdash + 'text-margin-x').pfValue;
      var marginY = ele.pstyle(pdash + 'text-margin-y').pfValue;
      var isEdge = ele.isEdge();
      var halign = ele.pstyle('text-halign').value;
      var valign = ele.pstyle('text-valign').value;
      if (isEdge) {
        halign = 'center';
        valign = 'center';
      }
      textX += marginX;
      textY += marginY;
      var theta;
      if (!applyRotation) {
        theta = 0;
      } else {
        theta = this.getTextAngle(ele, prefix);
      }
      if (theta !== 0) {
        orgTextX = textX;
        orgTextY = textY;
        context.translate(orgTextX, orgTextY);
        context.rotate(theta);
        textX = 0;
        textY = 0;
      }
      switch (valign) {
        case 'top':
          break;
        case 'center':
          textY += textH / 2;
          break;
        case 'bottom':
          textY += textH;
          break;
      }
      var backgroundOpacity = ele.pstyle('text-background-opacity').value;
      var borderOpacity = ele.pstyle('text-border-opacity').value;
      var textBorderWidth = ele.pstyle('text-border-width').pfValue;
      var backgroundPadding = ele.pstyle('text-background-padding').pfValue;
      var styleShape = ele.pstyle('text-background-shape').strValue;
      var rounded = styleShape.indexOf('round') === 0;
      var roundRadius = 2;
      if (backgroundOpacity > 0 || textBorderWidth > 0 && borderOpacity > 0) {
        var bgX = textX - backgroundPadding;
        switch (halign) {
          case 'left':
            bgX -= textW;
            break;
          case 'center':
            bgX -= textW / 2;
            break;
        }
        var bgY = textY - textH - backgroundPadding;
        var bgW = textW + 2 * backgroundPadding;
        var bgH = textH + 2 * backgroundPadding;
        if (backgroundOpacity > 0) {
          var textFill = context.fillStyle;
          var textBackgroundColor = ele.pstyle('text-background-color').value;
          context.fillStyle = 'rgba(' + textBackgroundColor[0] + ',' + textBackgroundColor[1] + ',' + textBackgroundColor[2] + ',' + backgroundOpacity * parentOpacity + ')';
          if (rounded) {
            roundRect(context, bgX, bgY, bgW, bgH, roundRadius);
          } else {
            context.fillRect(bgX, bgY, bgW, bgH);
          }
          context.fillStyle = textFill;
        }
        if (textBorderWidth > 0 && borderOpacity > 0) {
          var textStroke = context.strokeStyle;
          var textLineWidth = context.lineWidth;
          var textBorderColor = ele.pstyle('text-border-color').value;
          var textBorderStyle = ele.pstyle('text-border-style').value;
          context.strokeStyle = 'rgba(' + textBorderColor[0] + ',' + textBorderColor[1] + ',' + textBorderColor[2] + ',' + borderOpacity * parentOpacity + ')';
          context.lineWidth = textBorderWidth;
          if (context.setLineDash) {
            // for very outofdate browsers
            switch (textBorderStyle) {
              case 'dotted':
                context.setLineDash([1, 1]);
                break;
              case 'dashed':
                context.setLineDash([4, 2]);
                break;
              case 'double':
                context.lineWidth = textBorderWidth / 4; // 50% reserved for white between the two borders
                context.setLineDash([]);
                break;
              case 'solid':
                context.setLineDash([]);
                break;
            }
          }
          if (rounded) {
            roundRect(context, bgX, bgY, bgW, bgH, roundRadius, 'stroke');
          } else {
            context.strokeRect(bgX, bgY, bgW, bgH);
          }
          if (textBorderStyle === 'double') {
            var whiteWidth = textBorderWidth / 2;
            if (rounded) {
              roundRect(context, bgX + whiteWidth, bgY + whiteWidth, bgW - whiteWidth * 2, bgH - whiteWidth * 2, roundRadius, 'stroke');
            } else {
              context.strokeRect(bgX + whiteWidth, bgY + whiteWidth, bgW - whiteWidth * 2, bgH - whiteWidth * 2);
            }
          }
          if (context.setLineDash) {
            // for very outofdate browsers
            context.setLineDash([]);
          }
          context.lineWidth = textLineWidth;
          context.strokeStyle = textStroke;
        }
      }
      var lineWidth = 2 * ele.pstyle('text-outline-width').pfValue; // *2 b/c the stroke is drawn centred on the middle

      if (lineWidth > 0) {
        context.lineWidth = lineWidth;
      }
      if (ele.pstyle('text-wrap').value === 'wrap') {
        var lines = getPrefixedProperty(rscratch, 'labelWrapCachedLines', prefix);
        var lineHeight = getPrefixedProperty(rscratch, 'labelLineHeight', prefix);
        var halfTextW = textW / 2;
        var justification = this.getLabelJustification(ele);
        if (justification === 'auto') ; else if (halign === 'left') {
          // auto justification : right
          if (justification === 'left') {
            textX += -textW;
          } else if (justification === 'center') {
            textX += -halfTextW;
          } // else same as auto
        } else if (halign === 'center') {
          // auto justfication : center
          if (justification === 'left') {
            textX += -halfTextW;
          } else if (justification === 'right') {
            textX += halfTextW;
          } // else same as auto
        } else if (halign === 'right') {
          // auto justification : left
          if (justification === 'center') {
            textX += halfTextW;
          } else if (justification === 'right') {
            textX += textW;
          } // else same as auto
        }

        switch (valign) {
          case 'top':
            textY -= (lines.length - 1) * lineHeight;
            break;
          case 'center':
          case 'bottom':
            textY -= (lines.length - 1) * lineHeight;
            break;
        }
        for (var l = 0; l < lines.length; l++) {
          if (lineWidth > 0) {
            context.strokeText(lines[l], textX, textY);
          }
          context.fillText(lines[l], textX, textY);
          textY += lineHeight;
        }
      } else {
        if (lineWidth > 0) {
          context.strokeText(text, textX, textY);
        }
        context.fillText(text, textX, textY);
      }
      if (theta !== 0) {
        context.rotate(-theta);
        context.translate(-orgTextX, -orgTextY);
      }
    }
  };

  /* global Path2D */
  var CRp$5 = {};
  CRp$5.drawNode = function (context, node, shiftToOriginWithBb) {
    var drawLabel = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;
    var shouldDrawOverlay = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
    var shouldDrawOpacity = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
    var r = this;
    var nodeWidth, nodeHeight;
    var _p = node._private;
    var rs = _p.rscratch;
    var pos = node.position();
    if (!number$1(pos.x) || !number$1(pos.y)) {
      return; // can't draw node with undefined position
    }

    if (shouldDrawOpacity && !node.visible()) {
      return;
    }
    var eleOpacity = shouldDrawOpacity ? node.effectiveOpacity() : 1;
    var usePaths = r.usePaths();
    var path;
    var pathCacheHit = false;
    var padding = node.padding();
    nodeWidth = node.width() + 2 * padding;
    nodeHeight = node.height() + 2 * padding;

    //
    // setup shift

    var bb;
    if (shiftToOriginWithBb) {
      bb = shiftToOriginWithBb;
      context.translate(-bb.x1, -bb.y1);
    }

    //
    // load bg image

    var bgImgProp = node.pstyle('background-image');
    var urls = bgImgProp.value;
    var urlDefined = new Array(urls.length);
    var image = new Array(urls.length);
    var numImages = 0;
    for (var i = 0; i < urls.length; i++) {
      var url = urls[i];
      var defd = urlDefined[i] = url != null && url !== 'none';
      if (defd) {
        var bgImgCrossOrigin = node.cy().style().getIndexedStyle(node, 'background-image-crossorigin', 'value', i);
        numImages++;

        // get image, and if not loaded then ask to redraw when later loaded
        image[i] = r.getCachedImage(url, bgImgCrossOrigin, function () {
          _p.backgroundTimestamp = Date.now();
          node.emitAndNotify('background');
        });
      }
    }

    //
    // setup styles

    var darkness = node.pstyle('background-blacken').value;
    var borderWidth = node.pstyle('border-width').pfValue;
    var bgOpacity = node.pstyle('background-opacity').value * eleOpacity;
    var borderColor = node.pstyle('border-color').value;
    var borderStyle = node.pstyle('border-style').value;
    var borderOpacity = node.pstyle('border-opacity').value * eleOpacity;
    var outlineWidth = node.pstyle('outline-width').pfValue;
    var outlineColor = node.pstyle('outline-color').value;
    var outlineStyle = node.pstyle('outline-style').value;
    var outlineOpacity = node.pstyle('outline-opacity').value * eleOpacity;
    var outlineOffset = node.pstyle('outline-offset').value;
    context.lineJoin = 'miter'; // so borders are square with the node shape

    var setupShapeColor = function setupShapeColor() {
      var bgOpy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : bgOpacity;
      r.eleFillStyle(context, node, bgOpy);
    };
    var setupBorderColor = function setupBorderColor() {
      var bdrOpy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : borderOpacity;
      r.colorStrokeStyle(context, borderColor[0], borderColor[1], borderColor[2], bdrOpy);
    };
    var setupOutlineColor = function setupOutlineColor() {
      var otlnOpy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : outlineOpacity;
      r.colorStrokeStyle(context, outlineColor[0], outlineColor[1], outlineColor[2], otlnOpy);
    };

    //
    // setup shape

    var getPath = function getPath(width, height, shape, points) {
      var pathCache = r.nodePathCache = r.nodePathCache || [];
      var key = hashStrings(shape === 'polygon' ? shape + ',' + points.join(',') : shape, '' + height, '' + width);
      var cachedPath = pathCache[key];
      var path;
      var cacheHit = false;
      if (cachedPath != null) {
        path = cachedPath;
        cacheHit = true;
        rs.pathCache = path;
      } else {
        path = new Path2D();
        pathCache[key] = rs.pathCache = path;
      }
      return {
        path: path,
        cacheHit: cacheHit
      };
    };
    var styleShape = node.pstyle('shape').strValue;
    var shapePts = node.pstyle('shape-polygon-points').pfValue;
    if (usePaths) {
      context.translate(pos.x, pos.y);
      var shapePath = getPath(nodeWidth, nodeHeight, styleShape, shapePts);
      path = shapePath.path;
      pathCacheHit = shapePath.cacheHit;
    }
    var drawShape = function drawShape() {
      if (!pathCacheHit) {
        var npos = pos;
        if (usePaths) {
          npos = {
            x: 0,
            y: 0
          };
        }
        r.nodeShapes[r.getNodeShape(node)].draw(path || context, npos.x, npos.y, nodeWidth, nodeHeight);
      }
      if (usePaths) {
        context.fill(path);
      } else {
        context.fill();
      }
    };
    var drawImages = function drawImages() {
      var nodeOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : eleOpacity;
      var inside = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
      var prevBging = _p.backgrounding;
      var totalCompleted = 0;
      for (var _i = 0; _i < image.length; _i++) {
        var bgContainment = node.cy().style().getIndexedStyle(node, 'background-image-containment', 'value', _i);
        if (inside && bgContainment === 'over' || !inside && bgContainment === 'inside') {
          totalCompleted++;
          continue;
        }
        if (urlDefined[_i] && image[_i].complete && !image[_i].error) {
          totalCompleted++;
          r.drawInscribedImage(context, image[_i], node, _i, nodeOpacity);
        }
      }
      _p.backgrounding = !(totalCompleted === numImages);
      if (prevBging !== _p.backgrounding) {
        // update style b/c :backgrounding state changed
        node.updateStyle(false);
      }
    };
    var drawPie = function drawPie() {
      var redrawShape = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      var pieOpacity = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : eleOpacity;
      if (r.hasPie(node)) {
        r.drawPie(context, node, pieOpacity);

        // redraw/restore path if steps after pie need it
        if (redrawShape) {
          if (!usePaths) {
            r.nodeShapes[r.getNodeShape(node)].draw(context, pos.x, pos.y, nodeWidth, nodeHeight);
          }
        }
      }
    };
    var darken = function darken() {
      var darkenOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : eleOpacity;
      var opacity = (darkness > 0 ? darkness : -darkness) * darkenOpacity;
      var c = darkness > 0 ? 0 : 255;
      if (darkness !== 0) {
        r.colorFillStyle(context, c, c, c, opacity);
        if (usePaths) {
          context.fill(path);
        } else {
          context.fill();
        }
      }
    };
    var drawBorder = function drawBorder() {
      if (borderWidth > 0) {
        context.lineWidth = borderWidth;
        context.lineCap = 'butt';
        if (context.setLineDash) {
          // for very outofdate browsers
          switch (borderStyle) {
            case 'dotted':
              context.setLineDash([1, 1]);
              break;
            case 'dashed':
              context.setLineDash([4, 2]);
              break;
            case 'solid':
            case 'double':
              context.setLineDash([]);
              break;
          }
        }
        if (usePaths) {
          context.stroke(path);
        } else {
          context.stroke();
        }
        if (borderStyle === 'double') {
          context.lineWidth = borderWidth / 3;
          var gco = context.globalCompositeOperation;
          context.globalCompositeOperation = 'destination-out';
          if (usePaths) {
            context.stroke(path);
          } else {
            context.stroke();
          }
          context.globalCompositeOperation = gco;
        }

        // reset in case we changed the border style
        if (context.setLineDash) {
          // for very outofdate browsers
          context.setLineDash([]);
        }
      }
    };
    var drawOutline = function drawOutline() {
      if (outlineWidth > 0) {
        context.lineWidth = outlineWidth;
        context.lineCap = 'butt';
        if (context.setLineDash) {
          // for very outofdate browsers
          switch (outlineStyle) {
            case 'dotted':
              context.setLineDash([1, 1]);
              break;
            case 'dashed':
              context.setLineDash([4, 2]);
              break;
            case 'solid':
            case 'double':
              context.setLineDash([]);
              break;
          }
        }
        var npos = pos;
        if (usePaths) {
          npos = {
            x: 0,
            y: 0
          };
        }
        var shape = r.getNodeShape(node);
        var scaleX = (nodeWidth + borderWidth + (outlineWidth + outlineOffset)) / nodeWidth;
        var scaleY = (nodeHeight + borderWidth + (outlineWidth + outlineOffset)) / nodeHeight;
        var sWidth = nodeWidth * scaleX;
        var sHeight = nodeHeight * scaleY;
        var points = r.nodeShapes[shape].points;
        var _path;
        if (usePaths) {
          var outlinePath = getPath(sWidth, sHeight, shape, points);
          _path = outlinePath.path;
        }

        // draw the outline path, either by using expanded points or by scaling 
        // the dimensions, depending on shape
        if (shape === "ellipse") {
          r.drawEllipsePath(_path || context, npos.x, npos.y, sWidth, sHeight);
        } else if (['round-diamond', 'round-heptagon', 'round-hexagon', 'round-octagon', 'round-pentagon', 'round-polygon', 'round-triangle', 'round-tag'].includes(shape)) {
          var sMult = 0;
          var offsetX = 0;
          var offsetY = 0;
          if (shape === 'round-diamond') {
            sMult = (borderWidth + outlineOffset + outlineWidth) * 1.4;
          } else if (shape === 'round-heptagon') {
            sMult = (borderWidth + outlineOffset + outlineWidth) * 1.075;
            offsetY = -(borderWidth / 2 + outlineOffset + outlineWidth) / 35;
          } else if (shape === 'round-hexagon') {
            sMult = (borderWidth + outlineOffset + outlineWidth) * 1.12;
          } else if (shape === 'round-pentagon') {
            sMult = (borderWidth + outlineOffset + outlineWidth) * 1.13;
            offsetY = -(borderWidth / 2 + outlineOffset + outlineWidth) / 15;
          } else if (shape === 'round-tag') {
            sMult = (borderWidth + outlineOffset + outlineWidth) * 1.12;
            offsetX = (borderWidth / 2 + outlineWidth + outlineOffset) * .07;
          } else if (shape === 'round-triangle') {
            sMult = (borderWidth + outlineOffset + outlineWidth) * (Math.PI / 2);
            offsetY = -(borderWidth + outlineOffset / 2 + outlineWidth) / Math.PI;
          }
          if (sMult !== 0) {
            scaleX = (nodeWidth + sMult) / nodeWidth;
            scaleY = (nodeHeight + sMult) / nodeHeight;
          }
          r.drawRoundPolygonPath(_path || context, npos.x + offsetX, npos.y + offsetY, nodeWidth * scaleX, nodeHeight * scaleY, points);
        } else if (['roundrectangle', 'round-rectangle'].includes(shape)) {
          r.drawRoundRectanglePath(_path || context, npos.x, npos.y, sWidth, sHeight);
        } else if (['cutrectangle', 'cut-rectangle'].includes(shape)) {
          r.drawCutRectanglePath(_path || context, npos.x, npos.y, sWidth, sHeight);
        } else if (['bottomroundrectangle', 'bottom-round-rectangle'].includes(shape)) {
          r.drawBottomRoundRectanglePath(_path || context, npos.x, npos.y, sWidth, sHeight);
        } else if (shape === "barrel") {
          r.drawBarrelPath(_path || context, npos.x, npos.y, sWidth, sHeight);
        } else if (shape.startsWith("polygon") || ['rhomboid', 'right-rhomboid', 'round-tag', 'tag', 'vee'].includes(shape)) {
          var pad = (borderWidth + outlineWidth + outlineOffset) / nodeWidth;
          points = joinLines(expandPolygon(points, pad));
          r.drawPolygonPath(_path || context, npos.x, npos.y, nodeWidth, nodeHeight, points);
        } else {
          var _pad = (borderWidth + outlineWidth + outlineOffset) / nodeWidth;
          points = joinLines(expandPolygon(points, -_pad));
          r.drawPolygonPath(_path || context, npos.x, npos.y, nodeWidth, nodeHeight, points);
        }
        if (usePaths) {
          context.stroke(_path);
        } else {
          context.stroke();
        }
        if (outlineStyle === 'double') {
          context.lineWidth = borderWidth / 3;
          var gco = context.globalCompositeOperation;
          context.globalCompositeOperation = 'destination-out';
          if (usePaths) {
            context.stroke(_path);
          } else {
            context.stroke();
          }
          context.globalCompositeOperation = gco;
        }

        // reset in case we changed the border style
        if (context.setLineDash) {
          // for very outofdate browsers
          context.setLineDash([]);
        }
      }
    };
    var drawOverlay = function drawOverlay() {
      if (shouldDrawOverlay) {
        r.drawNodeOverlay(context, node, pos, nodeWidth, nodeHeight);
      }
    };
    var drawUnderlay = function drawUnderlay() {
      if (shouldDrawOverlay) {
        r.drawNodeUnderlay(context, node, pos, nodeWidth, nodeHeight);
      }
    };
    var drawText = function drawText() {
      r.drawElementText(context, node, null, drawLabel);
    };
    var ghost = node.pstyle('ghost').value === 'yes';
    if (ghost) {
      var gx = node.pstyle('ghost-offset-x').pfValue;
      var gy = node.pstyle('ghost-offset-y').pfValue;
      var ghostOpacity = node.pstyle('ghost-opacity').value;
      var effGhostOpacity = ghostOpacity * eleOpacity;
      context.translate(gx, gy);
      setupOutlineColor();
      drawOutline();
      setupShapeColor(ghostOpacity * bgOpacity);
      drawShape();
      drawImages(effGhostOpacity, true);
      setupBorderColor(ghostOpacity * borderOpacity);
      drawBorder();
      drawPie(darkness !== 0 || borderWidth !== 0);
      drawImages(effGhostOpacity, false);
      darken(effGhostOpacity);
      context.translate(-gx, -gy);
    }
    if (usePaths) {
      context.translate(-pos.x, -pos.y);
    }
    drawUnderlay();
    if (usePaths) {
      context.translate(pos.x, pos.y);
    }
    setupOutlineColor();
    drawOutline();
    setupShapeColor();
    drawShape();
    drawImages(eleOpacity, true);
    setupBorderColor();
    drawBorder();
    drawPie(darkness !== 0 || borderWidth !== 0);
    drawImages(eleOpacity, false);
    darken();
    if (usePaths) {
      context.translate(-pos.x, -pos.y);
    }
    drawText();
    drawOverlay();

    //
    // clean up shift

    if (shiftToOriginWithBb) {
      context.translate(bb.x1, bb.y1);
    }
  };
  var drawNodeOverlayUnderlay = function drawNodeOverlayUnderlay(overlayOrUnderlay) {
    if (!['overlay', 'underlay'].includes(overlayOrUnderlay)) {
      throw new Error('Invalid state');
    }
    return function (context, node, pos, nodeWidth, nodeHeight) {
      var r = this;
      if (!node.visible()) {
        return;
      }
      var padding = node.pstyle("".concat(overlayOrUnderlay, "-padding")).pfValue;
      var opacity = node.pstyle("".concat(overlayOrUnderlay, "-opacity")).value;
      var color = node.pstyle("".concat(overlayOrUnderlay, "-color")).value;
      var shape = node.pstyle("".concat(overlayOrUnderlay, "-shape")).value;
      if (opacity > 0) {
        pos = pos || node.position();
        if (nodeWidth == null || nodeHeight == null) {
          var _padding = node.padding();
          nodeWidth = node.width() + 2 * _padding;
          nodeHeight = node.height() + 2 * _padding;
        }
        r.colorFillStyle(context, color[0], color[1], color[2], opacity);
        r.nodeShapes[shape].draw(context, pos.x, pos.y, nodeWidth + padding * 2, nodeHeight + padding * 2);
        context.fill();
      }
    };
  };
  CRp$5.drawNodeOverlay = drawNodeOverlayUnderlay('overlay');
  CRp$5.drawNodeUnderlay = drawNodeOverlayUnderlay('underlay');

  // does the node have at least one pie piece?
  CRp$5.hasPie = function (node) {
    node = node[0]; // ensure ele ref

    return node._private.hasPie;
  };
  CRp$5.drawPie = function (context, node, nodeOpacity, pos) {
    node = node[0]; // ensure ele ref
    pos = pos || node.position();
    var cyStyle = node.cy().style();
    var pieSize = node.pstyle('pie-size');
    var x = pos.x;
    var y = pos.y;
    var nodeW = node.width();
    var nodeH = node.height();
    var radius = Math.min(nodeW, nodeH) / 2; // must fit in node
    var lastPercent = 0; // what % to continue drawing pie slices from on [0, 1]
    var usePaths = this.usePaths();
    if (usePaths) {
      x = 0;
      y = 0;
    }
    if (pieSize.units === '%') {
      radius = radius * pieSize.pfValue;
    } else if (pieSize.pfValue !== undefined) {
      radius = pieSize.pfValue / 2;
    }
    for (var i = 1; i <= cyStyle.pieBackgroundN; i++) {
      // 1..N
      var size = node.pstyle('pie-' + i + '-background-size').value;
      var color = node.pstyle('pie-' + i + '-background-color').value;
      var opacity = node.pstyle('pie-' + i + '-background-opacity').value * nodeOpacity;
      var percent = size / 100; // map integer range [0, 100] to [0, 1]

      // percent can't push beyond 1
      if (percent + lastPercent > 1) {
        percent = 1 - lastPercent;
      }
      var angleStart = 1.5 * Math.PI + 2 * Math.PI * lastPercent; // start at 12 o'clock and go clockwise
      var angleDelta = 2 * Math.PI * percent;
      var angleEnd = angleStart + angleDelta;

      // ignore if
      // - zero size
      // - we're already beyond the full circle
      // - adding the current slice would go beyond the full circle
      if (size === 0 || lastPercent >= 1 || lastPercent + percent > 1) {
        continue;
      }
      context.beginPath();
      context.moveTo(x, y);
      context.arc(x, y, radius, angleStart, angleEnd);
      context.closePath();
      this.colorFillStyle(context, color[0], color[1], color[2], opacity);
      context.fill();
      lastPercent += percent;
    }
  };

  var CRp$4 = {};
  var motionBlurDelay = 100;

  // var isFirefox = typeof InstallTrigger !== 'undefined';

  CRp$4.getPixelRatio = function () {
    var context = this.data.contexts[0];
    if (this.forcedPixelRatio != null) {
      return this.forcedPixelRatio;
    }
    var backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1;
    return (window.devicePixelRatio || 1) / backingStore; // eslint-disable-line no-undef
  };

  CRp$4.paintCache = function (context) {
    var caches = this.paintCaches = this.paintCaches || [];
    var needToCreateCache = true;
    var cache;
    for (var i = 0; i < caches.length; i++) {
      cache = caches[i];
      if (cache.context === context) {
        needToCreateCache = false;
        break;
      }
    }
    if (needToCreateCache) {
      cache = {
        context: context
      };
      caches.push(cache);
    }
    return cache;
  };
  CRp$4.createGradientStyleFor = function (context, shapeStyleName, ele, fill, opacity) {
    var gradientStyle;
    var usePaths = this.usePaths();
    var colors = ele.pstyle(shapeStyleName + '-gradient-stop-colors').value,
      positions = ele.pstyle(shapeStyleName + '-gradient-stop-positions').pfValue;
    if (fill === 'radial-gradient') {
      if (ele.isEdge()) {
        var start = ele.sourceEndpoint(),
          end = ele.targetEndpoint(),
          mid = ele.midpoint();
        var d1 = dist(start, mid);
        var d2 = dist(end, mid);
        gradientStyle = context.createRadialGradient(mid.x, mid.y, 0, mid.x, mid.y, Math.max(d1, d2));
      } else {
        var pos = usePaths ? {
            x: 0,
            y: 0
          } : ele.position(),
          width = ele.paddedWidth(),
          height = ele.paddedHeight();
        gradientStyle = context.createRadialGradient(pos.x, pos.y, 0, pos.x, pos.y, Math.max(width, height));
      }
    } else {
      if (ele.isEdge()) {
        var _start = ele.sourceEndpoint(),
          _end = ele.targetEndpoint();
        gradientStyle = context.createLinearGradient(_start.x, _start.y, _end.x, _end.y);
      } else {
        var _pos = usePaths ? {
            x: 0,
            y: 0
          } : ele.position(),
          _width = ele.paddedWidth(),
          _height = ele.paddedHeight(),
          halfWidth = _width / 2,
          halfHeight = _height / 2;
        var direction = ele.pstyle('background-gradient-direction').value;
        switch (direction) {
          case 'to-bottom':
            gradientStyle = context.createLinearGradient(_pos.x, _pos.y - halfHeight, _pos.x, _pos.y + halfHeight);
            break;
          case 'to-top':
            gradientStyle = context.createLinearGradient(_pos.x, _pos.y + halfHeight, _pos.x, _pos.y - halfHeight);
            break;
          case 'to-left':
            gradientStyle = context.createLinearGradient(_pos.x + halfWidth, _pos.y, _pos.x - halfWidth, _pos.y);
            break;
          case 'to-right':
            gradientStyle = context.createLinearGradient(_pos.x - halfWidth, _pos.y, _pos.x + halfWidth, _pos.y);
            break;
          case 'to-bottom-right':
          case 'to-right-bottom':
            gradientStyle = context.createLinearGradient(_pos.x - halfWidth, _pos.y - halfHeight, _pos.x + halfWidth, _pos.y + halfHeight);
            break;
          case 'to-top-right':
          case 'to-right-top':
            gradientStyle = context.createLinearGradient(_pos.x - halfWidth, _pos.y + halfHeight, _pos.x + halfWidth, _pos.y - halfHeight);
            break;
          case 'to-bottom-left':
          case 'to-left-bottom':
            gradientStyle = context.createLinearGradient(_pos.x + halfWidth, _pos.y - halfHeight, _pos.x - halfWidth, _pos.y + halfHeight);
            break;
          case 'to-top-left':
          case 'to-left-top':
            gradientStyle = context.createLinearGradient(_pos.x + halfWidth, _pos.y + halfHeight, _pos.x - halfWidth, _pos.y - halfHeight);
            break;
        }
      }
    }
    if (!gradientStyle) return null; // invalid gradient style

    var hasPositions = positions.length === colors.length;
    var length = colors.length;
    for (var i = 0; i < length; i++) {
      gradientStyle.addColorStop(hasPositions ? positions[i] : i / (length - 1), 'rgba(' + colors[i][0] + ',' + colors[i][1] + ',' + colors[i][2] + ',' + opacity + ')');
    }
    return gradientStyle;
  };
  CRp$4.gradientFillStyle = function (context, ele, fill, opacity) {
    var gradientStyle = this.createGradientStyleFor(context, 'background', ele, fill, opacity);
    if (!gradientStyle) return null; // error
    context.fillStyle = gradientStyle;
  };
  CRp$4.colorFillStyle = function (context, r, g, b, a) {
    context.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
    // turn off for now, seems context does its own caching

    // var cache = this.paintCache(context);

    // var fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';

    // if( cache.fillStyle !== fillStyle ){
    //   context.fillStyle = cache.fillStyle = fillStyle;
    // }
  };

  CRp$4.eleFillStyle = function (context, ele, opacity) {
    var backgroundFill = ele.pstyle('background-fill').value;
    if (backgroundFill === 'linear-gradient' || backgroundFill === 'radial-gradient') {
      this.gradientFillStyle(context, ele, backgroundFill, opacity);
    } else {
      var backgroundColor = ele.pstyle('background-color').value;
      this.colorFillStyle(context, backgroundColor[0], backgroundColor[1], backgroundColor[2], opacity);
    }
  };
  CRp$4.gradientStrokeStyle = function (context, ele, fill, opacity) {
    var gradientStyle = this.createGradientStyleFor(context, 'line', ele, fill, opacity);
    if (!gradientStyle) return null; // error
    context.strokeStyle = gradientStyle;
  };
  CRp$4.colorStrokeStyle = function (context, r, g, b, a) {
    context.strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
    // turn off for now, seems context does its own caching

    // var cache = this.paintCache(context);

    // var strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';

    // if( cache.strokeStyle !== strokeStyle ){
    //   context.strokeStyle = cache.strokeStyle = strokeStyle;
    // }
  };

  CRp$4.eleStrokeStyle = function (context, ele, opacity) {
    var lineFill = ele.pstyle('line-fill').value;
    if (lineFill === 'linear-gradient' || lineFill === 'radial-gradient') {
      this.gradientStrokeStyle(context, ele, lineFill, opacity);
    } else {
      var lineColor = ele.pstyle('line-color').value;
      this.colorStrokeStyle(context, lineColor[0], lineColor[1], lineColor[2], opacity);
    }
  };

  // Resize canvas
  CRp$4.matchCanvasSize = function (container) {
    var r = this;
    var data = r.data;
    var bb = r.findContainerClientCoords();
    var width = bb[2];
    var height = bb[3];
    var pixelRatio = r.getPixelRatio();
    var mbPxRatio = r.motionBlurPxRatio;
    if (container === r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_NODE] || container === r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_DRAG]) {
      pixelRatio = mbPxRatio;
    }
    var canvasWidth = width * pixelRatio;
    var canvasHeight = height * pixelRatio;
    var canvas;
    if (canvasWidth === r.canvasWidth && canvasHeight === r.canvasHeight) {
      return; // save cycles if same
    }

    r.fontCaches = null; // resizing resets the style

    var canvasContainer = data.canvasContainer;
    canvasContainer.style.width = width + 'px';
    canvasContainer.style.height = height + 'px';
    for (var i = 0; i < r.CANVAS_LAYERS; i++) {
      canvas = data.canvases[i];
      canvas.width = canvasWidth;
      canvas.height = canvasHeight;
      canvas.style.width = width + 'px';
      canvas.style.height = height + 'px';
    }
    for (var i = 0; i < r.BUFFER_COUNT; i++) {
      canvas = data.bufferCanvases[i];
      canvas.width = canvasWidth;
      canvas.height = canvasHeight;
      canvas.style.width = width + 'px';
      canvas.style.height = height + 'px';
    }
    r.textureMult = 1;
    if (pixelRatio <= 1) {
      canvas = data.bufferCanvases[r.TEXTURE_BUFFER];
      r.textureMult = 2;
      canvas.width = canvasWidth * r.textureMult;
      canvas.height = canvasHeight * r.textureMult;
    }
    r.canvasWidth = canvasWidth;
    r.canvasHeight = canvasHeight;
  };
  CRp$4.renderTo = function (cxt, zoom, pan, pxRatio) {
    this.render({
      forcedContext: cxt,
      forcedZoom: zoom,
      forcedPan: pan,
      drawAllLayers: true,
      forcedPxRatio: pxRatio
    });
  };
  CRp$4.render = function (options) {
    options = options || staticEmptyObject();
    var forcedContext = options.forcedContext;
    var drawAllLayers = options.drawAllLayers;
    var drawOnlyNodeLayer = options.drawOnlyNodeLayer;
    var forcedZoom = options.forcedZoom;
    var forcedPan = options.forcedPan;
    var r = this;
    var pixelRatio = options.forcedPxRatio === undefined ? this.getPixelRatio() : options.forcedPxRatio;
    var cy = r.cy;
    var data = r.data;
    var needDraw = data.canvasNeedsRedraw;
    var textureDraw = r.textureOnViewport && !forcedContext && (r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming);
    var motionBlur = options.motionBlur !== undefined ? options.motionBlur : r.motionBlur;
    var mbPxRatio = r.motionBlurPxRatio;
    var hasCompoundNodes = cy.hasCompoundNodes();
    var inNodeDragGesture = r.hoverData.draggingEles;
    var inBoxSelection = r.hoverData.selecting || r.touchData.selecting ? true : false;
    motionBlur = motionBlur && !forcedContext && r.motionBlurEnabled && !inBoxSelection;
    var motionBlurFadeEffect = motionBlur;
    if (!forcedContext) {
      if (r.prevPxRatio !== pixelRatio) {
        r.invalidateContainerClientCoordsCache();
        r.matchCanvasSize(r.container);
        r.redrawHint('eles', true);
        r.redrawHint('drag', true);
      }
      r.prevPxRatio = pixelRatio;
    }
    if (!forcedContext && r.motionBlurTimeout) {
      clearTimeout(r.motionBlurTimeout);
    }
    if (motionBlur) {
      if (r.mbFrames == null) {
        r.mbFrames = 0;
      }
      r.mbFrames++;
      if (r.mbFrames < 3) {
        // need several frames before even high quality motionblur
        motionBlurFadeEffect = false;
      }

      // go to lower quality blurry frames when several m/b frames have been rendered (avoids flashing)
      if (r.mbFrames > r.minMbLowQualFrames) {
        //r.fullQualityMb = false;
        r.motionBlurPxRatio = r.mbPxRBlurry;
      }
    }
    if (r.clearingMotionBlur) {
      r.motionBlurPxRatio = 1;
    }

    // b/c drawToContext() may be async w.r.t. redraw(), keep track of last texture frame
    // because a rogue async texture frame would clear needDraw
    if (r.textureDrawLastFrame && !textureDraw) {
      needDraw[r.NODE] = true;
      needDraw[r.SELECT_BOX] = true;
    }
    var style = cy.style();
    var zoom = cy.zoom();
    var effectiveZoom = forcedZoom !== undefined ? forcedZoom : zoom;
    var pan = cy.pan();
    var effectivePan = {
      x: pan.x,
      y: pan.y
    };
    var vp = {
      zoom: zoom,
      pan: {
        x: pan.x,
        y: pan.y
      }
    };
    var prevVp = r.prevViewport;
    var viewportIsDiff = prevVp === undefined || vp.zoom !== prevVp.zoom || vp.pan.x !== prevVp.pan.x || vp.pan.y !== prevVp.pan.y;

    // we want the low quality motionblur only when the viewport is being manipulated etc (where it's not noticed)
    if (!viewportIsDiff && !(inNodeDragGesture && !hasCompoundNodes)) {
      r.motionBlurPxRatio = 1;
    }
    if (forcedPan) {
      effectivePan = forcedPan;
    }

    // apply pixel ratio

    effectiveZoom *= pixelRatio;
    effectivePan.x *= pixelRatio;
    effectivePan.y *= pixelRatio;
    var eles = r.getCachedZSortedEles();
    function mbclear(context, x, y, w, h) {
      var gco = context.globalCompositeOperation;
      context.globalCompositeOperation = 'destination-out';
      r.colorFillStyle(context, 255, 255, 255, r.motionBlurTransparency);
      context.fillRect(x, y, w, h);
      context.globalCompositeOperation = gco;
    }
    function setContextTransform(context, clear) {
      var ePan, eZoom, w, h;
      if (!r.clearingMotionBlur && (context === data.bufferContexts[r.MOTIONBLUR_BUFFER_NODE] || context === data.bufferContexts[r.MOTIONBLUR_BUFFER_DRAG])) {
        ePan = {
          x: pan.x * mbPxRatio,
          y: pan.y * mbPxRatio
        };
        eZoom = zoom * mbPxRatio;
        w = r.canvasWidth * mbPxRatio;
        h = r.canvasHeight * mbPxRatio;
      } else {
        ePan = effectivePan;
        eZoom = effectiveZoom;
        w = r.canvasWidth;
        h = r.canvasHeight;
      }
      context.setTransform(1, 0, 0, 1, 0, 0);
      if (clear === 'motionBlur') {
        mbclear(context, 0, 0, w, h);
      } else if (!forcedContext && (clear === undefined || clear)) {
        context.clearRect(0, 0, w, h);
      }
      if (!drawAllLayers) {
        context.translate(ePan.x, ePan.y);
        context.scale(eZoom, eZoom);
      }
      if (forcedPan) {
        context.translate(forcedPan.x, forcedPan.y);
      }
      if (forcedZoom) {
        context.scale(forcedZoom, forcedZoom);
      }
    }
    if (!textureDraw) {
      r.textureDrawLastFrame = false;
    }
    if (textureDraw) {
      r.textureDrawLastFrame = true;
      if (!r.textureCache) {
        r.textureCache = {};
        r.textureCache.bb = cy.mutableElements().boundingBox();
        r.textureCache.texture = r.data.bufferCanvases[r.TEXTURE_BUFFER];
        var cxt = r.data.bufferContexts[r.TEXTURE_BUFFER];
        cxt.setTransform(1, 0, 0, 1, 0, 0);
        cxt.clearRect(0, 0, r.canvasWidth * r.textureMult, r.canvasHeight * r.textureMult);
        r.render({
          forcedContext: cxt,
          drawOnlyNodeLayer: true,
          forcedPxRatio: pixelRatio * r.textureMult
        });
        var vp = r.textureCache.viewport = {
          zoom: cy.zoom(),
          pan: cy.pan(),
          width: r.canvasWidth,
          height: r.canvasHeight
        };
        vp.mpan = {
          x: (0 - vp.pan.x) / vp.zoom,
          y: (0 - vp.pan.y) / vp.zoom
        };
      }
      needDraw[r.DRAG] = false;
      needDraw[r.NODE] = false;
      var context = data.contexts[r.NODE];
      var texture = r.textureCache.texture;
      var vp = r.textureCache.viewport;
      context.setTransform(1, 0, 0, 1, 0, 0);
      if (motionBlur) {
        mbclear(context, 0, 0, vp.width, vp.height);
      } else {
        context.clearRect(0, 0, vp.width, vp.height);
      }
      var outsideBgColor = style.core('outside-texture-bg-color').value;
      var outsideBgOpacity = style.core('outside-texture-bg-opacity').value;
      r.colorFillStyle(context, outsideBgColor[0], outsideBgColor[1], outsideBgColor[2], outsideBgOpacity);
      context.fillRect(0, 0, vp.width, vp.height);
      var zoom = cy.zoom();
      setContextTransform(context, false);
      context.clearRect(vp.mpan.x, vp.mpan.y, vp.width / vp.zoom / pixelRatio, vp.height / vp.zoom / pixelRatio);
      context.drawImage(texture, vp.mpan.x, vp.mpan.y, vp.width / vp.zoom / pixelRatio, vp.height / vp.zoom / pixelRatio);
    } else if (r.textureOnViewport && !forcedContext) {
      // clear the cache since we don't need it
      r.textureCache = null;
    }
    var extent = cy.extent();
    var vpManip = r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming || r.hoverData.draggingEles || r.cy.animated();
    var hideEdges = r.hideEdgesOnViewport && vpManip;
    var needMbClear = [];
    needMbClear[r.NODE] = !needDraw[r.NODE] && motionBlur && !r.clearedForMotionBlur[r.NODE] || r.clearingMotionBlur;
    if (needMbClear[r.NODE]) {
      r.clearedForMotionBlur[r.NODE] = true;
    }
    needMbClear[r.DRAG] = !needDraw[r.DRAG] && motionBlur && !r.clearedForMotionBlur[r.DRAG] || r.clearingMotionBlur;
    if (needMbClear[r.DRAG]) {
      r.clearedForMotionBlur[r.DRAG] = true;
    }
    if (needDraw[r.NODE] || drawAllLayers || drawOnlyNodeLayer || needMbClear[r.NODE]) {
      var useBuffer = motionBlur && !needMbClear[r.NODE] && mbPxRatio !== 1;
      var context = forcedContext || (useBuffer ? r.data.bufferContexts[r.MOTIONBLUR_BUFFER_NODE] : data.contexts[r.NODE]);
      var clear = motionBlur && !useBuffer ? 'motionBlur' : undefined;
      setContextTransform(context, clear);
      if (hideEdges) {
        r.drawCachedNodes(context, eles.nondrag, pixelRatio, extent);
      } else {
        r.drawLayeredElements(context, eles.nondrag, pixelRatio, extent);
      }
      if (r.debug) {
        r.drawDebugPoints(context, eles.nondrag);
      }
      if (!drawAllLayers && !motionBlur) {
        needDraw[r.NODE] = false;
      }
    }
    if (!drawOnlyNodeLayer && (needDraw[r.DRAG] || drawAllLayers || needMbClear[r.DRAG])) {
      var useBuffer = motionBlur && !needMbClear[r.DRAG] && mbPxRatio !== 1;
      var context = forcedContext || (useBuffer ? r.data.bufferContexts[r.MOTIONBLUR_BUFFER_DRAG] : data.contexts[r.DRAG]);
      setContextTransform(context, motionBlur && !useBuffer ? 'motionBlur' : undefined);
      if (hideEdges) {
        r.drawCachedNodes(context, eles.drag, pixelRatio, extent);
      } else {
        r.drawCachedElements(context, eles.drag, pixelRatio, extent);
      }
      if (r.debug) {
        r.drawDebugPoints(context, eles.drag);
      }
      if (!drawAllLayers && !motionBlur) {
        needDraw[r.DRAG] = false;
      }
    }
    if (r.showFps || !drawOnlyNodeLayer && needDraw[r.SELECT_BOX] && !drawAllLayers) {
      var context = forcedContext || data.contexts[r.SELECT_BOX];
      setContextTransform(context);
      if (r.selection[4] == 1 && (r.hoverData.selecting || r.touchData.selecting)) {
        var zoom = r.cy.zoom();
        var borderWidth = style.core('selection-box-border-width').value / zoom;
        context.lineWidth = borderWidth;
        context.fillStyle = 'rgba(' + style.core('selection-box-color').value[0] + ',' + style.core('selection-box-color').value[1] + ',' + style.core('selection-box-color').value[2] + ',' + style.core('selection-box-opacity').value + ')';
        context.fillRect(r.selection[0], r.selection[1], r.selection[2] - r.selection[0], r.selection[3] - r.selection[1]);
        if (borderWidth > 0) {
          context.strokeStyle = 'rgba(' + style.core('selection-box-border-color').value[0] + ',' + style.core('selection-box-border-color').value[1] + ',' + style.core('selection-box-border-color').value[2] + ',' + style.core('selection-box-opacity').value + ')';
          context.strokeRect(r.selection[0], r.selection[1], r.selection[2] - r.selection[0], r.selection[3] - r.selection[1]);
        }
      }
      if (data.bgActivePosistion && !r.hoverData.selecting) {
        var zoom = r.cy.zoom();
        var pos = data.bgActivePosistion;
        context.fillStyle = 'rgba(' + style.core('active-bg-color').value[0] + ',' + style.core('active-bg-color').value[1] + ',' + style.core('active-bg-color').value[2] + ',' + style.core('active-bg-opacity').value + ')';
        context.beginPath();
        context.arc(pos.x, pos.y, style.core('active-bg-size').pfValue / zoom, 0, 2 * Math.PI);
        context.fill();
      }
      var timeToRender = r.lastRedrawTime;
      if (r.showFps && timeToRender) {
        timeToRender = Math.round(timeToRender);
        var fps = Math.round(1000 / timeToRender);
        context.setTransform(1, 0, 0, 1, 0, 0);
        context.fillStyle = 'rgba(255, 0, 0, 0.75)';
        context.strokeStyle = 'rgba(255, 0, 0, 0.75)';
        context.lineWidth = 1;
        context.fillText('1 frame = ' + timeToRender + ' ms = ' + fps + ' fps', 0, 20);
        var maxFps = 60;
        context.strokeRect(0, 30, 250, 20);
        context.fillRect(0, 30, 250 * Math.min(fps / maxFps, 1), 20);
      }
      if (!drawAllLayers) {
        needDraw[r.SELECT_BOX] = false;
      }
    }

    // motionblur: blit rendered blurry frames
    if (motionBlur && mbPxRatio !== 1) {
      var cxtNode = data.contexts[r.NODE];
      var txtNode = r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_NODE];
      var cxtDrag = data.contexts[r.DRAG];
      var txtDrag = r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_DRAG];
      var drawMotionBlur = function drawMotionBlur(cxt, txt, needClear) {
        cxt.setTransform(1, 0, 0, 1, 0, 0);
        if (needClear || !motionBlurFadeEffect) {
          cxt.clearRect(0, 0, r.canvasWidth, r.canvasHeight);
        } else {
          mbclear(cxt, 0, 0, r.canvasWidth, r.canvasHeight);
        }
        var pxr = mbPxRatio;
        cxt.drawImage(txt,
        // img
        0, 0,
        // sx, sy
        r.canvasWidth * pxr, r.canvasHeight * pxr,
        // sw, sh
        0, 0,
        // x, y
        r.canvasWidth, r.canvasHeight // w, h
        );
      };

      if (needDraw[r.NODE] || needMbClear[r.NODE]) {
        drawMotionBlur(cxtNode, txtNode, needMbClear[r.NODE]);
        needDraw[r.NODE] = false;
      }
      if (needDraw[r.DRAG] || needMbClear[r.DRAG]) {
        drawMotionBlur(cxtDrag, txtDrag, needMbClear[r.DRAG]);
        needDraw[r.DRAG] = false;
      }
    }
    r.prevViewport = vp;
    if (r.clearingMotionBlur) {
      r.clearingMotionBlur = false;
      r.motionBlurCleared = true;
      r.motionBlur = true;
    }
    if (motionBlur) {
      r.motionBlurTimeout = setTimeout(function () {
        r.motionBlurTimeout = null;
        r.clearedForMotionBlur[r.NODE] = false;
        r.clearedForMotionBlur[r.DRAG] = false;
        r.motionBlur = false;
        r.clearingMotionBlur = !textureDraw;
        r.mbFrames = 0;
        needDraw[r.NODE] = true;
        needDraw[r.DRAG] = true;
        r.redraw();
      }, motionBlurDelay);
    }
    if (!forcedContext) {
      cy.emit('render');
    }
  };

  var CRp$3 = {};

  // @O Polygon drawing
  CRp$3.drawPolygonPath = function (context, x, y, width, height, points) {
    var halfW = width / 2;
    var halfH = height / 2;
    if (context.beginPath) {
      context.beginPath();
    }
    context.moveTo(x + halfW * points[0], y + halfH * points[1]);
    for (var i = 1; i < points.length / 2; i++) {
      context.lineTo(x + halfW * points[i * 2], y + halfH * points[i * 2 + 1]);
    }
    context.closePath();
  };
  CRp$3.drawRoundPolygonPath = function (context, x, y, width, height, points) {
    var halfW = width / 2;
    var halfH = height / 2;
    var cornerRadius = getRoundPolygonRadius(width, height);
    if (context.beginPath) {
      context.beginPath();
    }
    for (var _i = 0; _i < points.length / 4; _i++) {
      var sourceUv = void 0,
        destUv = void 0;
      if (_i === 0) {
        sourceUv = points.length - 2;
      } else {
        sourceUv = _i * 4 - 2;
      }
      destUv = _i * 4 + 2;
      var px = x + halfW * points[_i * 4];
      var py = y + halfH * points[_i * 4 + 1];
      var cosTheta = -points[sourceUv] * points[destUv] - points[sourceUv + 1] * points[destUv + 1];
      var offset = cornerRadius / Math.tan(Math.acos(cosTheta) / 2);
      var cp0x = px - offset * points[sourceUv];
      var cp0y = py - offset * points[sourceUv + 1];
      var cp1x = px + offset * points[destUv];
      var cp1y = py + offset * points[destUv + 1];
      if (_i === 0) {
        context.moveTo(cp0x, cp0y);
      } else {
        context.lineTo(cp0x, cp0y);
      }
      context.arcTo(px, py, cp1x, cp1y, cornerRadius);
    }
    context.closePath();
  };

  // Round rectangle drawing
  CRp$3.drawRoundRectanglePath = function (context, x, y, width, height) {
    var halfWidth = width / 2;
    var halfHeight = height / 2;
    var cornerRadius = getRoundRectangleRadius(width, height);
    if (context.beginPath) {
      context.beginPath();
    }

    // Start at top middle
    context.moveTo(x, y - halfHeight);
    // Arc from middle top to right side
    context.arcTo(x + halfWidth, y - halfHeight, x + halfWidth, y, cornerRadius);
    // Arc from right side to bottom
    context.arcTo(x + halfWidth, y + halfHeight, x, y + halfHeight, cornerRadius);
    // Arc from bottom to left side
    context.arcTo(x - halfWidth, y + halfHeight, x - halfWidth, y, cornerRadius);
    // Arc from left side to topBorder
    context.arcTo(x - halfWidth, y - halfHeight, x, y - halfHeight, cornerRadius);
    // Join line
    context.lineTo(x, y - halfHeight);
    context.closePath();
  };
  CRp$3.drawBottomRoundRectanglePath = function (context, x, y, width, height) {
    var halfWidth = width / 2;
    var halfHeight = height / 2;
    var cornerRadius = getRoundRectangleRadius(width, height);
    if (context.beginPath) {
      context.beginPath();
    }

    // Start at top middle
    context.moveTo(x, y - halfHeight);
    context.lineTo(x + halfWidth, y - halfHeight);
    context.lineTo(x + halfWidth, y);
    context.arcTo(x + halfWidth, y + halfHeight, x, y + halfHeight, cornerRadius);
    context.arcTo(x - halfWidth, y + halfHeight, x - halfWidth, y, cornerRadius);
    context.lineTo(x - halfWidth, y - halfHeight);
    context.lineTo(x, y - halfHeight);
    context.closePath();
  };
  CRp$3.drawCutRectanglePath = function (context, x, y, width, height) {
    var halfWidth = width / 2;
    var halfHeight = height / 2;
    var cornerLength = getCutRectangleCornerLength();
    if (context.beginPath) {
      context.beginPath();
    }
    context.moveTo(x - halfWidth + cornerLength, y - halfHeight);
    context.lineTo(x + halfWidth - cornerLength, y - halfHeight);
    context.lineTo(x + halfWidth, y - halfHeight + cornerLength);
    context.lineTo(x + halfWidth, y + halfHeight - cornerLength);
    context.lineTo(x + halfWidth - cornerLength, y + halfHeight);
    context.lineTo(x - halfWidth + cornerLength, y + halfHeight);
    context.lineTo(x - halfWidth, y + halfHeight - cornerLength);
    context.lineTo(x - halfWidth, y - halfHeight + cornerLength);
    context.closePath();
  };
  CRp$3.drawBarrelPath = function (context, x, y, width, height) {
    var halfWidth = width / 2;
    var halfHeight = height / 2;
    var xBegin = x - halfWidth;
    var xEnd = x + halfWidth;
    var yBegin = y - halfHeight;
    var yEnd = y + halfHeight;
    var barrelCurveConstants = getBarrelCurveConstants(width, height);
    var wOffset = barrelCurveConstants.widthOffset;
    var hOffset = barrelCurveConstants.heightOffset;
    var ctrlPtXOffset = barrelCurveConstants.ctrlPtOffsetPct * wOffset;
    if (context.beginPath) {
      context.beginPath();
    }
    context.moveTo(xBegin, yBegin + hOffset);
    context.lineTo(xBegin, yEnd - hOffset);
    context.quadraticCurveTo(xBegin + ctrlPtXOffset, yEnd, xBegin + wOffset, yEnd);
    context.lineTo(xEnd - wOffset, yEnd);
    context.quadraticCurveTo(xEnd - ctrlPtXOffset, yEnd, xEnd, yEnd - hOffset);
    context.lineTo(xEnd, yBegin + hOffset);
    context.quadraticCurveTo(xEnd - ctrlPtXOffset, yBegin, xEnd - wOffset, yBegin);
    context.lineTo(xBegin + wOffset, yBegin);
    context.quadraticCurveTo(xBegin + ctrlPtXOffset, yBegin, xBegin, yBegin + hOffset);
    context.closePath();
  };
  var sin0 = Math.sin(0);
  var cos0 = Math.cos(0);
  var sin = {};
  var cos = {};
  var ellipseStepSize = Math.PI / 40;
  for (var i = 0 * Math.PI; i < 2 * Math.PI; i += ellipseStepSize) {
    sin[i] = Math.sin(i);
    cos[i] = Math.cos(i);
  }
  CRp$3.drawEllipsePath = function (context, centerX, centerY, width, height) {
    if (context.beginPath) {
      context.beginPath();
    }
    if (context.ellipse) {
      context.ellipse(centerX, centerY, width / 2, height / 2, 0, 0, 2 * Math.PI);
    } else {
      var xPos, yPos;
      var rw = width / 2;
      var rh = height / 2;
      for (var i = 0 * Math.PI; i < 2 * Math.PI; i += ellipseStepSize) {
        xPos = centerX - rw * sin[i] * sin0 + rw * cos[i] * cos0;
        yPos = centerY + rh * cos[i] * sin0 + rh * sin[i] * cos0;
        if (i === 0) {
          context.moveTo(xPos, yPos);
        } else {
          context.lineTo(xPos, yPos);
        }
      }
    }
    context.closePath();
  };

  /* global atob, ArrayBuffer, Uint8Array, Blob */
  var CRp$2 = {};
  CRp$2.createBuffer = function (w, h) {
    var buffer = document.createElement('canvas'); // eslint-disable-line no-undef
    buffer.width = w;
    buffer.height = h;
    return [buffer, buffer.getContext('2d')];
  };
  CRp$2.bufferCanvasImage = function (options) {
    var cy = this.cy;
    var eles = cy.mutableElements();
    var bb = eles.boundingBox();
    var ctrRect = this.findContainerClientCoords();
    var width = options.full ? Math.ceil(bb.w) : ctrRect[2];
    var height = options.full ? Math.ceil(bb.h) : ctrRect[3];
    var specdMaxDims = number$1(options.maxWidth) || number$1(options.maxHeight);
    var pxRatio = this.getPixelRatio();
    var scale = 1;
    if (options.scale !== undefined) {
      width *= options.scale;
      height *= options.scale;
      scale = options.scale;
    } else if (specdMaxDims) {
      var maxScaleW = Infinity;
      var maxScaleH = Infinity;
      if (number$1(options.maxWidth)) {
        maxScaleW = scale * options.maxWidth / width;
      }
      if (number$1(options.maxHeight)) {
        maxScaleH = scale * options.maxHeight / height;
      }
      scale = Math.min(maxScaleW, maxScaleH);
      width *= scale;
      height *= scale;
    }
    if (!specdMaxDims) {
      width *= pxRatio;
      height *= pxRatio;
      scale *= pxRatio;
    }
    var buffCanvas = document.createElement('canvas'); // eslint-disable-line no-undef

    buffCanvas.width = width;
    buffCanvas.height = height;
    buffCanvas.style.width = width + 'px';
    buffCanvas.style.height = height + 'px';
    var buffCxt = buffCanvas.getContext('2d');

    // Rasterize the layers, but only if container has nonzero size
    if (width > 0 && height > 0) {
      buffCxt.clearRect(0, 0, width, height);
      buffCxt.globalCompositeOperation = 'source-over';
      var zsortedEles = this.getCachedZSortedEles();
      if (options.full) {
        // draw the full bounds of the graph
        buffCxt.translate(-bb.x1 * scale, -bb.y1 * scale);
        buffCxt.scale(scale, scale);
        this.drawElements(buffCxt, zsortedEles);
        buffCxt.scale(1 / scale, 1 / scale);
        buffCxt.translate(bb.x1 * scale, bb.y1 * scale);
      } else {
        // draw the current view
        var pan = cy.pan();
        var translation = {
          x: pan.x * scale,
          y: pan.y * scale
        };
        scale *= cy.zoom();
        buffCxt.translate(translation.x, translation.y);
        buffCxt.scale(scale, scale);
        this.drawElements(buffCxt, zsortedEles);
        buffCxt.scale(1 / scale, 1 / scale);
        buffCxt.translate(-translation.x, -translation.y);
      }

      // need to fill bg at end like this in order to fill cleared transparent pixels in jpgs
      if (options.bg) {
        buffCxt.globalCompositeOperation = 'destination-over';
        buffCxt.fillStyle = options.bg;
        buffCxt.rect(0, 0, width, height);
        buffCxt.fill();
      }
    }
    return buffCanvas;
  };
  function b64ToBlob(b64, mimeType) {
    var bytes = atob(b64);
    var buff = new ArrayBuffer(bytes.length);
    var buffUint8 = new Uint8Array(buff);
    for (var i = 0; i < bytes.length; i++) {
      buffUint8[i] = bytes.charCodeAt(i);
    }
    return new Blob([buff], {
      type: mimeType
    });
  }
  function b64UriToB64(b64uri) {
    var i = b64uri.indexOf(',');
    return b64uri.substr(i + 1);
  }
  function output(options, canvas, mimeType) {
    var getB64Uri = function getB64Uri() {
      return canvas.toDataURL(mimeType, options.quality);
    };
    switch (options.output) {
      case 'blob-promise':
        return new Promise$1(function (resolve, reject) {
          try {
            canvas.toBlob(function (blob) {
              if (blob != null) {
                resolve(blob);
              } else {
                reject(new Error('`canvas.toBlob()` sent a null value in its callback'));
              }
            }, mimeType, options.quality);
          } catch (err) {
            reject(err);
          }
        });
      case 'blob':
        return b64ToBlob(b64UriToB64(getB64Uri()), mimeType);
      case 'base64':
        return b64UriToB64(getB64Uri());
      case 'base64uri':
      default:
        return getB64Uri();
    }
  }
  CRp$2.png = function (options) {
    return output(options, this.bufferCanvasImage(options), 'image/png');
  };
  CRp$2.jpg = function (options) {
    return output(options, this.bufferCanvasImage(options), 'image/jpeg');
  };

  var CRp$1 = {};
  CRp$1.nodeShapeImpl = function (name, context, centerX, centerY, width, height, points) {
    switch (name) {
      case 'ellipse':
        return this.drawEllipsePath(context, centerX, centerY, width, height);
      case 'polygon':
        return this.drawPolygonPath(context, centerX, centerY, width, height, points);
      case 'round-polygon':
        return this.drawRoundPolygonPath(context, centerX, centerY, width, height, points);
      case 'roundrectangle':
      case 'round-rectangle':
        return this.drawRoundRectanglePath(context, centerX, centerY, width, height);
      case 'cutrectangle':
      case 'cut-rectangle':
        return this.drawCutRectanglePath(context, centerX, centerY, width, height);
      case 'bottomroundrectangle':
      case 'bottom-round-rectangle':
        return this.drawBottomRoundRectanglePath(context, centerX, centerY, width, height);
      case 'barrel':
        return this.drawBarrelPath(context, centerX, centerY, width, height);
    }
  };

  var CR = CanvasRenderer;
  var CRp = CanvasRenderer.prototype;
  CRp.CANVAS_LAYERS = 3;
  //
  CRp.SELECT_BOX = 0;
  CRp.DRAG = 1;
  CRp.NODE = 2;
  CRp.BUFFER_COUNT = 3;
  //
  CRp.TEXTURE_BUFFER = 0;
  CRp.MOTIONBLUR_BUFFER_NODE = 1;
  CRp.MOTIONBLUR_BUFFER_DRAG = 2;
  function CanvasRenderer(options) {
    var r = this;
    r.data = {
      canvases: new Array(CRp.CANVAS_LAYERS),
      contexts: new Array(CRp.CANVAS_LAYERS),
      canvasNeedsRedraw: new Array(CRp.CANVAS_LAYERS),
      bufferCanvases: new Array(CRp.BUFFER_COUNT),
      bufferContexts: new Array(CRp.CANVAS_LAYERS)
    };
    var tapHlOffAttr = '-webkit-tap-highlight-color';
    var tapHlOffStyle = 'rgba(0,0,0,0)';
    r.data.canvasContainer = document.createElement('div'); // eslint-disable-line no-undef
    var containerStyle = r.data.canvasContainer.style;
    r.data.canvasContainer.style[tapHlOffAttr] = tapHlOffStyle;
    containerStyle.position = 'relative';
    containerStyle.zIndex = '0';
    containerStyle.overflow = 'hidden';
    var container = options.cy.container();
    container.appendChild(r.data.canvasContainer);
    container.style[tapHlOffAttr] = tapHlOffStyle;
    var styleMap = {
      '-webkit-user-select': 'none',
      '-moz-user-select': '-moz-none',
      'user-select': 'none',
      '-webkit-tap-highlight-color': 'rgba(0,0,0,0)',
      'outline-style': 'none'
    };
    if (ms()) {
      styleMap['-ms-touch-action'] = 'none';
      styleMap['touch-action'] = 'none';
    }
    for (var i = 0; i < CRp.CANVAS_LAYERS; i++) {
      var canvas = r.data.canvases[i] = document.createElement('canvas'); // eslint-disable-line no-undef
      r.data.contexts[i] = canvas.getContext('2d');
      Object.keys(styleMap).forEach(function (k) {
        canvas.style[k] = styleMap[k];
      });
      canvas.style.position = 'absolute';
      canvas.setAttribute('data-id', 'layer' + i);
      canvas.style.zIndex = String(CRp.CANVAS_LAYERS - i);
      r.data.canvasContainer.appendChild(canvas);
      r.data.canvasNeedsRedraw[i] = false;
    }
    r.data.topCanvas = r.data.canvases[0];
    r.data.canvases[CRp.NODE].setAttribute('data-id', 'layer' + CRp.NODE + '-node');
    r.data.canvases[CRp.SELECT_BOX].setAttribute('data-id', 'layer' + CRp.SELECT_BOX + '-selectbox');
    r.data.canvases[CRp.DRAG].setAttribute('data-id', 'layer' + CRp.DRAG + '-drag');
    for (var i = 0; i < CRp.BUFFER_COUNT; i++) {
      r.data.bufferCanvases[i] = document.createElement('canvas'); // eslint-disable-line no-undef
      r.data.bufferContexts[i] = r.data.bufferCanvases[i].getContext('2d');
      r.data.bufferCanvases[i].style.position = 'absolute';
      r.data.bufferCanvases[i].setAttribute('data-id', 'buffer' + i);
      r.data.bufferCanvases[i].style.zIndex = String(-i - 1);
      r.data.bufferCanvases[i].style.visibility = 'hidden';
      //r.data.canvasContainer.appendChild(r.data.bufferCanvases[i]);
    }

    r.pathsEnabled = true;
    var emptyBb = makeBoundingBox();
    var getBoxCenter = function getBoxCenter(bb) {
      return {
        x: (bb.x1 + bb.x2) / 2,
        y: (bb.y1 + bb.y2) / 2
      };
    };
    var getCenterOffset = function getCenterOffset(bb) {
      return {
        x: -bb.w / 2,
        y: -bb.h / 2
      };
    };
    var backgroundTimestampHasChanged = function backgroundTimestampHasChanged(ele) {
      var _p = ele[0]._private;
      var same = _p.oldBackgroundTimestamp === _p.backgroundTimestamp;
      return !same;
    };
    var getStyleKey = function getStyleKey(ele) {
      return ele[0]._private.nodeKey;
    };
    var getLabelKey = function getLabelKey(ele) {
      return ele[0]._private.labelStyleKey;
    };
    var getSourceLabelKey = function getSourceLabelKey(ele) {
      return ele[0]._private.sourceLabelStyleKey;
    };
    var getTargetLabelKey = function getTargetLabelKey(ele) {
      return ele[0]._private.targetLabelStyleKey;
    };
    var drawElement = function drawElement(context, ele, bb, scaledLabelShown, useEleOpacity) {
      return r.drawElement(context, ele, bb, false, false, useEleOpacity);
    };
    var drawLabel = function drawLabel(context, ele, bb, scaledLabelShown, useEleOpacity) {
      return r.drawElementText(context, ele, bb, scaledLabelShown, 'main', useEleOpacity);
    };
    var drawSourceLabel = function drawSourceLabel(context, ele, bb, scaledLabelShown, useEleOpacity) {
      return r.drawElementText(context, ele, bb, scaledLabelShown, 'source', useEleOpacity);
    };
    var drawTargetLabel = function drawTargetLabel(context, ele, bb, scaledLabelShown, useEleOpacity) {
      return r.drawElementText(context, ele, bb, scaledLabelShown, 'target', useEleOpacity);
    };
    var getElementBox = function getElementBox(ele) {
      ele.boundingBox();
      return ele[0]._private.bodyBounds;
    };
    var getLabelBox = function getLabelBox(ele) {
      ele.boundingBox();
      return ele[0]._private.labelBounds.main || emptyBb;
    };
    var getSourceLabelBox = function getSourceLabelBox(ele) {
      ele.boundingBox();
      return ele[0]._private.labelBounds.source || emptyBb;
    };
    var getTargetLabelBox = function getTargetLabelBox(ele) {
      ele.boundingBox();
      return ele[0]._private.labelBounds.target || emptyBb;
    };
    var isLabelVisibleAtScale = function isLabelVisibleAtScale(ele, scaledLabelShown) {
      return scaledLabelShown;
    };
    var getElementRotationPoint = function getElementRotationPoint(ele) {
      return getBoxCenter(getElementBox(ele));
    };
    var addTextMargin = function addTextMargin(prefix, pt, ele) {
      var pre = prefix ? prefix + '-' : '';
      return {
        x: pt.x + ele.pstyle(pre + 'text-margin-x').pfValue,
        y: pt.y + ele.pstyle(pre + 'text-margin-y').pfValue
      };
    };
    var getRsPt = function getRsPt(ele, x, y) {
      var rs = ele[0]._private.rscratch;
      return {
        x: rs[x],
        y: rs[y]
      };
    };
    var getLabelRotationPoint = function getLabelRotationPoint(ele) {
      return addTextMargin('', getRsPt(ele, 'labelX', 'labelY'), ele);
    };
    var getSourceLabelRotationPoint = function getSourceLabelRotationPoint(ele) {
      return addTextMargin('source', getRsPt(ele, 'sourceLabelX', 'sourceLabelY'), ele);
    };
    var getTargetLabelRotationPoint = function getTargetLabelRotationPoint(ele) {
      return addTextMargin('target', getRsPt(ele, 'targetLabelX', 'targetLabelY'), ele);
    };
    var getElementRotationOffset = function getElementRotationOffset(ele) {
      return getCenterOffset(getElementBox(ele));
    };
    var getSourceLabelRotationOffset = function getSourceLabelRotationOffset(ele) {
      return getCenterOffset(getSourceLabelBox(ele));
    };
    var getTargetLabelRotationOffset = function getTargetLabelRotationOffset(ele) {
      return getCenterOffset(getTargetLabelBox(ele));
    };
    var getLabelRotationOffset = function getLabelRotationOffset(ele) {
      var bb = getLabelBox(ele);
      var p = getCenterOffset(getLabelBox(ele));
      if (ele.isNode()) {
        switch (ele.pstyle('text-halign').value) {
          case 'left':
            p.x = -bb.w;
            break;
          case 'right':
            p.x = 0;
            break;
        }
        switch (ele.pstyle('text-valign').value) {
          case 'top':
            p.y = -bb.h;
            break;
          case 'bottom':
            p.y = 0;
            break;
        }
      }
      return p;
    };
    var eleTxrCache = r.data.eleTxrCache = new ElementTextureCache(r, {
      getKey: getStyleKey,
      doesEleInvalidateKey: backgroundTimestampHasChanged,
      drawElement: drawElement,
      getBoundingBox: getElementBox,
      getRotationPoint: getElementRotationPoint,
      getRotationOffset: getElementRotationOffset,
      allowEdgeTxrCaching: false,
      allowParentTxrCaching: false
    });
    var lblTxrCache = r.data.lblTxrCache = new ElementTextureCache(r, {
      getKey: getLabelKey,
      drawElement: drawLabel,
      getBoundingBox: getLabelBox,
      getRotationPoint: getLabelRotationPoint,
      getRotationOffset: getLabelRotationOffset,
      isVisible: isLabelVisibleAtScale
    });
    var slbTxrCache = r.data.slbTxrCache = new ElementTextureCache(r, {
      getKey: getSourceLabelKey,
      drawElement: drawSourceLabel,
      getBoundingBox: getSourceLabelBox,
      getRotationPoint: getSourceLabelRotationPoint,
      getRotationOffset: getSourceLabelRotationOffset,
      isVisible: isLabelVisibleAtScale
    });
    var tlbTxrCache = r.data.tlbTxrCache = new ElementTextureCache(r, {
      getKey: getTargetLabelKey,
      drawElement: drawTargetLabel,
      getBoundingBox: getTargetLabelBox,
      getRotationPoint: getTargetLabelRotationPoint,
      getRotationOffset: getTargetLabelRotationOffset,
      isVisible: isLabelVisibleAtScale
    });
    var lyrTxrCache = r.data.lyrTxrCache = new LayeredTextureCache(r);
    r.onUpdateEleCalcs(function invalidateTextureCaches(willDraw, eles) {
      // each cache should check for sub-key diff to see that the update affects that cache particularly
      eleTxrCache.invalidateElements(eles);
      lblTxrCache.invalidateElements(eles);
      slbTxrCache.invalidateElements(eles);
      tlbTxrCache.invalidateElements(eles);

      // any change invalidates the layers
      lyrTxrCache.invalidateElements(eles);

      // update the old bg timestamp so diffs can be done in the ele txr caches
      for (var _i = 0; _i < eles.length; _i++) {
        var _p = eles[_i]._private;
        _p.oldBackgroundTimestamp = _p.backgroundTimestamp;
      }
    });
    var refineInLayers = function refineInLayers(reqs) {
      for (var i = 0; i < reqs.length; i++) {
        lyrTxrCache.enqueueElementRefinement(reqs[i].ele);
      }
    };
    eleTxrCache.onDequeue(refineInLayers);
    lblTxrCache.onDequeue(refineInLayers);
    slbTxrCache.onDequeue(refineInLayers);
    tlbTxrCache.onDequeue(refineInLayers);
  }
  CRp.redrawHint = function (group, bool) {
    var r = this;
    switch (group) {
      case 'eles':
        r.data.canvasNeedsRedraw[CRp.NODE] = bool;
        break;
      case 'drag':
        r.data.canvasNeedsRedraw[CRp.DRAG] = bool;
        break;
      case 'select':
        r.data.canvasNeedsRedraw[CRp.SELECT_BOX] = bool;
        break;
    }
  };

  // whether to use Path2D caching for drawing
  var pathsImpld = typeof Path2D !== 'undefined';
  CRp.path2dEnabled = function (on) {
    if (on === undefined) {
      return this.pathsEnabled;
    }
    this.pathsEnabled = on ? true : false;
  };
  CRp.usePaths = function () {
    return pathsImpld && this.pathsEnabled;
  };
  CRp.setImgSmoothing = function (context, bool) {
    if (context.imageSmoothingEnabled != null) {
      context.imageSmoothingEnabled = bool;
    } else {
      context.webkitImageSmoothingEnabled = bool;
      context.mozImageSmoothingEnabled = bool;
      context.msImageSmoothingEnabled = bool;
    }
  };
  CRp.getImgSmoothing = function (context) {
    if (context.imageSmoothingEnabled != null) {
      return context.imageSmoothingEnabled;
    } else {
      return context.webkitImageSmoothingEnabled || context.mozImageSmoothingEnabled || context.msImageSmoothingEnabled;
    }
  };
  CRp.makeOffscreenCanvas = function (width, height) {
    var canvas;
    if ((typeof OffscreenCanvas === "undefined" ? "undefined" : _typeof(OffscreenCanvas)) !== ("undefined" )) {
      canvas = new OffscreenCanvas(width, height);
    } else {
      canvas = document.createElement('canvas'); // eslint-disable-line no-undef
      canvas.width = width;
      canvas.height = height;
    }
    return canvas;
  };
  [CRp$a, CRp$9, CRp$8, CRp$7, CRp$6, CRp$5, CRp$4, CRp$3, CRp$2, CRp$1].forEach(function (props) {
    extend(CRp, props);
  });

  var renderer = [{
    name: 'null',
    impl: NullRenderer
  }, {
    name: 'base',
    impl: BR
  }, {
    name: 'canvas',
    impl: CR
  }];

  var incExts = [{
    type: 'layout',
    extensions: layout
  }, {
    type: 'renderer',
    extensions: renderer
  }];

  // registered extensions to cytoscape, indexed by name
  var extensions = {};

  // registered modules for extensions, indexed by name
  var modules = {};
  function setExtension(type, name, registrant) {
    var ext = registrant;
    var overrideErr = function overrideErr(field) {
      warn('Can not register `' + name + '` for `' + type + '` since `' + field + '` already exists in the prototype and can not be overridden');
    };
    if (type === 'core') {
      if (Core.prototype[name]) {
        return overrideErr(name);
      } else {
        Core.prototype[name] = registrant;
      }
    } else if (type === 'collection') {
      if (Collection.prototype[name]) {
        return overrideErr(name);
      } else {
        Collection.prototype[name] = registrant;
      }
    } else if (type === 'layout') {
      // fill in missing layout functions in the prototype

      var Layout = function Layout(options) {
        this.options = options;
        registrant.call(this, options);

        // make sure layout has _private for use w/ std apis like .on()
        if (!plainObject(this._private)) {
          this._private = {};
        }
        this._private.cy = options.cy;
        this._private.listeners = [];
        this.createEmitter();
      };
      var layoutProto = Layout.prototype = Object.create(registrant.prototype);
      var optLayoutFns = [];
      for (var i = 0; i < optLayoutFns.length; i++) {
        var fnName = optLayoutFns[i];
        layoutProto[fnName] = layoutProto[fnName] || function () {
          return this;
        };
      }

      // either .start() or .run() is defined, so autogen the other
      if (layoutProto.start && !layoutProto.run) {
        layoutProto.run = function () {
          this.start();
          return this;
        };
      } else if (!layoutProto.start && layoutProto.run) {
        layoutProto.start = function () {
          this.run();
          return this;
        };
      }
      var regStop = registrant.prototype.stop;
      layoutProto.stop = function () {
        var opts = this.options;
        if (opts && opts.animate) {
          var anis = this.animations;
          if (anis) {
            for (var _i = 0; _i < anis.length; _i++) {
              anis[_i].stop();
            }
          }
        }
        if (regStop) {
          regStop.call(this);
        } else {
          this.emit('layoutstop');
        }
        return this;
      };
      if (!layoutProto.destroy) {
        layoutProto.destroy = function () {
          return this;
        };
      }
      layoutProto.cy = function () {
        return this._private.cy;
      };
      var getCy = function getCy(layout) {
        return layout._private.cy;
      };
      var emitterOpts = {
        addEventFields: function addEventFields(layout, evt) {
          evt.layout = layout;
          evt.cy = getCy(layout);
          evt.target = layout;
        },
        bubble: function bubble() {
          return true;
        },
        parent: function parent(layout) {
          return getCy(layout);
        }
      };
      extend(layoutProto, {
        createEmitter: function createEmitter() {
          this._private.emitter = new Emitter(emitterOpts, this);
          return this;
        },
        emitter: function emitter() {
          return this._private.emitter;
        },
        on: function on(evt, cb) {
          this.emitter().on(evt, cb);
          return this;
        },
        one: function one(evt, cb) {
          this.emitter().one(evt, cb);
          return this;
        },
        once: function once(evt, cb) {
          this.emitter().one(evt, cb);
          return this;
        },
        removeListener: function removeListener(evt, cb) {
          this.emitter().removeListener(evt, cb);
          return this;
        },
        removeAllListeners: function removeAllListeners() {
          this.emitter().removeAllListeners();
          return this;
        },
        emit: function emit(evt, params) {
          this.emitter().emit(evt, params);
          return this;
        }
      });
      define.eventAliasesOn(layoutProto);
      ext = Layout; // replace with our wrapped layout
    } else if (type === 'renderer' && name !== 'null' && name !== 'base') {
      // user registered renderers inherit from base

      var BaseRenderer = getExtension('renderer', 'base');
      var bProto = BaseRenderer.prototype;
      var RegistrantRenderer = registrant;
      var rProto = registrant.prototype;
      var Renderer = function Renderer() {
        BaseRenderer.apply(this, arguments);
        RegistrantRenderer.apply(this, arguments);
      };
      var proto = Renderer.prototype;
      for (var pName in bProto) {
        var pVal = bProto[pName];
        var existsInR = rProto[pName] != null;
        if (existsInR) {
          return overrideErr(pName);
        }
        proto[pName] = pVal; // take impl from base
      }

      for (var _pName in rProto) {
        proto[_pName] = rProto[_pName]; // take impl from registrant
      }

      bProto.clientFunctions.forEach(function (name) {
        proto[name] = proto[name] || function () {
          error('Renderer does not implement `renderer.' + name + '()` on its prototype');
        };
      });
      ext = Renderer;
    } else if (type === '__proto__' || type === 'constructor' || type === 'prototype') {
      // to avoid potential prototype pollution
      return error(type + ' is an illegal type to be registered, possibly lead to prototype pollutions');
    }
    return setMap({
      map: extensions,
      keys: [type, name],
      value: ext
    });
  }
  function getExtension(type, name) {
    return getMap({
      map: extensions,
      keys: [type, name]
    });
  }
  function setModule(type, name, moduleType, moduleName, registrant) {
    return setMap({
      map: modules,
      keys: [type, name, moduleType, moduleName],
      value: registrant
    });
  }
  function getModule(type, name, moduleType, moduleName) {
    return getMap({
      map: modules,
      keys: [type, name, moduleType, moduleName]
    });
  }
  var extension = function extension() {
    // e.g. extension('renderer', 'svg')
    if (arguments.length === 2) {
      return getExtension.apply(null, arguments);
    }

    // e.g. extension('renderer', 'svg', { ... })
    else if (arguments.length === 3) {
      return setExtension.apply(null, arguments);
    }

    // e.g. extension('renderer', 'svg', 'nodeShape', 'ellipse')
    else if (arguments.length === 4) {
      return getModule.apply(null, arguments);
    }

    // e.g. extension('renderer', 'svg', 'nodeShape', 'ellipse', { ... })
    else if (arguments.length === 5) {
      return setModule.apply(null, arguments);
    } else {
      error('Invalid extension access syntax');
    }
  };

  // allows a core instance to access extensions internally
  Core.prototype.extension = extension;

  // included extensions
  incExts.forEach(function (group) {
    group.extensions.forEach(function (ext) {
      setExtension(group.type, ext.name, ext.impl);
    });
  });

  // a dummy stylesheet object that doesn't need a reference to the core
  // (useful for init)
  var Stylesheet = function Stylesheet() {
    if (!(this instanceof Stylesheet)) {
      return new Stylesheet();
    }
    this.length = 0;
  };
  var sheetfn = Stylesheet.prototype;
  sheetfn.instanceString = function () {
    return 'stylesheet';
  };

  // just store the selector to be parsed later
  sheetfn.selector = function (selector) {
    var i = this.length++;
    this[i] = {
      selector: selector,
      properties: []
    };
    return this; // chaining
  };

  // just store the property to be parsed later
  sheetfn.css = function (name, value) {
    var i = this.length - 1;
    if (string(name)) {
      this[i].properties.push({
        name: name,
        value: value
      });
    } else if (plainObject(name)) {
      var map = name;
      var propNames = Object.keys(map);
      for (var j = 0; j < propNames.length; j++) {
        var key = propNames[j];
        var mapVal = map[key];
        if (mapVal == null) {
          continue;
        }
        var prop = Style.properties[key] || Style.properties[dash2camel(key)];
        if (prop == null) {
          continue;
        }
        var _name = prop.name;
        var _value = mapVal;
        this[i].properties.push({
          name: _name,
          value: _value
        });
      }
    }
    return this; // chaining
  };

  sheetfn.style = sheetfn.css;

  // generate a real style object from the dummy stylesheet
  sheetfn.generateStyle = function (cy) {
    var style = new Style(cy);
    return this.appendToStyle(style);
  };

  // append a dummy stylesheet object on a real style object
  sheetfn.appendToStyle = function (style) {
    for (var i = 0; i < this.length; i++) {
      var context = this[i];
      var selector = context.selector;
      var props = context.properties;
      style.selector(selector); // apply selector

      for (var j = 0; j < props.length; j++) {
        var prop = props[j];
        style.css(prop.name, prop.value); // apply property
      }
    }

    return style;
  };

  var version = "3.28.1";

  var cytoscape = function cytoscape(options) {
    // if no options specified, use default
    if (options === undefined) {
      options = {};
    }

    // create instance
    if (plainObject(options)) {
      return new Core(options);
    }

    // allow for registration of extensions
    else if (string(options)) {
      return extension.apply(extension, arguments);
    }
  };

  // e.g. cytoscape.use( require('cytoscape-foo'), bar )
  cytoscape.use = function (ext) {
    var args = Array.prototype.slice.call(arguments, 1); // args to pass to ext

    args.unshift(cytoscape); // cytoscape is first arg to ext

    ext.apply(null, args);
    return this;
  };
  cytoscape.warnings = function (bool) {
    return warnings(bool);
  };

  // replaced by build system
  cytoscape.version = version;

  // expose public apis (mostly for extensions)
  cytoscape.stylesheet = cytoscape.Stylesheet = Stylesheet;

  return cytoscape;

}));


/***/ }),

/***/ 23143:
/***/ (function(module) {

(function webpackUniversalModuleDefinition(root, factory) {
	if(true)
		module.exports = factory();
	else {}
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// The require function
/******/ 	function __nested_webpack_require_543__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __nested_webpack_require_543__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__nested_webpack_require_543__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__nested_webpack_require_543__.c = installedModules;
/******/
/******/ 	// identity function for calling harmony imports with the correct context
/******/ 	__nested_webpack_require_543__.i = function(value) { return value; };
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__nested_webpack_require_543__.d = function(exports, name, getter) {
/******/ 		if(!__nested_webpack_require_543__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__nested_webpack_require_543__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__nested_webpack_require_543__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__nested_webpack_require_543__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__nested_webpack_require_543__.p = "";
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __nested_webpack_require_543__(__nested_webpack_require_543__.s = 26);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function LayoutConstants() {}

/**
 * Layout Quality: 0:draft, 1:default, 2:proof
 */
LayoutConstants.QUALITY = 1;

/**
 * Default parameters
 */
LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED = false;
LayoutConstants.DEFAULT_INCREMENTAL = false;
LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT = true;
LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT = false;
LayoutConstants.DEFAULT_ANIMATION_PERIOD = 50;
LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES = false;

// -----------------------------------------------------------------------------
// Section: General other constants
// -----------------------------------------------------------------------------
/*
 * Margins of a graph to be applied on bouding rectangle of its contents. We
 * assume margins on all four sides to be uniform.
 */
LayoutConstants.DEFAULT_GRAPH_MARGIN = 15;

/*
 * Whether to consider labels in node dimensions or not
 */
LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = false;

/*
 * Default dimension of a non-compound node.
 */
LayoutConstants.SIMPLE_NODE_SIZE = 40;

/*
 * Default dimension of a non-compound node.
 */
LayoutConstants.SIMPLE_NODE_HALF_SIZE = LayoutConstants.SIMPLE_NODE_SIZE / 2;

/*
 * Empty compound node size. When a compound node is empty, its both
 * dimensions should be of this value.
 */
LayoutConstants.EMPTY_COMPOUND_NODE_SIZE = 40;

/*
 * Minimum length that an edge should take during layout
 */
LayoutConstants.MIN_EDGE_LENGTH = 1;

/*
 * World boundaries that layout operates on
 */
LayoutConstants.WORLD_BOUNDARY = 1000000;

/*
 * World boundaries that random positioning can be performed with
 */
LayoutConstants.INITIAL_WORLD_BOUNDARY = LayoutConstants.WORLD_BOUNDARY / 1000;

/*
 * Coordinates of the world center
 */
LayoutConstants.WORLD_CENTER_X = 1200;
LayoutConstants.WORLD_CENTER_Y = 900;

module.exports = LayoutConstants;

/***/ }),
/* 1 */
/***/ (function(module, exports, __nested_webpack_require_4947__) {

"use strict";


var LGraphObject = __nested_webpack_require_4947__(2);
var IGeometry = __nested_webpack_require_4947__(8);
var IMath = __nested_webpack_require_4947__(9);

function LEdge(source, target, vEdge) {
  LGraphObject.call(this, vEdge);

  this.isOverlapingSourceAndTarget = false;
  this.vGraphObject = vEdge;
  this.bendpoints = [];
  this.source = source;
  this.target = target;
}

LEdge.prototype = Object.create(LGraphObject.prototype);

for (var prop in LGraphObject) {
  LEdge[prop] = LGraphObject[prop];
}

LEdge.prototype.getSource = function () {
  return this.source;
};

LEdge.prototype.getTarget = function () {
  return this.target;
};

LEdge.prototype.isInterGraph = function () {
  return this.isInterGraph;
};

LEdge.prototype.getLength = function () {
  return this.length;
};

LEdge.prototype.isOverlapingSourceAndTarget = function () {
  return this.isOverlapingSourceAndTarget;
};

LEdge.prototype.getBendpoints = function () {
  return this.bendpoints;
};

LEdge.prototype.getLca = function () {
  return this.lca;
};

LEdge.prototype.getSourceInLca = function () {
  return this.sourceInLca;
};

LEdge.prototype.getTargetInLca = function () {
  return this.targetInLca;
};

LEdge.prototype.getOtherEnd = function (node) {
  if (this.source === node) {
    return this.target;
  } else if (this.target === node) {
    return this.source;
  } else {
    throw "Node is not incident with this edge";
  }
};

LEdge.prototype.getOtherEndInGraph = function (node, graph) {
  var otherEnd = this.getOtherEnd(node);
  var root = graph.getGraphManager().getRoot();

  while (true) {
    if (otherEnd.getOwner() == graph) {
      return otherEnd;
    }

    if (otherEnd.getOwner() == root) {
      break;
    }

    otherEnd = otherEnd.getOwner().getParent();
  }

  return null;
};

LEdge.prototype.updateLength = function () {
  var clipPointCoordinates = new Array(4);

  this.isOverlapingSourceAndTarget = IGeometry.getIntersection(this.target.getRect(), this.source.getRect(), clipPointCoordinates);

  if (!this.isOverlapingSourceAndTarget) {
    this.lengthX = clipPointCoordinates[0] - clipPointCoordinates[2];
    this.lengthY = clipPointCoordinates[1] - clipPointCoordinates[3];

    if (Math.abs(this.lengthX) < 1.0) {
      this.lengthX = IMath.sign(this.lengthX);
    }

    if (Math.abs(this.lengthY) < 1.0) {
      this.lengthY = IMath.sign(this.lengthY);
    }

    this.length = Math.sqrt(this.lengthX * this.lengthX + this.lengthY * this.lengthY);
  }
};

LEdge.prototype.updateLengthSimple = function () {
  this.lengthX = this.target.getCenterX() - this.source.getCenterX();
  this.lengthY = this.target.getCenterY() - this.source.getCenterY();

  if (Math.abs(this.lengthX) < 1.0) {
    this.lengthX = IMath.sign(this.lengthX);
  }

  if (Math.abs(this.lengthY) < 1.0) {
    this.lengthY = IMath.sign(this.lengthY);
  }

  this.length = Math.sqrt(this.lengthX * this.lengthX + this.lengthY * this.lengthY);
};

module.exports = LEdge;

/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function LGraphObject(vGraphObject) {
  this.vGraphObject = vGraphObject;
}

module.exports = LGraphObject;

/***/ }),
/* 3 */
/***/ (function(module, exports, __nested_webpack_require_8167__) {

"use strict";


var LGraphObject = __nested_webpack_require_8167__(2);
var Integer = __nested_webpack_require_8167__(10);
var RectangleD = __nested_webpack_require_8167__(13);
var LayoutConstants = __nested_webpack_require_8167__(0);
var RandomSeed = __nested_webpack_require_8167__(16);
var PointD = __nested_webpack_require_8167__(4);

function LNode(gm, loc, size, vNode) {
  //Alternative constructor 1 : LNode(LGraphManager gm, Point loc, Dimension size, Object vNode)
  if (size == null && vNode == null) {
    vNode = loc;
  }

  LGraphObject.call(this, vNode);

  //Alternative constructor 2 : LNode(Layout layout, Object vNode)
  if (gm.graphManager != null) gm = gm.graphManager;

  this.estimatedSize = Integer.MIN_VALUE;
  this.inclusionTreeDepth = Integer.MAX_VALUE;
  this.vGraphObject = vNode;
  this.edges = [];
  this.graphManager = gm;

  if (size != null && loc != null) this.rect = new RectangleD(loc.x, loc.y, size.width, size.height);else this.rect = new RectangleD();
}

LNode.prototype = Object.create(LGraphObject.prototype);
for (var prop in LGraphObject) {
  LNode[prop] = LGraphObject[prop];
}

LNode.prototype.getEdges = function () {
  return this.edges;
};

LNode.prototype.getChild = function () {
  return this.child;
};

LNode.prototype.getOwner = function () {
  //  if (this.owner != null) {
  //    if (!(this.owner == null || this.owner.getNodes().indexOf(this) > -1)) {
  //      throw "assert failed";
  //    }
  //  }

  return this.owner;
};

LNode.prototype.getWidth = function () {
  return this.rect.width;
};

LNode.prototype.setWidth = function (width) {
  this.rect.width = width;
};

LNode.prototype.getHeight = function () {
  return this.rect.height;
};

LNode.prototype.setHeight = function (height) {
  this.rect.height = height;
};

LNode.prototype.getCenterX = function () {
  return this.rect.x + this.rect.width / 2;
};

LNode.prototype.getCenterY = function () {
  return this.rect.y + this.rect.height / 2;
};

LNode.prototype.getCenter = function () {
  return new PointD(this.rect.x + this.rect.width / 2, this.rect.y + this.rect.height / 2);
};

LNode.prototype.getLocation = function () {
  return new PointD(this.rect.x, this.rect.y);
};

LNode.prototype.getRect = function () {
  return this.rect;
};

LNode.prototype.getDiagonal = function () {
  return Math.sqrt(this.rect.width * this.rect.width + this.rect.height * this.rect.height);
};

/**
 * This method returns half the diagonal length of this node.
 */
LNode.prototype.getHalfTheDiagonal = function () {
  return Math.sqrt(this.rect.height * this.rect.height + this.rect.width * this.rect.width) / 2;
};

LNode.prototype.setRect = function (upperLeft, dimension) {
  this.rect.x = upperLeft.x;
  this.rect.y = upperLeft.y;
  this.rect.width = dimension.width;
  this.rect.height = dimension.height;
};

LNode.prototype.setCenter = function (cx, cy) {
  this.rect.x = cx - this.rect.width / 2;
  this.rect.y = cy - this.rect.height / 2;
};

LNode.prototype.setLocation = function (x, y) {
  this.rect.x = x;
  this.rect.y = y;
};

LNode.prototype.moveBy = function (dx, dy) {
  this.rect.x += dx;
  this.rect.y += dy;
};

LNode.prototype.getEdgeListToNode = function (to) {
  var edgeList = [];
  var edge;
  var self = this;

  self.edges.forEach(function (edge) {

    if (edge.target == to) {
      if (edge.source != self) throw "Incorrect edge source!";

      edgeList.push(edge);
    }
  });

  return edgeList;
};

LNode.prototype.getEdgesBetween = function (other) {
  var edgeList = [];
  var edge;

  var self = this;
  self.edges.forEach(function (edge) {

    if (!(edge.source == self || edge.target == self)) throw "Incorrect edge source and/or target";

    if (edge.target == other || edge.source == other) {
      edgeList.push(edge);
    }
  });

  return edgeList;
};

LNode.prototype.getNeighborsList = function () {
  var neighbors = new Set();

  var self = this;
  self.edges.forEach(function (edge) {

    if (edge.source == self) {
      neighbors.add(edge.target);
    } else {
      if (edge.target != self) {
        throw "Incorrect incidency!";
      }

      neighbors.add(edge.source);
    }
  });

  return neighbors;
};

LNode.prototype.withChildren = function () {
  var withNeighborsList = new Set();
  var childNode;
  var children;

  withNeighborsList.add(this);

  if (this.child != null) {
    var nodes = this.child.getNodes();
    for (var i = 0; i < nodes.length; i++) {
      childNode = nodes[i];
      children = childNode.withChildren();
      children.forEach(function (node) {
        withNeighborsList.add(node);
      });
    }
  }

  return withNeighborsList;
};

LNode.prototype.getNoOfChildren = function () {
  var noOfChildren = 0;
  var childNode;

  if (this.child == null) {
    noOfChildren = 1;
  } else {
    var nodes = this.child.getNodes();
    for (var i = 0; i < nodes.length; i++) {
      childNode = nodes[i];

      noOfChildren += childNode.getNoOfChildren();
    }
  }

  if (noOfChildren == 0) {
    noOfChildren = 1;
  }
  return noOfChildren;
};

LNode.prototype.getEstimatedSize = function () {
  if (this.estimatedSize == Integer.MIN_VALUE) {
    throw "assert failed";
  }
  return this.estimatedSize;
};

LNode.prototype.calcEstimatedSize = function () {
  if (this.child == null) {
    return this.estimatedSize = (this.rect.width + this.rect.height) / 2;
  } else {
    this.estimatedSize = this.child.calcEstimatedSize();
    this.rect.width = this.estimatedSize;
    this.rect.height = this.estimatedSize;

    return this.estimatedSize;
  }
};

LNode.prototype.scatter = function () {
  var randomCenterX;
  var randomCenterY;

  var minX = -LayoutConstants.INITIAL_WORLD_BOUNDARY;
  var maxX = LayoutConstants.INITIAL_WORLD_BOUNDARY;
  randomCenterX = LayoutConstants.WORLD_CENTER_X + RandomSeed.nextDouble() * (maxX - minX) + minX;

  var minY = -LayoutConstants.INITIAL_WORLD_BOUNDARY;
  var maxY = LayoutConstants.INITIAL_WORLD_BOUNDARY;
  randomCenterY = LayoutConstants.WORLD_CENTER_Y + RandomSeed.nextDouble() * (maxY - minY) + minY;

  this.rect.x = randomCenterX;
  this.rect.y = randomCenterY;
};

LNode.prototype.updateBounds = function () {
  if (this.getChild() == null) {
    throw "assert failed";
  }
  if (this.getChild().getNodes().length != 0) {
    // wrap the children nodes by re-arranging the boundaries
    var childGraph = this.getChild();
    childGraph.updateBounds(true);

    this.rect.x = childGraph.getLeft();
    this.rect.y = childGraph.getTop();

    this.setWidth(childGraph.getRight() - childGraph.getLeft());
    this.setHeight(childGraph.getBottom() - childGraph.getTop());

    // Update compound bounds considering its label properties    
    if (LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS) {

      var width = childGraph.getRight() - childGraph.getLeft();
      var height = childGraph.getBottom() - childGraph.getTop();

      if (this.labelWidth > width) {
        this.rect.x -= (this.labelWidth - width) / 2;
        this.setWidth(this.labelWidth);
      }

      if (this.labelHeight > height) {
        if (this.labelPos == "center") {
          this.rect.y -= (this.labelHeight - height) / 2;
        } else if (this.labelPos == "top") {
          this.rect.y -= this.labelHeight - height;
        }
        this.setHeight(this.labelHeight);
      }
    }
  }
};

LNode.prototype.getInclusionTreeDepth = function () {
  if (this.inclusionTreeDepth == Integer.MAX_VALUE) {
    throw "assert failed";
  }
  return this.inclusionTreeDepth;
};

LNode.prototype.transform = function (trans) {
  var left = this.rect.x;

  if (left > LayoutConstants.WORLD_BOUNDARY) {
    left = LayoutConstants.WORLD_BOUNDARY;
  } else if (left < -LayoutConstants.WORLD_BOUNDARY) {
    left = -LayoutConstants.WORLD_BOUNDARY;
  }

  var top = this.rect.y;

  if (top > LayoutConstants.WORLD_BOUNDARY) {
    top = LayoutConstants.WORLD_BOUNDARY;
  } else if (top < -LayoutConstants.WORLD_BOUNDARY) {
    top = -LayoutConstants.WORLD_BOUNDARY;
  }

  var leftTop = new PointD(left, top);
  var vLeftTop = trans.inverseTransformPoint(leftTop);

  this.setLocation(vLeftTop.x, vLeftTop.y);
};

LNode.prototype.getLeft = function () {
  return this.rect.x;
};

LNode.prototype.getRight = function () {
  return this.rect.x + this.rect.width;
};

LNode.prototype.getTop = function () {
  return this.rect.y;
};

LNode.prototype.getBottom = function () {
  return this.rect.y + this.rect.height;
};

LNode.prototype.getParent = function () {
  if (this.owner == null) {
    return null;
  }

  return this.owner.getParent();
};

module.exports = LNode;

/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function PointD(x, y) {
  if (x == null && y == null) {
    this.x = 0;
    this.y = 0;
  } else {
    this.x = x;
    this.y = y;
  }
}

PointD.prototype.getX = function () {
  return this.x;
};

PointD.prototype.getY = function () {
  return this.y;
};

PointD.prototype.setX = function (x) {
  this.x = x;
};

PointD.prototype.setY = function (y) {
  this.y = y;
};

PointD.prototype.getDifference = function (pt) {
  return new DimensionD(this.x - pt.x, this.y - pt.y);
};

PointD.prototype.getCopy = function () {
  return new PointD(this.x, this.y);
};

PointD.prototype.translate = function (dim) {
  this.x += dim.width;
  this.y += dim.height;
  return this;
};

module.exports = PointD;

/***/ }),
/* 5 */
/***/ (function(module, exports, __nested_webpack_require_17549__) {

"use strict";


var LGraphObject = __nested_webpack_require_17549__(2);
var Integer = __nested_webpack_require_17549__(10);
var LayoutConstants = __nested_webpack_require_17549__(0);
var LGraphManager = __nested_webpack_require_17549__(6);
var LNode = __nested_webpack_require_17549__(3);
var LEdge = __nested_webpack_require_17549__(1);
var RectangleD = __nested_webpack_require_17549__(13);
var Point = __nested_webpack_require_17549__(12);
var LinkedList = __nested_webpack_require_17549__(11);

function LGraph(parent, obj2, vGraph) {
  LGraphObject.call(this, vGraph);
  this.estimatedSize = Integer.MIN_VALUE;
  this.margin = LayoutConstants.DEFAULT_GRAPH_MARGIN;
  this.edges = [];
  this.nodes = [];
  this.isConnected = false;
  this.parent = parent;

  if (obj2 != null && obj2 instanceof LGraphManager) {
    this.graphManager = obj2;
  } else if (obj2 != null && obj2 instanceof Layout) {
    this.graphManager = obj2.graphManager;
  }
}

LGraph.prototype = Object.create(LGraphObject.prototype);
for (var prop in LGraphObject) {
  LGraph[prop] = LGraphObject[prop];
}

LGraph.prototype.getNodes = function () {
  return this.nodes;
};

LGraph.prototype.getEdges = function () {
  return this.edges;
};

LGraph.prototype.getGraphManager = function () {
  return this.graphManager;
};

LGraph.prototype.getParent = function () {
  return this.parent;
};

LGraph.prototype.getLeft = function () {
  return this.left;
};

LGraph.prototype.getRight = function () {
  return this.right;
};

LGraph.prototype.getTop = function () {
  return this.top;
};

LGraph.prototype.getBottom = function () {
  return this.bottom;
};

LGraph.prototype.isConnected = function () {
  return this.isConnected;
};

LGraph.prototype.add = function (obj1, sourceNode, targetNode) {
  if (sourceNode == null && targetNode == null) {
    var newNode = obj1;
    if (this.graphManager == null) {
      throw "Graph has no graph mgr!";
    }
    if (this.getNodes().indexOf(newNode) > -1) {
      throw "Node already in graph!";
    }
    newNode.owner = this;
    this.getNodes().push(newNode);

    return newNode;
  } else {
    var newEdge = obj1;
    if (!(this.getNodes().indexOf(sourceNode) > -1 && this.getNodes().indexOf(targetNode) > -1)) {
      throw "Source or target not in graph!";
    }

    if (!(sourceNode.owner == targetNode.owner && sourceNode.owner == this)) {
      throw "Both owners must be this graph!";
    }

    if (sourceNode.owner != targetNode.owner) {
      return null;
    }

    // set source and target
    newEdge.source = sourceNode;
    newEdge.target = targetNode;

    // set as intra-graph edge
    newEdge.isInterGraph = false;

    // add to graph edge list
    this.getEdges().push(newEdge);

    // add to incidency lists
    sourceNode.edges.push(newEdge);

    if (targetNode != sourceNode) {
      targetNode.edges.push(newEdge);
    }

    return newEdge;
  }
};

LGraph.prototype.remove = function (obj) {
  var node = obj;
  if (obj instanceof LNode) {
    if (node == null) {
      throw "Node is null!";
    }
    if (!(node.owner != null && node.owner == this)) {
      throw "Owner graph is invalid!";
    }
    if (this.graphManager == null) {
      throw "Owner graph manager is invalid!";
    }
    // remove incident edges first (make a copy to do it safely)
    var edgesToBeRemoved = node.edges.slice();
    var edge;
    var s = edgesToBeRemoved.length;
    for (var i = 0; i < s; i++) {
      edge = edgesToBeRemoved[i];

      if (edge.isInterGraph) {
        this.graphManager.remove(edge);
      } else {
        edge.source.owner.remove(edge);
      }
    }

    // now the node itself
    var index = this.nodes.indexOf(node);
    if (index == -1) {
      throw "Node not in owner node list!";
    }

    this.nodes.splice(index, 1);
  } else if (obj instanceof LEdge) {
    var edge = obj;
    if (edge == null) {
      throw "Edge is null!";
    }
    if (!(edge.source != null && edge.target != null)) {
      throw "Source and/or target is null!";
    }
    if (!(edge.source.owner != null && edge.target.owner != null && edge.source.owner == this && edge.target.owner == this)) {
      throw "Source and/or target owner is invalid!";
    }

    var sourceIndex = edge.source.edges.indexOf(edge);
    var targetIndex = edge.target.edges.indexOf(edge);
    if (!(sourceIndex > -1 && targetIndex > -1)) {
      throw "Source and/or target doesn't know this edge!";
    }

    edge.source.edges.splice(sourceIndex, 1);

    if (edge.target != edge.source) {
      edge.target.edges.splice(targetIndex, 1);
    }

    var index = edge.source.owner.getEdges().indexOf(edge);
    if (index == -1) {
      throw "Not in owner's edge list!";
    }

    edge.source.owner.getEdges().splice(index, 1);
  }
};

LGraph.prototype.updateLeftTop = function () {
  var top = Integer.MAX_VALUE;
  var left = Integer.MAX_VALUE;
  var nodeTop;
  var nodeLeft;
  var margin;

  var nodes = this.getNodes();
  var s = nodes.length;

  for (var i = 0; i < s; i++) {
    var lNode = nodes[i];
    nodeTop = lNode.getTop();
    nodeLeft = lNode.getLeft();

    if (top > nodeTop) {
      top = nodeTop;
    }

    if (left > nodeLeft) {
      left = nodeLeft;
    }
  }

  // Do we have any nodes in this graph?
  if (top == Integer.MAX_VALUE) {
    return null;
  }

  if (nodes[0].getParent().paddingLeft != undefined) {
    margin = nodes[0].getParent().paddingLeft;
  } else {
    margin = this.margin;
  }

  this.left = left - margin;
  this.top = top - margin;

  // Apply the margins and return the result
  return new Point(this.left, this.top);
};

LGraph.prototype.updateBounds = function (recursive) {
  // calculate bounds
  var left = Integer.MAX_VALUE;
  var right = -Integer.MAX_VALUE;
  var top = Integer.MAX_VALUE;
  var bottom = -Integer.MAX_VALUE;
  var nodeLeft;
  var nodeRight;
  var nodeTop;
  var nodeBottom;
  var margin;

  var nodes = this.nodes;
  var s = nodes.length;
  for (var i = 0; i < s; i++) {
    var lNode = nodes[i];

    if (recursive && lNode.child != null) {
      lNode.updateBounds();
    }
    nodeLeft = lNode.getLeft();
    nodeRight = lNode.getRight();
    nodeTop = lNode.getTop();
    nodeBottom = lNode.getBottom();

    if (left > nodeLeft) {
      left = nodeLeft;
    }

    if (right < nodeRight) {
      right = nodeRight;
    }

    if (top > nodeTop) {
      top = nodeTop;
    }

    if (bottom < nodeBottom) {
      bottom = nodeBottom;
    }
  }

  var boundingRect = new RectangleD(left, top, right - left, bottom - top);
  if (left == Integer.MAX_VALUE) {
    this.left = this.parent.getLeft();
    this.right = this.parent.getRight();
    this.top = this.parent.getTop();
    this.bottom = this.parent.getBottom();
  }

  if (nodes[0].getParent().paddingLeft != undefined) {
    margin = nodes[0].getParent().paddingLeft;
  } else {
    margin = this.margin;
  }

  this.left = boundingRect.x - margin;
  this.right = boundingRect.x + boundingRect.width + margin;
  this.top = boundingRect.y - margin;
  this.bottom = boundingRect.y + boundingRect.height + margin;
};

LGraph.calculateBounds = function (nodes) {
  var left = Integer.MAX_VALUE;
  var right = -Integer.MAX_VALUE;
  var top = Integer.MAX_VALUE;
  var bottom = -Integer.MAX_VALUE;
  var nodeLeft;
  var nodeRight;
  var nodeTop;
  var nodeBottom;

  var s = nodes.length;

  for (var i = 0; i < s; i++) {
    var lNode = nodes[i];
    nodeLeft = lNode.getLeft();
    nodeRight = lNode.getRight();
    nodeTop = lNode.getTop();
    nodeBottom = lNode.getBottom();

    if (left > nodeLeft) {
      left = nodeLeft;
    }

    if (right < nodeRight) {
      right = nodeRight;
    }

    if (top > nodeTop) {
      top = nodeTop;
    }

    if (bottom < nodeBottom) {
      bottom = nodeBottom;
    }
  }

  var boundingRect = new RectangleD(left, top, right - left, bottom - top);

  return boundingRect;
};

LGraph.prototype.getInclusionTreeDepth = function () {
  if (this == this.graphManager.getRoot()) {
    return 1;
  } else {
    return this.parent.getInclusionTreeDepth();
  }
};

LGraph.prototype.getEstimatedSize = function () {
  if (this.estimatedSize == Integer.MIN_VALUE) {
    throw "assert failed";
  }
  return this.estimatedSize;
};

LGraph.prototype.calcEstimatedSize = function () {
  var size = 0;
  var nodes = this.nodes;
  var s = nodes.length;

  for (var i = 0; i < s; i++) {
    var lNode = nodes[i];
    size += lNode.calcEstimatedSize();
  }

  if (size == 0) {
    this.estimatedSize = LayoutConstants.EMPTY_COMPOUND_NODE_SIZE;
  } else {
    this.estimatedSize = size / Math.sqrt(this.nodes.length);
  }

  return this.estimatedSize;
};

LGraph.prototype.updateConnected = function () {
  var self = this;
  if (this.nodes.length == 0) {
    this.isConnected = true;
    return;
  }

  var queue = new LinkedList();
  var visited = new Set();
  var currentNode = this.nodes[0];
  var neighborEdges;
  var currentNeighbor;
  var childrenOfNode = currentNode.withChildren();
  childrenOfNode.forEach(function (node) {
    queue.push(node);
    visited.add(node);
  });

  while (queue.length !== 0) {
    currentNode = queue.shift();

    // Traverse all neighbors of this node
    neighborEdges = currentNode.getEdges();
    var size = neighborEdges.length;
    for (var i = 0; i < size; i++) {
      var neighborEdge = neighborEdges[i];
      currentNeighbor = neighborEdge.getOtherEndInGraph(currentNode, this);

      // Add unvisited neighbors to the list to visit
      if (currentNeighbor != null && !visited.has(currentNeighbor)) {
        var childrenOfNeighbor = currentNeighbor.withChildren();

        childrenOfNeighbor.forEach(function (node) {
          queue.push(node);
          visited.add(node);
        });
      }
    }
  }

  this.isConnected = false;

  if (visited.size >= this.nodes.length) {
    var noOfVisitedInThisGraph = 0;

    visited.forEach(function (visitedNode) {
      if (visitedNode.owner == self) {
        noOfVisitedInThisGraph++;
      }
    });

    if (noOfVisitedInThisGraph == this.nodes.length) {
      this.isConnected = true;
    }
  }
};

module.exports = LGraph;

/***/ }),
/* 6 */
/***/ (function(module, exports, __nested_webpack_require_27617__) {

"use strict";


var LGraph;
var LEdge = __nested_webpack_require_27617__(1);

function LGraphManager(layout) {
  LGraph = __nested_webpack_require_27617__(5); // It may be better to initilize this out of this function but it gives an error (Right-hand side of 'instanceof' is not callable) now.
  this.layout = layout;

  this.graphs = [];
  this.edges = [];
}

LGraphManager.prototype.addRoot = function () {
  var ngraph = this.layout.newGraph();
  var nnode = this.layout.newNode(null);
  var root = this.add(ngraph, nnode);
  this.setRootGraph(root);
  return this.rootGraph;
};

LGraphManager.prototype.add = function (newGraph, parentNode, newEdge, sourceNode, targetNode) {
  //there are just 2 parameters are passed then it adds an LGraph else it adds an LEdge
  if (newEdge == null && sourceNode == null && targetNode == null) {
    if (newGraph == null) {
      throw "Graph is null!";
    }
    if (parentNode == null) {
      throw "Parent node is null!";
    }
    if (this.graphs.indexOf(newGraph) > -1) {
      throw "Graph already in this graph mgr!";
    }

    this.graphs.push(newGraph);

    if (newGraph.parent != null) {
      throw "Already has a parent!";
    }
    if (parentNode.child != null) {
      throw "Already has a child!";
    }

    newGraph.parent = parentNode;
    parentNode.child = newGraph;

    return newGraph;
  } else {
    //change the order of the parameters
    targetNode = newEdge;
    sourceNode = parentNode;
    newEdge = newGraph;
    var sourceGraph = sourceNode.getOwner();
    var targetGraph = targetNode.getOwner();

    if (!(sourceGraph != null && sourceGraph.getGraphManager() == this)) {
      throw "Source not in this graph mgr!";
    }
    if (!(targetGraph != null && targetGraph.getGraphManager() == this)) {
      throw "Target not in this graph mgr!";
    }

    if (sourceGraph == targetGraph) {
      newEdge.isInterGraph = false;
      return sourceGraph.add(newEdge, sourceNode, targetNode);
    } else {
      newEdge.isInterGraph = true;

      // set source and target
      newEdge.source = sourceNode;
      newEdge.target = targetNode;

      // add edge to inter-graph edge list
      if (this.edges.indexOf(newEdge) > -1) {
        throw "Edge already in inter-graph edge list!";
      }

      this.edges.push(newEdge);

      // add edge to source and target incidency lists
      if (!(newEdge.source != null && newEdge.target != null)) {
        throw "Edge source and/or target is null!";
      }

      if (!(newEdge.source.edges.indexOf(newEdge) == -1 && newEdge.target.edges.indexOf(newEdge) == -1)) {
        throw "Edge already in source and/or target incidency list!";
      }

      newEdge.source.edges.push(newEdge);
      newEdge.target.edges.push(newEdge);

      return newEdge;
    }
  }
};

LGraphManager.prototype.remove = function (lObj) {
  if (lObj instanceof LGraph) {
    var graph = lObj;
    if (graph.getGraphManager() != this) {
      throw "Graph not in this graph mgr";
    }
    if (!(graph == this.rootGraph || graph.parent != null && graph.parent.graphManager == this)) {
      throw "Invalid parent node!";
    }

    // first the edges (make a copy to do it safely)
    var edgesToBeRemoved = [];

    edgesToBeRemoved = edgesToBeRemoved.concat(graph.getEdges());

    var edge;
    var s = edgesToBeRemoved.length;
    for (var i = 0; i < s; i++) {
      edge = edgesToBeRemoved[i];
      graph.remove(edge);
    }

    // then the nodes (make a copy to do it safely)
    var nodesToBeRemoved = [];

    nodesToBeRemoved = nodesToBeRemoved.concat(graph.getNodes());

    var node;
    s = nodesToBeRemoved.length;
    for (var i = 0; i < s; i++) {
      node = nodesToBeRemoved[i];
      graph.remove(node);
    }

    // check if graph is the root
    if (graph == this.rootGraph) {
      this.setRootGraph(null);
    }

    // now remove the graph itself
    var index = this.graphs.indexOf(graph);
    this.graphs.splice(index, 1);

    // also reset the parent of the graph
    graph.parent = null;
  } else if (lObj instanceof LEdge) {
    edge = lObj;
    if (edge == null) {
      throw "Edge is null!";
    }
    if (!edge.isInterGraph) {
      throw "Not an inter-graph edge!";
    }
    if (!(edge.source != null && edge.target != null)) {
      throw "Source and/or target is null!";
    }

    // remove edge from source and target nodes' incidency lists

    if (!(edge.source.edges.indexOf(edge) != -1 && edge.target.edges.indexOf(edge) != -1)) {
      throw "Source and/or target doesn't know this edge!";
    }

    var index = edge.source.edges.indexOf(edge);
    edge.source.edges.splice(index, 1);
    index = edge.target.edges.indexOf(edge);
    edge.target.edges.splice(index, 1);

    // remove edge from owner graph manager's inter-graph edge list

    if (!(edge.source.owner != null && edge.source.owner.getGraphManager() != null)) {
      throw "Edge owner graph or owner graph manager is null!";
    }
    if (edge.source.owner.getGraphManager().edges.indexOf(edge) == -1) {
      throw "Not in owner graph manager's edge list!";
    }

    var index = edge.source.owner.getGraphManager().edges.indexOf(edge);
    edge.source.owner.getGraphManager().edges.splice(index, 1);
  }
};

LGraphManager.prototype.updateBounds = function () {
  this.rootGraph.updateBounds(true);
};

LGraphManager.prototype.getGraphs = function () {
  return this.graphs;
};

LGraphManager.prototype.getAllNodes = function () {
  if (this.allNodes == null) {
    var nodeList = [];
    var graphs = this.getGraphs();
    var s = graphs.length;
    for (var i = 0; i < s; i++) {
      nodeList = nodeList.concat(graphs[i].getNodes());
    }
    this.allNodes = nodeList;
  }
  return this.allNodes;
};

LGraphManager.prototype.resetAllNodes = function () {
  this.allNodes = null;
};

LGraphManager.prototype.resetAllEdges = function () {
  this.allEdges = null;
};

LGraphManager.prototype.resetAllNodesToApplyGravitation = function () {
  this.allNodesToApplyGravitation = null;
};

LGraphManager.prototype.getAllEdges = function () {
  if (this.allEdges == null) {
    var edgeList = [];
    var graphs = this.getGraphs();
    var s = graphs.length;
    for (var i = 0; i < graphs.length; i++) {
      edgeList = edgeList.concat(graphs[i].getEdges());
    }

    edgeList = edgeList.concat(this.edges);

    this.allEdges = edgeList;
  }
  return this.allEdges;
};

LGraphManager.prototype.getAllNodesToApplyGravitation = function () {
  return this.allNodesToApplyGravitation;
};

LGraphManager.prototype.setAllNodesToApplyGravitation = function (nodeList) {
  if (this.allNodesToApplyGravitation != null) {
    throw "assert failed";
  }

  this.allNodesToApplyGravitation = nodeList;
};

LGraphManager.prototype.getRoot = function () {
  return this.rootGraph;
};

LGraphManager.prototype.setRootGraph = function (graph) {
  if (graph.getGraphManager() != this) {
    throw "Root not in this graph mgr!";
  }

  this.rootGraph = graph;
  // root graph must have a root node associated with it for convenience
  if (graph.parent == null) {
    graph.parent = this.layout.newNode("Root node");
  }
};

LGraphManager.prototype.getLayout = function () {
  return this.layout;
};

LGraphManager.prototype.isOneAncestorOfOther = function (firstNode, secondNode) {
  if (!(firstNode != null && secondNode != null)) {
    throw "assert failed";
  }

  if (firstNode == secondNode) {
    return true;
  }
  // Is second node an ancestor of the first one?
  var ownerGraph = firstNode.getOwner();
  var parentNode;

  do {
    parentNode = ownerGraph.getParent();

    if (parentNode == null) {
      break;
    }

    if (parentNode == secondNode) {
      return true;
    }

    ownerGraph = parentNode.getOwner();
    if (ownerGraph == null) {
      break;
    }
  } while (true);
  // Is first node an ancestor of the second one?
  ownerGraph = secondNode.getOwner();

  do {
    parentNode = ownerGraph.getParent();

    if (parentNode == null) {
      break;
    }

    if (parentNode == firstNode) {
      return true;
    }

    ownerGraph = parentNode.getOwner();
    if (ownerGraph == null) {
      break;
    }
  } while (true);

  return false;
};

LGraphManager.prototype.calcLowestCommonAncestors = function () {
  var edge;
  var sourceNode;
  var targetNode;
  var sourceAncestorGraph;
  var targetAncestorGraph;

  var edges = this.getAllEdges();
  var s = edges.length;
  for (var i = 0; i < s; i++) {
    edge = edges[i];

    sourceNode = edge.source;
    targetNode = edge.target;
    edge.lca = null;
    edge.sourceInLca = sourceNode;
    edge.targetInLca = targetNode;

    if (sourceNode == targetNode) {
      edge.lca = sourceNode.getOwner();
      continue;
    }

    sourceAncestorGraph = sourceNode.getOwner();

    while (edge.lca == null) {
      edge.targetInLca = targetNode;
      targetAncestorGraph = targetNode.getOwner();

      while (edge.lca == null) {
        if (targetAncestorGraph == sourceAncestorGraph) {
          edge.lca = targetAncestorGraph;
          break;
        }

        if (targetAncestorGraph == this.rootGraph) {
          break;
        }

        if (edge.lca != null) {
          throw "assert failed";
        }
        edge.targetInLca = targetAncestorGraph.getParent();
        targetAncestorGraph = edge.targetInLca.getOwner();
      }

      if (sourceAncestorGraph == this.rootGraph) {
        break;
      }

      if (edge.lca == null) {
        edge.sourceInLca = sourceAncestorGraph.getParent();
        sourceAncestorGraph = edge.sourceInLca.getOwner();
      }
    }

    if (edge.lca == null) {
      throw "assert failed";
    }
  }
};

LGraphManager.prototype.calcLowestCommonAncestor = function (firstNode, secondNode) {
  if (firstNode == secondNode) {
    return firstNode.getOwner();
  }
  var firstOwnerGraph = firstNode.getOwner();

  do {
    if (firstOwnerGraph == null) {
      break;
    }
    var secondOwnerGraph = secondNode.getOwner();

    do {
      if (secondOwnerGraph == null) {
        break;
      }

      if (secondOwnerGraph == firstOwnerGraph) {
        return secondOwnerGraph;
      }
      secondOwnerGraph = secondOwnerGraph.getParent().getOwner();
    } while (true);

    firstOwnerGraph = firstOwnerGraph.getParent().getOwner();
  } while (true);

  return firstOwnerGraph;
};

LGraphManager.prototype.calcInclusionTreeDepths = function (graph, depth) {
  if (graph == null && depth == null) {
    graph = this.rootGraph;
    depth = 1;
  }
  var node;

  var nodes = graph.getNodes();
  var s = nodes.length;
  for (var i = 0; i < s; i++) {
    node = nodes[i];
    node.inclusionTreeDepth = depth;

    if (node.child != null) {
      this.calcInclusionTreeDepths(node.child, depth + 1);
    }
  }
};

LGraphManager.prototype.includesInvalidEdge = function () {
  var edge;

  var s = this.edges.length;
  for (var i = 0; i < s; i++) {
    edge = this.edges[i];

    if (this.isOneAncestorOfOther(edge.source, edge.target)) {
      return true;
    }
  }
  return false;
};

module.exports = LGraphManager;

/***/ }),
/* 7 */
/***/ (function(module, exports, __nested_webpack_require_38707__) {

"use strict";


var LayoutConstants = __nested_webpack_require_38707__(0);

function FDLayoutConstants() {}

//FDLayoutConstants inherits static props in LayoutConstants
for (var prop in LayoutConstants) {
  FDLayoutConstants[prop] = LayoutConstants[prop];
}

FDLayoutConstants.MAX_ITERATIONS = 2500;

FDLayoutConstants.DEFAULT_EDGE_LENGTH = 50;
FDLayoutConstants.DEFAULT_SPRING_STRENGTH = 0.45;
FDLayoutConstants.DEFAULT_REPULSION_STRENGTH = 4500.0;
FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH = 0.4;
FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = 1.0;
FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR = 3.8;
FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = 1.5;
FDLayoutConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION = true;
FDLayoutConstants.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION = true;
FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = 0.3;
FDLayoutConstants.COOLING_ADAPTATION_FACTOR = 0.33;
FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT = 1000;
FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT = 5000;
FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL = 100.0;
FDLayoutConstants.MAX_NODE_DISPLACEMENT = FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL * 3;
FDLayoutConstants.MIN_REPULSION_DIST = FDLayoutConstants.DEFAULT_EDGE_LENGTH / 10.0;
FDLayoutConstants.CONVERGENCE_CHECK_PERIOD = 100;
FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = 0.1;
FDLayoutConstants.MIN_EDGE_LENGTH = 1;
FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD = 10;

module.exports = FDLayoutConstants;

/***/ }),
/* 8 */
/***/ (function(module, exports, __nested_webpack_require_40298__) {

"use strict";


/**
 * This class maintains a list of static geometry related utility methods.
 *
 *
 * Copyright: i-Vis Research Group, Bilkent University, 2007 - present
 */

var Point = __nested_webpack_require_40298__(12);

function IGeometry() {}

/**
 * This method calculates *half* the amount in x and y directions of the two
 * input rectangles needed to separate them keeping their respective
 * positioning, and returns the result in the input array. An input
 * separation buffer added to the amount in both directions. We assume that
 * the two rectangles do intersect.
 */
IGeometry.calcSeparationAmount = function (rectA, rectB, overlapAmount, separationBuffer) {
  if (!rectA.intersects(rectB)) {
    throw "assert failed";
  }

  var directions = new Array(2);

  this.decideDirectionsForOverlappingNodes(rectA, rectB, directions);

  overlapAmount[0] = Math.min(rectA.getRight(), rectB.getRight()) - Math.max(rectA.x, rectB.x);
  overlapAmount[1] = Math.min(rectA.getBottom(), rectB.getBottom()) - Math.max(rectA.y, rectB.y);

  // update the overlapping amounts for the following cases:
  if (rectA.getX() <= rectB.getX() && rectA.getRight() >= rectB.getRight()) {
    /* Case x.1:
    *
    * rectA
    * 	|                       |
    * 	|        _________      |
    * 	|        |       |      |
    * 	|________|_______|______|
    * 			 |       |
    *           |       |
    *        rectB
    */
    overlapAmount[0] += Math.min(rectB.getX() - rectA.getX(), rectA.getRight() - rectB.getRight());
  } else if (rectB.getX() <= rectA.getX() && rectB.getRight() >= rectA.getRight()) {
    /* Case x.2:
    *
    * rectB
    * 	|                       |
    * 	|        _________      |
    * 	|        |       |      |
    * 	|________|_______|______|
    * 			 |       |
    *           |       |
    *        rectA
    */
    overlapAmount[0] += Math.min(rectA.getX() - rectB.getX(), rectB.getRight() - rectA.getRight());
  }
  if (rectA.getY() <= rectB.getY() && rectA.getBottom() >= rectB.getBottom()) {
    /* Case y.1:
     *          ________ rectA
     *         |
     *         |
     *   ______|____  rectB
     *         |    |
     *         |    |
     *   ______|____|
     *         |
     *         |
     *         |________
     *
     */
    overlapAmount[1] += Math.min(rectB.getY() - rectA.getY(), rectA.getBottom() - rectB.getBottom());
  } else if (rectB.getY() <= rectA.getY() && rectB.getBottom() >= rectA.getBottom()) {
    /* Case y.2:
    *          ________ rectB
    *         |
    *         |
    *   ______|____  rectA
    *         |    |
    *         |    |
    *   ______|____|
    *         |
    *         |
    *         |________
    *
    */
    overlapAmount[1] += Math.min(rectA.getY() - rectB.getY(), rectB.getBottom() - rectA.getBottom());
  }

  // find slope of the line passes two centers
  var slope = Math.abs((rectB.getCenterY() - rectA.getCenterY()) / (rectB.getCenterX() - rectA.getCenterX()));
  // if centers are overlapped
  if (rectB.getCenterY() === rectA.getCenterY() && rectB.getCenterX() === rectA.getCenterX()) {
    // assume the slope is 1 (45 degree)
    slope = 1.0;
  }

  var moveByY = slope * overlapAmount[0];
  var moveByX = overlapAmount[1] / slope;
  if (overlapAmount[0] < moveByX) {
    moveByX = overlapAmount[0];
  } else {
    moveByY = overlapAmount[1];
  }
  // return half the amount so that if each rectangle is moved by these
  // amounts in opposite directions, overlap will be resolved
  overlapAmount[0] = -1 * directions[0] * (moveByX / 2 + separationBuffer);
  overlapAmount[1] = -1 * directions[1] * (moveByY / 2 + separationBuffer);
};

/**
 * This method decides the separation direction of overlapping nodes
 *
 * if directions[0] = -1, then rectA goes left
 * if directions[0] = 1,  then rectA goes right
 * if directions[1] = -1, then rectA goes up
 * if directions[1] = 1,  then rectA goes down
 */
IGeometry.decideDirectionsForOverlappingNodes = function (rectA, rectB, directions) {
  if (rectA.getCenterX() < rectB.getCenterX()) {
    directions[0] = -1;
  } else {
    directions[0] = 1;
  }

  if (rectA.getCenterY() < rectB.getCenterY()) {
    directions[1] = -1;
  } else {
    directions[1] = 1;
  }
};

/**
 * This method calculates the intersection (clipping) points of the two
 * input rectangles with line segment defined by the centers of these two
 * rectangles. The clipping points are saved in the input double array and
 * whether or not the two rectangles overlap is returned.
 */
IGeometry.getIntersection2 = function (rectA, rectB, result) {
  //result[0-1] will contain clipPoint of rectA, result[2-3] will contain clipPoint of rectB
  var p1x = rectA.getCenterX();
  var p1y = rectA.getCenterY();
  var p2x = rectB.getCenterX();
  var p2y = rectB.getCenterY();

  //if two rectangles intersect, then clipping points are centers
  if (rectA.intersects(rectB)) {
    result[0] = p1x;
    result[1] = p1y;
    result[2] = p2x;
    result[3] = p2y;
    return true;
  }
  //variables for rectA
  var topLeftAx = rectA.getX();
  var topLeftAy = rectA.getY();
  var topRightAx = rectA.getRight();
  var bottomLeftAx = rectA.getX();
  var bottomLeftAy = rectA.getBottom();
  var bottomRightAx = rectA.getRight();
  var halfWidthA = rectA.getWidthHalf();
  var halfHeightA = rectA.getHeightHalf();
  //variables for rectB
  var topLeftBx = rectB.getX();
  var topLeftBy = rectB.getY();
  var topRightBx = rectB.getRight();
  var bottomLeftBx = rectB.getX();
  var bottomLeftBy = rectB.getBottom();
  var bottomRightBx = rectB.getRight();
  var halfWidthB = rectB.getWidthHalf();
  var halfHeightB = rectB.getHeightHalf();

  //flag whether clipping points are found
  var clipPointAFound = false;
  var clipPointBFound = false;

  // line is vertical
  if (p1x === p2x) {
    if (p1y > p2y) {
      result[0] = p1x;
      result[1] = topLeftAy;
      result[2] = p2x;
      result[3] = bottomLeftBy;
      return false;
    } else if (p1y < p2y) {
      result[0] = p1x;
      result[1] = bottomLeftAy;
      result[2] = p2x;
      result[3] = topLeftBy;
      return false;
    } else {
      //not line, return null;
    }
  }
  // line is horizontal
  else if (p1y === p2y) {
      if (p1x > p2x) {
        result[0] = topLeftAx;
        result[1] = p1y;
        result[2] = topRightBx;
        result[3] = p2y;
        return false;
      } else if (p1x < p2x) {
        result[0] = topRightAx;
        result[1] = p1y;
        result[2] = topLeftBx;
        result[3] = p2y;
        return false;
      } else {
        //not valid line, return null;
      }
    } else {
      //slopes of rectA's and rectB's diagonals
      var slopeA = rectA.height / rectA.width;
      var slopeB = rectB.height / rectB.width;

      //slope of line between center of rectA and center of rectB
      var slopePrime = (p2y - p1y) / (p2x - p1x);
      var cardinalDirectionA = void 0;
      var cardinalDirectionB = void 0;
      var tempPointAx = void 0;
      var tempPointAy = void 0;
      var tempPointBx = void 0;
      var tempPointBy = void 0;

      //determine whether clipping point is the corner of nodeA
      if (-slopeA === slopePrime) {
        if (p1x > p2x) {
          result[0] = bottomLeftAx;
          result[1] = bottomLeftAy;
          clipPointAFound = true;
        } else {
          result[0] = topRightAx;
          result[1] = topLeftAy;
          clipPointAFound = true;
        }
      } else if (slopeA === slopePrime) {
        if (p1x > p2x) {
          result[0] = topLeftAx;
          result[1] = topLeftAy;
          clipPointAFound = true;
        } else {
          result[0] = bottomRightAx;
          result[1] = bottomLeftAy;
          clipPointAFound = true;
        }
      }

      //determine whether clipping point is the corner of nodeB
      if (-slopeB === slopePrime) {
        if (p2x > p1x) {
          result[2] = bottomLeftBx;
          result[3] = bottomLeftBy;
          clipPointBFound = true;
        } else {
          result[2] = topRightBx;
          result[3] = topLeftBy;
          clipPointBFound = true;
        }
      } else if (slopeB === slopePrime) {
        if (p2x > p1x) {
          result[2] = topLeftBx;
          result[3] = topLeftBy;
          clipPointBFound = true;
        } else {
          result[2] = bottomRightBx;
          result[3] = bottomLeftBy;
          clipPointBFound = true;
        }
      }

      //if both clipping points are corners
      if (clipPointAFound && clipPointBFound) {
        return false;
      }

      //determine Cardinal Direction of rectangles
      if (p1x > p2x) {
        if (p1y > p2y) {
          cardinalDirectionA = this.getCardinalDirection(slopeA, slopePrime, 4);
          cardinalDirectionB = this.getCardinalDirection(slopeB, slopePrime, 2);
        } else {
          cardinalDirectionA = this.getCardinalDirection(-slopeA, slopePrime, 3);
          cardinalDirectionB = this.getCardinalDirection(-slopeB, slopePrime, 1);
        }
      } else {
        if (p1y > p2y) {
          cardinalDirectionA = this.getCardinalDirection(-slopeA, slopePrime, 1);
          cardinalDirectionB = this.getCardinalDirection(-slopeB, slopePrime, 3);
        } else {
          cardinalDirectionA = this.getCardinalDirection(slopeA, slopePrime, 2);
          cardinalDirectionB = this.getCardinalDirection(slopeB, slopePrime, 4);
        }
      }
      //calculate clipping Point if it is not found before
      if (!clipPointAFound) {
        switch (cardinalDirectionA) {
          case 1:
            tempPointAy = topLeftAy;
            tempPointAx = p1x + -halfHeightA / slopePrime;
            result[0] = tempPointAx;
            result[1] = tempPointAy;
            break;
          case 2:
            tempPointAx = bottomRightAx;
            tempPointAy = p1y + halfWidthA * slopePrime;
            result[0] = tempPointAx;
            result[1] = tempPointAy;
            break;
          case 3:
            tempPointAy = bottomLeftAy;
            tempPointAx = p1x + halfHeightA / slopePrime;
            result[0] = tempPointAx;
            result[1] = tempPointAy;
            break;
          case 4:
            tempPointAx = bottomLeftAx;
            tempPointAy = p1y + -halfWidthA * slopePrime;
            result[0] = tempPointAx;
            result[1] = tempPointAy;
            break;
        }
      }
      if (!clipPointBFound) {
        switch (cardinalDirectionB) {
          case 1:
            tempPointBy = topLeftBy;
            tempPointBx = p2x + -halfHeightB / slopePrime;
            result[2] = tempPointBx;
            result[3] = tempPointBy;
            break;
          case 2:
            tempPointBx = bottomRightBx;
            tempPointBy = p2y + halfWidthB * slopePrime;
            result[2] = tempPointBx;
            result[3] = tempPointBy;
            break;
          case 3:
            tempPointBy = bottomLeftBy;
            tempPointBx = p2x + halfHeightB / slopePrime;
            result[2] = tempPointBx;
            result[3] = tempPointBy;
            break;
          case 4:
            tempPointBx = bottomLeftBx;
            tempPointBy = p2y + -halfWidthB * slopePrime;
            result[2] = tempPointBx;
            result[3] = tempPointBy;
            break;
        }
      }
    }
  return false;
};

/**
 * This method returns in which cardinal direction does input point stays
 * 1: North
 * 2: East
 * 3: South
 * 4: West
 */
IGeometry.getCardinalDirection = function (slope, slopePrime, line) {
  if (slope > slopePrime) {
    return line;
  } else {
    return 1 + line % 4;
  }
};

/**
 * This method calculates the intersection of the two lines defined by
 * point pairs (s1,s2) and (f1,f2).
 */
IGeometry.getIntersection = function (s1, s2, f1, f2) {
  if (f2 == null) {
    return this.getIntersection2(s1, s2, f1);
  }

  var x1 = s1.x;
  var y1 = s1.y;
  var x2 = s2.x;
  var y2 = s2.y;
  var x3 = f1.x;
  var y3 = f1.y;
  var x4 = f2.x;
  var y4 = f2.y;
  var x = void 0,
      y = void 0; // intersection point
  var a1 = void 0,
      a2 = void 0,
      b1 = void 0,
      b2 = void 0,
      c1 = void 0,
      c2 = void 0; // coefficients of line eqns.
  var denom = void 0;

  a1 = y2 - y1;
  b1 = x1 - x2;
  c1 = x2 * y1 - x1 * y2; // { a1*x + b1*y + c1 = 0 is line 1 }

  a2 = y4 - y3;
  b2 = x3 - x4;
  c2 = x4 * y3 - x3 * y4; // { a2*x + b2*y + c2 = 0 is line 2 }

  denom = a1 * b2 - a2 * b1;

  if (denom === 0) {
    return null;
  }

  x = (b1 * c2 - b2 * c1) / denom;
  y = (a2 * c1 - a1 * c2) / denom;

  return new Point(x, y);
};

/**
 * This method finds and returns the angle of the vector from the + x-axis
 * in clockwise direction (compatible w/ Java coordinate system!).
 */
IGeometry.angleOfVector = function (Cx, Cy, Nx, Ny) {
  var C_angle = void 0;

  if (Cx !== Nx) {
    C_angle = Math.atan((Ny - Cy) / (Nx - Cx));

    if (Nx < Cx) {
      C_angle += Math.PI;
    } else if (Ny < Cy) {
      C_angle += this.TWO_PI;
    }
  } else if (Ny < Cy) {
    C_angle = this.ONE_AND_HALF_PI; // 270 degrees
  } else {
    C_angle = this.HALF_PI; // 90 degrees
  }

  return C_angle;
};

/**
 * This method checks whether the given two line segments (one with point
 * p1 and p2, the other with point p3 and p4) intersect at a point other
 * than these points.
 */
IGeometry.doIntersect = function (p1, p2, p3, p4) {
  var a = p1.x;
  var b = p1.y;
  var c = p2.x;
  var d = p2.y;
  var p = p3.x;
  var q = p3.y;
  var r = p4.x;
  var s = p4.y;
  var det = (c - a) * (s - q) - (r - p) * (d - b);

  if (det === 0) {
    return false;
  } else {
    var lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det;
    var gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det;
    return 0 < lambda && lambda < 1 && 0 < gamma && gamma < 1;
  }
};

// -----------------------------------------------------------------------------
// Section: Class Constants
// -----------------------------------------------------------------------------
/**
 * Some useful pre-calculated constants
 */
IGeometry.HALF_PI = 0.5 * Math.PI;
IGeometry.ONE_AND_HALF_PI = 1.5 * Math.PI;
IGeometry.TWO_PI = 2.0 * Math.PI;
IGeometry.THREE_PI = 3.0 * Math.PI;

module.exports = IGeometry;

/***/ }),
/* 9 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function IMath() {}

/**
 * This method returns the sign of the input value.
 */
IMath.sign = function (value) {
  if (value > 0) {
    return 1;
  } else if (value < 0) {
    return -1;
  } else {
    return 0;
  }
};

IMath.floor = function (value) {
  return value < 0 ? Math.ceil(value) : Math.floor(value);
};

IMath.ceil = function (value) {
  return value < 0 ? Math.floor(value) : Math.ceil(value);
};

module.exports = IMath;

/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function Integer() {}

Integer.MAX_VALUE = 2147483647;
Integer.MIN_VALUE = -2147483648;

module.exports = Integer;

/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var nodeFrom = function nodeFrom(value) {
  return { value: value, next: null, prev: null };
};

var add = function add(prev, node, next, list) {
  if (prev !== null) {
    prev.next = node;
  } else {
    list.head = node;
  }

  if (next !== null) {
    next.prev = node;
  } else {
    list.tail = node;
  }

  node.prev = prev;
  node.next = next;

  list.length++;

  return node;
};

var _remove = function _remove(node, list) {
  var prev = node.prev,
      next = node.next;


  if (prev !== null) {
    prev.next = next;
  } else {
    list.head = next;
  }

  if (next !== null) {
    next.prev = prev;
  } else {
    list.tail = prev;
  }

  node.prev = node.next = null;

  list.length--;

  return node;
};

var LinkedList = function () {
  function LinkedList(vals) {
    var _this = this;

    _classCallCheck(this, LinkedList);

    this.length = 0;
    this.head = null;
    this.tail = null;

    if (vals != null) {
      vals.forEach(function (v) {
        return _this.push(v);
      });
    }
  }

  _createClass(LinkedList, [{
    key: "size",
    value: function size() {
      return this.length;
    }
  }, {
    key: "insertBefore",
    value: function insertBefore(val, otherNode) {
      return add(otherNode.prev, nodeFrom(val), otherNode, this);
    }
  }, {
    key: "insertAfter",
    value: function insertAfter(val, otherNode) {
      return add(otherNode, nodeFrom(val), otherNode.next, this);
    }
  }, {
    key: "insertNodeBefore",
    value: function insertNodeBefore(newNode, otherNode) {
      return add(otherNode.prev, newNode, otherNode, this);
    }
  }, {
    key: "insertNodeAfter",
    value: function insertNodeAfter(newNode, otherNode) {
      return add(otherNode, newNode, otherNode.next, this);
    }
  }, {
    key: "push",
    value: function push(val) {
      return add(this.tail, nodeFrom(val), null, this);
    }
  }, {
    key: "unshift",
    value: function unshift(val) {
      return add(null, nodeFrom(val), this.head, this);
    }
  }, {
    key: "remove",
    value: function remove(node) {
      return _remove(node, this);
    }
  }, {
    key: "pop",
    value: function pop() {
      return _remove(this.tail, this).value;
    }
  }, {
    key: "popNode",
    value: function popNode() {
      return _remove(this.tail, this);
    }
  }, {
    key: "shift",
    value: function shift() {
      return _remove(this.head, this).value;
    }
  }, {
    key: "shiftNode",
    value: function shiftNode() {
      return _remove(this.head, this);
    }
  }, {
    key: "get_object_at",
    value: function get_object_at(index) {
      if (index <= this.length()) {
        var i = 1;
        var current = this.head;
        while (i < index) {
          current = current.next;
          i++;
        }
        return current.value;
      }
    }
  }, {
    key: "set_object_at",
    value: function set_object_at(index, value) {
      if (index <= this.length()) {
        var i = 1;
        var current = this.head;
        while (i < index) {
          current = current.next;
          i++;
        }
        current.value = value;
      }
    }
  }]);

  return LinkedList;
}();

module.exports = LinkedList;

/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


/*
 *This class is the javascript implementation of the Point.java class in jdk
 */
function Point(x, y, p) {
  this.x = null;
  this.y = null;
  if (x == null && y == null && p == null) {
    this.x = 0;
    this.y = 0;
  } else if (typeof x == 'number' && typeof y == 'number' && p == null) {
    this.x = x;
    this.y = y;
  } else if (x.constructor.name == 'Point' && y == null && p == null) {
    p = x;
    this.x = p.x;
    this.y = p.y;
  }
}

Point.prototype.getX = function () {
  return this.x;
};

Point.prototype.getY = function () {
  return this.y;
};

Point.prototype.getLocation = function () {
  return new Point(this.x, this.y);
};

Point.prototype.setLocation = function (x, y, p) {
  if (x.constructor.name == 'Point' && y == null && p == null) {
    p = x;
    this.setLocation(p.x, p.y);
  } else if (typeof x == 'number' && typeof y == 'number' && p == null) {
    //if both parameters are integer just move (x,y) location
    if (parseInt(x) == x && parseInt(y) == y) {
      this.move(x, y);
    } else {
      this.x = Math.floor(x + 0.5);
      this.y = Math.floor(y + 0.5);
    }
  }
};

Point.prototype.move = function (x, y) {
  this.x = x;
  this.y = y;
};

Point.prototype.translate = function (dx, dy) {
  this.x += dx;
  this.y += dy;
};

Point.prototype.equals = function (obj) {
  if (obj.constructor.name == "Point") {
    var pt = obj;
    return this.x == pt.x && this.y == pt.y;
  }
  return this == obj;
};

Point.prototype.toString = function () {
  return new Point().constructor.name + "[x=" + this.x + ",y=" + this.y + "]";
};

module.exports = Point;

/***/ }),
/* 13 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function RectangleD(x, y, width, height) {
  this.x = 0;
  this.y = 0;
  this.width = 0;
  this.height = 0;

  if (x != null && y != null && width != null && height != null) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
  }
}

RectangleD.prototype.getX = function () {
  return this.x;
};

RectangleD.prototype.setX = function (x) {
  this.x = x;
};

RectangleD.prototype.getY = function () {
  return this.y;
};

RectangleD.prototype.setY = function (y) {
  this.y = y;
};

RectangleD.prototype.getWidth = function () {
  return this.width;
};

RectangleD.prototype.setWidth = function (width) {
  this.width = width;
};

RectangleD.prototype.getHeight = function () {
  return this.height;
};

RectangleD.prototype.setHeight = function (height) {
  this.height = height;
};

RectangleD.prototype.getRight = function () {
  return this.x + this.width;
};

RectangleD.prototype.getBottom = function () {
  return this.y + this.height;
};

RectangleD.prototype.intersects = function (a) {
  if (this.getRight() < a.x) {
    return false;
  }

  if (this.getBottom() < a.y) {
    return false;
  }

  if (a.getRight() < this.x) {
    return false;
  }

  if (a.getBottom() < this.y) {
    return false;
  }

  return true;
};

RectangleD.prototype.getCenterX = function () {
  return this.x + this.width / 2;
};

RectangleD.prototype.getMinX = function () {
  return this.getX();
};

RectangleD.prototype.getMaxX = function () {
  return this.getX() + this.width;
};

RectangleD.prototype.getCenterY = function () {
  return this.y + this.height / 2;
};

RectangleD.prototype.getMinY = function () {
  return this.getY();
};

RectangleD.prototype.getMaxY = function () {
  return this.getY() + this.height;
};

RectangleD.prototype.getWidthHalf = function () {
  return this.width / 2;
};

RectangleD.prototype.getHeightHalf = function () {
  return this.height / 2;
};

module.exports = RectangleD;

/***/ }),
/* 14 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

function UniqueIDGeneretor() {}

UniqueIDGeneretor.lastID = 0;

UniqueIDGeneretor.createID = function (obj) {
  if (UniqueIDGeneretor.isPrimitive(obj)) {
    return obj;
  }
  if (obj.uniqueID != null) {
    return obj.uniqueID;
  }
  obj.uniqueID = UniqueIDGeneretor.getString();
  UniqueIDGeneretor.lastID++;
  return obj.uniqueID;
};

UniqueIDGeneretor.getString = function (id) {
  if (id == null) id = UniqueIDGeneretor.lastID;
  return "Object#" + id + "";
};

UniqueIDGeneretor.isPrimitive = function (arg) {
  var type = typeof arg === "undefined" ? "undefined" : _typeof(arg);
  return arg == null || type != "object" && type != "function";
};

module.exports = UniqueIDGeneretor;

/***/ }),
/* 15 */
/***/ (function(module, exports, __nested_webpack_require_64072__) {

"use strict";


function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

var LayoutConstants = __nested_webpack_require_64072__(0);
var LGraphManager = __nested_webpack_require_64072__(6);
var LNode = __nested_webpack_require_64072__(3);
var LEdge = __nested_webpack_require_64072__(1);
var LGraph = __nested_webpack_require_64072__(5);
var PointD = __nested_webpack_require_64072__(4);
var Transform = __nested_webpack_require_64072__(17);
var Emitter = __nested_webpack_require_64072__(27);

function Layout(isRemoteUse) {
  Emitter.call(this);

  //Layout Quality: 0:draft, 1:default, 2:proof
  this.layoutQuality = LayoutConstants.QUALITY;
  //Whether layout should create bendpoints as needed or not
  this.createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED;
  //Whether layout should be incremental or not
  this.incremental = LayoutConstants.DEFAULT_INCREMENTAL;
  //Whether we animate from before to after layout node positions
  this.animationOnLayout = LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT;
  //Whether we animate the layout process or not
  this.animationDuringLayout = LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT;
  //Number iterations that should be done between two successive animations
  this.animationPeriod = LayoutConstants.DEFAULT_ANIMATION_PERIOD;
  /**
   * Whether or not leaf nodes (non-compound nodes) are of uniform sizes. When
   * they are, both spring and repulsion forces between two leaf nodes can be
   * calculated without the expensive clipping point calculations, resulting
   * in major speed-up.
   */
  this.uniformLeafNodeSizes = LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES;
  /**
   * This is used for creation of bendpoints by using dummy nodes and edges.
   * Maps an LEdge to its dummy bendpoint path.
   */
  this.edgeToDummyNodes = new Map();
  this.graphManager = new LGraphManager(this);
  this.isLayoutFinished = false;
  this.isSubLayout = false;
  this.isRemoteUse = false;

  if (isRemoteUse != null) {
    this.isRemoteUse = isRemoteUse;
  }
}

Layout.RANDOM_SEED = 1;

Layout.prototype = Object.create(Emitter.prototype);

Layout.prototype.getGraphManager = function () {
  return this.graphManager;
};

Layout.prototype.getAllNodes = function () {
  return this.graphManager.getAllNodes();
};

Layout.prototype.getAllEdges = function () {
  return this.graphManager.getAllEdges();
};

Layout.prototype.getAllNodesToApplyGravitation = function () {
  return this.graphManager.getAllNodesToApplyGravitation();
};

Layout.prototype.newGraphManager = function () {
  var gm = new LGraphManager(this);
  this.graphManager = gm;
  return gm;
};

Layout.prototype.newGraph = function (vGraph) {
  return new LGraph(null, this.graphManager, vGraph);
};

Layout.prototype.newNode = function (vNode) {
  return new LNode(this.graphManager, vNode);
};

Layout.prototype.newEdge = function (vEdge) {
  return new LEdge(null, null, vEdge);
};

Layout.prototype.checkLayoutSuccess = function () {
  return this.graphManager.getRoot() == null || this.graphManager.getRoot().getNodes().length == 0 || this.graphManager.includesInvalidEdge();
};

Layout.prototype.runLayout = function () {
  this.isLayoutFinished = false;

  if (this.tilingPreLayout) {
    this.tilingPreLayout();
  }

  this.initParameters();
  var isLayoutSuccessfull;

  if (this.checkLayoutSuccess()) {
    isLayoutSuccessfull = false;
  } else {
    isLayoutSuccessfull = this.layout();
  }

  if (LayoutConstants.ANIMATE === 'during') {
    // If this is a 'during' layout animation. Layout is not finished yet. 
    // We need to perform these in index.js when layout is really finished.
    return false;
  }

  if (isLayoutSuccessfull) {
    if (!this.isSubLayout) {
      this.doPostLayout();
    }
  }

  if (this.tilingPostLayout) {
    this.tilingPostLayout();
  }

  this.isLayoutFinished = true;

  return isLayoutSuccessfull;
};

/**
 * This method performs the operations required after layout.
 */
Layout.prototype.doPostLayout = function () {
  //assert !isSubLayout : "Should not be called on sub-layout!";
  // Propagate geometric changes to v-level objects
  if (!this.incremental) {
    this.transform();
  }
  this.update();
};

/**
 * This method updates the geometry of the target graph according to
 * calculated layout.
 */
Layout.prototype.update2 = function () {
  // update bend points
  if (this.createBendsAsNeeded) {
    this.createBendpointsFromDummyNodes();

    // reset all edges, since the topology has changed
    this.graphManager.resetAllEdges();
  }

  // perform edge, node and root updates if layout is not called
  // remotely
  if (!this.isRemoteUse) {
    // update all edges
    var edge;
    var allEdges = this.graphManager.getAllEdges();
    for (var i = 0; i < allEdges.length; i++) {
      edge = allEdges[i];
      //      this.update(edge);
    }

    // recursively update nodes
    var node;
    var nodes = this.graphManager.getRoot().getNodes();
    for (var i = 0; i < nodes.length; i++) {
      node = nodes[i];
      //      this.update(node);
    }

    // update root graph
    this.update(this.graphManager.getRoot());
  }
};

Layout.prototype.update = function (obj) {
  if (obj == null) {
    this.update2();
  } else if (obj instanceof LNode) {
    var node = obj;
    if (node.getChild() != null) {
      // since node is compound, recursively update child nodes
      var nodes = node.getChild().getNodes();
      for (var i = 0; i < nodes.length; i++) {
        update(nodes[i]);
      }
    }

    // if the l-level node is associated with a v-level graph object,
    // then it is assumed that the v-level node implements the
    // interface Updatable.
    if (node.vGraphObject != null) {
      // cast to Updatable without any type check
      var vNode = node.vGraphObject;

      // call the update method of the interface
      vNode.update(node);
    }
  } else if (obj instanceof LEdge) {
    var edge = obj;
    // if the l-level edge is associated with a v-level graph object,
    // then it is assumed that the v-level edge implements the
    // interface Updatable.

    if (edge.vGraphObject != null) {
      // cast to Updatable without any type check
      var vEdge = edge.vGraphObject;

      // call the update method of the interface
      vEdge.update(edge);
    }
  } else if (obj instanceof LGraph) {
    var graph = obj;
    // if the l-level graph is associated with a v-level graph object,
    // then it is assumed that the v-level object implements the
    // interface Updatable.

    if (graph.vGraphObject != null) {
      // cast to Updatable without any type check
      var vGraph = graph.vGraphObject;

      // call the update method of the interface
      vGraph.update(graph);
    }
  }
};

/**
 * This method is used to set all layout parameters to default values
 * determined at compile time.
 */
Layout.prototype.initParameters = function () {
  if (!this.isSubLayout) {
    this.layoutQuality = LayoutConstants.QUALITY;
    this.animationDuringLayout = LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT;
    this.animationPeriod = LayoutConstants.DEFAULT_ANIMATION_PERIOD;
    this.animationOnLayout = LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT;
    this.incremental = LayoutConstants.DEFAULT_INCREMENTAL;
    this.createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED;
    this.uniformLeafNodeSizes = LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES;
  }

  if (this.animationDuringLayout) {
    this.animationOnLayout = false;
  }
};

Layout.prototype.transform = function (newLeftTop) {
  if (newLeftTop == undefined) {
    this.transform(new PointD(0, 0));
  } else {
    // create a transformation object (from Eclipse to layout). When an
    // inverse transform is applied, we get upper-left coordinate of the
    // drawing or the root graph at given input coordinate (some margins
    // already included in calculation of left-top).

    var trans = new Transform();
    var leftTop = this.graphManager.getRoot().updateLeftTop();

    if (leftTop != null) {
      trans.setWorldOrgX(newLeftTop.x);
      trans.setWorldOrgY(newLeftTop.y);

      trans.setDeviceOrgX(leftTop.x);
      trans.setDeviceOrgY(leftTop.y);

      var nodes = this.getAllNodes();
      var node;

      for (var i = 0; i < nodes.length; i++) {
        node = nodes[i];
        node.transform(trans);
      }
    }
  }
};

Layout.prototype.positionNodesRandomly = function (graph) {

  if (graph == undefined) {
    //assert !this.incremental;
    this.positionNodesRandomly(this.getGraphManager().getRoot());
    this.getGraphManager().getRoot().updateBounds(true);
  } else {
    var lNode;
    var childGraph;

    var nodes = graph.getNodes();
    for (var i = 0; i < nodes.length; i++) {
      lNode = nodes[i];
      childGraph = lNode.getChild();

      if (childGraph == null) {
        lNode.scatter();
      } else if (childGraph.getNodes().length == 0) {
        lNode.scatter();
      } else {
        this.positionNodesRandomly(childGraph);
        lNode.updateBounds();
      }
    }
  }
};

/**
 * This method returns a list of trees where each tree is represented as a
 * list of l-nodes. The method returns a list of size 0 when:
 * - The graph is not flat or
 * - One of the component(s) of the graph is not a tree.
 */
Layout.prototype.getFlatForest = function () {
  var flatForest = [];
  var isForest = true;

  // Quick reference for all nodes in the graph manager associated with
  // this layout. The list should not be changed.
  var allNodes = this.graphManager.getRoot().getNodes();

  // First be sure that the graph is flat
  var isFlat = true;

  for (var i = 0; i < allNodes.length; i++) {
    if (allNodes[i].getChild() != null) {
      isFlat = false;
    }
  }

  // Return empty forest if the graph is not flat.
  if (!isFlat) {
    return flatForest;
  }

  // Run BFS for each component of the graph.

  var visited = new Set();
  var toBeVisited = [];
  var parents = new Map();
  var unProcessedNodes = [];

  unProcessedNodes = unProcessedNodes.concat(allNodes);

  // Each iteration of this loop finds a component of the graph and
  // decides whether it is a tree or not. If it is a tree, adds it to the
  // forest and continued with the next component.

  while (unProcessedNodes.length > 0 && isForest) {
    toBeVisited.push(unProcessedNodes[0]);

    // Start the BFS. Each iteration of this loop visits a node in a
    // BFS manner.
    while (toBeVisited.length > 0 && isForest) {
      //pool operation
      var currentNode = toBeVisited[0];
      toBeVisited.splice(0, 1);
      visited.add(currentNode);

      // Traverse all neighbors of this node
      var neighborEdges = currentNode.getEdges();

      for (var i = 0; i < neighborEdges.length; i++) {
        var currentNeighbor = neighborEdges[i].getOtherEnd(currentNode);

        // If BFS is not growing from this neighbor.
        if (parents.get(currentNode) != currentNeighbor) {
          // We haven't previously visited this neighbor.
          if (!visited.has(currentNeighbor)) {
            toBeVisited.push(currentNeighbor);
            parents.set(currentNeighbor, currentNode);
          }
          // Since we have previously visited this neighbor and
          // this neighbor is not parent of currentNode, given
          // graph contains a component that is not tree, hence
          // it is not a forest.
          else {
              isForest = false;
              break;
            }
        }
      }
    }

    // The graph contains a component that is not a tree. Empty
    // previously found trees. The method will end.
    if (!isForest) {
      flatForest = [];
    }
    // Save currently visited nodes as a tree in our forest. Reset
    // visited and parents lists. Continue with the next component of
    // the graph, if any.
    else {
        var temp = [].concat(_toConsumableArray(visited));
        flatForest.push(temp);
        //flatForest = flatForest.concat(temp);
        //unProcessedNodes.removeAll(visited);
        for (var i = 0; i < temp.length; i++) {
          var value = temp[i];
          var index = unProcessedNodes.indexOf(value);
          if (index > -1) {
            unProcessedNodes.splice(index, 1);
          }
        }
        visited = new Set();
        parents = new Map();
      }
  }

  return flatForest;
};

/**
 * This method creates dummy nodes (an l-level node with minimal dimensions)
 * for the given edge (one per bendpoint). The existing l-level structure
 * is updated accordingly.
 */
Layout.prototype.createDummyNodesForBendpoints = function (edge) {
  var dummyNodes = [];
  var prev = edge.source;

  var graph = this.graphManager.calcLowestCommonAncestor(edge.source, edge.target);

  for (var i = 0; i < edge.bendpoints.length; i++) {
    // create new dummy node
    var dummyNode = this.newNode(null);
    dummyNode.setRect(new Point(0, 0), new Dimension(1, 1));

    graph.add(dummyNode);

    // create new dummy edge between prev and dummy node
    var dummyEdge = this.newEdge(null);
    this.graphManager.add(dummyEdge, prev, dummyNode);

    dummyNodes.add(dummyNode);
    prev = dummyNode;
  }

  var dummyEdge = this.newEdge(null);
  this.graphManager.add(dummyEdge, prev, edge.target);

  this.edgeToDummyNodes.set(edge, dummyNodes);

  // remove real edge from graph manager if it is inter-graph
  if (edge.isInterGraph()) {
    this.graphManager.remove(edge);
  }
  // else, remove the edge from the current graph
  else {
      graph.remove(edge);
    }

  return dummyNodes;
};

/**
 * This method creates bendpoints for edges from the dummy nodes
 * at l-level.
 */
Layout.prototype.createBendpointsFromDummyNodes = function () {
  var edges = [];
  edges = edges.concat(this.graphManager.getAllEdges());
  edges = [].concat(_toConsumableArray(this.edgeToDummyNodes.keys())).concat(edges);

  for (var k = 0; k < edges.length; k++) {
    var lEdge = edges[k];

    if (lEdge.bendpoints.length > 0) {
      var path = this.edgeToDummyNodes.get(lEdge);

      for (var i = 0; i < path.length; i++) {
        var dummyNode = path[i];
        var p = new PointD(dummyNode.getCenterX(), dummyNode.getCenterY());

        // update bendpoint's location according to dummy node
        var ebp = lEdge.bendpoints.get(i);
        ebp.x = p.x;
        ebp.y = p.y;

        // remove the dummy node, dummy edges incident with this
        // dummy node is also removed (within the remove method)
        dummyNode.getOwner().remove(dummyNode);
      }

      // add the real edge to graph
      this.graphManager.add(lEdge, lEdge.source, lEdge.target);
    }
  }
};

Layout.transform = function (sliderValue, defaultValue, minDiv, maxMul) {
  if (minDiv != undefined && maxMul != undefined) {
    var value = defaultValue;

    if (sliderValue <= 50) {
      var minValue = defaultValue / minDiv;
      value -= (defaultValue - minValue) / 50 * (50 - sliderValue);
    } else {
      var maxValue = defaultValue * maxMul;
      value += (maxValue - defaultValue) / 50 * (sliderValue - 50);
    }

    return value;
  } else {
    var a, b;

    if (sliderValue <= 50) {
      a = 9.0 * defaultValue / 500.0;
      b = defaultValue / 10.0;
    } else {
      a = 9.0 * defaultValue / 50.0;
      b = -8 * defaultValue;
    }

    return a * sliderValue + b;
  }
};

/**
 * This method finds and returns the center of the given nodes, assuming
 * that the given nodes form a tree in themselves.
 */
Layout.findCenterOfTree = function (nodes) {
  var list = [];
  list = list.concat(nodes);

  var removedNodes = [];
  var remainingDegrees = new Map();
  var foundCenter = false;
  var centerNode = null;

  if (list.length == 1 || list.length == 2) {
    foundCenter = true;
    centerNode = list[0];
  }

  for (var i = 0; i < list.length; i++) {
    var node = list[i];
    var degree = node.getNeighborsList().size;
    remainingDegrees.set(node, node.getNeighborsList().size);

    if (degree == 1) {
      removedNodes.push(node);
    }
  }

  var tempList = [];
  tempList = tempList.concat(removedNodes);

  while (!foundCenter) {
    var tempList2 = [];
    tempList2 = tempList2.concat(tempList);
    tempList = [];

    for (var i = 0; i < list.length; i++) {
      var node = list[i];

      var index = list.indexOf(node);
      if (index >= 0) {
        list.splice(index, 1);
      }

      var neighbours = node.getNeighborsList();

      neighbours.forEach(function (neighbour) {
        if (removedNodes.indexOf(neighbour) < 0) {
          var otherDegree = remainingDegrees.get(neighbour);
          var newDegree = otherDegree - 1;

          if (newDegree == 1) {
            tempList.push(neighbour);
          }

          remainingDegrees.set(neighbour, newDegree);
        }
      });
    }

    removedNodes = removedNodes.concat(tempList);

    if (list.length == 1 || list.length == 2) {
      foundCenter = true;
      centerNode = list[0];
    }
  }

  return centerNode;
};

/**
 * During the coarsening process, this layout may be referenced by two graph managers
 * this setter function grants access to change the currently being used graph manager
 */
Layout.prototype.setGraphManager = function (gm) {
  this.graphManager = gm;
};

module.exports = Layout;

/***/ }),
/* 16 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function RandomSeed() {}
// adapted from: https://stackoverflow.com/a/19303725
RandomSeed.seed = 1;
RandomSeed.x = 0;

RandomSeed.nextDouble = function () {
  RandomSeed.x = Math.sin(RandomSeed.seed++) * 10000;
  return RandomSeed.x - Math.floor(RandomSeed.x);
};

module.exports = RandomSeed;

/***/ }),
/* 17 */
/***/ (function(module, exports, __nested_webpack_require_81860__) {

"use strict";


var PointD = __nested_webpack_require_81860__(4);

function Transform(x, y) {
  this.lworldOrgX = 0.0;
  this.lworldOrgY = 0.0;
  this.ldeviceOrgX = 0.0;
  this.ldeviceOrgY = 0.0;
  this.lworldExtX = 1.0;
  this.lworldExtY = 1.0;
  this.ldeviceExtX = 1.0;
  this.ldeviceExtY = 1.0;
}

Transform.prototype.getWorldOrgX = function () {
  return this.lworldOrgX;
};

Transform.prototype.setWorldOrgX = function (wox) {
  this.lworldOrgX = wox;
};

Transform.prototype.getWorldOrgY = function () {
  return this.lworldOrgY;
};

Transform.prototype.setWorldOrgY = function (woy) {
  this.lworldOrgY = woy;
};

Transform.prototype.getWorldExtX = function () {
  return this.lworldExtX;
};

Transform.prototype.setWorldExtX = function (wex) {
  this.lworldExtX = wex;
};

Transform.prototype.getWorldExtY = function () {
  return this.lworldExtY;
};

Transform.prototype.setWorldExtY = function (wey) {
  this.lworldExtY = wey;
};

/* Device related */

Transform.prototype.getDeviceOrgX = function () {
  return this.ldeviceOrgX;
};

Transform.prototype.setDeviceOrgX = function (dox) {
  this.ldeviceOrgX = dox;
};

Transform.prototype.getDeviceOrgY = function () {
  return this.ldeviceOrgY;
};

Transform.prototype.setDeviceOrgY = function (doy) {
  this.ldeviceOrgY = doy;
};

Transform.prototype.getDeviceExtX = function () {
  return this.ldeviceExtX;
};

Transform.prototype.setDeviceExtX = function (dex) {
  this.ldeviceExtX = dex;
};

Transform.prototype.getDeviceExtY = function () {
  return this.ldeviceExtY;
};

Transform.prototype.setDeviceExtY = function (dey) {
  this.ldeviceExtY = dey;
};

Transform.prototype.transformX = function (x) {
  var xDevice = 0.0;
  var worldExtX = this.lworldExtX;
  if (worldExtX != 0.0) {
    xDevice = this.ldeviceOrgX + (x - this.lworldOrgX) * this.ldeviceExtX / worldExtX;
  }

  return xDevice;
};

Transform.prototype.transformY = function (y) {
  var yDevice = 0.0;
  var worldExtY = this.lworldExtY;
  if (worldExtY != 0.0) {
    yDevice = this.ldeviceOrgY + (y - this.lworldOrgY) * this.ldeviceExtY / worldExtY;
  }

  return yDevice;
};

Transform.prototype.inverseTransformX = function (x) {
  var xWorld = 0.0;
  var deviceExtX = this.ldeviceExtX;
  if (deviceExtX != 0.0) {
    xWorld = this.lworldOrgX + (x - this.ldeviceOrgX) * this.lworldExtX / deviceExtX;
  }

  return xWorld;
};

Transform.prototype.inverseTransformY = function (y) {
  var yWorld = 0.0;
  var deviceExtY = this.ldeviceExtY;
  if (deviceExtY != 0.0) {
    yWorld = this.lworldOrgY + (y - this.ldeviceOrgY) * this.lworldExtY / deviceExtY;
  }
  return yWorld;
};

Transform.prototype.inverseTransformPoint = function (inPoint) {
  var outPoint = new PointD(this.inverseTransformX(inPoint.x), this.inverseTransformY(inPoint.y));
  return outPoint;
};

module.exports = Transform;

/***/ }),
/* 18 */
/***/ (function(module, exports, __nested_webpack_require_84747__) {

"use strict";


function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

var Layout = __nested_webpack_require_84747__(15);
var FDLayoutConstants = __nested_webpack_require_84747__(7);
var LayoutConstants = __nested_webpack_require_84747__(0);
var IGeometry = __nested_webpack_require_84747__(8);
var IMath = __nested_webpack_require_84747__(9);

function FDLayout() {
  Layout.call(this);

  this.useSmartIdealEdgeLengthCalculation = FDLayoutConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION;
  this.idealEdgeLength = FDLayoutConstants.DEFAULT_EDGE_LENGTH;
  this.springConstant = FDLayoutConstants.DEFAULT_SPRING_STRENGTH;
  this.repulsionConstant = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH;
  this.gravityConstant = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH;
  this.compoundGravityConstant = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH;
  this.gravityRangeFactor = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR;
  this.compoundGravityRangeFactor = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR;
  this.displacementThresholdPerNode = 3.0 * FDLayoutConstants.DEFAULT_EDGE_LENGTH / 100;
  this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL;
  this.initialCoolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL;
  this.totalDisplacement = 0.0;
  this.oldTotalDisplacement = 0.0;
  this.maxIterations = FDLayoutConstants.MAX_ITERATIONS;
}

FDLayout.prototype = Object.create(Layout.prototype);

for (var prop in Layout) {
  FDLayout[prop] = Layout[prop];
}

FDLayout.prototype.initParameters = function () {
  Layout.prototype.initParameters.call(this, arguments);

  this.totalIterations = 0;
  this.notAnimatedIterations = 0;

  this.useFRGridVariant = FDLayoutConstants.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION;

  this.grid = [];
};

FDLayout.prototype.calcIdealEdgeLengths = function () {
  var edge;
  var lcaDepth;
  var source;
  var target;
  var sizeOfSourceInLca;
  var sizeOfTargetInLca;

  var allEdges = this.getGraphManager().getAllEdges();
  for (var i = 0; i < allEdges.length; i++) {
    edge = allEdges[i];

    edge.idealLength = this.idealEdgeLength;

    if (edge.isInterGraph) {
      source = edge.getSource();
      target = edge.getTarget();

      sizeOfSourceInLca = edge.getSourceInLca().getEstimatedSize();
      sizeOfTargetInLca = edge.getTargetInLca().getEstimatedSize();

      if (this.useSmartIdealEdgeLengthCalculation) {
        edge.idealLength += sizeOfSourceInLca + sizeOfTargetInLca - 2 * LayoutConstants.SIMPLE_NODE_SIZE;
      }

      lcaDepth = edge.getLca().getInclusionTreeDepth();

      edge.idealLength += FDLayoutConstants.DEFAULT_EDGE_LENGTH * FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR * (source.getInclusionTreeDepth() + target.getInclusionTreeDepth() - 2 * lcaDepth);
    }
  }
};

FDLayout.prototype.initSpringEmbedder = function () {

  var s = this.getAllNodes().length;
  if (this.incremental) {
    if (s > FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) {
      this.coolingFactor = Math.max(this.coolingFactor * FDLayoutConstants.COOLING_ADAPTATION_FACTOR, this.coolingFactor - (s - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) / (FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) * this.coolingFactor * (1 - FDLayoutConstants.COOLING_ADAPTATION_FACTOR));
    }
    this.maxNodeDisplacement = FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL;
  } else {
    if (s > FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) {
      this.coolingFactor = Math.max(FDLayoutConstants.COOLING_ADAPTATION_FACTOR, 1.0 - (s - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) / (FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) * (1 - FDLayoutConstants.COOLING_ADAPTATION_FACTOR));
    } else {
      this.coolingFactor = 1.0;
    }
    this.initialCoolingFactor = this.coolingFactor;
    this.maxNodeDisplacement = FDLayoutConstants.MAX_NODE_DISPLACEMENT;
  }

  this.maxIterations = Math.max(this.getAllNodes().length * 5, this.maxIterations);

  this.totalDisplacementThreshold = this.displacementThresholdPerNode * this.getAllNodes().length;

  this.repulsionRange = this.calcRepulsionRange();
};

FDLayout.prototype.calcSpringForces = function () {
  var lEdges = this.getAllEdges();
  var edge;

  for (var i = 0; i < lEdges.length; i++) {
    edge = lEdges[i];

    this.calcSpringForce(edge, edge.idealLength);
  }
};

FDLayout.prototype.calcRepulsionForces = function () {
  var gridUpdateAllowed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
  var forceToNodeSurroundingUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

  var i, j;
  var nodeA, nodeB;
  var lNodes = this.getAllNodes();
  var processedNodeSet;

  if (this.useFRGridVariant) {
    if (this.totalIterations % FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD == 1 && gridUpdateAllowed) {
      this.updateGrid();
    }

    processedNodeSet = new Set();

    // calculate repulsion forces between each nodes and its surrounding
    for (i = 0; i < lNodes.length; i++) {
      nodeA = lNodes[i];
      this.calculateRepulsionForceOfANode(nodeA, processedNodeSet, gridUpdateAllowed, forceToNodeSurroundingUpdate);
      processedNodeSet.add(nodeA);
    }
  } else {
    for (i = 0; i < lNodes.length; i++) {
      nodeA = lNodes[i];

      for (j = i + 1; j < lNodes.length; j++) {
        nodeB = lNodes[j];

        // If both nodes are not members of the same graph, skip.
        if (nodeA.getOwner() != nodeB.getOwner()) {
          continue;
        }

        this.calcRepulsionForce(nodeA, nodeB);
      }
    }
  }
};

FDLayout.prototype.calcGravitationalForces = function () {
  var node;
  var lNodes = this.getAllNodesToApplyGravitation();

  for (var i = 0; i < lNodes.length; i++) {
    node = lNodes[i];
    this.calcGravitationalForce(node);
  }
};

FDLayout.prototype.moveNodes = function () {
  var lNodes = this.getAllNodes();
  var node;

  for (var i = 0; i < lNodes.length; i++) {
    node = lNodes[i];
    node.move();
  }
};

FDLayout.prototype.calcSpringForce = function (edge, idealLength) {
  var sourceNode = edge.getSource();
  var targetNode = edge.getTarget();

  var length;
  var springForce;
  var springForceX;
  var springForceY;

  // Update edge length
  if (this.uniformLeafNodeSizes && sourceNode.getChild() == null && targetNode.getChild() == null) {
    edge.updateLengthSimple();
  } else {
    edge.updateLength();

    if (edge.isOverlapingSourceAndTarget) {
      return;
    }
  }

  length = edge.getLength();

  if (length == 0) return;

  // Calculate spring forces
  springForce = this.springConstant * (length - idealLength);

  // Project force onto x and y axes
  springForceX = springForce * (edge.lengthX / length);
  springForceY = springForce * (edge.lengthY / length);

  // Apply forces on the end nodes
  sourceNode.springForceX += springForceX;
  sourceNode.springForceY += springForceY;
  targetNode.springForceX -= springForceX;
  targetNode.springForceY -= springForceY;
};

FDLayout.prototype.calcRepulsionForce = function (nodeA, nodeB) {
  var rectA = nodeA.getRect();
  var rectB = nodeB.getRect();
  var overlapAmount = new Array(2);
  var clipPoints = new Array(4);
  var distanceX;
  var distanceY;
  var distanceSquared;
  var distance;
  var repulsionForce;
  var repulsionForceX;
  var repulsionForceY;

  if (rectA.intersects(rectB)) // two nodes overlap
    {
      // calculate separation amount in x and y directions
      IGeometry.calcSeparationAmount(rectA, rectB, overlapAmount, FDLayoutConstants.DEFAULT_EDGE_LENGTH / 2.0);

      repulsionForceX = 2 * overlapAmount[0];
      repulsionForceY = 2 * overlapAmount[1];

      var childrenConstant = nodeA.noOfChildren * nodeB.noOfChildren / (nodeA.noOfChildren + nodeB.noOfChildren);

      // Apply forces on the two nodes
      nodeA.repulsionForceX -= childrenConstant * repulsionForceX;
      nodeA.repulsionForceY -= childrenConstant * repulsionForceY;
      nodeB.repulsionForceX += childrenConstant * repulsionForceX;
      nodeB.repulsionForceY += childrenConstant * repulsionForceY;
    } else // no overlap
    {
      // calculate distance

      if (this.uniformLeafNodeSizes && nodeA.getChild() == null && nodeB.getChild() == null) // simply base repulsion on distance of node centers
        {
          distanceX = rectB.getCenterX() - rectA.getCenterX();
          distanceY = rectB.getCenterY() - rectA.getCenterY();
        } else // use clipping points
        {
          IGeometry.getIntersection(rectA, rectB, clipPoints);

          distanceX = clipPoints[2] - clipPoints[0];
          distanceY = clipPoints[3] - clipPoints[1];
        }

      // No repulsion range. FR grid variant should take care of this.
      if (Math.abs(distanceX) < FDLayoutConstants.MIN_REPULSION_DIST) {
        distanceX = IMath.sign(distanceX) * FDLayoutConstants.MIN_REPULSION_DIST;
      }

      if (Math.abs(distanceY) < FDLayoutConstants.MIN_REPULSION_DIST) {
        distanceY = IMath.sign(distanceY) * FDLayoutConstants.MIN_REPULSION_DIST;
      }

      distanceSquared = distanceX * distanceX + distanceY * distanceY;
      distance = Math.sqrt(distanceSquared);

      repulsionForce = this.repulsionConstant * nodeA.noOfChildren * nodeB.noOfChildren / distanceSquared;

      // Project force onto x and y axes
      repulsionForceX = repulsionForce * distanceX / distance;
      repulsionForceY = repulsionForce * distanceY / distance;

      // Apply forces on the two nodes    
      nodeA.repulsionForceX -= repulsionForceX;
      nodeA.repulsionForceY -= repulsionForceY;
      nodeB.repulsionForceX += repulsionForceX;
      nodeB.repulsionForceY += repulsionForceY;
    }
};

FDLayout.prototype.calcGravitationalForce = function (node) {
  var ownerGraph;
  var ownerCenterX;
  var ownerCenterY;
  var distanceX;
  var distanceY;
  var absDistanceX;
  var absDistanceY;
  var estimatedSize;
  ownerGraph = node.getOwner();

  ownerCenterX = (ownerGraph.getRight() + ownerGraph.getLeft()) / 2;
  ownerCenterY = (ownerGraph.getTop() + ownerGraph.getBottom()) / 2;
  distanceX = node.getCenterX() - ownerCenterX;
  distanceY = node.getCenterY() - ownerCenterY;
  absDistanceX = Math.abs(distanceX) + node.getWidth() / 2;
  absDistanceY = Math.abs(distanceY) + node.getHeight() / 2;

  if (node.getOwner() == this.graphManager.getRoot()) // in the root graph
    {
      estimatedSize = ownerGraph.getEstimatedSize() * this.gravityRangeFactor;

      if (absDistanceX > estimatedSize || absDistanceY > estimatedSize) {
        node.gravitationForceX = -this.gravityConstant * distanceX;
        node.gravitationForceY = -this.gravityConstant * distanceY;
      }
    } else // inside a compound
    {
      estimatedSize = ownerGraph.getEstimatedSize() * this.compoundGravityRangeFactor;

      if (absDistanceX > estimatedSize || absDistanceY > estimatedSize) {
        node.gravitationForceX = -this.gravityConstant * distanceX * this.compoundGravityConstant;
        node.gravitationForceY = -this.gravityConstant * distanceY * this.compoundGravityConstant;
      }
    }
};

FDLayout.prototype.isConverged = function () {
  var converged;
  var oscilating = false;

  if (this.totalIterations > this.maxIterations / 3) {
    oscilating = Math.abs(this.totalDisplacement - this.oldTotalDisplacement) < 2;
  }

  converged = this.totalDisplacement < this.totalDisplacementThreshold;

  this.oldTotalDisplacement = this.totalDisplacement;

  return converged || oscilating;
};

FDLayout.prototype.animate = function () {
  if (this.animationDuringLayout && !this.isSubLayout) {
    if (this.notAnimatedIterations == this.animationPeriod) {
      this.update();
      this.notAnimatedIterations = 0;
    } else {
      this.notAnimatedIterations++;
    }
  }
};

//This method calculates the number of children (weight) for all nodes
FDLayout.prototype.calcNoOfChildrenForAllNodes = function () {
  var node;
  var allNodes = this.graphManager.getAllNodes();

  for (var i = 0; i < allNodes.length; i++) {
    node = allNodes[i];
    node.noOfChildren = node.getNoOfChildren();
  }
};

// -----------------------------------------------------------------------------
// Section: FR-Grid Variant Repulsion Force Calculation
// -----------------------------------------------------------------------------

FDLayout.prototype.calcGrid = function (graph) {

  var sizeX = 0;
  var sizeY = 0;

  sizeX = parseInt(Math.ceil((graph.getRight() - graph.getLeft()) / this.repulsionRange));
  sizeY = parseInt(Math.ceil((graph.getBottom() - graph.getTop()) / this.repulsionRange));

  var grid = new Array(sizeX);

  for (var i = 0; i < sizeX; i++) {
    grid[i] = new Array(sizeY);
  }

  for (var i = 0; i < sizeX; i++) {
    for (var j = 0; j < sizeY; j++) {
      grid[i][j] = new Array();
    }
  }

  return grid;
};

FDLayout.prototype.addNodeToGrid = function (v, left, top) {

  var startX = 0;
  var finishX = 0;
  var startY = 0;
  var finishY = 0;

  startX = parseInt(Math.floor((v.getRect().x - left) / this.repulsionRange));
  finishX = parseInt(Math.floor((v.getRect().width + v.getRect().x - left) / this.repulsionRange));
  startY = parseInt(Math.floor((v.getRect().y - top) / this.repulsionRange));
  finishY = parseInt(Math.floor((v.getRect().height + v.getRect().y - top) / this.repulsionRange));

  for (var i = startX; i <= finishX; i++) {
    for (var j = startY; j <= finishY; j++) {
      this.grid[i][j].push(v);
      v.setGridCoordinates(startX, finishX, startY, finishY);
    }
  }
};

FDLayout.prototype.updateGrid = function () {
  var i;
  var nodeA;
  var lNodes = this.getAllNodes();

  this.grid = this.calcGrid(this.graphManager.getRoot());

  // put all nodes to proper grid cells
  for (i = 0; i < lNodes.length; i++) {
    nodeA = lNodes[i];
    this.addNodeToGrid(nodeA, this.graphManager.getRoot().getLeft(), this.graphManager.getRoot().getTop());
  }
};

FDLayout.prototype.calculateRepulsionForceOfANode = function (nodeA, processedNodeSet, gridUpdateAllowed, forceToNodeSurroundingUpdate) {

  if (this.totalIterations % FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD == 1 && gridUpdateAllowed || forceToNodeSurroundingUpdate) {
    var surrounding = new Set();
    nodeA.surrounding = new Array();
    var nodeB;
    var grid = this.grid;

    for (var i = nodeA.startX - 1; i < nodeA.finishX + 2; i++) {
      for (var j = nodeA.startY - 1; j < nodeA.finishY + 2; j++) {
        if (!(i < 0 || j < 0 || i >= grid.length || j >= grid[0].length)) {
          for (var k = 0; k < grid[i][j].length; k++) {
            nodeB = grid[i][j][k];

            // If both nodes are not members of the same graph, 
            // or both nodes are the same, skip.
            if (nodeA.getOwner() != nodeB.getOwner() || nodeA == nodeB) {
              continue;
            }

            // check if the repulsion force between
            // nodeA and nodeB has already been calculated
            if (!processedNodeSet.has(nodeB) && !surrounding.has(nodeB)) {
              var distanceX = Math.abs(nodeA.getCenterX() - nodeB.getCenterX()) - (nodeA.getWidth() / 2 + nodeB.getWidth() / 2);
              var distanceY = Math.abs(nodeA.getCenterY() - nodeB.getCenterY()) - (nodeA.getHeight() / 2 + nodeB.getHeight() / 2);

              // if the distance between nodeA and nodeB 
              // is less then calculation range
              if (distanceX <= this.repulsionRange && distanceY <= this.repulsionRange) {
                //then add nodeB to surrounding of nodeA
                surrounding.add(nodeB);
              }
            }
          }
        }
      }
    }

    nodeA.surrounding = [].concat(_toConsumableArray(surrounding));
  }
  for (i = 0; i < nodeA.surrounding.length; i++) {
    this.calcRepulsionForce(nodeA, nodeA.surrounding[i]);
  }
};

FDLayout.prototype.calcRepulsionRange = function () {
  return 0.0;
};

module.exports = FDLayout;

/***/ }),
/* 19 */
/***/ (function(module, exports, __nested_webpack_require_100902__) {

"use strict";


var LEdge = __nested_webpack_require_100902__(1);
var FDLayoutConstants = __nested_webpack_require_100902__(7);

function FDLayoutEdge(source, target, vEdge) {
  LEdge.call(this, source, target, vEdge);
  this.idealLength = FDLayoutConstants.DEFAULT_EDGE_LENGTH;
}

FDLayoutEdge.prototype = Object.create(LEdge.prototype);

for (var prop in LEdge) {
  FDLayoutEdge[prop] = LEdge[prop];
}

module.exports = FDLayoutEdge;

/***/ }),
/* 20 */
/***/ (function(module, exports, __nested_webpack_require_101387__) {

"use strict";


var LNode = __nested_webpack_require_101387__(3);

function FDLayoutNode(gm, loc, size, vNode) {
  // alternative constructor is handled inside LNode
  LNode.call(this, gm, loc, size, vNode);
  //Spring, repulsion and gravitational forces acting on this node
  this.springForceX = 0;
  this.springForceY = 0;
  this.repulsionForceX = 0;
  this.repulsionForceY = 0;
  this.gravitationForceX = 0;
  this.gravitationForceY = 0;
  //Amount by which this node is to be moved in this iteration
  this.displacementX = 0;
  this.displacementY = 0;

  //Start and finish grid coordinates that this node is fallen into
  this.startX = 0;
  this.finishX = 0;
  this.startY = 0;
  this.finishY = 0;

  //Geometric neighbors of this node
  this.surrounding = [];
}

FDLayoutNode.prototype = Object.create(LNode.prototype);

for (var prop in LNode) {
  FDLayoutNode[prop] = LNode[prop];
}

FDLayoutNode.prototype.setGridCoordinates = function (_startX, _finishX, _startY, _finishY) {
  this.startX = _startX;
  this.finishX = _finishX;
  this.startY = _startY;
  this.finishY = _finishY;
};

module.exports = FDLayoutNode;

/***/ }),
/* 21 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function DimensionD(width, height) {
  this.width = 0;
  this.height = 0;
  if (width !== null && height !== null) {
    this.height = height;
    this.width = width;
  }
}

DimensionD.prototype.getWidth = function () {
  return this.width;
};

DimensionD.prototype.setWidth = function (width) {
  this.width = width;
};

DimensionD.prototype.getHeight = function () {
  return this.height;
};

DimensionD.prototype.setHeight = function (height) {
  this.height = height;
};

module.exports = DimensionD;

/***/ }),
/* 22 */
/***/ (function(module, exports, __nested_webpack_require_103173__) {

"use strict";


var UniqueIDGeneretor = __nested_webpack_require_103173__(14);

function HashMap() {
  this.map = {};
  this.keys = [];
}

HashMap.prototype.put = function (key, value) {
  var theId = UniqueIDGeneretor.createID(key);
  if (!this.contains(theId)) {
    this.map[theId] = value;
    this.keys.push(key);
  }
};

HashMap.prototype.contains = function (key) {
  var theId = UniqueIDGeneretor.createID(key);
  return this.map[key] != null;
};

HashMap.prototype.get = function (key) {
  var theId = UniqueIDGeneretor.createID(key);
  return this.map[theId];
};

HashMap.prototype.keySet = function () {
  return this.keys;
};

module.exports = HashMap;

/***/ }),
/* 23 */
/***/ (function(module, exports, __nested_webpack_require_103901__) {

"use strict";


var UniqueIDGeneretor = __nested_webpack_require_103901__(14);

function HashSet() {
  this.set = {};
}
;

HashSet.prototype.add = function (obj) {
  var theId = UniqueIDGeneretor.createID(obj);
  if (!this.contains(theId)) this.set[theId] = obj;
};

HashSet.prototype.remove = function (obj) {
  delete this.set[UniqueIDGeneretor.createID(obj)];
};

HashSet.prototype.clear = function () {
  this.set = {};
};

HashSet.prototype.contains = function (obj) {
  return this.set[UniqueIDGeneretor.createID(obj)] == obj;
};

HashSet.prototype.isEmpty = function () {
  return this.size() === 0;
};

HashSet.prototype.size = function () {
  return Object.keys(this.set).length;
};

//concats this.set to the given list
HashSet.prototype.addAllTo = function (list) {
  var keys = Object.keys(this.set);
  var length = keys.length;
  for (var i = 0; i < length; i++) {
    list.push(this.set[keys[i]]);
  }
};

HashSet.prototype.size = function () {
  return Object.keys(this.set).length;
};

HashSet.prototype.addAll = function (list) {
  var s = list.length;
  for (var i = 0; i < s; i++) {
    var v = list[i];
    this.add(v);
  }
};

module.exports = HashSet;

/***/ }),
/* 24 */
/***/ (function(module, exports, __nested_webpack_require_105138__) {

"use strict";


var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * A classic Quicksort algorithm with Hoare's partition
 * - Works also on LinkedList objects
 *
 * Copyright: i-Vis Research Group, Bilkent University, 2007 - present
 */

var LinkedList = __nested_webpack_require_105138__(11);

var Quicksort = function () {
    function Quicksort(A, compareFunction) {
        _classCallCheck(this, Quicksort);

        if (compareFunction !== null || compareFunction !== undefined) this.compareFunction = this._defaultCompareFunction;

        var length = void 0;
        if (A instanceof LinkedList) length = A.size();else length = A.length;

        this._quicksort(A, 0, length - 1);
    }

    _createClass(Quicksort, [{
        key: '_quicksort',
        value: function _quicksort(A, p, r) {
            if (p < r) {
                var q = this._partition(A, p, r);
                this._quicksort(A, p, q);
                this._quicksort(A, q + 1, r);
            }
        }
    }, {
        key: '_partition',
        value: function _partition(A, p, r) {
            var x = this._get(A, p);
            var i = p;
            var j = r;
            while (true) {
                while (this.compareFunction(x, this._get(A, j))) {
                    j--;
                }while (this.compareFunction(this._get(A, i), x)) {
                    i++;
                }if (i < j) {
                    this._swap(A, i, j);
                    i++;
                    j--;
                } else return j;
            }
        }
    }, {
        key: '_get',
        value: function _get(object, index) {
            if (object instanceof LinkedList) return object.get_object_at(index);else return object[index];
        }
    }, {
        key: '_set',
        value: function _set(object, index, value) {
            if (object instanceof LinkedList) object.set_object_at(index, value);else object[index] = value;
        }
    }, {
        key: '_swap',
        value: function _swap(A, i, j) {
            var temp = this._get(A, i);
            this._set(A, i, this._get(A, j));
            this._set(A, j, temp);
        }
    }, {
        key: '_defaultCompareFunction',
        value: function _defaultCompareFunction(a, b) {
            return b > a;
        }
    }]);

    return Quicksort;
}();

module.exports = Quicksort;

/***/ }),
/* 25 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 *   Needleman-Wunsch algorithm is an procedure to compute the optimal global alignment of two string
 *   sequences by S.B.Needleman and C.D.Wunsch (1970).
 *
 *   Aside from the inputs, you can assign the scores for,
 *   - Match: The two characters at the current index are same.
 *   - Mismatch: The two characters at the current index are different.
 *   - Insertion/Deletion(gaps): The best alignment involves one letter aligning to a gap in the other string.
 */

var NeedlemanWunsch = function () {
    function NeedlemanWunsch(sequence1, sequence2) {
        var match_score = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
        var mismatch_penalty = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : -1;
        var gap_penalty = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : -1;

        _classCallCheck(this, NeedlemanWunsch);

        this.sequence1 = sequence1;
        this.sequence2 = sequence2;
        this.match_score = match_score;
        this.mismatch_penalty = mismatch_penalty;
        this.gap_penalty = gap_penalty;

        // Just the remove redundancy
        this.iMax = sequence1.length + 1;
        this.jMax = sequence2.length + 1;

        // Grid matrix of scores
        this.grid = new Array(this.iMax);
        for (var i = 0; i < this.iMax; i++) {
            this.grid[i] = new Array(this.jMax);

            for (var j = 0; j < this.jMax; j++) {
                this.grid[i][j] = 0;
            }
        }

        // Traceback matrix (2D array, each cell is an array of boolean values for [`Diag`, `Up`, `Left`] positions)
        this.tracebackGrid = new Array(this.iMax);
        for (var _i = 0; _i < this.iMax; _i++) {
            this.tracebackGrid[_i] = new Array(this.jMax);

            for (var _j = 0; _j < this.jMax; _j++) {
                this.tracebackGrid[_i][_j] = [null, null, null];
            }
        }

        // The aligned sequences (return multiple possibilities)
        this.alignments = [];

        // Final alignment score
        this.score = -1;

        // Calculate scores and tracebacks
        this.computeGrids();
    }

    _createClass(NeedlemanWunsch, [{
        key: "getScore",
        value: function getScore() {
            return this.score;
        }
    }, {
        key: "getAlignments",
        value: function getAlignments() {
            return this.alignments;
        }

        // Main dynamic programming procedure

    }, {
        key: "computeGrids",
        value: function computeGrids() {
            // Fill in the first row
            for (var j = 1; j < this.jMax; j++) {
                this.grid[0][j] = this.grid[0][j - 1] + this.gap_penalty;
                this.tracebackGrid[0][j] = [false, false, true];
            }

            // Fill in the first column
            for (var i = 1; i < this.iMax; i++) {
                this.grid[i][0] = this.grid[i - 1][0] + this.gap_penalty;
                this.tracebackGrid[i][0] = [false, true, false];
            }

            // Fill the rest of the grid
            for (var _i2 = 1; _i2 < this.iMax; _i2++) {
                for (var _j2 = 1; _j2 < this.jMax; _j2++) {
                    // Find the max score(s) among [`Diag`, `Up`, `Left`]
                    var diag = void 0;
                    if (this.sequence1[_i2 - 1] === this.sequence2[_j2 - 1]) diag = this.grid[_i2 - 1][_j2 - 1] + this.match_score;else diag = this.grid[_i2 - 1][_j2 - 1] + this.mismatch_penalty;

                    var up = this.grid[_i2 - 1][_j2] + this.gap_penalty;
                    var left = this.grid[_i2][_j2 - 1] + this.gap_penalty;

                    // If there exists multiple max values, capture them for multiple paths
                    var maxOf = [diag, up, left];
                    var indices = this.arrayAllMaxIndexes(maxOf);

                    // Update Grids
                    this.grid[_i2][_j2] = maxOf[indices[0]];
                    this.tracebackGrid[_i2][_j2] = [indices.includes(0), indices.includes(1), indices.includes(2)];
                }
            }

            // Update alignment score
            this.score = this.grid[this.iMax - 1][this.jMax - 1];
        }

        // Gets all possible valid sequence combinations

    }, {
        key: "alignmentTraceback",
        value: function alignmentTraceback() {
            var inProcessAlignments = [];

            inProcessAlignments.push({ pos: [this.sequence1.length, this.sequence2.length],
                seq1: "",
                seq2: ""
            });

            while (inProcessAlignments[0]) {
                var current = inProcessAlignments[0];
                var directions = this.tracebackGrid[current.pos[0]][current.pos[1]];

                if (directions[0]) {
                    inProcessAlignments.push({ pos: [current.pos[0] - 1, current.pos[1] - 1],
                        seq1: this.sequence1[current.pos[0] - 1] + current.seq1,
                        seq2: this.sequence2[current.pos[1] - 1] + current.seq2
                    });
                }
                if (directions[1]) {
                    inProcessAlignments.push({ pos: [current.pos[0] - 1, current.pos[1]],
                        seq1: this.sequence1[current.pos[0] - 1] + current.seq1,
                        seq2: '-' + current.seq2
                    });
                }
                if (directions[2]) {
                    inProcessAlignments.push({ pos: [current.pos[0], current.pos[1] - 1],
                        seq1: '-' + current.seq1,
                        seq2: this.sequence2[current.pos[1] - 1] + current.seq2
                    });
                }

                if (current.pos[0] === 0 && current.pos[1] === 0) this.alignments.push({ sequence1: current.seq1,
                    sequence2: current.seq2
                });

                inProcessAlignments.shift();
            }

            return this.alignments;
        }

        // Helper Functions

    }, {
        key: "getAllIndexes",
        value: function getAllIndexes(arr, val) {
            var indexes = [],
                i = -1;
            while ((i = arr.indexOf(val, i + 1)) !== -1) {
                indexes.push(i);
            }
            return indexes;
        }
    }, {
        key: "arrayAllMaxIndexes",
        value: function arrayAllMaxIndexes(array) {
            return this.getAllIndexes(array, Math.max.apply(null, array));
        }
    }]);

    return NeedlemanWunsch;
}();

module.exports = NeedlemanWunsch;

/***/ }),
/* 26 */
/***/ (function(module, exports, __nested_webpack_require_115611__) {

"use strict";


var layoutBase = function layoutBase() {
  return;
};

layoutBase.FDLayout = __nested_webpack_require_115611__(18);
layoutBase.FDLayoutConstants = __nested_webpack_require_115611__(7);
layoutBase.FDLayoutEdge = __nested_webpack_require_115611__(19);
layoutBase.FDLayoutNode = __nested_webpack_require_115611__(20);
layoutBase.DimensionD = __nested_webpack_require_115611__(21);
layoutBase.HashMap = __nested_webpack_require_115611__(22);
layoutBase.HashSet = __nested_webpack_require_115611__(23);
layoutBase.IGeometry = __nested_webpack_require_115611__(8);
layoutBase.IMath = __nested_webpack_require_115611__(9);
layoutBase.Integer = __nested_webpack_require_115611__(10);
layoutBase.Point = __nested_webpack_require_115611__(12);
layoutBase.PointD = __nested_webpack_require_115611__(4);
layoutBase.RandomSeed = __nested_webpack_require_115611__(16);
layoutBase.RectangleD = __nested_webpack_require_115611__(13);
layoutBase.Transform = __nested_webpack_require_115611__(17);
layoutBase.UniqueIDGeneretor = __nested_webpack_require_115611__(14);
layoutBase.Quicksort = __nested_webpack_require_115611__(24);
layoutBase.LinkedList = __nested_webpack_require_115611__(11);
layoutBase.LGraphObject = __nested_webpack_require_115611__(2);
layoutBase.LGraph = __nested_webpack_require_115611__(5);
layoutBase.LEdge = __nested_webpack_require_115611__(1);
layoutBase.LGraphManager = __nested_webpack_require_115611__(6);
layoutBase.LNode = __nested_webpack_require_115611__(3);
layoutBase.Layout = __nested_webpack_require_115611__(15);
layoutBase.LayoutConstants = __nested_webpack_require_115611__(0);
layoutBase.NeedlemanWunsch = __nested_webpack_require_115611__(25);

module.exports = layoutBase;

/***/ }),
/* 27 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


function Emitter() {
  this.listeners = [];
}

var p = Emitter.prototype;

p.addListener = function (event, callback) {
  this.listeners.push({
    event: event,
    callback: callback
  });
};

p.removeListener = function (event, callback) {
  for (var i = this.listeners.length; i >= 0; i--) {
    var l = this.listeners[i];

    if (l.event === event && l.callback === callback) {
      this.listeners.splice(i, 1);
    }
  }
};

p.emit = function (event, data) {
  for (var i = 0; i < this.listeners.length; i++) {
    var l = this.listeners[i];

    if (event === l.event) {
      l.callback(data);
    }
  }
};

module.exports = Emitter;

/***/ })
/******/ ]);
});

/***/ }),

/***/ 98055:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   diagram: () => (/* binding */ diagram)
/* harmony export */ });
/* harmony import */ var _mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(29997);
/* harmony import */ var d3__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(41506);
/* harmony import */ var cytoscape_dist_cytoscape_umd_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(15790);
/* harmony import */ var cytoscape_dist_cytoscape_umd_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(cytoscape_dist_cytoscape_umd_js__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var cytoscape_cose_bilkent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(43457);
/* harmony import */ var cytoscape_cose_bilkent__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(cytoscape_cose_bilkent__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(3219);
/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(78041);
/* harmony import */ var khroma__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(75263);
/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74353);
/* harmony import */ var dayjs__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(dayjs__WEBPACK_IMPORTED_MODULE_3__);
/* harmony import */ var _braintree_sanitize_url__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(16750);
/* harmony import */ var dompurify__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(54665);
/* harmony import */ var dagre_d3_es_src_dagre_index_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(80071);
/* harmony import */ var dagre_d3_es_src_graphlib_index_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(697);
/* harmony import */ var dagre_d3_es_src_graphlib_json_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(83765);
/* harmony import */ var dagre_d3_es__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(43709);
/* harmony import */ var dayjs_plugin_isoWeek_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(68313);
/* harmony import */ var dayjs_plugin_isoWeek_js__WEBPACK_IMPORTED_MODULE_10___default = /*#__PURE__*/__webpack_require__.n(dayjs_plugin_isoWeek_js__WEBPACK_IMPORTED_MODULE_10__);
/* harmony import */ var dayjs_plugin_customParseFormat_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(90445);
/* harmony import */ var dayjs_plugin_customParseFormat_js__WEBPACK_IMPORTED_MODULE_11___default = /*#__PURE__*/__webpack_require__.n(dayjs_plugin_customParseFormat_js__WEBPACK_IMPORTED_MODULE_11__);
/* harmony import */ var dayjs_plugin_advancedFormat_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(97375);
/* harmony import */ var dayjs_plugin_advancedFormat_js__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(dayjs_plugin_advancedFormat_js__WEBPACK_IMPORTED_MODULE_12__);
























var parser = function() {
  var o = function(k, v, o2, l) {
    for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v)
      ;
    return o2;
  }, $V0 = [1, 4], $V1 = [1, 13], $V2 = [1, 12], $V3 = [1, 15], $V4 = [1, 16], $V5 = [1, 20], $V6 = [1, 19], $V7 = [6, 7, 8], $V8 = [1, 26], $V9 = [1, 24], $Va = [1, 25], $Vb = [6, 7, 11], $Vc = [1, 6, 13, 15, 16, 19, 22], $Vd = [1, 33], $Ve = [1, 34], $Vf = [1, 6, 7, 11, 13, 15, 16, 19, 22];
  var parser2 = {
    trace: function trace() {
    },
    yy: {},
    symbols_: { "error": 2, "start": 3, "mindMap": 4, "spaceLines": 5, "SPACELINE": 6, "NL": 7, "MINDMAP": 8, "document": 9, "stop": 10, "EOF": 11, "statement": 12, "SPACELIST": 13, "node": 14, "ICON": 15, "CLASS": 16, "nodeWithId": 17, "nodeWithoutId": 18, "NODE_DSTART": 19, "NODE_DESCR": 20, "NODE_DEND": 21, "NODE_ID": 22, "$accept": 0, "$end": 1 },
    terminals_: { 2: "error", 6: "SPACELINE", 7: "NL", 8: "MINDMAP", 11: "EOF", 13: "SPACELIST", 15: "ICON", 16: "CLASS", 19: "NODE_DSTART", 20: "NODE_DESCR", 21: "NODE_DEND", 22: "NODE_ID" },
    productions_: [0, [3, 1], [3, 2], [5, 1], [5, 2], [5, 2], [4, 2], [4, 3], [10, 1], [10, 1], [10, 1], [10, 2], [10, 2], [9, 3], [9, 2], [12, 2], [12, 2], [12, 2], [12, 1], [12, 1], [12, 1], [12, 1], [12, 1], [14, 1], [14, 1], [18, 3], [17, 1], [17, 4]],
    performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {
      var $0 = $$.length - 1;
      switch (yystate) {
        case 6:
        case 7:
          return yy;
        case 8:
          yy.getLogger().trace("Stop NL ");
          break;
        case 9:
          yy.getLogger().trace("Stop EOF ");
          break;
        case 11:
          yy.getLogger().trace("Stop NL2 ");
          break;
        case 12:
          yy.getLogger().trace("Stop EOF2 ");
          break;
        case 15:
          yy.getLogger().info("Node: ", $$[$0].id);
          yy.addNode($$[$0 - 1].length, $$[$0].id, $$[$0].descr, $$[$0].type);
          break;
        case 16:
          yy.getLogger().trace("Icon: ", $$[$0]);
          yy.decorateNode({ icon: $$[$0] });
          break;
        case 17:
        case 21:
          yy.decorateNode({ class: $$[$0] });
          break;
        case 18:
          yy.getLogger().trace("SPACELIST");
          break;
        case 19:
          yy.getLogger().trace("Node: ", $$[$0].id);
          yy.addNode(0, $$[$0].id, $$[$0].descr, $$[$0].type);
          break;
        case 20:
          yy.decorateNode({ icon: $$[$0] });
          break;
        case 25:
          yy.getLogger().trace("node found ..", $$[$0 - 2]);
          this.$ = { id: $$[$0 - 1], descr: $$[$0 - 1], type: yy.getType($$[$0 - 2], $$[$0]) };
          break;
        case 26:
          this.$ = { id: $$[$0], descr: $$[$0], type: yy.nodeType.DEFAULT };
          break;
        case 27:
          yy.getLogger().trace("node found ..", $$[$0 - 3]);
          this.$ = { id: $$[$0 - 3], descr: $$[$0 - 1], type: yy.getType($$[$0 - 2], $$[$0]) };
          break;
      }
    },
    table: [{ 3: 1, 4: 2, 5: 3, 6: [1, 5], 8: $V0 }, { 1: [3] }, { 1: [2, 1] }, { 4: 6, 6: [1, 7], 7: [1, 8], 8: $V0 }, { 6: $V1, 7: [1, 10], 9: 9, 12: 11, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, o($V7, [2, 3]), { 1: [2, 2] }, o($V7, [2, 4]), o($V7, [2, 5]), { 1: [2, 6], 6: $V1, 12: 21, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, { 6: $V1, 9: 22, 12: 11, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, { 6: $V8, 7: $V9, 10: 23, 11: $Va }, o($Vb, [2, 22], { 17: 17, 18: 18, 14: 27, 15: [1, 28], 16: [1, 29], 19: $V5, 22: $V6 }), o($Vb, [2, 18]), o($Vb, [2, 19]), o($Vb, [2, 20]), o($Vb, [2, 21]), o($Vb, [2, 23]), o($Vb, [2, 24]), o($Vb, [2, 26], { 19: [1, 30] }), { 20: [1, 31] }, { 6: $V8, 7: $V9, 10: 32, 11: $Va }, { 1: [2, 7], 6: $V1, 12: 21, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, o($Vc, [2, 14], { 7: $Vd, 11: $Ve }), o($Vf, [2, 8]), o($Vf, [2, 9]), o($Vf, [2, 10]), o($Vb, [2, 15]), o($Vb, [2, 16]), o($Vb, [2, 17]), { 20: [1, 35] }, { 21: [1, 36] }, o($Vc, [2, 13], { 7: $Vd, 11: $Ve }), o($Vf, [2, 11]), o($Vf, [2, 12]), { 21: [1, 37] }, o($Vb, [2, 25]), o($Vb, [2, 27])],
    defaultActions: { 2: [2, 1], 6: [2, 2] },
    parseError: function parseError2(str, hash) {
      if (hash.recoverable) {
        this.trace(str);
      } else {
        var error = new Error(str);
        error.hash = hash;
        throw error;
      }
    },
    parse: function parse(input) {
      var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, TERROR = 2, EOF = 1;
      var args = lstack.slice.call(arguments, 1);
      var lexer2 = Object.create(this.lexer);
      var sharedState = { yy: {} };
      for (var k in this.yy) {
        if (Object.prototype.hasOwnProperty.call(this.yy, k)) {
          sharedState.yy[k] = this.yy[k];
        }
      }
      lexer2.setInput(input, sharedState.yy);
      sharedState.yy.lexer = lexer2;
      sharedState.yy.parser = this;
      if (typeof lexer2.yylloc == "undefined") {
        lexer2.yylloc = {};
      }
      var yyloc = lexer2.yylloc;
      lstack.push(yyloc);
      var ranges = lexer2.options && lexer2.options.ranges;
      if (typeof sharedState.yy.parseError === "function") {
        this.parseError = sharedState.yy.parseError;
      } else {
        this.parseError = Object.getPrototypeOf(this).parseError;
      }
      function lex() {
        var token;
        token = tstack.pop() || lexer2.lex() || EOF;
        if (typeof token !== "number") {
          if (token instanceof Array) {
            tstack = token;
            token = tstack.pop();
          }
          token = self.symbols_[token] || token;
        }
        return token;
      }
      var symbol, state, action, r, yyval = {}, p, len, newState, expected;
      while (true) {
        state = stack[stack.length - 1];
        if (this.defaultActions[state]) {
          action = this.defaultActions[state];
        } else {
          if (symbol === null || typeof symbol == "undefined") {
            symbol = lex();
          }
          action = table[state] && table[state][symbol];
        }
        if (typeof action === "undefined" || !action.length || !action[0]) {
          var errStr = "";
          expected = [];
          for (p in table[state]) {
            if (this.terminals_[p] && p > TERROR) {
              expected.push("'" + this.terminals_[p] + "'");
            }
          }
          if (lexer2.showPosition) {
            errStr = "Parse error on line " + (yylineno + 1) + ":\n" + lexer2.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
          } else {
            errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == EOF ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'");
          }
          this.parseError(errStr, {
            text: lexer2.match,
            token: this.terminals_[symbol] || symbol,
            line: lexer2.yylineno,
            loc: yyloc,
            expected
          });
        }
        if (action[0] instanceof Array && action.length > 1) {
          throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
        }
        switch (action[0]) {
          case 1:
            stack.push(symbol);
            vstack.push(lexer2.yytext);
            lstack.push(lexer2.yylloc);
            stack.push(action[1]);
            symbol = null;
            {
              yyleng = lexer2.yyleng;
              yytext = lexer2.yytext;
              yylineno = lexer2.yylineno;
              yyloc = lexer2.yylloc;
            }
            break;
          case 2:
            len = this.productions_[action[1]][1];
            yyval.$ = vstack[vstack.length - len];
            yyval._$ = {
              first_line: lstack[lstack.length - (len || 1)].first_line,
              last_line: lstack[lstack.length - 1].last_line,
              first_column: lstack[lstack.length - (len || 1)].first_column,
              last_column: lstack[lstack.length - 1].last_column
            };
            if (ranges) {
              yyval._$.range = [
                lstack[lstack.length - (len || 1)].range[0],
                lstack[lstack.length - 1].range[1]
              ];
            }
            r = this.performAction.apply(yyval, [
              yytext,
              yyleng,
              yylineno,
              sharedState.yy,
              action[1],
              vstack,
              lstack
            ].concat(args));
            if (typeof r !== "undefined") {
              return r;
            }
            if (len) {
              stack = stack.slice(0, -1 * len * 2);
              vstack = vstack.slice(0, -1 * len);
              lstack = lstack.slice(0, -1 * len);
            }
            stack.push(this.productions_[action[1]][0]);
            vstack.push(yyval.$);
            lstack.push(yyval._$);
            newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
            stack.push(newState);
            break;
          case 3:
            return true;
        }
      }
      return true;
    }
  };
  var lexer = function() {
    var lexer2 = {
      EOF: 1,
      parseError: function parseError2(str, hash) {
        if (this.yy.parser) {
          this.yy.parser.parseError(str, hash);
        } else {
          throw new Error(str);
        }
      },
      // resets the lexer, sets new input
      setInput: function(input, yy) {
        this.yy = yy || this.yy || {};
        this._input = input;
        this._more = this._backtrack = this.done = false;
        this.yylineno = this.yyleng = 0;
        this.yytext = this.matched = this.match = "";
        this.conditionStack = ["INITIAL"];
        this.yylloc = {
          first_line: 1,
          first_column: 0,
          last_line: 1,
          last_column: 0
        };
        if (this.options.ranges) {
          this.yylloc.range = [0, 0];
        }
        this.offset = 0;
        return this;
      },
      // consumes and returns one char from the input
      input: function() {
        var ch = this._input[0];
        this.yytext += ch;
        this.yyleng++;
        this.offset++;
        this.match += ch;
        this.matched += ch;
        var lines = ch.match(/(?:\r\n?|\n).*/g);
        if (lines) {
          this.yylineno++;
          this.yylloc.last_line++;
        } else {
          this.yylloc.last_column++;
        }
        if (this.options.ranges) {
          this.yylloc.range[1]++;
        }
        this._input = this._input.slice(1);
        return ch;
      },
      // unshifts one char (or a string) into the input
      unput: function(ch) {
        var len = ch.length;
        var lines = ch.split(/(?:\r\n?|\n)/g);
        this._input = ch + this._input;
        this.yytext = this.yytext.substr(0, this.yytext.length - len);
        this.offset -= len;
        var oldLines = this.match.split(/(?:\r\n?|\n)/g);
        this.match = this.match.substr(0, this.match.length - 1);
        this.matched = this.matched.substr(0, this.matched.length - 1);
        if (lines.length - 1) {
          this.yylineno -= lines.length - 1;
        }
        var r = this.yylloc.range;
        this.yylloc = {
          first_line: this.yylloc.first_line,
          last_line: this.yylineno + 1,
          first_column: this.yylloc.first_column,
          last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len
        };
        if (this.options.ranges) {
          this.yylloc.range = [r[0], r[0] + this.yyleng - len];
        }
        this.yyleng = this.yytext.length;
        return this;
      },
      // When called from action, caches matched text and appends it on next action
      more: function() {
        this._more = true;
        return this;
      },
      // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.
      reject: function() {
        if (this.options.backtrack_lexer) {
          this._backtrack = true;
        } else {
          return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\n" + this.showPosition(), {
            text: "",
            token: null,
            line: this.yylineno
          });
        }
        return this;
      },
      // retain first n characters of the match
      less: function(n) {
        this.unput(this.match.slice(n));
      },
      // displays already matched input, i.e. for error messages
      pastInput: function() {
        var past = this.matched.substr(0, this.matched.length - this.match.length);
        return (past.length > 20 ? "..." : "") + past.substr(-20).replace(/\n/g, "");
      },
      // displays upcoming input, i.e. for error messages
      upcomingInput: function() {
        var next = this.match;
        if (next.length < 20) {
          next += this._input.substr(0, 20 - next.length);
        }
        return (next.substr(0, 20) + (next.length > 20 ? "..." : "")).replace(/\n/g, "");
      },
      // displays the character position where the lexing error occurred, i.e. for error messages
      showPosition: function() {
        var pre = this.pastInput();
        var c = new Array(pre.length + 1).join("-");
        return pre + this.upcomingInput() + "\n" + c + "^";
      },
      // test the lexed token: return FALSE when not a match, otherwise return token
      test_match: function(match, indexed_rule) {
        var token, lines, backup;
        if (this.options.backtrack_lexer) {
          backup = {
            yylineno: this.yylineno,
            yylloc: {
              first_line: this.yylloc.first_line,
              last_line: this.last_line,
              first_column: this.yylloc.first_column,
              last_column: this.yylloc.last_column
            },
            yytext: this.yytext,
            match: this.match,
            matches: this.matches,
            matched: this.matched,
            yyleng: this.yyleng,
            offset: this.offset,
            _more: this._more,
            _input: this._input,
            yy: this.yy,
            conditionStack: this.conditionStack.slice(0),
            done: this.done
          };
          if (this.options.ranges) {
            backup.yylloc.range = this.yylloc.range.slice(0);
          }
        }
        lines = match[0].match(/(?:\r\n?|\n).*/g);
        if (lines) {
          this.yylineno += lines.length;
        }
        this.yylloc = {
          first_line: this.yylloc.last_line,
          last_line: this.yylineno + 1,
          first_column: this.yylloc.last_column,
          last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length
        };
        this.yytext += match[0];
        this.match += match[0];
        this.matches = match;
        this.yyleng = this.yytext.length;
        if (this.options.ranges) {
          this.yylloc.range = [this.offset, this.offset += this.yyleng];
        }
        this._more = false;
        this._backtrack = false;
        this._input = this._input.slice(match[0].length);
        this.matched += match[0];
        token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);
        if (this.done && this._input) {
          this.done = false;
        }
        if (token) {
          return token;
        } else if (this._backtrack) {
          for (var k in backup) {
            this[k] = backup[k];
          }
          return false;
        }
        return false;
      },
      // return next match in input
      next: function() {
        if (this.done) {
          return this.EOF;
        }
        if (!this._input) {
          this.done = true;
        }
        var token, match, tempMatch, index;
        if (!this._more) {
          this.yytext = "";
          this.match = "";
        }
        var rules = this._currentRules();
        for (var i = 0; i < rules.length; i++) {
          tempMatch = this._input.match(this.rules[rules[i]]);
          if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
            match = tempMatch;
            index = i;
            if (this.options.backtrack_lexer) {
              token = this.test_match(tempMatch, rules[i]);
              if (token !== false) {
                return token;
              } else if (this._backtrack) {
                match = false;
                continue;
              } else {
                return false;
              }
            } else if (!this.options.flex) {
              break;
            }
          }
        }
        if (match) {
          token = this.test_match(match, rules[index]);
          if (token !== false) {
            return token;
          }
          return false;
        }
        if (this._input === "") {
          return this.EOF;
        } else {
          return this.parseError("Lexical error on line " + (this.yylineno + 1) + ". Unrecognized text.\n" + this.showPosition(), {
            text: "",
            token: null,
            line: this.yylineno
          });
        }
      },
      // return next match that has a token
      lex: function lex() {
        var r = this.next();
        if (r) {
          return r;
        } else {
          return this.lex();
        }
      },
      // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)
      begin: function begin(condition) {
        this.conditionStack.push(condition);
      },
      // pop the previously active lexer condition state off the condition stack
      popState: function popState() {
        var n = this.conditionStack.length - 1;
        if (n > 0) {
          return this.conditionStack.pop();
        } else {
          return this.conditionStack[0];
        }
      },
      // produce the lexer rule set which is active for the currently active lexer condition state
      _currentRules: function _currentRules() {
        if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {
          return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;
        } else {
          return this.conditions["INITIAL"].rules;
        }
      },
      // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available
      topState: function topState(n) {
        n = this.conditionStack.length - 1 - Math.abs(n || 0);
        if (n >= 0) {
          return this.conditionStack[n];
        } else {
          return "INITIAL";
        }
      },
      // alias for begin(condition)
      pushState: function pushState(condition) {
        this.begin(condition);
      },
      // return the number of states currently on the stack
      stateStackSize: function stateStackSize() {
        return this.conditionStack.length;
      },
      options: { "case-insensitive": true },
      performAction: function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {
        switch ($avoiding_name_collisions) {
          case 0:
            yy.getLogger().trace("Found comment", yy_.yytext);
            break;
          case 1:
            return 8;
          case 2:
            this.begin("CLASS");
            break;
          case 3:
            this.popState();
            return 16;
          case 4:
            this.popState();
            break;
          case 5:
            yy.getLogger().trace("Begin icon");
            this.begin("ICON");
            break;
          case 6:
            yy.getLogger().trace("SPACELINE");
            return 6;
          case 7:
            return 7;
          case 8:
            return 15;
          case 9:
            yy.getLogger().trace("end icon");
            this.popState();
            break;
          case 10:
            yy.getLogger().trace("Exploding node");
            this.begin("NODE");
            return 19;
          case 11:
            yy.getLogger().trace("Cloud");
            this.begin("NODE");
            return 19;
          case 12:
            yy.getLogger().trace("Explosion Bang");
            this.begin("NODE");
            return 19;
          case 13:
            yy.getLogger().trace("Cloud Bang");
            this.begin("NODE");
            return 19;
          case 14:
            this.begin("NODE");
            return 19;
          case 15:
            this.begin("NODE");
            return 19;
          case 16:
            this.begin("NODE");
            return 19;
          case 17:
            this.begin("NODE");
            return 19;
          case 18:
            return 13;
          case 19:
            return 22;
          case 20:
            return 11;
          case 21:
            yy.getLogger().trace("Starting NSTR");
            this.begin("NSTR");
            break;
          case 22:
            yy.getLogger().trace("description:", yy_.yytext);
            return "NODE_DESCR";
          case 23:
            this.popState();
            break;
          case 24:
            this.popState();
            yy.getLogger().trace("node end ))");
            return "NODE_DEND";
          case 25:
            this.popState();
            yy.getLogger().trace("node end )");
            return "NODE_DEND";
          case 26:
            this.popState();
            yy.getLogger().trace("node end ...", yy_.yytext);
            return "NODE_DEND";
          case 27:
            this.popState();
            yy.getLogger().trace("node end ((");
            return "NODE_DEND";
          case 28:
            this.popState();
            yy.getLogger().trace("node end (-");
            return "NODE_DEND";
          case 29:
            this.popState();
            yy.getLogger().trace("node end (-");
            return "NODE_DEND";
          case 30:
            this.popState();
            yy.getLogger().trace("node end ((");
            return "NODE_DEND";
          case 31:
            this.popState();
            yy.getLogger().trace("node end ((");
            return "NODE_DEND";
          case 32:
            yy.getLogger().trace("Long description:", yy_.yytext);
            return 20;
          case 33:
            yy.getLogger().trace("Long description:", yy_.yytext);
            return 20;
        }
      },
      rules: [/^(?:\s*%%.*)/i, /^(?:mindmap\b)/i, /^(?::::)/i, /^(?:.+)/i, /^(?:\n)/i, /^(?:::icon\()/i, /^(?:[\s]+[\n])/i, /^(?:[\n]+)/i, /^(?:[^\)]+)/i, /^(?:\))/i, /^(?:-\))/i, /^(?:\(-)/i, /^(?:\)\))/i, /^(?:\))/i, /^(?:\(\()/i, /^(?:\{\{)/i, /^(?:\()/i, /^(?:\[)/i, /^(?:[\s]+)/i, /^(?:[^\(\[\n\-\)\{\}]+)/i, /^(?:$)/i, /^(?:["])/i, /^(?:[^"]+)/i, /^(?:["])/i, /^(?:[\)]\))/i, /^(?:[\)])/i, /^(?:[\]])/i, /^(?:\}\})/i, /^(?:\(-)/i, /^(?:-\))/i, /^(?:\(\()/i, /^(?:\()/i, /^(?:[^\)\]\(\}]+)/i, /^(?:.+(?!\(\())/i],
      conditions: { "CLASS": { "rules": [3, 4], "inclusive": false }, "ICON": { "rules": [8, 9], "inclusive": false }, "NSTR": { "rules": [22, 23], "inclusive": false }, "NODE": { "rules": [21, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33], "inclusive": false }, "INITIAL": { "rules": [0, 1, 2, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], "inclusive": true } }
    };
    return lexer2;
  }();
  parser2.lexer = lexer;
  function Parser() {
    this.yy = {};
  }
  Parser.prototype = parser2;
  parser2.Parser = Parser;
  return new Parser();
}();
parser.parser = parser;
const mindmapParser = parser;
const sanitizeText = (text) => (0,_mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.n)(text, (0,_mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.g)());
let nodes = [];
let cnt = 0;
let elements = {};
const clear = () => {
  nodes = [];
  cnt = 0;
  elements = {};
};
const getParent = function(level) {
  for (let i = nodes.length - 1; i >= 0; i--) {
    if (nodes[i].level < level) {
      return nodes[i];
    }
  }
  return null;
};
const getMindmap = () => {
  return nodes.length > 0 ? nodes[0] : null;
};
const addNode = (level, id, descr, type) => {
  _mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.l.info("addNode", level, id, descr, type);
  const conf = (0,_mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.g)();
  const node = {
    id: cnt++,
    nodeId: sanitizeText(id),
    level,
    descr: sanitizeText(descr),
    type,
    children: [],
    width: (0,_mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.g)().mindmap.maxNodeWidth
  };
  switch (node.type) {
    case nodeType.ROUNDED_RECT:
      node.padding = 2 * conf.mindmap.padding;
      break;
    case nodeType.RECT:
      node.padding = 2 * conf.mindmap.padding;
      break;
    case nodeType.HEXAGON:
      node.padding = 2 * conf.mindmap.padding;
      break;
    default:
      node.padding = conf.mindmap.padding;
  }
  const parent = getParent(level);
  if (parent) {
    parent.children.push(node);
    nodes.push(node);
  } else {
    if (nodes.length === 0) {
      nodes.push(node);
    } else {
      let error = new Error(
        'There can be only one root. No parent could be found for ("' + node.descr + '")'
      );
      error.hash = {
        text: "branch " + name,
        token: "branch " + name,
        line: "1",
        loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 },
        expected: ['"checkout ' + name + '"']
      };
      throw error;
    }
  }
};
const nodeType = {
  DEFAULT: 0,
  NO_BORDER: 0,
  ROUNDED_RECT: 1,
  RECT: 2,
  CIRCLE: 3,
  CLOUD: 4,
  BANG: 5,
  HEXAGON: 6
};
const getType = (startStr, endStr) => {
  _mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.l.debug("In get type", startStr, endStr);
  switch (startStr) {
    case "[":
      return nodeType.RECT;
    case "(":
      return endStr === ")" ? nodeType.ROUNDED_RECT : nodeType.CLOUD;
    case "((":
      return nodeType.CIRCLE;
    case ")":
      return nodeType.CLOUD;
    case "))":
      return nodeType.BANG;
    case "{{":
      return nodeType.HEXAGON;
    default:
      return nodeType.DEFAULT;
  }
};
const setElementForId = (id, element) => {
  elements[id] = element;
};
const decorateNode = (decoration) => {
  const node = nodes[nodes.length - 1];
  if (decoration && decoration.icon) {
    node.icon = sanitizeText(decoration.icon);
  }
  if (decoration && decoration.class) {
    node.class = sanitizeText(decoration.class);
  }
};
const type2Str = (type) => {
  switch (type) {
    case nodeType.DEFAULT:
      return "no-border";
    case nodeType.RECT:
      return "rect";
    case nodeType.ROUNDED_RECT:
      return "rounded-rect";
    case nodeType.CIRCLE:
      return "circle";
    case nodeType.CLOUD:
      return "cloud";
    case nodeType.BANG:
      return "bang";
    case nodeType.HEXAGON:
      return "hexgon";
    default:
      return "no-border";
  }
};
let parseError;
const setErrorHandler = (handler) => {
  parseError = handler;
};
const getLogger = () => _mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.l;
const getNodeById = (id) => nodes[id];
const getElementById = (id) => elements[id];
const mindmapDb = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
  __proto__: null,
  addNode,
  clear,
  decorateNode,
  getElementById,
  getLogger,
  getMindmap,
  getNodeById,
  getType,
  nodeType,
  get parseError() {
    return parseError;
  },
  sanitizeText,
  setElementForId,
  setErrorHandler,
  type2Str
}, Symbol.toStringTag, { value: "Module" }));
const MAX_SECTIONS = 12;
function wrap(text, width) {
  text.each(function() {
    var text2 = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(this), words = text2.text().split(/(\s+|<br>)/).reverse(), word, line = [], lineHeight = 1.1, y = text2.attr("y"), dy = parseFloat(text2.attr("dy")), tspan = text2.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
    for (let j = 0; j < words.length; j++) {
      word = words[words.length - 1 - j];
      line.push(word);
      tspan.text(line.join(" ").trim());
      if (tspan.node().getComputedTextLength() > width || word === "<br>") {
        line.pop();
        tspan.text(line.join(" ").trim());
        if (word === "<br>") {
          line = [""];
        } else {
          line = [word];
        }
        tspan = text2.append("tspan").attr("x", 0).attr("y", y).attr("dy", lineHeight + "em").text(word);
      }
    }
  });
}
const defaultBkg = function(elem, node, section) {
  const rd = 5;
  elem.append("path").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr(
    "d",
    `M0 ${node.height - rd} v${-node.height + 2 * rd} q0,-5 5,-5 h${node.width - 2 * rd} q5,0 5,5 v${node.height - rd} H0 Z`
  );
  elem.append("line").attr("class", "node-line-" + section).attr("x1", 0).attr("y1", node.height).attr("x2", node.width).attr("y2", node.height);
};
const rectBkg = function(elem, node) {
  elem.append("rect").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr("height", node.height).attr("width", node.width);
};
const cloudBkg = function(elem, node) {
  const w = node.width;
  const h = node.height;
  const r1 = 0.15 * w;
  const r2 = 0.25 * w;
  const r3 = 0.35 * w;
  const r4 = 0.2 * w;
  elem.append("path").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr(
    "d",
    `M0 0 a${r1},${r1} 0 0,1 ${w * 0.25},${-1 * w * 0.1}
      a${r3},${r3} 1 0,1 ${w * 0.4},${-1 * w * 0.1}
      a${r2},${r2} 1 0,1 ${w * 0.35},${1 * w * 0.2}

      a${r1},${r1} 1 0,1 ${w * 0.15},${1 * h * 0.35}
      a${r4},${r4} 1 0,1 ${-1 * w * 0.15},${1 * h * 0.65}

      a${r2},${r1} 1 0,1 ${-1 * w * 0.25},${w * 0.15}
      a${r3},${r3} 1 0,1 ${-1 * w * 0.5},${0}
      a${r1},${r1} 1 0,1 ${-1 * w * 0.25},${-1 * w * 0.15}

      a${r1},${r1} 1 0,1 ${-1 * w * 0.1},${-1 * h * 0.35}
      a${r4},${r4} 1 0,1 ${w * 0.1},${-1 * h * 0.65}

    H0 V0 Z`
  );
};
const bangBkg = function(elem, node) {
  const w = node.width;
  const h = node.height;
  const r = 0.15 * w;
  elem.append("path").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr(
    "d",
    `M0 0 a${r},${r} 1 0,0 ${w * 0.25},${-1 * h * 0.1}
      a${r},${r} 1 0,0 ${w * 0.25},${0}
      a${r},${r} 1 0,0 ${w * 0.25},${0}
      a${r},${r} 1 0,0 ${w * 0.25},${1 * h * 0.1}

      a${r},${r} 1 0,0 ${w * 0.15},${1 * h * 0.33}
      a${r * 0.8},${r * 0.8} 1 0,0 ${0},${1 * h * 0.34}
      a${r},${r} 1 0,0 ${-1 * w * 0.15},${1 * h * 0.33}

      a${r},${r} 1 0,0 ${-1 * w * 0.25},${h * 0.15}
      a${r},${r} 1 0,0 ${-1 * w * 0.25},${0}
      a${r},${r} 1 0,0 ${-1 * w * 0.25},${0}
      a${r},${r} 1 0,0 ${-1 * w * 0.25},${-1 * h * 0.15}

      a${r},${r} 1 0,0 ${-1 * w * 0.1},${-1 * h * 0.33}
      a${r * 0.8},${r * 0.8} 1 0,0 ${0},${-1 * h * 0.34}
      a${r},${r} 1 0,0 ${w * 0.1},${-1 * h * 0.33}

    H0 V0 Z`
  );
};
const circleBkg = function(elem, node) {
  elem.append("circle").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr("r", node.width / 2);
};
function insertPolygonShape(parent, w, h, points, node) {
  return parent.insert("polygon", ":first-child").attr(
    "points",
    points.map(function(d) {
      return d.x + "," + d.y;
    }).join(" ")
  ).attr("transform", "translate(" + (node.width - w) / 2 + ", " + h + ")");
}
const hexagonBkg = function(elem, node) {
  const h = node.height;
  const f = 4;
  const m = h / f;
  const w = node.width - node.padding + 2 * m;
  const points = [
    { x: m, y: 0 },
    { x: w - m, y: 0 },
    { x: w, y: -h / 2 },
    { x: w - m, y: -h },
    { x: m, y: -h },
    { x: 0, y: -h / 2 }
  ];
  insertPolygonShape(elem, w, h, points, node);
};
const roundedRectBkg = function(elem, node) {
  elem.append("rect").attr("id", "node-" + node.id).attr("class", "node-bkg node-" + type2Str(node.type)).attr("height", node.height).attr("rx", node.padding).attr("ry", node.padding).attr("width", node.width);
};
const drawNode = function(elem, node, fullSection, conf) {
  const section = fullSection % (MAX_SECTIONS - 1);
  const nodeElem = elem.append("g");
  node.section = section;
  let sectionClass = "section-" + section;
  if (section < 0) {
    sectionClass += " section-root";
  }
  nodeElem.attr("class", (node.class ? node.class + " " : "") + "mindmap-node " + sectionClass);
  const bkgElem = nodeElem.append("g");
  const textElem = nodeElem.append("g");
  const txt = textElem.append("text").text(node.descr).attr("dy", "1em").attr("alignment-baseline", "middle").attr("dominant-baseline", "middle").attr("text-anchor", "middle").call(wrap, node.width);
  const bbox = txt.node().getBBox();
  const fontSize = conf.fontSize.replace ? conf.fontSize.replace("px", "") : conf.fontSize;
  node.height = bbox.height + fontSize * 1.1 * 0.5 + node.padding;
  node.width = bbox.width + 2 * node.padding;
  if (node.icon) {
    if (node.type === nodeType.CIRCLE) {
      node.height += 50;
      node.width += 50;
      const icon = nodeElem.append("foreignObject").attr("height", "50px").attr("width", node.width).attr("style", "text-align: center;");
      icon.append("div").attr("class", "icon-container").append("i").attr("class", "node-icon-" + section + " " + node.icon);
      textElem.attr(
        "transform",
        "translate(" + node.width / 2 + ", " + (node.height / 2 - 1.5 * node.padding) + ")"
      );
    } else {
      node.width += 50;
      const orgHeight = node.height;
      node.height = Math.max(orgHeight, 60);
      const heightDiff = Math.abs(node.height - orgHeight);
      const icon = nodeElem.append("foreignObject").attr("width", "60px").attr("height", node.height).attr("style", "text-align: center;margin-top:" + heightDiff / 2 + "px;");
      icon.append("div").attr("class", "icon-container").append("i").attr("class", "node-icon-" + section + " " + node.icon);
      textElem.attr(
        "transform",
        "translate(" + (25 + node.width / 2) + ", " + (heightDiff / 2 + node.padding / 2) + ")"
      );
    }
  } else {
    textElem.attr("transform", "translate(" + node.width / 2 + ", " + node.padding / 2 + ")");
  }
  switch (node.type) {
    case nodeType.DEFAULT:
      defaultBkg(bkgElem, node, section);
      break;
    case nodeType.ROUNDED_RECT:
      roundedRectBkg(bkgElem, node);
      break;
    case nodeType.RECT:
      rectBkg(bkgElem, node);
      break;
    case nodeType.CIRCLE:
      bkgElem.attr("transform", "translate(" + node.width / 2 + ", " + +node.height / 2 + ")");
      circleBkg(bkgElem, node);
      break;
    case nodeType.CLOUD:
      cloudBkg(bkgElem, node);
      break;
    case nodeType.BANG:
      bangBkg(bkgElem, node);
      break;
    case nodeType.HEXAGON:
      hexagonBkg(bkgElem, node);
      break;
  }
  setElementForId(node.id, nodeElem);
  return node.height;
};
const drawEdge = function drawEdge2(edgesElem, mindmap, parent, depth, fullSection) {
  const section = fullSection % (MAX_SECTIONS - 1);
  const sx = parent.x + parent.width / 2;
  const sy = parent.y + parent.height / 2;
  const ex = mindmap.x + mindmap.width / 2;
  const ey = mindmap.y + mindmap.height / 2;
  const mx = ex > sx ? sx + Math.abs(sx - ex) / 2 : sx - Math.abs(sx - ex) / 2;
  const my = ey > sy ? sy + Math.abs(sy - ey) / 2 : sy - Math.abs(sy - ey) / 2;
  const qx = ex > sx ? Math.abs(sx - mx) / 2 + sx : -Math.abs(sx - mx) / 2 + sx;
  const qy = ey > sy ? Math.abs(sy - my) / 2 + sy : -Math.abs(sy - my) / 2 + sy;
  edgesElem.append("path").attr(
    "d",
    parent.direction === "TB" || parent.direction === "BT" ? `M${sx},${sy} Q${sx},${qy} ${mx},${my} T${ex},${ey}` : `M${sx},${sy} Q${qx},${sy} ${mx},${my} T${ex},${ey}`
  ).attr("class", "edge section-edge-" + section + " edge-depth-" + depth);
};
const positionNode = function(node) {
  const nodeElem = getElementById(node.id);
  const x = node.x || 0;
  const y = node.y || 0;
  nodeElem.attr("transform", "translate(" + x + "," + y + ")");
};
const svgDraw = { drawNode, positionNode, drawEdge };
cytoscape_dist_cytoscape_umd_js__WEBPACK_IMPORTED_MODULE_1___default().use((cytoscape_cose_bilkent__WEBPACK_IMPORTED_MODULE_2___default()));
function drawNodes(svg, mindmap, section, conf) {
  svgDraw.drawNode(svg, mindmap, section, conf);
  if (mindmap.children) {
    mindmap.children.forEach((child, index) => {
      drawNodes(svg, child, section < 0 ? index : section, conf);
    });
  }
}
function drawEdges(edgesEl, cy) {
  cy.edges().map((edge, id) => {
    const data = edge.data();
    if (edge[0]._private.bodyBounds) {
      const bounds = edge[0]._private.rscratch;
      _mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.l.trace("Edge: ", id, data);
      edgesEl.insert("path").attr(
        "d",
        `M ${bounds.startX},${bounds.startY} L ${bounds.midX},${bounds.midY} L${bounds.endX},${bounds.endY} `
      ).attr("class", "edge section-edge-" + data.section + " edge-depth-" + data.depth);
    }
  });
}
function addNodes(mindmap, cy, conf, level) {
  cy.add({
    group: "nodes",
    data: {
      id: mindmap.id,
      labelText: mindmap.descr,
      height: mindmap.height,
      width: mindmap.width,
      level,
      nodeId: mindmap.id,
      padding: mindmap.padding,
      type: mindmap.type
    },
    position: {
      x: mindmap.x,
      y: mindmap.y
    }
  });
  if (mindmap.children) {
    mindmap.children.forEach((child) => {
      addNodes(child, cy, conf, level + 1);
      cy.add({
        group: "edges",
        data: {
          id: `${mindmap.id}_${child.id}`,
          source: mindmap.id,
          target: child.id,
          depth: level,
          section: child.section
        }
      });
    });
  }
}
function layoutMindmap(node, conf) {
  return new Promise((resolve) => {
    const renderEl = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body").append("div").attr("id", "cy").attr("style", "display:none");
    const cy = cytoscape_dist_cytoscape_umd_js__WEBPACK_IMPORTED_MODULE_1___default()({
      container: document.getElementById("cy"),
      // container to render in
      style: [
        {
          selector: "edge",
          style: {
            "curve-style": "bezier"
          }
        }
      ]
    });
    renderEl.remove();
    addNodes(node, cy, conf, 0);
    cy.nodes().forEach(function(n) {
      n.layoutDimensions = () => {
        const data = n.data();
        return { w: data.width, h: data.height };
      };
    });
    cy.layout({
      name: "cose-bilkent",
      quality: "proof",
      // headless: true,
      styleEnabled: false,
      animate: false
    }).run();
    cy.ready((e) => {
      _mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.l.info("Ready", e);
      resolve(cy);
    });
  });
}
function positionNodes(cy) {
  cy.nodes().map((node, id) => {
    const data = node.data();
    data.x = node.position().x;
    data.y = node.position().y;
    svgDraw.positionNode(data);
    const el = getElementById(data.nodeId);
    _mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.l.info("Id:", id, "Position: (", node.position().x, ", ", node.position().y, ")", data);
    el.attr(
      "transform",
      `translate(${node.position().x - data.width / 2}, ${node.position().y - data.height / 2})`
    );
    el.attr("attr", `apa-${id})`);
  });
}
const draw = async (text, id, version, diagObj) => {
  const conf = (0,_mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.g)();
  diagObj.db.clear();
  diagObj.parser.parse(text);
  _mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.l.debug("Renering info diagram\n" + text);
  const securityLevel = (0,_mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.g)().securityLevel;
  let sandboxElement;
  if (securityLevel === "sandbox") {
    sandboxElement = (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("#i" + id);
  }
  const root = securityLevel === "sandbox" ? (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)(sandboxElement.nodes()[0].contentDocument.body) : (0,d3__WEBPACK_IMPORTED_MODULE_0__/* .select */ .Ltv)("body");
  const svg = root.select("#" + id);
  svg.append("g");
  const mm = diagObj.db.getMindmap();
  const edgesElem = svg.append("g");
  edgesElem.attr("class", "mindmap-edges");
  const nodesElem = svg.append("g");
  nodesElem.attr("class", "mindmap-nodes");
  drawNodes(nodesElem, mm, -1, conf);
  const cy = await layoutMindmap(mm, conf);
  drawEdges(edgesElem, cy);
  positionNodes(cy);
  (0,_mermaid_ae477ddf_js__WEBPACK_IMPORTED_MODULE_13__.s)(void 0, svg, conf.mindmap.padding, conf.mindmap.useMaxWidth);
};
const mindmapRenderer = {
  draw
};
const genSections = (options) => {
  let sections = "";
  for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) {
    options["lineColor" + i] = options["lineColor" + i] || options["cScaleInv" + i];
    if ((0,khroma__WEBPACK_IMPORTED_MODULE_14__/* ["default"] */ .A)(options["lineColor" + i])) {
      options["lineColor" + i] = (0,khroma__WEBPACK_IMPORTED_MODULE_15__/* ["default"] */ .A)(options["lineColor" + i], 20);
    } else {
      options["lineColor" + i] = (0,khroma__WEBPACK_IMPORTED_MODULE_16__/* ["default"] */ .A)(options["lineColor" + i], 20);
    }
  }
  for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) {
    const sw = "" + (17 - 3 * i);
    sections += `
    .section-${i - 1} rect, .section-${i - 1} path, .section-${i - 1} circle, .section-${i - 1} polygon, .section-${i - 1} path  {
      fill: ${options["cScale" + i]};
    }
    .section-${i - 1} text {
     fill: ${options["cScaleLabel" + i]};
    }
    .node-icon-${i - 1} {
      font-size: 40px;
      color: ${options["cScaleLabel" + i]};
    }
    .section-edge-${i - 1}{
      stroke: ${options["cScale" + i]};
    }
    .edge-depth-${i - 1}{
      stroke-width: ${sw};
    }
    .section-${i - 1} line {
      stroke: ${options["cScaleInv" + i]} ;
      stroke-width: 3;
    }

    .disabled, .disabled circle, .disabled text {
      fill: lightgray;
    }
    .disabled text {
      fill: #efefef;
    }
    `;
  }
  return sections;
};
const getStyles = (options) => `
  .edge {
    stroke-width: 3;
  }
  ${genSections(options)}
  .section-root rect, .section-root path, .section-root circle, .section-root polygon  {
    fill: ${options.git0};
  }
  .section-root text {
    fill: ${options.gitBranchLabel0};
  }
  .icon-container {
    height:100%;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .edge {
    fill: none;
  }
`;
const mindmapStyles = getStyles;
const diagram = {
  db: mindmapDb,
  renderer: mindmapRenderer,
  parser: mindmapParser,
  styles: mindmapStyles
};

//# sourceMappingURL=mindmap-definition-44684416.js.map


/***/ }),

/***/ 3219:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";

// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  A: () => (/* binding */ is_dark)
});

// EXTERNAL MODULE: ./node_modules/khroma/dist/utils/index.js + 3 modules
var utils = __webpack_require__(72453);
// EXTERNAL MODULE: ./node_modules/khroma/dist/color/index.js + 4 modules
var dist_color = __webpack_require__(74886);
;// CONCATENATED MODULE: ./node_modules/khroma/dist/methods/luminance.js
/* IMPORT */


/* MAIN */
//SOURCE: https://planetcalc.com/7779
const luminance = (color) => {
    const { r, g, b } = dist_color/* default */.A.parse(color);
    const luminance = .2126 * utils/* default */.A.channel.toLinear(r) + .7152 * utils/* default */.A.channel.toLinear(g) + .0722 * utils/* default */.A.channel.toLinear(b);
    return utils/* default */.A.lang.round(luminance);
};
/* EXPORT */
/* harmony default export */ const methods_luminance = (luminance);

;// CONCATENATED MODULE: ./node_modules/khroma/dist/methods/is_light.js
/* IMPORT */

/* MAIN */
const isLight = (color) => {
    return methods_luminance(color) >= .5;
};
/* EXPORT */
/* harmony default export */ const is_light = (isLight);

;// CONCATENATED MODULE: ./node_modules/khroma/dist/methods/is_dark.js
/* IMPORT */

/* MAIN */
const isDark = (color) => {
    return !is_light(color);
};
/* EXPORT */
/* harmony default export */ const is_dark = (isDark);


/***/ })

};
;