diff --git a/VQI_PathwayEditor.js b/VQI_PathwayEditor.js index 54e4c3c..b1e39bc 100755 --- a/VQI_PathwayEditor.js +++ b/VQI_PathwayEditor.js @@ -184,6 +184,18 @@ var VQI_PathwayEditor = function (parent) { strVar += " <\/input>"; strVar += " "; strVar += "
"; + strVar += "
"; + strVar += "
"; strVar += "
"; @@ -354,13 +366,25 @@ var VQI_PathwayEditor = function (parent) { cy.$("node")[i].style("backgroundImage", cy.$("node")[i].data("backgroundImage")); cy.$("node")[i].data("Type", "image"); } - } - - for (var i = 0; i < cy.$("node").length; i++) { - if (typeof (cy.$("node")[i].data("zIndex")) != "undefined") { + + if (typeof (cy.$("node")[i].data("zIndex")) != "undefined") { cy.$("node")[i].style("zIndex", cy.$("node")[i].data("zIndex")); } } + + for (var i = 0;i < cy.$("edge").length; i++){ + if (typeof (cy.$("edge")[i].data("curveStyle")) != "undefined") { + cy.$("edge")[i].style("curve-style", cy.$("edge")[i].data("curveStyle")); + } + + if (typeof (cy.$("edge")[i].data("segmentDistances")) != "undefined") { + cy.$("edge")[i].style("segment-distances", cy.$("edge")[i].data("segmentDistances")); + } + + if (typeof (cy.$("edge")[i].data("segmentWeights")) != "undefined") { + cy.$("edge")[i].style("segment-weights", cy.$("edge")[i].data("segmentWeights")); + } + } } function preAddProcessing(obj) { @@ -752,6 +776,9 @@ var VQI_PathwayEditor = function (parent) { source: node.children()[x].connectedEdges()[j].data('source'), target: node.children()[x].connectedEdges()[j].data('target'), StartArrow: node.children()[x].connectedEdges()[j].data('StartArrow'), + curveStyle: node.children()[x].connectedEdges()[j].data('curveStyle'), + segmentDistances: node.children()[x].connectedEdges()[j].data('segmentDistances'), + segmentWeights: node.children()[x].connectedEdges()[j].data('segmentWeights'), selected: node.children()[x].connectedEdges()[j].data('selected') } }) @@ -822,6 +849,9 @@ var VQI_PathwayEditor = function (parent) { source: node.children()[x].connectedEdges()[j].data('source'), target: node.children()[x].connectedEdges()[j].data('target'), StartArrow: node.children()[x].connectedEdges()[j].data('StartArrow'), + curveStyle: node.children()[x].connectedEdges()[j].data('curveStyle'), + segmentDistances: node.children()[x].connectedEdges()[j].data('segmentDistances'), + segmentWeights: node.children()[x].connectedEdges()[j].data('segmentWeights'), selected: node.children()[x].connectedEdges()[j].data('selected') } }) @@ -892,6 +922,9 @@ var VQI_PathwayEditor = function (parent) { source: node.connectedEdges()[j].data('source'), target: node.connectedEdges()[j].data('target'), StartArrow: node.connectedEdges()[j].data('StartArrow'), + curveStyle: node.connectedEdges()[j].data('curveStyle'), + segmentDistances: node.connectedEdges()[j].data('segmentDistances'), + segmentWeights: node.connectedEdges()[j].data('segmentWeights'), selected: node.connectedEdges()[j].data('selected') } }) @@ -968,6 +1001,9 @@ var VQI_PathwayEditor = function (parent) { source: selectedForEditNodes[i].connectedEdges()[j].data('source'), target: selectedForEditNodes[i].connectedEdges()[j].data('target'), StartArrow: selectedForEditNodes[i].connectedEdges()[j].data('StartArrow'), + curveStyle: selectedForEditNodes[i].connectedEdges()[j].data('curveStyle'), + segmentDistances: selectedForEditNodes[i].connectedEdges()[j].data('segmentDistances'), + segmentWeights: selectedForEditNodes[i].connectedEdges()[j].data('segmentWeights'), selected: selectedForEditNodes[i].connectedEdges()[j].data('selected') } }) @@ -1429,6 +1465,31 @@ var VQI_PathwayEditor = function (parent) { dialogEdge.dialog("close"); saveState(); } + + function toggleEdgeStyle(){ + if(document.getElementById(parent + '-segmented-enable-disable').value == "enable") + edgeEnableSegmentedStyle(); + else + edgeDisableSegmentedStyle(); + } + + function edgeEnableSegmentedStyle(){ + var segmentDistances = document.getElementById(parent + "-segment-distances").value; + var segmentWeights = document.getElementById(parent + "-segment-weights").value; + selectedForEditEdges.style('curve-style','segments'); + selectedForEditEdges.style('segment-distances',segmentDistances); + selectedForEditEdges.style('segment-weights',segmentWeights); + selectedForEditEdges.data('curveStyle','segments'); + selectedForEditEdges.data('segmentDistances',segmentDistances); + selectedForEditEdges.data('segmentWeights',segmentWeights); + saveState(); + } + + function edgeDisableSegmentedStyle(){ + selectedForEditEdges.style('curve-style','bezier'); + selectedForEditEdges.data('curveStyle','bezier'); + saveState(); + } function moveElementtoBackground(event) { selectedForEditNodes.style("z-index", 0); @@ -1846,7 +1907,7 @@ var VQI_PathwayEditor = function (parent) { // edge elements default css (unselected) .selector('edge').css({ - 'line-color': 'black', + 'line-color': 'black', 'line-style': 'solid', 'opacity': 0.75, 'text-opacity': 0.75, @@ -2279,6 +2340,7 @@ var VQI_PathwayEditor = function (parent) { document.getElementById(parent + '-direction-apply').addEventListener('click', editEdgeDirection); document.getElementById(parent + '-arrow-type-edge-apply').addEventListener('click', editEdgeArrowType); document.getElementById(parent + '-line-type-edge-apply').addEventListener('click', editEdgeLineType); + document.getElementById(parent + '-apply-curve-changes').addEventListener('click', toggleEdgeStyle); document.getElementById(parent + '-new-pathway').addEventListener('click', dialogNewPathwayOpen); document.getElementById(parent + '-findpath').addEventListener('click', dialogPathfindOpen); diff --git a/dependencies/cytoscape.js-2.5.4/LICENSE b/dependencies/cytoscape.js-2.5.4/LICENSE new file mode 100644 index 0000000..02bbb60 --- /dev/null +++ b/dependencies/cytoscape.js-2.5.4/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/dependencies/cytoscape.js-2.5.4/cytoscape.js b/dependencies/cytoscape.js-2.5.4/cytoscape.js new file mode 100644 index 0000000..287b2ee --- /dev/null +++ b/dependencies/cytoscape.js-2.5.4/cytoscape.js @@ -0,0 +1,24521 @@ +/*! + * This file is part of Cytoscape.js 2.5.4. + * + * Cytoscape.js is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * Cytoscape.js is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * Cytoscape.js. If not, see . + */ + +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.cytoscape = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) { + var minPos = findMin(openSet, fScore); + var cMin = cy.getElementById( openSet[minPos] ); + steps++; + + // If we've found our goal, then we are done + if (cMin.id() == target.id()) { + var rPath = reconstructPath(source.id(), target.id(), cameFrom, []); + rPath.reverse(); + return { + found : true, + distance : gScore[cMin.id()], + path : eles.spawn(rPath), + steps : steps + }; + } + + // Add cMin to processed nodes + closedSet.push(cMin.id()); + // Remove cMin from boundary nodes + openSet.splice(minPos, 1); + + // Update scores for neighbors of cMin + // Take into account if graph is directed or not + var vwEdges = cMin.connectedEdges(); + if( directed ){ vwEdges = vwEdges.stdFilter(function(ele){ return ele.data('source') === cMin.id(); }); } + vwEdges = vwEdges.intersect(edges); + + for (var i = 0; i < vwEdges.length; i++) { + var e = vwEdges[i]; + var w = e.connectedNodes().stdFilter(function(n){ return n.id() !== cMin.id(); }).intersect(nodes); + + // if node is in closedSet, ignore it + if (closedSet.indexOf(w.id()) != -1) { + continue; + } + + // New tentative score for node w + var tempScore = gScore[cMin.id()] + weightFn.apply(e, [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 (openSet.indexOf(w.id()) == -1) { + gScore[w.id()] = tempScore; + fScore[w.id()] = tempScore + heuristic(w); + openSet.push(w.id()); // Add node to openSet + cameFrom[w.id()] = cMin.id(); + cameFromEdge[w.id()] = e.id(); + continue; + } + // w already in openSet, but with greater gScore + if (tempScore < gScore[w.id()]) { + gScore[w.id()] = tempScore; + fScore[w.id()] = tempScore + heuristic(w); + cameFrom[w.id()] = cMin.id(); + } + + } // 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 + + +module.exports = elesfn; + +},{"../../is":77}],3:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../../is'); +var util = _dereq_('../../util'); + +var elesfn = ({ + + // Implemented from pseudocode from wikipedia + bellmanFord: function(options) { + var eles = this; + + options = options || {}; + + // Weight function - optional + if (options.weight != null && is.fn(options.weight)) { + var weightFn = options.weight; + } else { + // If not specified, assume each edge has equal weight (1) + var weightFn = function(e) {return 1;}; + } + + // directed - optional + if (options.directed != null) { + var directed = options.directed; + } else { + var directed = false; + } + + // root - mandatory! + if (options.root != null) { + if (is.string(options.root)) { + // use it as a selector, e.g. "#rootID + var source = this.filter(options.root)[0]; + } else { + var source = options.root[0]; + } + } else { + return undefined; + } + + var cy = this._private.cy; + var edges = this.edges().stdFilter(function(e){ return !e.isLoop(); }); + var nodes = this.nodes(); + var numNodes = nodes.length; + + // mapping: node id -> position in nodes array + var id2position = {}; + for (var i = 0; i < numNodes; i++) { + id2position[nodes[i].id()] = i; + } + + // Initializations + var cost = []; + var predecessor = []; + var predEdge = []; + + for (var i = 0; i < numNodes; i++) { + if (nodes[i].id() === source.id()) { + cost[i] = 0; + } else { + cost[i] = Infinity; + } + predecessor[i] = undefined; + } + + // Edges relaxation + var flag = false; + for (var i = 1; i < numNodes; i++) { + flag = false; + for (var e = 0; e < edges.length; e++) { + var sourceIndex = id2position[edges[e].source().id()]; + var targetIndex = id2position[edges[e].target().id()]; + var weight = weightFn.apply(edges[e], [edges[e]]); + + var temp = cost[sourceIndex] + weight; + if (temp < cost[targetIndex]) { + cost[targetIndex] = temp; + predecessor[targetIndex] = sourceIndex; + predEdge[targetIndex] = edges[e]; + flag = true; + } + + // If undirected graph, we need to take into account the 'reverse' edge + if (!directed) { + var temp = cost[targetIndex] + weight; + if (temp < cost[sourceIndex]) { + cost[sourceIndex] = temp; + predecessor[sourceIndex] = targetIndex; + predEdge[sourceIndex] = edges[e]; + flag = true; + } + } + } + + if (!flag) { + break; + } + } + + if (flag) { + // Check for negative weight cycles + for (var e = 0; e < edges.length; e++) { + var sourceIndex = id2position[edges[e].source().id()]; + var targetIndex = id2position[edges[e].target().id()]; + var weight = weightFn.apply(edges[e], [edges[e]]); + + if (cost[sourceIndex] + weight < cost[targetIndex]) { + util.error("Graph contains a negative weight cycle for Bellman-Ford"); + return { pathTo: undefined, + distanceTo: undefined, + hasNegativeWeightCycle: true}; + } + } + } + + // Build result object + var position2id = []; + for (var i = 0; i < numNodes; i++) { + position2id.push(nodes[i].id()); + } + + + var res = { + distanceTo : function(to) { + if (is.string(to)) { + // to is a selector string + var toId = (cy.filter(to)[0]).id(); + } else { + // to is a node + var toId = to.id(); + } + + return cost[id2position[toId]]; + }, + + pathTo : function(to) { + + var reconstructPathAux = function(predecessor, fromPos, toPos, position2id, acumPath, predEdge) { + for(;;){ + // Add toId to path + acumPath.push( cy.getElementById(position2id[toPos]) ); + acumPath.push( predEdge[toPos] ); + + if (fromPos === toPos) { + // reached starting node + return acumPath; + } + + // If no path exists, discart acumulated path and return undefined + var predPos = predecessor[toPos]; + if (typeof predPos === "undefined") { + return undefined; + } + + toPos = predPos; + } + + }; + + if (is.string(to)) { + // to is a selector string + var toId = (cy.filter(to)[0]).id(); + } else { + // to is a node + var toId = to.id(); + } + var path = []; + + // This returns a reversed path + var res = reconstructPathAux(predecessor, + id2position[source.id()], + id2position[toId], + position2id, + path, + predEdge); + + // Get it in the correct order and return it + if (res != null) { + res.reverse(); + } + + return eles.spawn(res); + }, + + hasNegativeWeightCycle: false + }; + + return res; + + } // bellmanFord + +}); // elesfn + +module.exports = elesfn; + +},{"../../is":77,"../../util":94}],4:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../../is'); + +var elesfn = ({ + + // Implemented from the algorithm in the paper "On Variants of Shortest-Path Betweenness Centrality and their Generic Computation" by Ulrik Brandes + betweennessCentrality: function (options) { + options = options || {}; + + // Weight - optional + if (options.weight != null && is.fn(options.weight)) { + var weightFn = options.weight; + var weighted = true; + } else { + var weighted = false; + } + + // Directed - default false + if (options.directed != null && is.bool(options.directed)) { + var directed = options.directed; + } else { + var directed = false; + } + + var priorityInsert = function (queue, ele) { + queue.unshift(ele); + for (var i = 0; d[queue[i]] < d[queue[i + 1]] && i < queue.length - 1; i++) { + var tmp = queue[i]; + queue[i] = queue[i + 1]; + queue[i + 1] = tmp; + } + }; + + var cy = this._private.cy; + + // starting + var V = this.nodes(); + var A = {}; + var C = {}; + + // A contains the neighborhoods of every node + for (var i = 0; i < V.length; i++) { + if (directed) { + A[V[i].id()] = V[i].outgoers("node"); // get outgoers of every node + } else { + A[V[i].id()] = V[i].openNeighborhood("node"); // get neighbors of every node + } + } + + // C contains the betweenness values + for (var i = 0; i < V.length; i++) { + C[V[i].id()] = 0; + } + + for (var s = 0; s < V.length; s++) { + var S = []; // stack + var P = {}; + var g = {}; + var d = {}; + var Q = []; // queue + + // init dictionaries + for (var i = 0; i < V.length; i++) { + P[V[i].id()] = []; + g[V[i].id()] = 0; + d[V[i].id()] = Number.POSITIVE_INFINITY; + } + + g[V[s].id()] = 1; // sigma + d[V[s].id()] = 0; // distance to s + + Q.unshift(V[s].id()); + + while (Q.length > 0) { + var v = Q.pop(); + S.push(v); + if (weighted) { + A[v].forEach(function (w) { + if (cy.$('#' + v).edgesTo(w).length > 0) { + var edge = cy.$('#' + v).edgesTo(w)[0]; + } else { + var edge = w.edgesTo('#' + v)[0]; + } + + var edgeWeight = weightFn.apply(edge, [edge]); + + if (d[w.id()] > d[v] + edgeWeight) { + d[w.id()] = d[v] + edgeWeight; + if (Q.indexOf(w.id()) < 0) { //if w is not in Q + priorityInsert(Q, w.id()); + } else { // update position if w is in Q + Q.splice(Q.indexOf(w.id()), 1); + priorityInsert(Q, w.id()); + } + g[w.id()] = 0; + P[w.id()] = []; + } + if (d[w.id()] == d[v] + edgeWeight) { + g[w.id()] = g[w.id()] + g[v]; + P[w.id()].push(v); + } + }); + } else { + A[v].forEach(function (w) { + if (d[w.id()] == Number.POSITIVE_INFINITY) { + Q.unshift(w.id()); + d[w.id()] = d[v] + 1; + } + if (d[w.id()] == d[v] + 1) { + g[w.id()] = g[w.id()] + g[v]; + P[w.id()].push(v); + } + }); + } + } + + var e = {}; + for (var i = 0; i < V.length; i++) { + e[V[i].id()] = 0; + } + + while (S.length > 0) { + var w = S.pop(); + P[w].forEach(function (v) { + e[v] = e[v] + (g[v] / g[w]) * (1 + e[w]); + if (w != V[s].id()) + C[w] = C[w] + e[w]; + }); + } + } + + var max = 0; + for (var key in C) { + if (max < C[key]) + max = C[key]; + } + + var ret = { + betweenness: function (node) { + if (is.string(node)) { + var node = (cy.filter(node)[0]).id(); + } else { + var node = node.id(); + } + + return C[node]; + }, + + betweennessNormalized: function (node) { + if (is.string(node)) { + var node = (cy.filter(node)[0]).id(); + } else { + var node = node.id(); + } + + return C[node] / max; + } + }; + + // alias + ret.betweennessNormalised = ret.betweennessNormalized; + + return ret; + } // betweennessCentrality + +}); // elesfn + +// nice, short mathemathical alias +elesfn.bc = elesfn.betweennessCentrality; + +module.exports = elesfn; + +},{"../../is":77}],5:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../../is'); +var Heap = _dereq_('../../heap'); + +var defineSearch = function( params ){ + params = { + bfs: params.bfs || !params.dfs, + dfs: params.dfs || !params.bfs + }; + + // from pseudocode on wikipedia + return function searchFn( roots, fn, directed ){ + var options; + var std; + var thisArg; + if( is.plainObject(roots) && !is.elementOrCollection(roots) ){ + options = roots; + roots = options.roots || options.root; + fn = options.visit; + directed = options.directed; + std = options.std; + thisArg = options.thisArg; + } + + directed = arguments.length === 2 && !is.fn(fn) ? fn : directed; + fn = is.fn(fn) ? fn : function(){}; + + var cy = this._private.cy; + var v = roots = is.string(roots) ? this.filter(roots) : roots; + var Q = []; + var connectedNodes = []; + var connectedBy = {}; + var id2depth = {}; + var V = {}; + var j = 0; + var found; + var nodes = this.nodes(); + var edges = this.edges(); + + // enqueue v + for( var i = 0; i < v.length; i++ ){ + if( v[i].isNode() ){ + Q.unshift( v[i] ); + + if( params.bfs ){ + V[ v[i].id() ] = true; + + connectedNodes.push( v[i] ); + } + + id2depth[ v[i].id() ] = 0; + } + } + + while( Q.length !== 0 ){ + var v = params.bfs ? Q.shift() : Q.pop(); + + if( params.dfs ){ + if( V[ v.id() ] ){ continue; } + + V[ v.id() ] = true; + + connectedNodes.push( v ); + } + + var depth = id2depth[ v.id() ]; + var prevEdge = connectedBy[ v.id() ]; + var prevNode = prevEdge == null ? undefined : prevEdge.connectedNodes().not( v )[0]; + var ret; + + if( std ){ + ret = fn.call(thisArg, v, prevEdge, prevNode, j++, depth); + } else { + ret = fn.call(v, j++, depth, v, prevEdge, prevNode); + } + + if( ret === true ){ + found = v; + break; + } + + if( ret === false ){ + break; + } + + var vwEdges = v.connectedEdges(directed ? function(){ return this.data('source') === v.id(); } : undefined).intersect( edges ); + for( var i = 0; i < vwEdges.length; i++ ){ + var e = vwEdges[i]; + var w = e.connectedNodes(function(){ return this.id() !== v.id(); }).intersect( nodes ); + + if( w.length !== 0 && !V[ w.id() ] ){ + w = w[0]; + + Q.push( w ); + + if( params.bfs ){ + V[ w.id() ] = true; + + connectedNodes.push( w ); + } + + connectedBy[ w.id() ] = e; + + id2depth[ w.id() ] = id2depth[ v.id() ] + 1; + } + } + + } + + var connectedEles = []; + + for( var i = 0; i < connectedNodes.length; i++ ){ + var node = connectedNodes[i]; + var edge = connectedBy[ node.id() ]; + + if( edge ){ + connectedEles.push( edge ); + } + + connectedEles.push( node ); + } + + return { + path: cy.collection( connectedEles, { unique: true } ), + found: cy.collection( found ) + }; + }; +}; + +// search, spanning trees, etc +var elesfn = ({ + + breadthFirstSearch: defineSearch({ bfs: true }), + depthFirstSearch: defineSearch({ dfs: true }), + + // kruskal's algorithm (finds min spanning tree, assuming undirected graph) + // implemented from pseudocode from wikipedia + kruskal: function( weightFn ){ + var cy = this.cy(); + + weightFn = is.fn(weightFn) ? weightFn : function(){ return 1; }; // if not specified, assume each edge has equal weight (1) + + function findSet(ele){ + for( var i = 0; i < forest.length; i++ ){ + var eles = forest[i]; + + if( eles.anySame(ele) ){ + return { + eles: eles, + index: i + }; + } + } + } + + var A = cy.collection(cy, []); + var forest = []; + var nodes = this.nodes(); + + for( var i = 0; i < nodes.length; i++ ){ + forest.push( nodes[i].collection() ); + } + + var edges = this.edges(); + var S = edges.toArray().sort(function(a, b){ + var weightA = weightFn.call(a, a); + var weightB = weightFn.call(b, b); + + return weightA - weightB; + }); + + for(var i = 0; i < S.length; i++){ + var edge = S[i]; + var u = edge.source()[0]; + var v = edge.target()[0]; + var setU = findSet(u); + var setV = findSet(v); + + if( setU.index !== setV.index ){ + A = A.add( edge ); + + // combine forests for u and v + forest[ setU.index ] = setU.eles.add( setV.eles ); + forest.splice( setV.index, 1 ); + } + } + + return nodes.add( A ); + + }, + + dijkstra: function( root, weightFn, directed ){ + var options; + if( is.plainObject(root) && !is.elementOrCollection(root) ){ + options = root; + root = options.root; + weightFn = options.weight; + directed = options.directed; + } + + var cy = this._private.cy; + weightFn = is.fn(weightFn) ? weightFn : function(){ return 1; }; // if not specified, assume each edge has equal weight (1) + + var source = is.string(root) ? this.filter(root)[0] : root[0]; + var dist = {}; + var prev = {}; + var knownDist = {}; + + var edges = this.edges().filter(function(){ return !this.isLoop(); }); + var nodes = this.nodes(); + + var getDist = function(node){ + return dist[ node.id() ]; + }; + + var setDist = function(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(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.apply( edge, [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 === Math.Infinite ){ + break; + } + + var neighbors = u.neighborhood().intersect(nodes); + for( var i = 0; i < neighbors.length; i++ ){ + var v = neighbors[i]; + 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(node){ + var target = is.string(node) ? nodes.filter(node)[0] : node[0]; + + return knownDist[ target.id() ]; + }, + + pathTo: function(node){ + var target = is.string(node) ? nodes.filter(node)[0] : node[0]; + var S = []; + var u = target; + + if( target.length > 0 ){ + S.unshift( target ); + + while( prev[ u.id() ] ){ + var p = prev[ u.id() ]; + + S.unshift( p.edge ); + S.unshift( p.node ); + + u = p.node; + } + } + + return cy.collection( S ); + } + }; + } +}); + +// nice, short mathemathical alias +elesfn.bfs = elesfn.breadthFirstSearch; +elesfn.dfs = elesfn.depthFirstSearch; + +module.exports = elesfn; + +},{"../../heap":75,"../../is":77}],6:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../../is'); + +var elesfn = ({ + + closenessCentralityNormalized: function (options) { + options = options || {}; + + var cy = this.cy(); + + var harmonic = options.harmonic; + if( harmonic === undefined ){ + harmonic = true; + } + + var closenesses = {}; + var maxCloseness = 0; + var nodes = this.nodes(); + var fw = this.floydWarshall({ weight: options.weight, directed: options.directed }); + + // Compute closeness for every node and find the maximum closeness + for(var i = 0; i < nodes.length; i++){ + var currCloseness = 0; + for (var j = 0; j < nodes.length; j++) { + if (i != j) { + var d = fw.distance(nodes[i], nodes[j]); + + if( harmonic ){ + currCloseness += 1 / d; + } else { + currCloseness += d; + } + } + } + + if( !harmonic ){ + currCloseness = 1 / currCloseness; + } + + if (maxCloseness < currCloseness){ + maxCloseness = currCloseness; + } + + closenesses[nodes[i].id()] = currCloseness; + } + + return { + closeness: function (node) { + if (is.string(node)) { + // from is a selector string + var node = (cy.filter(node)[0]).id(); + } else { + // from is a node + var node = node.id(); + } + + return closenesses[node] / maxCloseness; + } + }; + }, + + // Implemented from pseudocode from wikipedia + closenessCentrality: function (options) { + options = options || {}; + + // root - mandatory! + if (options.root != null) { + if (is.string(options.root)) { + // use it as a selector, e.g. "#rootID + var root = this.filter(options.root)[0]; + } else { + var root = options.root[0]; + } + } else { + return undefined; + } + + // weight - optional + if (options.weight != null && is.fn(options.weight)) { + var weight = options.weight; + } else { + var weight = function(){return 1;}; + } + + // directed - optional + if (options.directed != null && is.bool(options.directed)) { + var directed = options.directed; + } else { + var directed = false; + } + + var harmonic = options.harmonic; + if( harmonic === undefined ){ + harmonic = true; + } + + // 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++){ + if (nodes[i].id() != root.id()){ + var d = dijkstra.distanceTo(nodes[i]); + + if( harmonic ){ + totalDistance += 1 / d; + } else { + totalDistance += d; + } + } + } + + return harmonic ? totalDistance : 1 / totalDistance; + } // closenessCentrality + +}); // elesfn + +// nice, short mathemathical alias +elesfn.cc = elesfn.closenessCentrality; +elesfn.ccn = elesfn.closenessCentralityNormalised = elesfn.closenessCentralityNormalized; + +module.exports = elesfn; + +},{"../../is":77}],7:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../../is'); +var util = _dereq_('../../util'); + +var elesfn = ({ + + degreeCentralityNormalized: function (options) { + options = options || {}; + + var cy = this.cy(); + + // directed - optional + if (options.directed != null) { + var directed = options.directed; + } else { + var directed = false; + } + + var nodes = this.nodes(); + var numNodes = nodes.length; + + if (!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 + var currDegree = this.degreeCentrality(util.extend({}, options, {root: node})); + if (maxDegree < currDegree.degree) + maxDegree = currDegree.degree; + + degrees[node.id()] = currDegree.degree; + } + + return { + degree: function (node) { + if (is.string(node)) { + // from is a selector string + var node = (cy.filter(node)[0]).id(); + } else { + // from is a node + var node = node.id(); + } + + return degrees[node] / maxDegree; + } + }; + } else { + var indegrees = {}; + var outdegrees = {}; + var maxIndegree = 0; + var maxOutdegree = 0; + + for (var i = 0; i < numNodes; i++) { + var node = nodes[i]; + // add current node to the current options object and call degreeCentrality + var currDegree = this.degreeCentrality(util.extend({}, options, {root: node})); + + if (maxIndegree < currDegree.indegree) + maxIndegree = currDegree.indegree; + + if (maxOutdegree < currDegree.outdegree) + maxOutdegree = currDegree.outdegree; + + indegrees[node.id()] = currDegree.indegree; + outdegrees[node.id()] = currDegree.outdegree; + } + + return { + indegree: function (node) { + if (is.string(node)) { + // from is a selector string + var node = (cy.filter(node)[0]).id(); + } else { + // from is a node + var node = node.id(); + } + + return indegrees[node] / maxIndegree; + }, + outdegree: function (node) { + if (is.string(node)) { + // from is a selector string + var node = (cy.filter(node)[0]).id(); + } else { + // from is a node + var node = node.id(); + } + + return outdegrees[node] / 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 (options) { + options = options || {}; + + var callingEles = this; + + // root - mandatory! + if (options != null && options.root != null) { + var root = is.string(options.root) ? this.filter(options.root)[0] : options.root[0]; + } else { + return undefined; + } + + // weight - optional + if (options.weight != null && is.fn(options.weight)) { + var weightFn = options.weight; + } else { + // If not specified, assume each edge has equal weight (1) + var weightFn = function (e) { + return 1; + }; + } + + // directed - optional + if (options.directed != null) { + var directed = options.directed; + } else { + var directed = false; + } + + // alpha - optional + if (options.alpha != null && is.number(options.alpha)) { + var alpha = options.alpha; + } else { + alpha = 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++) { + var edge = connEdges[i]; + s += weightFn.apply(edge, [edge]); + } + + return { + degree: Math.pow(k, 1 - alpha) * Math.pow(s, alpha) + }; + } else { + var incoming = root.connectedEdges('edge[target = "' + root.id() + '"]').intersection( callingEles ); + var outgoing = root.connectedEdges('edge[source = "' + root.id() + '"]').intersection( callingEles ); + 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 i = 0; i < incoming.length; i++) { + var edge = incoming[i]; + s_in += weightFn.apply(edge, [edge]); + } + + // Now, sum outgoing edge weights + for (var i = 0; i < outgoing.length; i++) { + var edge = outgoing[i]; + s_out += weightFn.apply(edge, [edge]); + } + + 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 mathemathical alias +elesfn.dc = elesfn.degreeCentrality; +elesfn.dcn = elesfn.degreeCentralityNormalised = elesfn.degreeCentralityNormalized; + +module.exports = elesfn; + +},{"../../is":77,"../../util":94}],8:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../../is'); + +var elesfn = ({ + + // Implemented from pseudocode from wikipedia + floydWarshall: function(options) { + options = options || {}; + + var cy = this.cy(); + + // Weight function - optional + if (options.weight != null && is.fn(options.weight)) { + var weightFn = options.weight; + } else { + // If not specified, assume each edge has equal weight (1) + var weightFn = function(e) {return 1;}; + } + + // directed - optional + if (options.directed != null) { + var directed = options.directed; + } else { + var directed = false; + } + + var edges = this.edges().stdFilter(function(e){ return !e.isLoop(); }); + var nodes = this.nodes(); + var numNodes = nodes.length; + + // mapping: node id -> position in nodes array + var id2position = {}; + for (var i = 0; i < numNodes; i++) { + id2position[nodes[i].id()] = i; + } + + // Initialize distance matrix + var dist = []; + for (var i = 0; i < numNodes; i++) { + var newRow = new Array(numNodes); + for (var j = 0; j < numNodes; j++) { + if (i == j) { + newRow[j] = 0; + } else { + newRow[j] = Infinity; + } + } + dist.push(newRow); + } + + // Initialize matrix used for path reconstruction + // Initialize distance matrix + var next = []; + var edgeNext = []; + + var initMatrix = function(next){ + for (var i = 0; i < numNodes; i++) { + var newRow = new Array(numNodes); + for (var j = 0; j < numNodes; j++) { + newRow[j] = undefined; + } + next.push(newRow); + } + }; + + initMatrix(next); + initMatrix(edgeNext); + + // Process edges + for (var i = 0; i < edges.length ; i++) { + var sourceIndex = id2position[edges[i].source().id()]; + var targetIndex = id2position[edges[i].target().id()]; + var weight = weightFn.apply(edges[i], [edges[i]]); + + // Check if already process another edge between same 2 nodes + if (dist[sourceIndex][targetIndex] > weight) { + dist[sourceIndex][targetIndex] = weight; + next[sourceIndex][targetIndex] = targetIndex; + edgeNext[sourceIndex][targetIndex] = edges[i]; + } + } + + // If undirected graph, process 'reversed' edges + if (!directed) { + for (var i = 0; i < edges.length ; i++) { + var sourceIndex = id2position[edges[i].target().id()]; + var targetIndex = id2position[edges[i].source().id()]; + var weight = weightFn.apply(edges[i], [edges[i]]); + + // Check if already process another edge between same 2 nodes + if (dist[sourceIndex][targetIndex] > weight) { + dist[sourceIndex][targetIndex] = weight; + next[sourceIndex][targetIndex] = targetIndex; + edgeNext[sourceIndex][targetIndex] = edges[i]; + } + } + } + + // Main loop + for (var k = 0; k < numNodes; k++) { + for (var i = 0; i < numNodes; i++) { + for (var j = 0; j < numNodes; j++) { + if (dist[i][k] + dist[k][j] < dist[i][j]) { + dist[i][j] = dist[i][k] + dist[k][j]; + next[i][j] = next[i][k]; + } + } + } + } + + // Build result object + var position2id = []; + for (var i = 0; i < numNodes; i++) { + position2id.push(nodes[i].id()); + } + + var res = { + distance: function(from, to) { + if (is.string(from)) { + // from is a selector string + var fromId = (cy.filter(from)[0]).id(); + } else { + // from is a node + var fromId = from.id(); + } + + if (is.string(to)) { + // to is a selector string + var toId = (cy.filter(to)[0]).id(); + } else { + // to is a node + var toId = to.id(); + } + + return dist[id2position[fromId]][id2position[toId]]; + }, + + path: function(from, to) { + var reconstructPathAux = function(from, to, next, position2id, edgeNext) { + if (from === to) { + return cy.getElementById( position2id[from] ); + } + if (next[from][to] === undefined) { + return undefined; + } + + var path = [ cy.getElementById(position2id[from]) ]; + var prev = from; + while (from !== to) { + prev = from; + from = next[from][to]; + + var edge = edgeNext[prev][from]; + path.push( edge ); + + path.push( cy.getElementById(position2id[from]) ); + } + return path; + }; + + if (is.string(from)) { + // from is a selector string + var fromId = (cy.filter(from)[0]).id(); + } else { + // from is a node + var fromId = from.id(); + } + + if (is.string(to)) { + // to is a selector string + var toId = (cy.filter(to)[0]).id(); + } else { + // to is a node + var toId = to.id(); + } + + var pathArr = reconstructPathAux(id2position[fromId], + id2position[toId], + next, + position2id, + edgeNext); + + return cy.collection( pathArr ); + } + }; + + return res; + + } // floydWarshall + +}); // elesfn + +module.exports = elesfn; + +},{"../../is":77}],9:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../../util'); + +var elesfn = {}; + +[ + _dereq_('./bfs-dfs'), + _dereq_('./a-star'), + _dereq_('./floyd-warshall'), + _dereq_('./bellman-ford'), + _dereq_('./kerger-stein'), + _dereq_('./page-rank'), + _dereq_('./degree-centrality'), + _dereq_('./closeness-centrality'), + _dereq_('./betweenness-centrality') +].forEach(function( props ){ + util.extend( elesfn, props ); +}); + +module.exports = elesfn; + +},{"../../util":94,"./a-star":2,"./bellman-ford":3,"./betweenness-centrality":4,"./bfs-dfs":5,"./closeness-centrality":6,"./degree-centrality":7,"./floyd-warshall":8,"./kerger-stein":10,"./page-rank":11}],10:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../../util'); + +var elesfn = ({ + + // Computes the minimum cut of an undirected graph + // Returns the correct answer with high probability + kargerStein: function(options) { + var eles = this; + + options = options || {}; + + // Function which colapses 2 (meta) nodes into one + // Updates the remaining edge lists + // Receives as a paramater the edge which causes the collapse + var colapse = function(edgeIndex, nodeMap, remainingEdges) { + var edgeInfo = remainingEdges[edgeIndex]; + var sourceIn = edgeInfo[1]; + var targetIn = edgeInfo[2]; + var partition1 = nodeMap[sourceIn]; + var partition2 = nodeMap[targetIn]; + + // Delete all edges between partition1 and partition2 + var newEdges = remainingEdges.filter(function(edge) { + if (nodeMap[edge[1]] === partition1 && nodeMap[edge[2]] === partition2) { + return false; + } + if (nodeMap[edge[1]] === partition2 && nodeMap[edge[2]] === partition1) { + return false; + } + return true; + }); + + // 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(0); + newEdges[i][1] = partition1; + } else if (edge[2] === partition2) { // Check target + newEdges[i] = edge.slice(0); + newEdges[i][2] = partition1; + } + } + + // Move all nodes from partition2 to partition1 + for (var i = 0; i < nodeMap.length; i++) { + if (nodeMap[i] === partition2) { + nodeMap[i] = partition1; + } + } + + return newEdges; + }; + + + // Contracts a graph until we reach a certain number of meta nodes + var contractUntil = function(metaNodeMap, + remainingEdges, + size, + sizeLimit) { + // Stop condition + if (size <= sizeLimit) { + return remainingEdges; + } + + // Choose an edge randomly + var edgeIndex = Math.floor((Math.random() * remainingEdges.length)); + + // Colapse graph based on edge + var newEdges = colapse(edgeIndex, metaNodeMap, remainingEdges); + + return contractUntil(metaNodeMap, + newEdges, + size - 1, + sizeLimit); + }; + + var cy = this._private.cy; + var edges = this.edges().stdFilter(function(e){ return !e.isLoop(); }); + var nodes = this.nodes(); + 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 / Math.sqrt(2)); + + if (numNodes < 2) { + util.error("At least 2 nodes are required for Karger-Stein algorithm"); + return undefined; + } + + // Create numerical identifiers for each node + // mapping: node id -> position in nodes array + // for reverse mapping, simply use nodes array + var id2position = {}; + for (var i = 0; i < numNodes; i++) { + id2position[nodes[i].id()] = i; + } + + // 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, id2position[e.source().id()], id2position[e.target().id()]]); + } + + // We will store the best cut found here + var minCutSize = Infinity; + var minCut; + + // Initial meta node partition + var originalMetaNode = []; + for (var i = 0; i < numNodes; i++) { + originalMetaNode.push(i); + } + + // Main loop + for (var iter = 0; iter <= numIter; iter++) { + // Create new meta node partition + var metaNodeMap = originalMetaNode.slice(0); + + // Contract until stop point (stopSize nodes) + var edgesState = contractUntil(metaNodeMap, edgeIndexes, numNodes, stopSize); + + // Create a copy of the colapsed nodes state + var metaNodeMap2 = metaNodeMap.slice(0); + + // Run 2 iterations starting in the stop state + var res1 = contractUntil(metaNodeMap, edgesState, stopSize, 2); + var res2 = contractUntil(metaNodeMap2, edgesState, stopSize, 2); + + // Is any of the 2 results the best cut so far? + if (res1.length <= res2.length && res1.length < minCutSize) { + minCutSize = res1.length; + minCut = [res1, metaNodeMap]; + } else if (res2.length <= res1.length && res2.length < minCutSize) { + minCutSize = res2.length; + minCut = [res2, metaNodeMap2]; + } + } // end of main loop + + + // Construct result + var resEdges = (minCut[0]).map(function(e){ return edges[e[0]]; }); + var partition1 = []; + var partition2 = []; + + // traverse metaNodeMap for best cut + var witnessNodePartition = minCut[1][0]; + for (var i = 0; i < minCut[1].length; i++) { + var partitionId = minCut[1][i]; + if (partitionId === witnessNodePartition) { + partition1.push(nodes[i]); + } else { + partition2.push(nodes[i]); + } + } + + var ret = { + cut: eles.spawn(cy, resEdges), + partition1: eles.spawn(partition1), + partition2: eles.spawn(partition2) + }; + + return ret; + } +}); // elesfn + + +module.exports = elesfn; + +},{"../../util":94}],11:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../../is'); + +var elesfn = ({ + + pageRank: function(options) { + options = options || {}; + + var normalizeVector = function(vector) { + var length = vector.length; + + // First, get sum of all elements + var total = 0; + for (var i = 0; i < length; i++) { + total += vector[i]; + } + + // Now, divide each by the sum of all elements + for (var i = 0; i < length; i++) { + vector[i] = vector[i] / total; + } + }; + + // dampingFactor - optional + if (options != null && + options.dampingFactor != null) { + var dampingFactor = options.dampingFactor; + } else { + var dampingFactor = 0.8; // Default damping factor + } + + // desired precision - optional + if (options != null && + options.precision != null) { + var epsilon = options.precision; + } else { + var epsilon = 0.000001; // Default precision + } + + // Max number of iterations - optional + if (options != null && + options.iterations != null) { + var numIter = options.iterations; + } else { + var numIter = 200; // Default number of iterations + } + + // Weight function - optional + if (options != null && + options.weight != null && + is.fn(options.weight)) { + var weightFn = options.weight; + } else { + // If not specified, assume each edge has equal weight (1) + var weightFn = function(e) {return 1;}; + } + + var cy = this._private.cy; + var edges = this.edges().stdFilter(function(e){ return !e.isLoop(); }); + var nodes = this.nodes(); + var numNodes = nodes.length; + var numEdges = edges.length; + + // Create numerical identifiers for each node + // mapping: node id -> position in nodes array + // for reverse mapping, simply use nodes array + var id2position = {}; + for (var i = 0; i < numNodes; i++) { + id2position[nodes[i].id()] = i; + } + + // 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 = []; + var columnSum = []; + var additionalProb = (1 - dampingFactor) / numNodes; + + // Create null matric + for (var i = 0; i < numNodes; i++) { + var newRow = []; + for (var j = 0; j < numNodes; j++) { + newRow.push(0.0); + } + matrix.push(newRow); + columnSum.push(0.0); + } + + // Now, process edges + for (var i = 0; i < numEdges; i++) { + var edge = edges[i]; + var s = id2position[edge.source().id()]; + var t = id2position[edge.target().id()]; + var w = weightFn.apply(edge, [edge]); + + // Update matrix + matrix[t][s] += 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 i = 0; i < numNodes; i++) { + matrix[i][j] = p; + } + } else { + // Node jth has outgoing link, compute normalized probabilities + for (var i = 0; i < numNodes; i++) { + matrix[i][j] = matrix[i][j] / columnSum[j] + additionalProb; + } + } + } + + // Compute dominant eigenvector using power method + var eigenvector = []; + var nullVector = []; + var previous; + + // Start with a vector of all 1's + // Also, initialize a null vector which will be used as shorthand + for (var i = 0; i < numNodes; i++) { + eigenvector.push(1.0); + nullVector.push(0.0); + } + + for (var iter = 0; iter < numIter; iter++) { + // New array with all 0's + var temp = nullVector.slice(0); + + // Multiply matrix with previous result + for (var i = 0; i < numNodes; i++) { + for (var j = 0; j < numNodes; j++) { + temp[i] += matrix[i][j] * eigenvector[j]; + } + } + + normalizeVector(temp); + previous = eigenvector; + eigenvector = temp; + + var diff = 0; + // Compute difference (squared module) of both vectors + for (var i = 0; i < numNodes; i++) { + diff += Math.pow(previous[i] - eigenvector[i], 2); + } + + // If difference is less than the desired threshold, stop iterating + if (diff < epsilon) { + break; + } + } + + // Construct result + var res = { + rank : function(node) { + if (is.string(node)) { + // is a selector string + var nodeId = (cy.filter(node)[0]).id(); + } else { + // is a node object + var nodeId = node.id(); + } + return eigenvector[id2position[nodeId]]; + } + }; + + + return res; + } // pageRank + +}); // elesfn + +module.exports = elesfn; + +},{"../../is":77}],12:[function(_dereq_,module,exports){ +'use strict'; + +var define = _dereq_('../define'); + +var elesfn = ({ + animate: define.animate(), + animation: define.animation(), + animated: define.animated(), + clearQueue: define.clearQueue(), + delay: define.delay(), + delayAnimation: define.delayAnimation(), + stop: define.stop() +}); + +module.exports = elesfn; + +},{"../define":41}],13:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../util'); + +var elesfn = ({ + classes: function( classes ){ + classes = classes.match(/\S+/g) || []; + var self = this; + var changed = []; + var classesMap = {}; + + // fill in classes map + for( var i = 0; i < classes.length; i++ ){ + var cls = classes[i]; + + classesMap[ cls ] = true; + } + + // 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[ cls ]; + + if( !eleHasClass ){ + changedEle = true; + break; + } + } + + // check if ele has classes outside of those passed + if( !changedEle ){ for( var eleCls in eleClasses ){ + var eleHasClass = eleClasses[ eleCls ]; + var specdClass = classesMap[ eleCls ]; // i.e. this class is passed to the function + + if( eleHasClass && !specdClass ){ + changedEle = true; + break; + } + } } + + if( changedEle ){ + _p.classes = util.copy( classesMap ); + + changed.push( ele ); + } + } + + // trigger update style on those eles that had class changes + if( changed.length > 0 ){ + this.spawn(changed) + .updateStyle() + .trigger('class') + ; + } + + return self; + }, + + addClass: function( classes ){ + return this.toggleClass( classes, true ); + }, + + hasClass: function( className ){ + var ele = this[0]; + return ( ele != null && ele._private.classes[className] ) ? true : false; + }, + + toggleClass: function( classesStr, toggle ){ + var classes = classesStr.match(/\S+/g) || []; + var self = this; + var changed = []; // eles who had classes changed + + for( var i = 0, il = self.length; i < il; i++ ){ + var ele = self[i]; + var changedEle = false; + + for( var j = 0; j < classes.length; j++ ){ + var cls = classes[j]; + var eleClasses = ele._private.classes; + var hasClass = eleClasses[cls]; + var shouldAdd = toggle || (toggle === undefined && !hasClass); + + if( shouldAdd ){ + eleClasses[cls] = true; + + if( !hasClass && !changedEle ){ + changed.push(ele); + changedEle = true; + } + } else { // then remove + eleClasses[cls] = false; + + if( hasClass && !changedEle ){ + 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() + .trigger('class') + ; + } + + return self; + }, + + removeClass: function( classes ){ + return this.toggleClass( classes, false ); + }, + + flashClass: function( 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; + } +}); + +module.exports = elesfn; + +},{"../util":94}],14:[function(_dereq_,module,exports){ +'use strict'; + +var elesfn = ({ + allAre: function( selector ){ + return this.filter(selector).length === this.length; + }, + + is: function( selector ){ + return this.filter(selector).length > 0; + }, + + some: function( 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( 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( collection ){ + collection = this.cy().collection( collection ); + + // cheap extra check + if( this.length !== collection.length ){ + return false; + } + + return this.intersect( collection ).length === this.length; + }, + + anySame: function( collection ){ + collection = this.cy().collection( collection ); + + return this.intersect( collection ).length > 0; + }, + + allAreNeighbors: function( collection ){ + collection = this.cy().collection( collection ); + + return this.neighborhood().intersect( collection ).length === collection.length; + } +}); + +elesfn.allAreNeighbours = elesfn.allAreNeighbors; + +module.exports = elesfn; + +},{}],15:[function(_dereq_,module,exports){ +'use strict'; + +var elesfn = ({ + parent: function( selector ){ + var parents = []; + var cy = this._private.cy; + + for( var i = 0; i < this.length; i++ ){ + var ele = this[i]; + var parent = cy.getElementById( ele._private.data.parent ); + + if( parent.size() > 0 ){ + parents.push( parent ); + } + } + + return this.spawn( parents, { unique: true } ).filter( selector ); + }, + + parents: function( 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, { unique: true } ).filter( selector ); + }, + + commonAncestors: function( 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( selector ){ + return this.stdFilter(function( ele ){ + return ele.isNode() && ele.parent().empty(); + }).filter( selector ); + }, + + nonorphans: function( selector ){ + return this.stdFilter(function( ele ){ + return ele.isNode() && ele.parent().nonempty(); + }).filter( selector ); + }, + + children: function( selector ){ + var children = []; + + for( var i = 0; i < this.length; i++ ){ + var ele = this[i]; + children = children.concat( ele._private.children ); + } + + return this.spawn( children, { unique: true } ).filter( selector ); + }, + + siblings: function( selector ){ + return this.parent().children().not( this ).filter( selector ); + }, + + isParent: function(){ + var ele = this[0]; + + if( ele ){ + return ele._private.children.length !== 0; + } + }, + + isChild: function(){ + var ele = this[0]; + + if( ele ){ + return ele._private.data.parent !== undefined && ele.parent().length !== 0; + } + }, + + descendants: function( 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, { unique: true } ).filter( selector ); + } +}); + +// aliases +elesfn.ancestors = elesfn.parents; + +module.exports = elesfn; + +},{}],16:[function(_dereq_,module,exports){ +'use strict'; + +var define = _dereq_('../define'); +var fn, elesfn; + +fn = elesfn = ({ + + 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(){ + var ele = this[0]; + + if( ele ){ + return ele._private.data.id; + } + } + +}); + +// aliases +fn.attr = fn.data; +fn.removeAttr = fn.removeData; + +module.exports = elesfn; + +},{"../define":41}],17:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../util'); + +var elesfn = {}; + +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; + } + }; +} + +util.extend(elesfn, { + 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; + }; +} + +util.extend(elesfn, { + 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; + }) +}); + +util.extend(elesfn, { + totalDegree: function( includeLoops ){ + var total = 0; + var nodes = this.nodes(); + + for( var i = 0; i < nodes.length; i++ ){ + total += nodes[i].degree( includeLoops ); + } + + return total; + } +}); + +module.exports = elesfn; + +},{"../util":94}],18:[function(_dereq_,module,exports){ +'use strict'; + +var define = _dereq_('../define'); +var is = _dereq_('../is'); +var util = _dereq_('../util'); +var fn, elesfn; + +fn = elesfn = ({ + + position: define.data({ + field: 'position', + bindingEvent: 'position', + allowBinding: true, + allowSetting: true, + settingEvent: 'position', + settingTriggersEvent: true, + triggerFnName: 'rtrigger', + allowGetting: true, + validKeys: ['x', 'y'], + onSet: function( eles ){ + var updatedEles = eles.updateCompoundBounds(); + updatedEles.rtrigger('position'); + }, + canSet: function( ele ){ + return !ele.locked() && !ele.isParent(); + } + }), + + // position but no notification to renderer + silentPosition: define.data({ + field: 'position', + bindingEvent: 'position', + allowBinding: false, + allowSetting: true, + settingEvent: 'position', + settingTriggersEvent: false, + triggerFnName: 'trigger', + allowGetting: true, + validKeys: ['x', 'y'], + onSet: function( eles ){ + eles.updateCompoundBounds(); + }, + canSet: function( ele ){ + return !ele.locked() && !ele.isParent(); + } + }), + + positions: function( pos, silent ){ + if( is.plainObject(pos) ){ + this.position(pos); + + } else if( is.fn(pos) ){ + var fn = pos; + + for( var i = 0; i < this.length; i++ ){ + var ele = this[i]; + + var pos = fn.apply(ele, [i, ele]); + + if( pos && !ele.locked() && !ele.isParent() ){ + var elePos = ele._private.position; + elePos.x = pos.x; + elePos.y = pos.y; + } + } + + var updatedEles = this.updateCompoundBounds(); + var toTrigger = updatedEles.length > 0 ? this.add( updatedEles ) : this; + + if( silent ){ + toTrigger.trigger('position'); + } else { + toTrigger.rtrigger('position'); + } + } + + return this; // chaining + }, + + silentPositions: function( pos ){ + return this.positions( pos, true ); + }, + + // get/set the rendered (i.e. on screen) positon of the element + renderedPosition: function( dim, val ){ + var ele = this[0]; + var cy = this.cy(); + var zoom = cy.zoom(); + var pan = cy.pan(); + var rpos = is.plainObject( dim ) ? dim : undefined; + var setting = rpos !== undefined || ( val !== undefined && is.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._private.position[dim] = ( val - pan[dim] )/zoom; + } else if( rpos !== undefined ){ // set whole position + ele._private.position = { + x: ( rpos.x - pan.x ) /zoom, + y: ( rpos.y - pan.y ) /zoom + }; + } + } + + this.rtrigger('position'); + } else { // getting + var pos = ele._private.position; + rpos = { + x: pos.x * zoom + pan.x, + y: pos.y * zoom + pan.y + }; + + 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( dim, val ){ + var ele = this[0]; + var cy = this.cy(); + var ppos = is.plainObject( dim ) ? dim : undefined; + var setting = ppos !== undefined || ( val !== undefined && is.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 ele = this[i]; + var parent = hasCompoundNodes ? ele.parent() : null; + var hasParent = parent && parent.length > 0; + var relativeToParent = hasParent; + + if( hasParent ){ + parent = parent[0]; + } + + var origin = relativeToParent ? parent._private.position : { x: 0, y: 0 }; + + if( val !== undefined ){ // set one dimension + ele._private.position[dim] = val + origin[dim]; + } else if( ppos !== undefined ){ // set whole position + ele._private.position = { + x: ppos.x + origin.x, + y: ppos.y + origin.y + }; + } + } + + this.rtrigger('position'); + + } else { // getting + var pos = ele._private.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._private.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 + }, + + 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 + }; + }, + + updateCompoundBounds: function(){ + var cy = this.cy(); + + if( !cy.styleEnabled() || !cy.hasCompoundNodes() ){ return cy.collection(); } // save cycles for non compound graphs or when style disabled + + var updated = []; + + function update( parent ){ + var children = parent.children(); + var style = parent._private.style; + var includeLabels = style['compound-sizing-wrt-labels'].value === 'include'; + var bb = children.boundingBox({ includeLabels: includeLabels, includeEdges: true }); + var padding = { + top: style['padding-top'].pfValue, + bottom: style['padding-bottom'].pfValue, + left: style['padding-left'].pfValue, + right: style['padding-right'].pfValue + }; + var pos = parent._private.position; + var didUpdate = false; + + if( style['width'].value === 'auto' ){ + parent._private.autoWidth = bb.w; + pos.x = (bb.x1 + bb.x2 - padding.left + padding.right)/2; + didUpdate = true; + } + + if( style['height'].value === 'auto' ){ + parent._private.autoHeight = bb.h; + pos.y = (bb.y1 + bb.y2 - padding.top + padding.bottom)/2; + didUpdate = true; + } + + if( didUpdate ){ + updated.push( parent ); + } + } + + // go up, level by level + var eles = this.parent(); + while( eles.nonempty() ){ + + // update each parent node in this level + for( var i = 0; i < eles.length; i++ ){ + var ele = eles[i]; + + update( ele ); + } + + // next level + eles = eles.parent(); + } + + // return changed + return this.spawn( updated ); + }, + + // get the bounding box of the elements (in raw model position) + boundingBox: function( options ){ + var eles = this; + var cy = eles._private.cy; + var cy_p = cy._private; + var styleEnabled = cy_p.styleEnabled; + + options = options || util.staticEmptyObject(); + + var includeNodes = options.includeNodes === undefined ? true : options.includeNodes; + var includeEdges = options.includeEdges === undefined ? true : options.includeEdges; + var includeLabels = options.includeLabels === undefined ? true : options.includeLabels; + + // recalculate projections etc + if( styleEnabled ){ + cy_p.renderer.recalculateRenderedStyle( this ); + } + + var x1 = Infinity; + var x2 = -Infinity; + var y1 = Infinity; + var y2 = -Infinity; + + // find bounds of elements + for( var i = 0; i < eles.length; i++ ){ + var ele = eles[i]; + var _p = ele._private; + var style = _p.style; + var display = styleEnabled ? _p.style['display'].value : 'element'; + var isNode = _p.group === 'nodes'; + var ex1, ex2, ey1, ey2, x, y; + var includedEle = false; + + if( display === 'none' ){ continue; } // then ele doesn't take up space + + if( isNode && includeNodes ){ + includedEle = true; + + var pos = _p.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; + + x1 = ex1 < x1 ? ex1 : x1; + x2 = ex2 > x2 ? ex2 : x2; + y1 = ey1 < y1 ? ey1 : y1; + y2 = ey2 > y2 ? ey2 : y2; + + } else if( ele.isEdge() && includeEdges ){ + includedEle = true; + + var n1 = _p.source; + var n1_p = n1._private; + var n1pos = n1_p.position; + + var n2 = _p.target; + var n2_p = n2._private; + var n2pos = n2_p.position; + + + // handle edge dimensions (rough box estimate) + ////////////////////////////////////////////// + + var rstyle = _p.rstyle || {}; + var w = 0; + var wHalf = 0; + + if( styleEnabled ){ + w = style['width'].pfValue; + wHalf = w/2; + } + + ex1 = n1pos.x; + ex2 = n2pos.x; + ey1 = n1pos.y; + ey2 = n2pos.y; + + if( ex1 > ex2 ){ + var temp = ex1; + ex1 = ex2; + ex2 = temp; + } + + if( ey1 > ey2 ){ + var temp = ey1; + ey1 = ey2; + ey2 = temp; + } + + // take into account edge width + ex1 -= wHalf; + ex2 += wHalf; + ey1 -= wHalf; + ey2 += wHalf; + + x1 = ex1 < x1 ? ex1 : x1; + x2 = ex2 > x2 ? ex2 : x2; + y1 = ey1 < y1 ? ey1 : y1; + y2 = ey2 > y2 ? ey2 : y2; + + // handle points along edge (sanity check) + ////////////////////////////////////////// + + if( styleEnabled ){ + var pts = rstyle.bezierPts || rstyle.linePts || []; + + 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; + + x1 = ex1 < x1 ? ex1 : x1; + x2 = ex2 > x2 ? ex2 : x2; + y1 = ey1 < y1 ? ey1 : y1; + y2 = ey2 > y2 ? ey2 : y2; + } + } + + // precise haystacks (sanity check) + /////////////////////////////////// + + if( styleEnabled && style['curve-style'].strValue === 'haystack' ){ + var hpts = rstyle.haystackPts; + + 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; + } + + x1 = ex1 < x1 ? ex1 : x1; + x2 = ex2 > x2 ? ex2 : x2; + y1 = ey1 < y1 ? ey1 : y1; + y2 = ey2 > y2 ? ey2 : y2; + } + + } // edges + + + // handle label dimensions + ////////////////////////// + + if( styleEnabled ){ + + var _p = ele._private; + var style = _p.style; + var rstyle = _p.rstyle; + var label = style['label'].strValue; + var fontSize = style['font-size']; + var halign = style['text-halign']; + var valign = style['text-valign']; + var labelWidth = rstyle.labelWidth; + var labelHeight = rstyle.labelHeight; + var labelX = rstyle.labelX; + var labelY = rstyle.labelY; + var isEdge = ele.isEdge(); + var autorotate = style['edge-text-rotation'].strValue === 'autorotate'; + + if( includeLabels && label && fontSize && labelHeight != null && labelWidth != null && labelX != null && labelY != null && halign && valign ){ + var lh = labelHeight; + var lw = labelWidth; + var lx1, lx2, ly1, ly2; + + if( isEdge ){ + lx1 = labelX - lw/2; + lx2 = labelX + lw/2; + ly1 = labelY - lh/2; + ly2 = labelY + lh/2; + + if( autorotate ){ + var theta = _p.rscratch.labelAngle; + var cos = Math.cos( theta ); + var sin = Math.sin( theta ); + + var rotate = function( x, y ){ + x = x - labelX; + y = y - labelY; + + return { + x: x*cos - y*sin + labelX, + y: x*sin + y*cos + labelY + }; + }; + + 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 ); + } + } 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; + } + } + + x1 = lx1 < x1 ? lx1 : x1; + x2 = lx2 > x2 ? lx2 : x2; + y1 = ly1 < y1 ? ly1 : y1; + y2 = ly2 > y2 ? ly2 : y2; + } + } // style enabled for labels + } // for + + var noninf = function(x){ + if( x === Infinity || x === -Infinity ){ + return 0; + } + + return x; + }; + + x1 = noninf(x1); + x2 = noninf(x2); + y1 = noninf(y1); + y2 = noninf(y2); + + return { + x1: x1, + x2: x2, + y1: y1, + y2: y2, + w: x2 - x1, + h: y2 - y1 + }; + } +}); + +var defineDimFns = function( opts ){ + opts.uppercaseName = util.capitalize( opts.name ); + opts.autoName = 'auto' + opts.uppercaseName; + opts.labelName = 'label' + opts.uppercaseName; + opts.outerName = 'outer' + opts.uppercaseName; + opts.uppercaseOuterName = util.capitalize( opts.outerName ); + + fn[ 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 ){ + var d = _p.style[ opts.name ]; + + switch( d.strValue ){ + case 'auto': + return _p[ opts.autoName ] || 0; + case 'label': + return _p.rstyle[ opts.labelName ] || 0; + default: + return d.pfValue; + } + } else { + return 1; + } + } + }; + + fn[ '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 style = _p.style; + var dim = ele[ opts.name ](); + var border = style['border-width'].pfValue; + var padding = style[ opts.paddings[0] ].pfValue + style[ opts.paddings[1] ].pfValue; + + return dim + border + padding; + } else { + return 1; + } + } + }; + + fn[ 'rendered' + opts.uppercaseName ] = function renderedDimImpl(){ + var ele = this[0]; + + if( ele ){ + var d = ele[ opts.name ](); + return d * this.cy().zoom(); + } + }; + + fn[ 'rendered' + opts.uppercaseOuterName ] = function renderedOuterDimImpl(){ + var ele = this[0]; + + if( ele ){ + var od = ele[ opts.outerName ](); + return od * this.cy().zoom(); + } + }; +}; + +defineDimFns({ + name: 'width', + paddings: ['padding-left', 'padding-right'] +}); + +defineDimFns({ + name: 'height', + paddings: ['padding-top', 'padding-bottom'] +}); + +// aliases +fn.modelPosition = fn.point = fn.position; +fn.modelPositions = fn.points = fn.positions; +fn.renderedPoint = fn.renderedPosition; +fn.relativePoint = fn.relativePosition; +fn.boundingbox = fn.boundingBox; +fn.renderedBoundingbox = fn.renderedBoundingBox; + +module.exports = elesfn; + +},{"../define":41,"../is":77,"../util":94}],19:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../util'); +var is = _dereq_('../is'); + +// represents a node or an edge +var Element = function(cy, params, restore){ + if( !(this instanceof Element) ){ + return new Element(cy, params, restore); + } + + var self = this; + restore = (restore === undefined || restore ? true : false); + + if( cy === undefined || params === undefined || !is.core(cy) ){ + util.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.source != null && params.data.target != null ){ + group = 'edges'; + } else { + group = 'nodes'; + } + } + + // validate group + if( group !== 'nodes' && group !== 'edges' ){ + util.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() + this._private = { + cy: cy, + single: true, // indicates this is an element + data: params.data || {}, // data object + position: params.position || {}, // (x, y) position pair + autoWidth: undefined, // width and height of nodes calculated by the renderer when set to special 'auto' value + autoHeight: undefined, + 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 + 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 + active: false, // whether the element is active from user interaction + classes: {}, // 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 + }; + + // renderedPosition overrides if specified + if( params.renderedPosition ){ + var rpos = params.renderedPosition; + var pan = cy.pan(); + var zoom = cy.zoom(); + + this._private.position = { + x: (rpos.x - pan.x)/zoom, + y: (rpos.y - pan.y)/zoom + }; + } + + if( is.string(params.classes) ){ + var classes = params.classes.split(/\s+/); + for( var i = 0, l = classes.length; i < l; i++ ){ + var cls = classes[i]; + if( !cls || cls === '' ){ continue; } + + self._private.classes[cls] = true; + } + } + + if( params.style || params.css ){ + cy.style().applyBypass( this, params.style || params.css ); + } + + if( restore === undefined || restore ){ + this.restore(); + } + +}; + +module.exports = Element; + +},{"../is":77,"../util":94}],20:[function(_dereq_,module,exports){ +'use strict'; + +var define = _dereq_('../define'); + +var elesfn = ({ + on: define.on(), // .on( events [, selector] [, data], handler) + one: define.on({ unbindSelfOnTrigger: true }), + once: define.on({ unbindAllBindersOnTrigger: true }), + off: define.off(), // .off( events [, selector] [, handler] ) + trigger: define.trigger(), // .trigger( events [, extraParams] ) + + rtrigger: function(event, extraParams){ // for internal use only + if( this.length === 0 ){ return; } // empty collections don't need to notify anything + + // notify renderer + this.cy().notify({ + type: event, + collection: this + }); + + this.trigger(event, extraParams); + return this; + } +}); + +// aliases: +define.eventAliasesOn( elesfn ); + +module.exports = elesfn; + +},{"../define":41}],21:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../is'); +var Selector = _dereq_('../selector'); + +var elesfn = ({ + nodes: function( selector ){ + return this.filter(function(i, element){ + return element.isNode(); + }).filter(selector); + }, + + edges: function( selector ){ + return this.filter(function(i, element){ + return element.isEdge(); + }).filter(selector); + }, + + filter: function( filter ){ + if( is.fn(filter) ){ + var elements = []; + + for( var i = 0; i < this.length; i++ ){ + var ele = this[i]; + + if( filter.apply(ele, [i, ele]) ){ + elements.push(ele); + } + } + + return this.spawn(elements); + + } else if( is.string(filter) || is.elementOrCollection(filter) ){ + return Selector(filter).filter(this); + + } else if( filter === undefined ){ + return this; + } + + return this.spawn(); // if not handled by above, give 'em an empty collection + }, + + not: function( toRemove ){ + if( !toRemove ){ + return this; + } else { + + if( is.string( toRemove ) ){ + toRemove = this.filter( toRemove ); + } + + var elements = []; + + for( var i = 0; i < this.length; i++ ){ + var element = this[i]; + + var remove = toRemove._private.ids[ element.id() ]; + if( !remove ){ + elements.push( element ); + } + } + + return this.spawn( elements ); + } + + }, + + absoluteComplement: function(){ + var cy = this._private.cy; + + return cy.elements().not( this ); + }, + + intersect: function( other ){ + // if a selector is specified, then filter by it instead + if( is.string(other) ){ + var selector = other; + return this.filter( selector ); + } + + var elements = []; + var col1 = this; + var col2 = other; + var col1Smaller = this.length < other.length; + // var ids1 = col1Smaller ? col1._private.ids : col2._private.ids; + var ids2 = col1Smaller ? col2._private.ids : col1._private.ids; + var col = col1Smaller ? col1 : col2; + + for( var i = 0; i < col.length; i++ ){ + var id = col[i]._private.data.id; + var ele = ids2[ id ]; + + if( ele ){ + elements.push( ele ); + } + } + + return this.spawn( elements ); + }, + + xor: function( other ){ + var cy = this._private.cy; + + if( is.string(other) ){ + other = cy.$( other ); + } + + var elements = []; + var col1 = this; + var col2 = other; + + var add = function( col, other ){ + + for( var i = 0; i < col.length; i++ ){ + var ele = col[i]; + var id = ele._private.data.id; + var inOther = other._private.ids[ id ]; + + if( !inOther ){ + elements.push( ele ); + } + } + + }; + + add( col1, col2 ); + add( col2, col1 ); + + return this.spawn( elements ); + }, + + diff: function( other ){ + var cy = this._private.cy; + + if( is.string(other) ){ + other = cy.$( other ); + } + + var left = []; + var right = []; + var both = []; + var col1 = this; + var col2 = other; + + var add = function( col, other, retEles ){ + + for( var i = 0; i < col.length; i++ ){ + var ele = col[i]; + var id = ele._private.data.id; + var inOther = other._private.ids[ id ]; + + if( inOther ){ + both.push( ele ); + } else { + retEles.push( ele ); + } + } + + }; + + add( col1, col2, left ); + add( col2, col1, right ); + + return { + left: this.spawn( left, { unique: true } ), + right: this.spawn( right, { unique: true } ), + both: this.spawn( both, { unique: true } ) + }; + }, + + add: function( toAdd ){ + var cy = this._private.cy; + + if( !toAdd ){ + return this; + } + + if( is.string(toAdd) ){ + var selector = toAdd; + toAdd = cy.elements(selector); + } + + var elements = []; + + for( var i = 0; i < this.length; i++ ){ + elements.push( this[i] ); + } + + for( var i = 0; i < toAdd.length; i++ ){ + + var add = !this._private.ids[ toAdd[i].id() ]; + if( add ){ + elements.push( toAdd[i] ); + } + } + + return this.spawn(elements); + }, + + // in place merge on calling collection + merge: function( toAdd ){ + var _p = this._private; + var cy = _p.cy; + + if( !toAdd ){ + return this; + } + + if( is.string(toAdd) ){ + var selector = toAdd; + toAdd = cy.elements(selector); + } + + for( var i = 0; i < toAdd.length; i++ ){ + var toAddEle = toAdd[i]; + var id = toAddEle.id(); + var add = !_p.ids[ id ]; + + if( add ){ + var index = this.length++; + + this[ index ] = toAddEle; + _p.ids[ id ] = toAddEle; + _p.indexes[ id ] = index; + } + } + + return this; // chaining + }, + + // remove single ele in place in calling collection + unmergeOne: function( ele ){ + ele = ele[0]; + + var _p = this._private; + var id = ele.id(); + var i = _p.indexes[ id ]; + + if( i == null ){ + return this; // no need to remove + } + + // remove ele + this[i] = undefined; + _p.ids[ id ] = undefined; + _p.indexes[ id ] = undefined; + + 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 ]; + + this[ lastEleI ] = undefined; + this[i] = lastEle; + _p.indexes[ lastEle.id() ] = i; + } + + // the collection is now 1 ele smaller + this.length--; + + return this; + }, + + // remove eles in place on calling collection + unmerge: function( toRemove ){ + var cy = this._private.cy; + + if( !toRemove ){ + return this; + } + + if( is.string(toRemove) ){ + var selector = toRemove; + toRemove = cy.elements(selector); + } + + for( var i = 0; i < toRemove.length; i++ ){ + this.unmergeOne( toRemove[i] ); + } + + return this; // chaining + }, + + map: function( 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; + }, + + stdFilter: function( fn, thisArg ){ + var filterEles = []; + var eles = this; + + for( var i = 0; i < eles.length; i++ ){ + var ele = eles[i]; + var include = thisArg ? fn.apply( thisArg, [ele, i, eles] ) : fn( ele, i, eles ); + + if( include ){ + filterEles.push( ele ); + } + } + + return this.spawn( filterEles ); + }, + + max: function( 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( 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 = elesfn; +fn['u'] = fn['|'] = fn['+'] = fn.union = fn.or = fn.add; +fn['\\'] = fn['!'] = fn['-'] = fn.difference = fn.relativeComplement = fn.subtract = fn.not; +fn['n'] = fn['&'] = fn['.'] = fn.and = fn.intersection = fn.intersect; +fn['^'] = fn['(+)'] = fn['(-)'] = fn.symmetricDifference = fn.symdiff = fn.xor; +fn.fnFilter = fn.filterFn = fn.stdFilter; +fn.complement = fn.abscomp = fn.absoluteComplement; + +module.exports = elesfn; + +},{"../is":77,"../selector":81}],22:[function(_dereq_,module,exports){ +'use strict'; + +var elesfn = ({ + isNode: function(){ + return this.group() === 'nodes'; + }, + + isEdge: function(){ + return this.group() === 'edges'; + }, + + isLoop: function(){ + return this.isEdge() && this.source().id() === this.target().id(); + }, + + isSimple: function(){ + return this.isEdge() && this.source().id() !== this.target().id(); + }, + + group: function(){ + var ele = this[0]; + + if( ele ){ + return ele._private.group; + } + } +}); + + +module.exports = elesfn; + +},{}],23:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../util'); +var is = _dereq_('../is'); + +var Element = _dereq_('./element'); + +// factory for generating edge ids when no id is specified for a new element +var idFactory = { + prefix: 'ele', + id: 0, + generate: function(cy, element, tryThisId){ + var json = is.element( element ) ? element._private : element; + var id = tryThisId != null ? tryThisId : this.prefix + this.id; + + if( cy.getElementById(id).empty() ){ + this.id++; // we've used the current id, so move it up + } else { // otherwise keep trying successive unused ids + while( !cy.getElementById(id).empty() ){ + id = this.prefix + ( ++this.id ); + } + } + + return id; + } +}; + +// represents a set of nodes, edges, or both together +var Collection = function(cy, elements, options){ + if( !(this instanceof Collection) ){ + return new Collection(cy, elements, options); + } + + if( cy === undefined || !is.core(cy) ){ + util.error('A collection must have a reference to the core'); + return; + } + + var ids = {}; + var indexes = {}; + var createdElements = false; + + if( !elements ){ + elements = []; + } else if( elements.length > 0 && is.plainObject( elements[0] ) && !is.element( elements[0] ) ){ + createdElements = true; + + // make elements from json and restore all at once later + var eles = []; + var elesIds = {}; + + 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 = idFactory.generate( cy, json ); + } else if( cy.getElementById( data.id ).length !== 0 || elesIds[ data.id ] ){ + continue; // can't create element if prior id already exists + } + + var ele = new Element( cy, json, false ); + eles.push( ele ); + elesIds[ data.id ] = true; + } + + elements = eles; + } + + this.length = 0; + + for( var i = 0, l = elements.length; i < l; i++ ){ + var element = elements[i]; + if( !element ){ continue; } + + var id = element._private.data.id; + + if( !options || (options.unique && !ids[ id ] ) ){ + ids[ id ] = element; + indexes[ id ] = this.length; + + this[ this.length ] = element; + this.length++; + } + } + + this._private = { + cy: cy, + ids: ids, + indexes: indexes + }; + + // restore the elements if we created them from json + if( createdElements ){ + 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 = Element.prototype = Collection.prototype; + +elesfn.instanceString = function(){ + return 'collection'; +}; + +elesfn.spawn = function( cy, eles, opts ){ + if( !is.core(cy) ){ // cy is optional + opts = eles; + eles = cy; + cy = this.cy(); + } + + return new Collection( cy, eles, opts ); +}; + +elesfn.cy = function(){ + return this._private.cy; +}; + +elesfn.element = function(){ + return this[0]; +}; + +elesfn.collection = function(){ + if( is.collection(this) ){ + return this; + } else { // an element + return new Collection( this._private.cy, [this] ); + } +}; + +elesfn.unique = function(){ + return new Collection( this._private.cy, this, { unique: true } ); +}; + +elesfn.getElementById = function( id ){ + var cy = this._private.cy; + var ele = this._private.ids[ id ]; + + return ele ? ele : new Collection(cy); // get ele or empty collection +}; + +elesfn.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( is.plainObject(obj) ){ // set + + cy.startBatch(); + + if( obj.data ){ + ele.data( obj.data ); + } + + if( obj.position ){ + ele.position( obj.position ); + } + + // ignore group -- immutable + + var checkSwitch = function( 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' ); + + if( obj.classes != null ){ + ele.classes( obj.classes ); + } + + cy.endBatch(); + + return this; + + } else if( obj === undefined ){ // get + + var json = { + data: util.copy( p.data ), + position: util.copy( p.position ), + group: p.group, + removed: p.removed, + selected: p.selected, + selectable: p.selectable, + locked: p.locked, + grabbable: p.grabbable, + classes: null + }; + + var classes = []; + for( var cls in p.classes ){ + if( p.classes[cls] ){ + classes.push(cls); + } + } + json.classes = classes.join(' '); + + return json; + } +}; + +elesfn.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.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.copy = elesfn.clone; + +elesfn.restore = function( notifyRenderer ){ + var self = this; + var restored = []; + var cy = self.cy(); + + if( notifyRenderer === undefined ){ + notifyRenderer = true; + } + + // create arrays of nodes and edges, since we need to + // restore the nodes first + var elements = []; + var nodes = [], edges = []; + var numNodes = 0; + var numEdges = 0; + for( var i = 0, l = self.length; i < l; i++ ){ + var ele = self[i]; + + // keep nodes first in the array and edges after + if( ele.isNode() ){ // put to front of array if node + nodes.push( ele ); + numNodes++; + } else { // put to end of array if edge + edges.push( ele ); + numEdges++; + } + } + + elements = nodes.concat( edges ); + + // now, restore each element + for( var i = 0, l = elements.length; i < l; i++ ){ + var ele = elements[i]; + + if( !ele.removed() ){ + // don't need to do anything + continue; + } + + var _private = ele._private; + var data = _private.data; + + // set id and validate + if( data.id === undefined ){ + data.id = idFactory.generate( cy, ele ); + + } else if( is.number(data.id) ){ + data.id = '' + data.id; // now it's a string + + } else if( is.emptyString(data.id) || !is.string(data.id) ){ + util.error('Can not create element with invalid string ID `' + data.id + '`'); + + // can't create element if it has empty string as id or non-string id + continue; + } else if( cy.getElementById( data.id ).length !== 0 ){ + util.error('Can not create second element with ID `' + data.id + '`'); + + // can't create element if one already has that id + continue; + } + + var id = data.id; // id is finalised, now let's keep a ref + + if( ele.isNode() ){ // extra checks for nodes + var node = ele; + 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( ele.isEdge() ){ // extra checks for edges + + var edge = ele; + var fields = ['source', 'target']; + var fieldsLength = fields.length; + var badSourceOrTarget = false; + for(var j = 0; j < fieldsLength; j++){ + + var field = fields[j]; + var val = data[field]; + + if( is.number(val) ){ + val = data[field] = '' + data[field]; // now string + } + + if( val == null || val === '' ){ + // can't create if source or target is not defined properly + util.error('Can not create edge `' + id + '` with unspecified ' + field); + badSourceOrTarget = true; + } else if( cy.getElementById(val).empty() ){ + // can't create edge if one of its nodes doesn't exist + util.error('Can not create edge `' + id + '` with nonexistant ' + field + ' `' + val + '`'); + badSourceOrTarget = true; + } + } + + if( badSourceOrTarget ){ continue; } // can't create this + + var src = cy.getElementById( data.source ); + var tgt = cy.getElementById( data.target ); + + src._private.edges.push( edge ); + tgt._private.edges.push( edge ); + + edge._private.source = src; + edge._private.target = tgt; + + } // if is edge + + // create mock ids map for element so it can be used like collections + _private.ids = {}; + _private.ids[ id ] = ele; + + _private.removed = false; + cy.addToPool( ele ); + + restored.push( ele ); + } // for each element + + // do compound node sanity checks + for( var i = 0; i < numNodes; i++ ){ // each node + var node = elements[i]; + var data = node._private.data; + + if( is.number(data.parent) ){ // then automake string + data.parent = '' + data.parent; + } + + var parentId = data.parent; + + var specifiedParent = parentId != null; + + if( specifiedParent ){ + var parent = cy.getElementById( parentId ); + + if( parent.empty() ){ + // non-existant parent; just remove it + data.parent = undefined; + } else { + var selfAsParent = false; + var ancestor = parent; + while( !ancestor.empty() ){ + if( node.same(ancestor) ){ + // mark self as parent and remove from data + selfAsParent = true; + data.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._private.hasCompoundNodes = true; + } + } // else + } // if specified parent + } // for each node + + restored = new Collection( cy, restored ); + if( restored.length > 0 ){ + + var toUpdateStyle = restored.add( restored.connectedNodes() ).add( restored.parent() ); + toUpdateStyle.updateStyle( notifyRenderer ); + + if( notifyRenderer ){ + restored.rtrigger('add'); + } else { + restored.trigger('add'); + } + } + + return self; // chainability +}; + +elesfn.removed = function(){ + var ele = this[0]; + return ele && ele._private.removed; +}; + +elesfn.inside = function(){ + var ele = this[0]; + return ele && !ele._private.removed; +}; + +elesfn.remove = function( notifyRenderer ){ + var self = this; + var removed = []; + var elesToRemove = []; + var elesToRemoveIds = {}; + var cy = self._private.cy; + + if( notifyRenderer === undefined ){ + notifyRenderer = true; + } + + // 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( 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; + for( var j = 0; j < connectedEdges.length; j++ ){ + var connectedEdge = connectedEdges[j]; + + if( edge === connectedEdge ){ + connectedEdges.splice( j, 1 ); + break; + } + } + } + + function removeChildRef(parent, ele){ + ele = ele[0]; + parent = parent[0]; + var children = parent._private.children; + + for( var j = 0; j < children.length; j++ ){ + if( children[j][0] === ele[0] ){ + children.splice(j, 1); + break; + } + } + } + + for( var i = 0; i < elesToRemove.length; i++ ){ + var ele = elesToRemove[i]; + + // mark as removed + ele._private.removed = true; + + // remove from core pool + cy.removeFromPool( ele ); + + // add to list of removed elements + removed.push( ele ); + + if( ele.isEdge() ){ // remove references to this edge in its connected nodes + var src = ele.source()[0]; + var tgt = ele.target()[0]; + + removeEdgeRef( src, ele ); + removeEdgeRef( tgt, ele ); + + } else { // remove reference to parent + var parent = ele.parent(); + + if( parent.length !== 0 ){ + removeChildRef(parent, ele); + } + } + } + + // check to see if we have a compound graph or not + var elesStillInside = cy._private.elements; + cy._private.hasCompoundNodes = false; + for( var i = 0; i < elesStillInside.length; i++ ){ + var ele = elesStillInside[i]; + + if( ele.isParent() ){ + cy._private.hasCompoundNodes = true; + break; + } + } + + var removedElements = new Collection( this.cy(), removed ); + if( removedElements.size() > 0 ){ + // must manually notify since trigger won't do this automatically once removed + + if( notifyRenderer ){ + this.cy().notify({ + type: 'remove', + collection: removedElements + }); + } + + removedElements.trigger('remove'); + } + + // check for empty remaining parent nodes + var checkedParentId = {}; + for( var i = 0; i < elesToRemove.length; i++ ){ + var ele = elesToRemove[i]; + var isNode = ele._private.group === 'nodes'; + var parentId = ele._private.data.parent; + + if( isNode && parentId !== undefined && !checkedParentId[ parentId ] ){ + checkedParentId[ parentId ] = true; + var parent = cy.getElementById( parentId ); + + if( parent && parent.length !== 0 && !parent._private.removed && parent.children().length === 0 ){ + parent.updateStyle(); + } + } + } + + return new Collection( cy, removed ); +}; + +elesfn.move = function( struct ){ + var cy = this._private.cy; + + if( struct.source !== undefined || struct.target !== undefined ){ + var srcId = struct.source; + var tgtId = struct.target; + var srcExists = cy.getElementById( srcId ).length > 0; + var tgtExists = cy.getElementById( tgtId ).length > 0; + + if( srcExists || tgtExists ){ + var jsons = this.jsons(); + + this.remove(); + + for( var i = 0; i < jsons.length; i++ ){ + var json = jsons[i]; + + if( json.group === 'edges' ){ + if( srcExists ){ json.data.source = srcId; } + if( tgtExists ){ json.data.target = tgtId; } + } + } + + return cy.add( jsons ); + } + + } else if( struct.parent !== undefined ){ // move node to new parent + var parentId = struct.parent; + var parentExists = parentId === null || cy.getElementById( parentId ).length > 0; + + if( parentExists ){ + var jsons = this.jsons(); + var descs = this.descendants(); + var descsEtc = descs.merge( descs.add(this).connectedEdges() ); + + this.remove(); // NB: also removes descendants and their connected edges + + for( var i = 0; i < this.length; i++ ){ + var json = jsons[i]; + + if( json.group === 'nodes' ){ + json.data.parent = parentId === null ? undefined : parentId; + } + } + } + + return cy.add( jsons ).merge( descsEtc.restore() ); + } + + return this; // if nothing done +}; + +[ + _dereq_('./algorithms'), + _dereq_('./animation'), + _dereq_('./class'), + _dereq_('./comparators'), + _dereq_('./compounds'), + _dereq_('./data'), + _dereq_('./degree'), + _dereq_('./dimensions'), + _dereq_('./events'), + _dereq_('./filter'), + _dereq_('./group'), + _dereq_('./index'), + _dereq_('./iteration'), + _dereq_('./layout'), + _dereq_('./style'), + _dereq_('./switch-functions'), + _dereq_('./traversing') +].forEach(function( props ){ + util.extend( elesfn, props ); +}); + +module.exports = Collection; + +},{"../is":77,"../util":94,"./algorithms":9,"./animation":12,"./class":13,"./comparators":14,"./compounds":15,"./data":16,"./degree":17,"./dimensions":18,"./element":19,"./events":20,"./filter":21,"./group":22,"./index":23,"./iteration":24,"./layout":25,"./style":26,"./switch-functions":27,"./traversing":28}],24:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../is'); +var zIndexSort = _dereq_('./zsort'); + +var elesfn = ({ + each: function(fn){ + if( is.fn(fn) ){ + for(var i = 0; i < this.length; i++){ + var ele = this[i]; + var ret = fn.apply( ele, [ i, ele ] ); + + if( ret === false ){ break; } // exit each early on return false + } + } + return this; + }, + + forEach: function(fn, thisArg){ + if( is.fn(fn) ){ + + for(var i = 0; i < this.length; 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(){ + var array = []; + + for(var i = 0; i < this.length; i++){ + array.push( this[i] ); + } + + return array; + }, + + slice: function(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(){ + return this.length; + }, + + eq: function(i){ + return this[i] || this.spawn(); + }, + + first: function(){ + return this[0] || this.spawn(); + }, + + last: function(){ + return this[ this.length - 1 ] || this.spawn(); + }, + + empty: function(){ + return this.length === 0; + }, + + nonempty: function(){ + return !this.empty(); + }, + + sort: function( sortFn ){ + if( !is.fn( sortFn ) ){ + return this; + } + + var sorted = this.toArray().sort( sortFn ); + + return this.spawn(sorted); + }, + + sortByZIndex: function(){ + return this.sort( zIndexSort ); + }, + + zDepth: function(){ + var ele = this[0]; + if( !ele ){ return undefined; } + + // var 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 Number.MAX_VALUE; // 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 + } + } +}); + +module.exports = elesfn; + +},{"../is":77,"./zsort":29}],25:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../is'); +var util = _dereq_('../util'); + +var elesfn = ({ + + // using standard layout options, apply position function (w/ or w/o animation) + layoutPositions: function( layout, options, fn ){ + var nodes = this.nodes(); + var cy = this.cy(); + + layout.trigger({ type: 'layoutstart', layout: layout }); + + layout.animations = []; + + if( options.animate ){ + for( var i = 0; i < nodes.length; i++ ){ + var node = nodes[i]; + var lastNode = i === nodes.length - 1; + + var newPos = fn.call( node, i, node ); + var pos = node.position(); + + if( !is.number(pos.x) || !is.number(pos.y) ){ + node.silentPosition({ x: 0, y: 0 }); + } + + var ani = node.animation({ + position: newPos, + duration: options.animationDuration, + easing: options.animationEasing, + step: !lastNode ? undefined : function(){ + if( options.fit ){ + cy.fit( options.eles, options.padding ); + } + }, + complete: !lastNode ? undefined : function(){ + if( options.zoom != null ){ + cy.zoom( options.zoom ); + } + + if( options.pan ){ + cy.pan( options.pan ); + } + + if( options.fit ){ + cy.fit( options.eles, options.padding ); + } + + layout.one('layoutstop', options.stop); + layout.trigger({ type: 'layoutstop', layout: layout }); + } + }); + + layout.animations.push( ani ); + + ani.play(); + } + + layout.one('layoutready', options.ready); + layout.trigger({ type: 'layoutready', layout: layout }); + } else { + nodes.positions( fn ); + + 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.trigger({ type: 'layoutready', layout: layout }); + + layout.one('layoutstop', options.stop); + layout.trigger({ type: 'layoutstop', layout: layout }); + } + + return this; // chaining + }, + + layout: function( options ){ + var cy = this.cy(); + + cy.layout( util.extend({}, options, { + eles: this + }) ); + + return this; + }, + + makeLayout: function( options ){ + var cy = this.cy(); + + return cy.makeLayout( util.extend({}, options, { + eles: this + }) ); + } + +}); + +// aliases: +elesfn.createLayout = elesfn.makeLayout; + +module.exports = elesfn; + +},{"../is":77,"../util":94}],26:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../is'); + +var elesfn = ({ + + // fully updates (recalculates) the style for the elements + updateStyle: function( notifyRenderer ){ + var cy = this._private.cy; + + if( !cy.styleEnabled() ){ return this; } + + if( cy._private.batchingStyle ){ + var bEles = cy._private.batchStyleEles; + + bEles.merge( this ); + + return this; // chaining and exit early when batching + } + + var style = cy.style(); + notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false; + + style.apply( this ); + + var updatedCompounds = this.updateCompoundBounds(); + var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this; + + if( notifyRenderer ){ + toNotify.rtrigger('style'); // let renderer know we changed style + } else { + toNotify.trigger('style'); // just fire the event + } + return this; // chaining + }, + + // just update the mappers in the elements' styles; cheaper than eles.updateStyle() + updateMappers: function( notifyRenderer ){ + var cy = this._private.cy; + var style = cy.style(); + notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false; + + if( !cy.styleEnabled() ){ return this; } + + style.updateMappers( this ); + + var updatedCompounds = this.updateCompoundBounds(); + var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this; + + if( notifyRenderer ){ + toNotify.rtrigger('style'); // let renderer know we changed style + } else { + toNotify.trigger('style'); // just fire the event + } + return this; // chaining + }, + + // 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) + renderedCss: function( property ){ + var cy = this.cy(); + if( !cy.styleEnabled() ){ return this; } + + var ele = this[0]; + + if( ele ){ + var renstyle = ele.cy().style().getRenderedStyle( ele ); + + if( property === undefined ){ + return renstyle; + } else { + return renstyle[ property ]; + } + } + }, + + // read the calculated css style of the element or override the style (via a bypass) + css: function( name, value ){ + var cy = this.cy(); + + if( !cy.styleEnabled() ){ return this; } + + var updateTransitions = false; + var style = cy.style(); + + if( is.plainObject(name) ){ // then extend the bypass + var props = name; + style.applyBypass( this, props, updateTransitions ); + + var updatedCompounds = this.updateCompoundBounds(); + var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this; + toNotify.rtrigger('style'); // let the renderer know we've updated style + + } else if( is.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 ); + + var updatedCompounds = this.updateCompoundBounds(); + var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this; + toNotify.rtrigger('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 + }, + + removeCss: function( 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 ele = eles[i]; + + style.removeBypasses( ele, names, updateTransitions ); + } + } + + var updatedCompounds = this.updateCompoundBounds(); + var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this; + toNotify.rtrigger('style'); // let the renderer know we've updated style + + return this; // chaining + }, + + show: function(){ + this.css('display', 'element'); + return this; // chaining + }, + + hide: function(){ + this.css('display', 'none'); + return this; // chaining + }, + + visible: function(){ + var cy = this.cy(); + if( !cy.styleEnabled() ){ return true; } + + var ele = this[0]; + var hasCompoundNodes = cy.hasCompoundNodes(); + + if( ele ){ + var style = ele._private.style; + + if( + style['visibility'].value !== 'visible' + || style['display'].value !== 'element' + ){ + return false; + } + + if( ele._private.group === 'nodes' ){ + if( !hasCompoundNodes ){ return true; } + + var parents = ele._private.data.parent ? ele.parents() : null; + + if( parents ){ + for( var i = 0; i < parents.length; i++ ){ + var parent = parents[i]; + var pStyle = parent._private.style; + var pVis = pStyle['visibility'].value; + var pDis = pStyle['display'].value; + + if( pVis !== 'visible' || pDis !== 'element' ){ + return false; + } + } + } + + return true; + } else { + var src = ele._private.source; + var tgt = ele._private.target; + + return src.visible() && tgt.visible(); + } + + } + }, + + hidden: function(){ + var ele = this[0]; + + if( ele ){ + return !ele.visible(); + } + }, + + effectiveOpacity: function(){ + 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 = _p.style.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._private.style.opacity.value; + + parentOpacity = opacity * parentOpacity; + } + } + + return parentOpacity; + } + }, + + transparent: function(){ + var cy = this.cy(); + if( !cy.styleEnabled() ){ return false; } + + var ele = this[0]; + var hasCompoundNodes = ele.cy().hasCompoundNodes(); + + if( ele ){ + if( !hasCompoundNodes ){ + return ele._private.style.opacity.value === 0; + } else { + return ele.effectiveOpacity() === 0; + } + } + }, + + isFullAutoParent: function(){ + var cy = this.cy(); + if( !cy.styleEnabled() ){ return false; } + + var ele = this[0]; + + if( ele ){ + var autoW = ele._private.style['width'].value === 'auto'; + var autoH = ele._private.style['height'].value === 'auto'; + + return ele.isParent() && autoW && autoH; + } + }, + + backgrounding: function(){ + var cy = this.cy(); + if( !cy.styleEnabled() ){ return false; } + + var ele = this[0]; + + return ele._private.backgrounding ? true : false; + } + +}); + + +elesfn.bypass = elesfn.style = elesfn.css; +elesfn.renderedStyle = elesfn.renderedCss; +elesfn.removeBypass = elesfn.removeStyle = elesfn.removeCss; + +module.exports = elesfn; + +},{"../is":77}],27:[function(_dereq_,module,exports){ +'use strict'; + +var elesfn = {}; + +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.bind( params.event, data, handler ); + } + + // e.g. cy.nodes().select( handler ) + else if( args.length === 1 ){ + var handler = args[0]; + this.bind( params.event, handler ); + } + + // e.g. cy.nodes().select() + else if( args.length === 0 ){ + 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.trigger( params.event ); + } + + return this; + }; +} + +function defineSwitchSet( params ){ + elesfn[ 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[ params.on ] = defineSwitchFunction({ + event: params.on, + field: params.field, + ableField: params.ableField, + overrideAble: params.overrideAble, + value: true + }); + + elesfn[ params.off ] = defineSwitchFunction({ + event: params.off, + field: params.field, + ableField: params.ableField, + overrideAble: params.overrideAble, + value: false + }); +} + +defineSwitchSet({ + field: 'locked', + overrideField: function(ele){ + return ele.cy().autolock() ? true : undefined; + }, + on: 'lock', + off: 'unlock' +}); + +defineSwitchSet({ + field: 'grabbable', + overrideField: function(ele){ + return ele.cy().autoungrabify() ? false : undefined; + }, + on: 'grabify', + off: 'ungrabify' +}); + +defineSwitchSet({ + field: 'selected', + ableField: 'selectable', + overrideAble: function(ele){ + return ele.cy().autounselectify() ? false : undefined; + }, + on: 'select', + off: 'unselect' +}); + +defineSwitchSet({ + field: 'selectable', + overrideField: function(ele){ + return ele.cy().autounselectify() ? false : undefined; + }, + on: 'selectify', + off: 'unselectify' +}); + +elesfn.deselect = elesfn.unselect; + +elesfn.grabbed = function(){ + var ele = this[0]; + if( ele ){ + return ele._private.grabbed; + } +}; + +defineSwitchSet({ + field: 'active', + on: 'activate', + off: 'unactivate' +}); + +elesfn.inactive = function(){ + var ele = this[0]; + if( ele ){ + return !ele._private.active; + } +}; + +module.exports = elesfn; + +},{}],28:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../util'); +var is = _dereq_('../is'); + +var elesfn = {}; + +util.extend(elesfn, { + // get the root nodes in the DAG + roots: function( selector ){ + var eles = this; + var roots = []; + + for( var i = 0; i < eles.length; i++ ){ + var ele = eles[i]; + if( !ele.isNode() ){ + continue; + } + + var hasEdgesPointingIn = ele.connectedEdges(function(){ + return this.data('target') === ele.id() && this.data('source') !== ele.id(); + }).length > 0; + + if( !hasEdgesPointingIn ){ + roots.push( ele ); + } + } + + return this.spawn( roots, { unique: true } ).filter( selector ); + }, + + // get the leaf nodes in the DAG + leaves: function( selector ){ + var eles = this; + var leaves = []; + + for( var i = 0; i < eles.length; i++ ){ + var ele = eles[i]; + if( !ele.isNode() ){ + continue; + } + + var hasEdgesPointingOut = ele.connectedEdges(function(){ + return this.data('source') === ele.id() && this.data('target') !== ele.id(); + }).length > 0; + + if( !hasEdgesPointingOut ){ + leaves.push( ele ); + } + } + + return this.spawn( leaves, { unique: true } ).filter( selector ); + }, + + // normally called children in graph theory + // these nodes =edges=> outgoing nodes + outgoers: function( selector ){ + var eles = this; + var oEles = []; + + for( var i = 0; i < eles.length; i++ ){ + var ele = eles[i]; + var eleId = ele.id(); + + if( !ele.isNode() ){ continue; } + + var edges = ele._private.edges; + for( var j = 0; j < edges.length; j++ ){ + var edge = edges[j]; + var srcId = edge._private.data.source; + var tgtId = edge._private.data.target; + + if( srcId === eleId && tgtId !== eleId ){ + oEles.push( edge ); + oEles.push( edge.target()[0] ); + } + } + } + + return this.spawn( oEles, { unique: true } ).filter( selector ); + }, + + // aka DAG descendants + successors: function( selector ){ + var eles = this; + var sEles = []; + var sElesIds = {}; + + for(;;){ + var outgoers = eles.outgoers(); + + if( outgoers.length === 0 ){ break; } // done if no outgoers left + + var newOutgoers = false; + for( var i = 0; i < outgoers.length; i++ ){ + var outgoer = outgoers[i]; + var outgoerId = outgoer.id(); + + if( !sElesIds[ outgoerId ] ){ + sElesIds[ outgoerId ] = true; + sEles.push( outgoer ); + newOutgoers = true; + } + } + + if( !newOutgoers ){ break; } // done if touched all outgoers already + + eles = outgoers; + } + + return this.spawn( sEles, { unique: true } ).filter( selector ); + }, + + // normally called parents in graph theory + // these nodes <=edges= incoming nodes + incomers: function( selector ){ + var eles = this; + var oEles = []; + + for( var i = 0; i < eles.length; i++ ){ + var ele = eles[i]; + var eleId = ele.id(); + + if( !ele.isNode() ){ continue; } + + var edges = ele._private.edges; + for( var j = 0; j < edges.length; j++ ){ + var edge = edges[j]; + var srcId = edge._private.data.source; + var tgtId = edge._private.data.target; + + if( tgtId === eleId && srcId !== eleId ){ + oEles.push( edge ); + oEles.push( edge.source()[0] ); + } + } + } + + return this.spawn( oEles, { unique: true } ).filter( selector ); + }, + + // aka DAG ancestors + predecessors: function( selector ){ + var eles = this; + var pEles = []; + var pElesIds = {}; + + for(;;){ + var incomers = eles.incomers(); + + if( incomers.length === 0 ){ break; } // done if no incomers left + + var newIncomers = false; + for( var i = 0; i < incomers.length; i++ ){ + var incomer = incomers[i]; + var incomerId = incomer.id(); + + if( !pElesIds[ incomerId ] ){ + pElesIds[ incomerId ] = true; + pEles.push( incomer ); + newIncomers = true; + } + } + + if( !newIncomers ){ break; } // done if touched all incomers already + + eles = incomers; + } + + return this.spawn( pEles, { unique: true } ).filter( selector ); + } +}); + + +// Neighbourhood functions +////////////////////////// + +util.extend(elesfn, { + neighborhood: 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._private.source; + var tgt = edge._private.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, { unique: true } ) ).filter( selector ); + }, + + closedNeighborhood: function(selector){ + return this.neighborhood().add( this ).filter( selector ); + }, + + openNeighborhood: function(selector){ + return this.neighborhood( selector ); + } +}); + +// aliases +elesfn.neighbourhood = elesfn.neighborhood; +elesfn.closedNeighbourhood = elesfn.closedNeighborhood; +elesfn.openNeighbourhood = elesfn.openNeighborhood; + +// Edge functions +///////////////// + +util.extend(elesfn, { + source: function( selector ){ + var ele = this[0]; + var src; + + if( ele ){ + src = ele._private.source; + } + + return src && selector ? src.filter( selector ) : src; + }, + + target: function( selector ){ + var ele = this[0]; + var tgt; + + if( ele ){ + tgt = ele._private.target; + } + + return tgt && selector ? tgt.filter( selector ) : tgt; + }, + + sources: defineSourceFunction({ + attr: 'source' + }), + + targets: defineSourceFunction({ + attr: 'target' + }) +}); + +function defineSourceFunction( params ){ + return function( 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, { unique: true } ).filter( selector ); + }; +} + +util.extend(elesfn, { + edgesWith: defineEdgesWithFunction(), + + edgesTo: defineEdgesWithFunction({ + thisIs: 'source' + }) +}); + +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( is.string(otherNodes) ){ + otherNodes = cy.$( otherNodes ); + } + + var thisIds = this._private.ids; + var otherIds = otherNodes._private.ids; + + 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 = thisIds[ edgeData.source ] && otherIds[ edgeData.target ]; + var otherToThis = otherIds[ edgeData.source ] && thisIds[ edgeData.target ]; + var edgeConnectsThisAndOther = thisToOther || otherToThis; + + if( !edgeConnectsThisAndOther ){ continue; } + + if( p.thisIs ){ + if( p.thisIs === 'source' && !thisToOther ){ continue; } + + if( p.thisIs === 'target' && !otherToThis ){ continue; } + } + + elements.push( edge ); + } + } + + return this.spawn( elements, { unique: true } ); + }; +} + +util.extend(elesfn, { + connectedEdges: 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, { unique: true } ).filter( selector ); + }, + + connectedNodes: 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, { unique: true } ).filter( selector ); + }, + + parallelEdges: defineParallelEdgesFunction(), + + codirectedEdges: defineParallelEdgesFunction({ + codirected: true + }) +}); + +function defineParallelEdgesFunction(params){ + var defaults = { + codirected: false + }; + params = util.extend({}, defaults, params); + + return function( selector ){ + 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 src1 = edge1.source()[0]; + var srcid1 = src1.id(); + var tgt1 = edge1.target()[0]; + var tgtid1 = tgt1.id(); + 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, { unique: true } ).filter( selector ); + }; + +} + +// Misc functions +///////////////// + +util.extend(elesfn, { + components: function(){ + var cy = this.cy(); + var visited = cy.collection(); + var unvisited = this.nodes(); + var components = []; + + var visitInComponent = function( node, component ){ + visited.merge( node ); + unvisited.unmerge( node ); + component.merge( node ); + }; + + do { + var component = cy.collection(); + components.push( component ); + + var root = unvisited[0]; + visitInComponent( root, component ); + + this.bfs({ + directed: false, + roots: root, + visit: function( i, depth, v, e, u ){ + visitInComponent( v, component ); + } + }); + + } while( unvisited.length > 0 ); + + return components.map(function( component ){ + return component.closedNeighborhood(); // add the edges + }); + } +}); + +module.exports = elesfn; + +},{"../is":77,"../util":94}],29:[function(_dereq_,module,exports){ +'use strict'; + +var zIndexSort = function( a, b ){ + var cy = a.cy(); + var a_p = a._private; + var b_p = b._private; + var zDiff = a_p.style['z-index'].value - b_p.style['z-index'].value; + var depthA = 0; + var depthB = 0; + var hasCompoundNodes = cy.hasCompoundNodes(); + var aIsNode = a_p.group === 'nodes'; + var aIsEdge = a_p.group === 'edges'; + var bIsNode = b_p.group === 'nodes'; + var bIsEdge = b_p.group === 'edges'; + + // no need to calculate element depth if there is no compound node + if( hasCompoundNodes ){ + depthA = a.zDepth(); + depthB = b.zDepth(); + } + + var depthDiff = depthA - depthB; + var sameDepth = depthDiff === 0; + + if( sameDepth ){ + + if( aIsNode && bIsEdge ){ + return 1; // 'a' is a node, it should be drawn later + + } else if( aIsEdge && bIsNode ){ + return -1; // 'a' is an edge, it should be drawn first + + } else { // both nodes or both edges + if( zDiff === 0 ){ // same z-index => compare indices in the core (order added to graph w/ last on top) + return a_p.index - b_p.index; + } else { + return zDiff; + } + } + + // elements on different level + } else { + return depthDiff; // deeper element should be drawn later + } + +}; + +module.exports = zIndexSort; + +},{}],30:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../is'); +var util = _dereq_('../util'); +var Collection = _dereq_('../collection'); +var Element = _dereq_('../collection/element'); +var window = _dereq_('../window'); +var document = window ? window.document : null; +var NullRenderer = _dereq_('../extensions/renderer/null'); + +var corefn = { + add: function(opts){ + + var elements; + var cy = this; + + // add the elements + if( is.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( is.array(opts) ){ + var jsons = opts; + + elements = new Collection(cy, jsons); + } + + // specify via opts.nodes and opts.edges + else if( is.plainObject(opts) && (is.array(opts.nodes) || is.array(opts.edges)) ){ + var elesByGroup = opts; + var jsons = []; + + var grs = ['nodes', 'edges']; + for( var i = 0, il = grs.length; i < il; i++ ){ + var group = grs[i]; + var elesArray = elesByGroup[group]; + + if( is.array(elesArray) ){ + + for( var j = 0, jl = elesArray.length; j < jl; j++ ){ + var json = util.extend( { group: group }, elesArray[j] ); + + jsons.push( json ); + } + } + } + + elements = new Collection(cy, jsons); + } + + // specify options for one element + else { + var json = opts; + elements = (new Element( cy, json )).collection(); + } + + return elements; + }, + + remove: function(collection){ + if( is.elementOrCollection(collection) ){ + collection = collection; + } else if( is.string(collection) ){ + var selector = collection; + collection = this.$( selector ); + } + + return collection.remove(); + }, + + load: function(elements, onload, ondone){ + var cy = this; + + cy.notifications(false); + + // remove old elements + var oldEles = cy.elements(); + if( oldEles.length > 0 ){ + oldEles.remove(); + } + + if( elements != null ){ + if( is.plainObject(elements) || is.array(elements) ){ + cy.add( elements ); + } + } + + cy.one('layoutready', function(e){ + cy.notifications(true); + cy.trigger(e); // we missed this event by turning notifications off, so pass it on + + cy.notify({ + type: 'load', + collection: cy.elements() + }); + + cy.one('load', onload); + cy.trigger('load'); + }).one('layoutstop', function(){ + cy.one('done', ondone); + cy.trigger('done'); + }); + + var layoutOpts = util.extend({}, cy._private.options.layout); + layoutOpts.eles = cy.$(); + + cy.layout( layoutOpts ); + + return this; + } +}; + +module.exports = corefn; + +},{"../collection":23,"../collection/element":19,"../extensions/renderer/null":73,"../is":77,"../util":94,"../window":100}],31:[function(_dereq_,module,exports){ +'use strict'; + +var define = _dereq_('../define'); +var util = _dereq_('../util'); +var is = _dereq_('../is'); + +var corefn = ({ + + // 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( eles ){ + var cy = this; + + if( !cy.styleEnabled() ){ return; } // save cycles when no style used + + cy._private.aniEles.merge( eles ); + }, + + stopAnimationLoop: function(){ + this._private.animationsRunning = false; + }, + + startAnimationLoop: function(){ + 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 globalAnimationStep(){ + if( !cy._private.animationsRunning ){ return; } + + util.requestAnimationFrame(function(now){ + handleElements(now); + globalAnimationStep(); + }); + } + + globalAnimationStep(); // first call + + function handleElements( now ){ + var eles = cy._private.aniEles; + var doneEles = []; + + function handleElement( 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 ){ + 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( ele, ani, now, isCore ); + + if( ani_p.applying ){ + ani_p.applying = false; + } + + callbacks( ani_p.frames ); + + 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; + } // handleElement + + // handle all eles + var ranEleAni = false; + for( var e = 0; e < eles.length; e++ ){ + var ele = eles[e]; + var handledThisEle = handleElement( ele ); + + ranEleAni = ranEleAni || handledThisEle; + } // each element + + var ranCoreAni = handleElement( cy, true ); + + // notify renderer + if( ranEleAni || ranCoreAni ){ + var toNotify; + + if( eles.length > 0 ){ + var updatedEles = eles.updateCompoundBounds(); + toNotify = updatedEles.length > 0 ? eles.add( updatedEles ) : eles; + } + + cy.notify({ + type: 'draw', + collection: toNotify + }); + } + + // remove elements from list of currently animating if its queues are empty + eles.unmerge( doneEles ); + + } // handleElements + + function startAnimation( self, ani, now ){ + var isCore = is.core( self ); + var isEles = !isCore; + var ele = self; + var style = cy._private.style; + var ani_p = ani._private; + + if( isEles ){ + var pos = ele._private.position; + + ani_p.startPosition = ani_p.startPosition || { + x: pos.x, + y: pos.y + }; + + ani_p.startStyle = ani_p.startStyle || style.getValueStyle( ele ); + } + + if( isCore ){ + var pan = cy._private.pan; + + ani_p.startPan = ani_p.startPan || { + x: pan.x, + y: pan.y + }; + + ani_p.startZoom = ani_p.startZoom != null ? ani_p.startZoom : cy._private.zoom; + } + + ani_p.started = true; + ani_p.startTime = now - ani_p.progress * ani_p.duration; + } + + function step( self, ani, now, isCore ){ + var style = cy._private.style; + var isEles = !isCore; + var _p = self._private; + var ani_p = ani._private; + var pEasing = ani_p.easing; + var startTime = ani_p.startTime; + + if( !ani_p.easingImpl ){ + + if( pEasing == null ){ // use default + ani_p.easingImpl = easings['linear']; + + } else { // then define w/ name + var easingVals; + + if( is.string( pEasing ) ){ + var easingProp = style.parse('transition-timing-function', pEasing); + + easingVals = easingProp.value; + + } else { // then assume preparsed array + easingVals = pEasing; + } + + var name, args; + + if( is.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; + var pos = _p.position; + if( endPos && isEles ){ + if( valid( startPos.x, endPos.x ) ){ + pos.x = ease( startPos.x, endPos.x, percent, easing ); + } + + if( valid( startPos.y, endPos.y ) ){ + pos.y = ease( startPos.y, endPos.y, percent, easing ); + } + } + + 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.trigger('pan'); + } + + var startZoom = ani_p.startZoom; + var endZoom = ani_p.zoom; + var animatingZoom = endZoom != null && isCore; + if( animatingZoom ){ + if( valid( startZoom, endZoom ) ){ + _p.zoom = ease( startZoom, endZoom, percent, easing ); + } + + self.trigger('zoom'); + } + + if( animatingPan || animatingZoom ){ + self.trigger('viewport'); + } + + var props = ani_p.style; + if( props && 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 easedVal = ease( start, end, percent, easing ); + + style.overrideBypass( self, name, easedVal ); + } // for props + + } // if + + } + + if( is.fn(ani_p.step) ){ + ani_p.step.apply( self, [ now ] ); + } + + ani_p.progress = percent; + + return percent; + } + + function valid(start, end){ + if( start == null || end == null ){ + return false; + } + + if( is.number(start) && is.number(end) ){ + return true; + } else if( (start) && (end) ){ + return true; + } + + return false; + } + + // assumes p0 = 0, p3 = 1 + function evalCubicBezier( p1, p2, t ){ + var one_t = 1 - t; + var tsq = t*t; + + return ( 3 * one_t * one_t * t * p1 ) + ( 3 * one_t * tsq * p2 ) + tsq * t; + } + + function cubicBezier( p1, p2 ){ + return function( start, end, percent ){ + return start + (end - start) * evalCubicBezier( p1, p2, percent ); + }; + } + + /* 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; + } + + while (true) { + /* 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 easings = { + 'linear': function( 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( tension, friction, duration ){ + var spring = generateSpringRK4( tension, friction, duration ); + + return function( start, end, percent ){ + return start + (end - start) * spring( percent ); + }; + }, + + 'cubic-bezier': function( x1, y1, x2, y2 ){ + return cubicBezier( x1, y1, x2, y2 ); + } + }; + + function ease( startProp, endProp, percent, easingFn ){ + if( percent < 0 ){ + percent = 0; + } else if( percent > 1 ){ + percent = 1; + } + + var start, end; + + if( startProp.pfValue != null || startProp.value != null ){ + start = startProp.pfValue != null ? startProp.pfValue : startProp.value; + } else { + start = startProp; + } + + if( endProp.pfValue != null || endProp.value != null ){ + end = endProp.pfValue != null ? endProp.pfValue : endProp.value; + } else { + end = endProp; + } + + if( is.number(start) && is.number(end) ){ + return easingFn( start, end, percent ); + + } else if( is.array(start) && is.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 = easingFn(si, ei, percent); + + if( startProp.roundValue ){ val = Math.round( val ); } + + easedArr.push( val ); + } else { + easedArr.push( ei ); + } + } + + return easedArr; + } + + return undefined; + } + + } + +}); + +module.exports = corefn; + +},{"../define":41,"../is":77,"../util":94}],32:[function(_dereq_,module,exports){ +'use strict'; + +var define = _dereq_('../define'); + +var corefn = ({ + on: define.on(), // .on( events [, selector] [, data], handler) + one: define.on({ unbindSelfOnTrigger: true }), + once: define.on({ unbindAllBindersOnTrigger: true }), + off: define.off(), // .off( events [, selector] [, handler] ) + trigger: define.trigger() // .trigger( events [, extraParams] ) +}); + +define.eventAliasesOn( corefn ); + +module.exports = corefn; + +},{"../define":41}],33:[function(_dereq_,module,exports){ +'use strict'; + +var corefn = ({ + + png: function( options ){ + var renderer = this._private.renderer; + options = options || {}; + + return renderer.png( options ); + }, + + jpg: function( options ){ + var renderer = this._private.renderer; + options = options || {}; + + options.bg = options.bg || '#fff'; + + return renderer.jpg( options ); + } + +}); + +corefn.jpeg = corefn.jpg; + +module.exports = corefn; + +},{}],34:[function(_dereq_,module,exports){ +'use strict'; + +var window = _dereq_('../window'); +var util = _dereq_('../util'); +var Collection = _dereq_('../collection'); +var is = _dereq_('../is'); +var Promise = _dereq_('../promise'); +var define = _dereq_('../define'); + +var Core = function( opts ){ + if( !(this instanceof Core) ){ + return new Core(opts); + } + var cy = this; + + opts = util.extend({}, opts); + + var container = opts.container; + + // allow for passing a wrapped jquery object + // e.g. cytoscape({ container: $('#cy') }) + if( container && !is.htmlElement( container ) && is.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 = util.extend( { name: head ? 'grid' : 'null' }, options.layout ); + options.renderer = util.extend( { name: head ? 'canvas' : 'null' }, options.renderer ); + + var defVal = function( 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 + initrender: false, // has initrender has been triggered + options: options, // cached options + elements: [], // array of elements + id2index: {}, // element id => index in elements array + listeners: [], // list of listeners + onRenders: [], // rendering listeners + aniEles: Collection(this), // elements being animated + scratch: {}, // scratch object for core + layout: null, + renderer: null, + 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: is.number(options.zoom) ? options.zoom : 1, + pan: { + x: is.plainObject(options.pan) && is.number(options.pan.x) ? options.pan.x : 0, + y: is.plainObject(options.pan) && is.number(options.pan.y) ? options.pan.y : 0 + }, + animation: { // object for currently-running animations + current: [], + queue: [] + }, + hasCompoundNodes: false, + deferredExecQueue: [] + }; + + // set selection type + var selType = options.selectionType; + if( selType === undefined || (selType !== 'additive' && selType !== 'single') ){ + // then set default + + _p.selectionType = 'single'; + } else { + _p.selectionType = selType; + } + + // init zoom bounds + if( is.number(options.minZoom) && is.number(options.maxZoom) && options.minZoom < options.maxZoom ){ + _p.minZoom = options.minZoom; + _p.maxZoom = options.maxZoom; + } else if( is.number(options.minZoom) && options.maxZoom === undefined ){ + _p.minZoom = options.minZoom; + } else if( is.number(options.maxZoom) && options.minZoom === undefined ){ + _p.maxZoom = options.maxZoom; + } + + var loadExtData = function( next ){ + var anyIsPromise = false; + + for( var i = 0; i < extData.length; i++ ){ + var datum = extData[i]; + + if( is.promise(datum) ){ + anyIsPromise = true; + break; + } + } + + if( anyIsPromise ){ + return Promise.all( extData ).then( next ); // load all data asynchronously, then exec rest of init + } else { + next( extData ); // exec synchronously for convenience + } + }; + + // create the renderer + cy.initRenderer( util.extend({ + hideEdgesOnViewport: options.hideEdgesOnViewport, + hideLabelsOnViewport: options.hideLabelsOnViewport, + textureOnViewport: options.textureOnViewport, + wheelSensitivity: is.number(options.wheelSensitivity) && options.wheelSensitivity > 0 ? options.wheelSensitivity : 1, + motionBlur: options.motionBlur === undefined ? true : options.motionBlur, // on by default + motionBlurOpacity: options.motionBlurOpacity === undefined ? 0.05 : options.motionBlurOpacity, + pixelRatio: is.number(options.pixelRatio) && options.pixelRatio > 0 ? options.pixelRatio : undefined, + desktopTapThreshold: options.desktopTapThreshold === undefined ? 4 : options.desktopTapThreshold, + touchTapThreshold: options.touchTapThreshold === undefined ? 8 : options.touchTapThreshold + }, options.renderer) ); + + var extData = [ options.style, options.elements ]; + loadExtData(function( thens ){ + var initStyle = thens[0]; + var initEles = thens[1]; + + // init style + if( _p.styleEnabled ){ + cy.setStyle( initStyle ); + } + + // trigger the passed function for the `initrender` event + if( options.initrender ){ + cy.on('initrender', options.initrender); + cy.on('initrender', function(){ + _p.initrender = true; + }); + } + + // initial load + cy.load(initEles, function(){ // onready + cy.startAnimationLoop(); + _p.ready = true; + + // if a ready callback is specified as an option, the bind it + if( is.fn( 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.trigger('ready'); + }, options.done); + + }); +}; + +var corefn = Core.prototype; // short alias + +util.extend(corefn, { + instanceString: function(){ + return 'core'; + }, + + isReady: function(){ + return this._private.ready; + }, + + ready: function( fn ){ + if( this.isReady() ){ + this.trigger('ready', [], fn); // just calls fn as though triggered via ready event + } else { + this.on('ready', fn); + } + + return this; + }, + + initrender: function(){ + return this._private.initrender; + }, + + destroy: function(){ + var cy = this; + + cy.stopAnimationLoop(); + + cy.notify({ type: 'destroy' }); // destroy the renderer + + var domEle = cy.container(); + if( domEle ){ + domEle._cyreg = null; + + while( domEle.childNodes.length > 0 ){ + domEle.removeChild( domEle.childNodes[0] ); + } + } + + return cy; + }, + + getElementById: function( id ){ + var index = this._private.id2index[ id ]; + if( index !== undefined ){ + return this._private.elements[ index ]; + } + + // worst case, return an empty collection + return Collection( this ); + }, + + selectionType: function(){ + return this._private.selectionType; + }, + + hasCompoundNodes: function(){ + return this._private.hasCompoundNodes; + }, + + styleEnabled: function(){ + return this._private.styleEnabled; + }, + + addToPool: function( eles ){ + var elements = this._private.elements; + var id2index = this._private.id2index; + + for( var i = 0; i < eles.length; i++ ){ + var ele = eles[i]; + + var id = ele._private.data.id; + var index = id2index[ id ]; + var alreadyInPool = index !== undefined; + + if( !alreadyInPool ){ + index = elements.length; + elements.push( ele ); + id2index[ id ] = index; + ele._private.index = index; + } + } + + return this; // chaining + }, + + removeFromPool: function( eles ){ + var elements = this._private.elements; + var id2index = this._private.id2index; + + for( var i = 0; i < eles.length; i++ ){ + var ele = eles[i]; + + var id = ele._private.data.id; + var index = id2index[ id ]; + var inPool = index !== undefined; + + if( inPool ){ + this._private.id2index[ id ] = undefined; + elements.splice(index, 1); + + // adjust the index of all elements past this index + for( var j = index; j < elements.length; j++ ){ + var jid = elements[j]._private.data.id; + id2index[ jid ]--; + elements[j]._private.index--; + } + } + } + }, + + container: function(){ + return this._private.container; + }, + + options: function(){ + return util.copy( this._private.options ); + }, + + json: function( obj ){ + var cy = this; + var _p = cy._private; + + if( is.plainObject(obj) ){ // set + + cy.startBatch(); + + if( obj.elements ){ + var idInJson = {}; + + var updateEles = function( jsons, gr ){ + for( var i = 0; i < jsons.length; i++ ){ + var json = jsons[i]; + var id = json.data.id; + var ele = cy.getElementById( id ); + + idInJson[ id ] = true; + + if( ele.length !== 0 ){ // existing element should be updated + ele.json( json ); + } else { // otherwise should be added + if( gr ){ + cy.add( util.extend({ group: gr }, json) ); + } else { + cy.add( json ); + } + } + } + }; + + if( is.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( is.array(elements) ){ + updateEles( elements, gr ); + } + } + } + + // elements not specified in json should be removed + cy.elements().stdFilter(function( ele ){ + return !idInJson[ ele.id() ]; + }).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 ); + } + } + + var fields = [ + 'minZoom', 'maxZoom', 'zoomingEnabled', 'userZoomingEnabled', + 'panningEnabled', 'userPanningEnabled', + 'boxSelectionEnabled', + 'autolock', 'autoungrabify', 'autounselectify' + ]; + + for( var i = 0; i < fields.length; i++ ){ + var f = fields[i]; + + if( obj[f] != null ){ + cy[f]( obj[f] ); + } + } + + cy.endBatch(); + + return this; // chaining + } else if( obj === undefined ){ // get + var json = {}; + + json.elements = {}; + cy.elements().each(function(i, 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.zoomingEnabled = cy._private.zoomingEnabled; + json.userZoomingEnabled = cy._private.userZoomingEnabled; + json.zoom = cy._private.zoom; + json.minZoom = cy._private.minZoom; + json.maxZoom = cy._private.maxZoom; + json.panningEnabled = cy._private.panningEnabled; + json.userPanningEnabled = cy._private.userPanningEnabled; + json.pan = util.copy( cy._private.pan ); + json.boxSelectionEnabled = cy._private.boxSelectionEnabled; + json.renderer = util.copy( cy._private.options.renderer ); + json.hideEdgesOnViewport = cy._private.options.hideEdgesOnViewport; + json.hideLabelsOnViewport = cy._private.options.hideLabelsOnViewport; + json.textureOnViewport = cy._private.options.textureOnViewport; + json.wheelSensitivity = cy._private.options.wheelSensitivity; + json.motionBlur = cy._private.options.motionBlur; + + return json; + } + }, + + scratch: define.data({ + field: 'scratch', + bindingEvent: 'scratch', + allowBinding: true, + allowSetting: true, + settingEvent: 'scratch', + settingTriggersEvent: true, + triggerFnName: 'trigger', + allowGetting: true + }), + + removeScratch: define.removeData({ + field: 'scratch', + event: 'scratch', + triggerFnName: 'trigger', + triggerEvent: true + }) + +}); + +[ + _dereq_('./add-remove'), + _dereq_('./animation'), + _dereq_('./events'), + _dereq_('./export'), + _dereq_('./layout'), + _dereq_('./notification'), + _dereq_('./renderer'), + _dereq_('./search'), + _dereq_('./style'), + _dereq_('./viewport') +].forEach(function( props ){ + util.extend( corefn, props ); +}); + +module.exports = Core; + +},{"../collection":23,"../define":41,"../is":77,"../promise":80,"../util":94,"../window":100,"./add-remove":30,"./animation":31,"./events":32,"./export":33,"./layout":35,"./notification":36,"./renderer":37,"./search":38,"./style":39,"./viewport":40}],35:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../util'); +var is = _dereq_('../is'); + +var corefn = ({ + + layout: function( params ){ + var layout = this._private.prevLayout = ( params == null ? this._private.prevLayout : this.makeLayout( params ) ); + + layout.run(); + + return this; // chaining + }, + + makeLayout: function( options ){ + var cy = this; + + if( options == null ){ + util.error('Layout options must be specified to make a layout'); + return; + } + + if( options.name == null ){ + util.error('A `name` must be specified to make a layout'); + return; + } + + var name = options.name; + var Layout = cy.extension('layout', name); + + if( Layout == null ){ + util.error('Can not apply layout: No such layout `' + name + '` found; did you include its JS file?'); + return; + } + + var eles; + if( is.string( options.eles ) ){ + eles = cy.$( options.eles ); + } else { + eles = options.eles != null ? options.eles : cy.$(); + } + + var layout = new Layout( util.extend({}, options, { + cy: cy, + eles: eles + }) ); + + return layout; + } + +}); + +corefn.createLayout = corefn.makeLayout; + +module.exports = corefn; + +},{"../is":77,"../util":94}],36:[function(_dereq_,module,exports){ +'use strict'; + +var corefn = ({ + notify: function( params ){ + var _p = this._private; + + if( _p.batchingNotify ){ + var bEles = _p.batchNotifyEles; + var bTypes = _p.batchNotifyTypes; + + if( params.collection ){ + bEles.merge( params.collection ); + } + + if( !bTypes.ids[ params.type ] ){ + bTypes.push( params.type ); + } + + return; // notifications are disabled during batching + } + + if( !_p.notificationsEnabled ){ return; } // exit on disabled + + var renderer = this.renderer(); + + renderer.notify(params); + }, + + notifications: function( bool ){ + var p = this._private; + + if( bool === undefined ){ + return p.notificationsEnabled; + } else { + p.notificationsEnabled = bool ? true : false; + } + }, + + noNotifications: function( callback ){ + this.notifications(false); + callback(); + this.notifications(true); + }, + + startBatch: function(){ + var _p = this._private; + + if( _p.batchCount == null ){ + _p.batchCount = 0; + } + + if( _p.batchCount === 0 ){ + _p.batchingStyle = _p.batchingNotify = true; + _p.batchStyleEles = this.collection(); + _p.batchNotifyEles = this.collection(); + _p.batchNotifyTypes = []; + + _p.batchNotifyTypes.ids = {}; + } + + _p.batchCount++; + + return this; + }, + + endBatch: function(){ + var _p = this._private; + + _p.batchCount--; + + if( _p.batchCount === 0 ){ + // update style for dirty eles + _p.batchingStyle = false; + _p.batchStyleEles.updateStyle(); + + // notify the renderer of queued eles and event types + _p.batchingNotify = false; + this.notify({ + type: _p.batchNotifyTypes, + collection: _p.batchNotifyEles + }); + } + + return this; + }, + + batch: function( callback ){ + this.startBatch(); + callback(); + this.endBatch(); + + return this; + }, + + // for backwards compatibility + batchData: function( map ){ + var cy = this; + + return this.batch(function(){ + for( var id in map ){ + var data = map[id]; + var ele = cy.getElementById( id ); + + ele.data( data ); + } + }); + } +}); + +module.exports = corefn; + +},{}],37:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../util'); + +var corefn = ({ + + renderTo: function( context, zoom, pan, pxRatio ){ + var r = this._private.renderer; + + r.renderTo( context, zoom, pan, pxRatio ); + return this; + }, + + renderer: function(){ + return this._private.renderer; + }, + + forceRender: function(){ + this.notify({ + type: 'draw' + }); + + return this; + }, + + resize: function(){ + this.notify({ + type: 'resize' + }); + + this.trigger('resize'); + + return this; + }, + + initRenderer: function( options ){ + var cy = this; + + var RendererProto = cy.extension('renderer', options.name); + if( RendererProto == null ){ + util.error('Can not initialise: No such renderer `%s` found; did you include its JS file?', options.name); + return; + } + + var rOpts = util.extend({}, options, { + cy: cy + }); + var renderer = cy._private.renderer = new RendererProto( rOpts ); + + renderer.init( rOpts ); + + }, + + triggerOnRender: function(){ + var cbs = this._private.onRenders; + + for( var i = 0; i < cbs.length; i++ ){ + var cb = cbs[i]; + + cb(); + } + + return this; + }, + + onRender: function( cb ){ + this._private.onRenders.push( cb ); + + return this; + }, + + offRender: function( fn ){ + var cbs = this._private.onRenders; + + if( fn == null ){ // unbind all + this._private.onRenders = []; + return this; + } + + for( var i = 0; i < cbs.length; i++ ){ // unbind specified + var cb = cbs[i]; + + if( fn === cb ){ + cbs.splice( i, 1 ); + break; + } + } + + return this; + } + +}); + +corefn.invalidateDimensions = corefn.resize; + +module.exports = corefn; + +},{"../util":94}],38:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../is'); +var Collection = _dereq_('../collection'); + +var corefn = ({ + + // 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( eles, opts ){ + + if( is.string( eles ) ){ + return this.$( eles ); + + } else if( is.elementOrCollection( eles ) ){ + return eles.collection(); + + } else if( is.array( eles ) ){ + return Collection( this, eles, opts ); + } + + return Collection( this ); + }, + + nodes: function( selector ){ + var nodes = this.$(function(){ + return this.isNode(); + }); + + if( selector ){ + return nodes.filter( selector ); + } + + return nodes; + }, + + edges: function( selector ){ + var edges = this.$(function(){ + return this.isEdge(); + }); + + if( selector ){ + return edges.filter( selector ); + } + + return edges; + }, + + // search the graph like jQuery + $: function( selector ){ + var eles = new Collection( this, this._private.elements ); + + if( selector ){ + return eles.filter( selector ); + } + + return eles; + } + +}); + +// aliases +corefn.elements = corefn.filter = corefn.$; + +module.exports = corefn; + +},{"../collection":23,"../is":77}],39:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../is'); +var Style = _dereq_('../style'); + +var corefn = ({ + + style: function( newStyle ){ + if( newStyle ){ + var s = this.setStyle( newStyle ); + + s.update(); + } + + return this._private.style; + }, + + setStyle: function( style ){ + var _p = this._private; + + if( is.stylesheet(style) ){ + _p.style = style.generateStyle(this); + + } else if( is.array(style) ) { + _p.style = Style.fromJson(this, style); + + } else if( is.string(style) ){ + _p.style = Style.fromString(this, style); + + } else { + _p.style = Style( this ); + } + + return _p.style; + } +}); + +module.exports = corefn; + +},{"../is":77,"../style":86}],40:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../is'); + +var corefn = ({ + + autolock: function(bool){ + if( bool !== undefined ){ + this._private.autolock = bool ? true : false; + } else { + return this._private.autolock; + } + + return this; // chaining + }, + + autoungrabify: function(bool){ + if( bool !== undefined ){ + this._private.autoungrabify = bool ? true : false; + } else { + return this._private.autoungrabify; + } + + return this; // chaining + }, + + autounselectify: function(bool){ + if( bool !== undefined ){ + this._private.autounselectify = bool ? true : false; + } else { + return this._private.autounselectify; + } + + return this; // chaining + }, + + panningEnabled: function( bool ){ + if( bool !== undefined ){ + this._private.panningEnabled = bool ? true : false; + } else { + return this._private.panningEnabled; + } + + return this; // chaining + }, + + userPanningEnabled: function( bool ){ + if( bool !== undefined ){ + this._private.userPanningEnabled = bool ? true : false; + } else { + return this._private.userPanningEnabled; + } + + return this; // chaining + }, + + zoomingEnabled: function( bool ){ + if( bool !== undefined ){ + this._private.zoomingEnabled = bool ? true : false; + } else { + return this._private.zoomingEnabled; + } + + return this; // chaining + }, + + userZoomingEnabled: function( bool ){ + if( bool !== undefined ){ + this._private.userZoomingEnabled = bool ? true : false; + } else { + return this._private.userZoomingEnabled; + } + + return this; // chaining + }, + + boxSelectionEnabled: function( bool ){ + if( bool !== undefined ){ + this._private.boxSelectionEnabled = bool ? true : false; + } else { + return this._private.boxSelectionEnabled; + } + + return this; // chaining + }, + + pan: function(){ + 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( is.string( args[0] ) ){ // .pan('x') + dim = args[0]; + return pan[ dim ]; + + } else if( is.plainObject( args[0] ) ) { // .pan({ x: 0, y: 100 }) + if( !this._private.panningEnabled ){ + return this; + } + + dims = args[0]; + x = dims.x; + y = dims.y; + + if( is.number(x) ){ + pan.x = x; + } + + if( is.number(y) ){ + pan.y = y; + } + + this.trigger('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') && is.number(val) ){ + pan[dim] = val; + } + + this.trigger('pan viewport'); + break; + + default: + break; // invalid + } + + this.notify({ // notify the renderer that the viewport changed + type: 'viewport' + }); + + return this; // chaining + }, + + panBy: function(params){ + 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( is.plainObject( args[0] ) ) { // .panBy({ x: 0, y: 100 }) + dims = args[0]; + x = dims.x; + y = dims.y; + + if( is.number(x) ){ + pan.x += x; + } + + if( is.number(y) ){ + pan.y += y; + } + + this.trigger('pan viewport'); + } + break; + + case 2: // .panBy('x', 100) + dim = args[0]; + val = args[1]; + + if( (dim === 'x' || dim === 'y') && is.number(val) ){ + pan[dim] += val; + } + + this.trigger('pan viewport'); + break; + + default: + break; // invalid + } + + this.notify({ // notify the renderer that the viewport changed + type: 'viewport' + }); + + return this; // chaining + }, + + fit: function( elements, padding ){ + var viewportState = this.getFitViewport( elements, padding ); + + if( viewportState ){ + var _p = this._private; + _p.zoom = viewportState.zoom; + _p.pan = viewportState.pan; + + this.trigger('pan zoom viewport'); + + this.notify({ // notify the renderer that the viewport changed + type: 'viewport' + }); + } + + return this; // chaining + }, + + getFitViewport: function( elements, padding ){ + if( is.number(elements) && padding === undefined ){ // elements is optional + padding = elements; + elements = undefined; + } + + if( !this._private.panningEnabled || !this._private.zoomingEnabled ){ + return; + } + + var bb; + + if( is.string(elements) ){ + var sel = elements; + elements = this.$( sel ); + + } else if( is.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( !is.elementOrCollection(elements) ){ + elements = this.elements(); + } + + bb = bb || elements.boundingBox(); + + var w = this.width(); + var h = this.height(); + var zoom; + padding = is.number(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; + }, + + minZoom: function( zoom ){ + if( zoom === undefined ){ + return this._private.minZoom; + } else if( is.number(zoom) ){ + this._private.minZoom = zoom; + } + + return this; + }, + + maxZoom: function( zoom ){ + if( zoom === undefined ){ + return this._private.maxZoom; + } else if( is.number(zoom) ){ + this._private.maxZoom = zoom; + } + + return this; + }, + + zoom: function( params ){ + var pos; // in rendered px + var zoom; + + if( params === undefined ){ // then get the zoom + return this._private.zoom; + + } else if( is.number(params) ){ // then set the zoom + zoom = params; + + } else if( is.plainObject(params) ){ // then zoom about a point + zoom = params.level; + + if( params.position ){ + var p = params.position; + var pan = this._private.pan; + var z = this._private.zoom; + + pos = { // convert to rendered px + x: p.x * z + pan.x, + y: p.y * z + pan.y + }; + } else if( params.renderedPosition ){ + pos = params.renderedPosition; + } + + if( pos && !this._private.panningEnabled ){ + return this; // panning disabled + } + } + + if( !this._private.zoomingEnabled ){ + return this; // zooming disabled + } + + if( !is.number(zoom) || ( pos && (!is.number(pos.x) || !is.number(pos.y)) ) ){ + return this; // can't zoom with invalid params + } + + // crop zoom + zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom; + zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom; + + if( pos ){ // set zoom about position + var pan1 = this._private.pan; + var zoom1 = this._private.zoom; + var zoom2 = zoom; + + var pan2 = { + x: -zoom2/zoom1 * (pos.x - pan1.x) + pos.x, + y: -zoom2/zoom1 * (pos.y - pan1.y) + pos.y + }; + + this._private.zoom = zoom; + this._private.pan = pan2; + + var posChanged = pan1.x !== pan2.x || pan1.y !== pan2.y; + this.trigger(' zoom ' + (posChanged ? ' pan ' : '') + ' viewport ' ); + + } else { // just set the zoom + this._private.zoom = zoom; + this.trigger('zoom viewport'); + } + + this.notify({ // notify the renderer that the viewport changed + type: 'viewport' + }); + + return this; // chaining + }, + + viewport: function( 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( !is.number(opts.zoom) ){ zoomDefd = false; } + if( !is.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( is.number(p.x) ){ + _p.pan.x = p.x; + panFailed = false; + } + + if( is.number(p.y) ){ + _p.pan.y = p.y; + panFailed = false; + } + + if( !panFailed ){ + events.push('pan'); + } + } + + if( events.length > 0 ){ + events.push('viewport'); + this.trigger( events.join(' ') ); + + this.notify({ + type: 'viewport' + }); + } + + return this; // chaining + }, + + center: function( elements ){ + var pan = this.getCenterPan( elements ); + + if( pan ){ + this._private.pan = pan; + + this.trigger('pan viewport'); + + this.notify({ // notify the renderer that the viewport changed + type: 'viewport' + }); + } + + return this; // chaining + }, + + getCenterPan: function( elements, zoom ){ + if( !this._private.panningEnabled ){ + return; + } + + if( is.string(elements) ){ + var selector = elements; + elements = this.elements( selector ); + } else if( !is.elementOrCollection(elements) ){ + elements = this.elements(); + } + + 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(){ + if( !this._private.panningEnabled || !this._private.zoomingEnabled ){ + return this; + } + + this.viewport({ + pan: { x: 0, y: 0 }, + zoom: 1 + }); + + return this; // chaining + }, + + width: function(){ + var container = this._private.container; + + if( container ){ + return container.clientWidth; + } + + return 1; // fallback if no container (not 0 b/c can be used for dividing etc) + }, + + height: function(){ + var container = this._private.container; + + if( container ){ + return container.clientHeight; + } + + return 1; // fallback if no container (not 0 b/c can be used for dividing etc) + }, + + extent: function(){ + 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(){ + var width = this.width(); + var height = this.height(); + + return { + x1: 0, + y1: 0, + x2: width, + y2: height, + w: width, + h: height + }; + } +}); + +// aliases +corefn.centre = corefn.center; + +// backwards compatibility +corefn.autolockNodes = corefn.autolock; +corefn.autoungrabifyNodes = corefn.autoungrabify; + +module.exports = corefn; + +},{"../is":77}],41:[function(_dereq_,module,exports){ +'use strict'; + +// use this module to cherry pick functions into your prototype +// (useful for functions shared between the core and collections, for example) + +// e.g. +// var foo = define.foo({ /* params... */ }) + +var util = _dereq_('./util'); +var is = _dereq_('./is'); +var Selector = _dereq_('./selector'); +var Promise = _dereq_('./promise'); +var Event = _dereq_('./event'); +var Animation = _dereq_('./animation'); + +var define = { + + // access data field + data: function( 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, + onSet: function( self ){}, + canSet: function( self ){ return true; } + }; + params = util.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( is.string(name) ){ // set or get property + + // .data('foo') + if( p.allowGetting && value === undefined ){ // get + + var ret; + if( single ){ + 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 ){ + for( var i = 0, l = all.length; i < l; i++ ){ + if( p.canSet( all[i] ) ){ + all[i]._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 && is.plainObject(name) ){ // extend + var obj = name; + var k, v; + + for( k in obj ){ + v = obj[ k ]; + + var valid = !p.immutableKeys[k]; + if( valid ){ + for( var i = 0, l = all.length; i < l; i++ ){ + if( p.canSet( all[i] ) ){ + all[i]._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 && is.fn(name) ){ // bind to event + var fn = name; + self.bind( p.bindingEvent, fn ); + + // .data() + } else if( p.allowGetting && name === undefined ){ // get whole object + var ret; + if( single ){ + ret = single._private[ p.field ]; + } + return ret; + } + + return self; // maintain chainability + }; // function + }, // data + + // remove data field + removeData: function( params ){ + var defaults = { + field: 'data', + event: 'data', + triggerFnName: 'trigger', + triggerEvent: false, + immutableKeys: {} // key => true if immutable + }; + params = util.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( is.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( is.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 ]; + + for( var key in _privateFields ){ + var validKeyToDelete = !p.immutableKeys[ key ]; + + if( validKeyToDelete ){ + _privateFields[ key ] = undefined; + } + } + } + + if( p.triggerEvent ){ + self[ p.triggerFnName ]( p.event ); + } + } + + return self; // maintain chaining + }; // function + }, // removeData + + // event function reusable stuff + event: { + regex: /(\w+)(\.\w+)?/, // regex for matching event strings (e.g. "click.namespace") + optionalTypeRegex: /(\w+)?(\.\w+)?/, + falseCallback: function(){ return false; } + }, + + // event binding + on: function( params ){ + var defaults = { + unbindSelfOnTrigger: false, + unbindAllBindersOnTrigger: false + }; + params = util.extend({}, defaults, params); + + return function onImpl(events, selector, data, callback){ + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + var eventsIsString = is.string(events); + var p = params; + + if( is.plainObject(selector) ){ // selector is actually data + callback = data; + data = selector; + selector = undefined; + } else if( is.fn(selector) || selector === false ){ // selector is actually callback + callback = selector; + data = undefined; + selector = undefined; + } + + if( is.fn(data) || data === false ){ // data is actually callback + callback = data; + data = undefined; + } + + // if there isn't a callback, we can't really do anything + // (can't speak for mapped events arg version) + if( !(is.fn(callback) || callback === false) && eventsIsString ){ + return self; // maintain chaining + } + + if( eventsIsString ){ // then convert to map + var map = {}; + map[ events ] = callback; + events = map; + } + + for( var evts in events ){ + callback = events[evts]; + if( callback === false ){ + callback = define.event.falseCallback; + } + + if( !is.fn(callback) ){ continue; } + + evts = evts.split(/\s+/); + for( var i = 0; i < evts.length; i++ ){ + var evt = evts[i]; + if( is.emptyString(evt) ){ continue; } + + var match = evt.match( define.event.regex ); // type[.namespace] + + if( match ){ + var type = match[1]; + var namespace = match[2] ? match[2] : undefined; + + var listener = { + callback: callback, // callback to run + data: data, // extra data in eventObj.data + delegated: selector ? true : false, // whether the evt is delegated + selector: selector, // the selector to match for delegated events + selObj: new Selector(selector), // cached selector object to save rebuilding + type: type, // the event type (e.g. 'click') + namespace: namespace, // the event namespace (e.g. ".foo") + unbindSelfOnTrigger: p.unbindSelfOnTrigger, + unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger, + binders: all // who bound together + }; + + for( var j = 0; j < all.length; j++ ){ + var _p = all[j]._private; + + _p.listeners = _p.listeners || []; + _p.listeners.push( listener ); + } + } + } // for events array + } // for events map + + return self; // maintain chaining + }; // function + }, // on + + eventAliasesOn: function( proto ){ + var p = proto; + + p.addListener = p.listen = p.bind = p.on; + p.removeListener = p.unlisten = p.unbind = p.off; + p.emit = p.trigger; + + // 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(function( resolve, reject ){ + var callback = function( e ){ + self.off.apply( self, offArgs ); + + resolve( e ); + }; + + var onArgs = args.concat([ callback ]); + var offArgs = onArgs.concat([]); + + self.on.apply( self, onArgs ); + }); + }; + }, + + off: function offImpl( params ){ + var defaults = { + }; + params = util.extend({}, defaults, params); + + return function(events, selector, callback){ + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + var eventsIsString = is.string(events); + + if( arguments.length === 0 ){ // then unbind all + + for( var i = 0; i < all.length; i++ ){ + all[i]._private.listeners = []; + } + + return self; // maintain chaining + } + + if( is.fn(selector) || selector === false ){ // selector is actually callback + callback = selector; + selector = undefined; + } + + if( eventsIsString ){ // then convert to map + var map = {}; + map[ events ] = callback; + events = map; + } + + for( var evts in events ){ + callback = events[evts]; + + if( callback === false ){ + callback = define.event.falseCallback; + } + + evts = evts.split(/\s+/); + for( var h = 0; h < evts.length; h++ ){ + var evt = evts[h]; + if( is.emptyString(evt) ){ continue; } + + var match = evt.match( define.event.optionalTypeRegex ); // [type][.namespace] + if( match ){ + var type = match[1] ? match[1] : undefined; + var namespace = match[2] ? match[2] : undefined; + + for( var i = 0; i < all.length; i++ ){ // + var listeners = all[i]._private.listeners = all[i]._private.listeners || []; + + for( var j = 0; j < listeners.length; j++ ){ + var listener = listeners[j]; + var nsMatches = !namespace || namespace === listener.namespace; + var typeMatches = !type || listener.type === type; + var cbMatches = !callback || callback === listener.callback; + var listenerMatches = nsMatches && typeMatches && cbMatches; + + // delete listener if it matches + if( listenerMatches ){ + listeners.splice(j, 1); + j--; + } + } // for listeners + } // for all + } // if match + } // for events array + + } // for events map + + return self; // maintain chaining + }; // function + }, // off + + trigger: function( params ){ + var defaults = {}; + params = util.extend({}, defaults, params); + + return function triggerImpl(events, extraParams, fnToTrigger){ + var self = this; + var selfIsArrayLike = self.length !== undefined; + var all = selfIsArrayLike ? self : [self]; // put in array if not array-like + var eventsIsString = is.string(events); + var eventsIsObject = is.plainObject(events); + var eventsIsEvent = is.event(events); + var cy = this._private.cy || ( is.core(this) ? this : null ); + var hasCompounds = cy ? cy.hasCompoundNodes() : false; + + if( eventsIsString ){ // then make a plain event object for each event name + var evts = events.split(/\s+/); + events = []; + + for( var i = 0; i < evts.length; i++ ){ + var evt = evts[i]; + if( is.emptyString(evt) ){ continue; } + + var match = evt.match( define.event.regex ); // type[.namespace] + var type = match[1]; + var namespace = match[2] ? match[2] : undefined; + + events.push( { + type: type, + namespace: namespace + } ); + } + } else if( eventsIsObject ){ // put in length 1 array + var eventArgObj = events; + + events = [ eventArgObj ]; + } + + if( extraParams ){ + if( !is.array(extraParams) ){ // make sure extra params are in an array if specified + extraParams = [ extraParams ]; + } + } else { // otherwise, we've got nothing + extraParams = []; + } + + for( var i = 0; i < events.length; i++ ){ // trigger each event in order + var evtObj = events[i]; + + for( var j = 0; j < all.length; j++ ){ // for each + var triggerer = all[j]; + var listeners = triggerer._private.listeners = triggerer._private.listeners || []; + var triggererIsElement = is.element(triggerer); + var bubbleUp = triggererIsElement || params.layout; + + // create the event for this element from the event object + var evt; + + if( eventsIsEvent ){ // then just get the object + evt = evtObj; + + evt.cyTarget = evt.cyTarget || triggerer; + evt.cy = evt.cy || cy; + + } else { // then we have to make one + evt = new Event( evtObj, { + cyTarget: triggerer, + cy: cy, + namespace: evtObj.namespace + } ); + } + + // if a layout was specified, then put it in the typed event + if( evtObj.layout ){ + evt.layout = evtObj.layout; + } + + // if triggered by layout, put in event + if( params.layout ){ + evt.layout = triggerer; + } + + // create a rendered position based on the passed position + if( evt.cyPosition ){ + var pos = evt.cyPosition; + var zoom = cy.zoom(); + var pan = cy.pan(); + + evt.cyRenderedPosition = { + x: pos.x * zoom + pan.x, + y: pos.y * zoom + pan.y + }; + } + + if( fnToTrigger ){ // then override the listeners list with just the one we specified + listeners = [{ + namespace: evt.namespace, + type: evt.type, + callback: fnToTrigger + }]; + } + + for( var k = 0; k < listeners.length; k++ ){ // check each listener + var lis = listeners[k]; + var nsMatches = !lis.namespace || lis.namespace === evt.namespace; + var typeMatches = lis.type === evt.type; + var targetMatches = lis.delegated ? ( triggerer !== evt.cyTarget && is.element(evt.cyTarget) && lis.selObj.matches(evt.cyTarget) ) : (true); // we're not going to validate the hierarchy; that's too expensive + var listenerMatches = nsMatches && typeMatches && targetMatches; + + if( listenerMatches ){ // then trigger it + var args = [ evt ]; + args = args.concat( extraParams ); // add extra params to args list + + if( lis.data ){ // add on data plugged into binding + evt.data = lis.data; + } else { // or clear it in case the event obj is reused + evt.data = undefined; + } + + if( lis.unbindSelfOnTrigger || lis.unbindAllBindersOnTrigger ){ // then remove listener + listeners.splice(k, 1); + k--; + } + + if( lis.unbindAllBindersOnTrigger ){ // then delete the listener for all binders + var binders = lis.binders; + for( var l = 0; l < binders.length; l++ ){ + var binder = binders[l]; + if( !binder || binder === triggerer ){ continue; } // already handled triggerer or we can't handle it + + var binderListeners = binder._private.listeners; + for( var m = 0; m < binderListeners.length; m++ ){ + var binderListener = binderListeners[m]; + + if( binderListener === lis ){ // delete listener from list + binderListeners.splice(m, 1); + m--; + } + } + } + } + + // run the callback + var context = lis.delegated ? evt.cyTarget : triggerer; + var ret = lis.callback.apply( context, args ); + + if( ret === false || evt.isPropagationStopped() ){ + // then don't bubble + bubbleUp = false; + + if( ret === false ){ + // returning false is a shorthand for stopping propagation and preventing the def. action + evt.stopPropagation(); + evt.preventDefault(); + } + } + } // if listener matches + } // for each listener + + // bubble up event for elements + if( bubbleUp ){ + var parent = hasCompounds ? triggerer._private.parent : null; + var hasParent = parent != null && parent.length !== 0; + + if( hasParent ){ // then bubble up to parent + parent = parent[0]; + parent.trigger(evt); + } else { // otherwise, bubble up to the core + cy.trigger(evt); + } + } + + } // for each of all + } // for each event + + return self; // maintain chaining + }; // function + }, // trigger + + animated: function( fnParams ){ + var defaults = {}; + fnParams = util.extend({}, defaults, fnParams); + + 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( fnParams ){ + var defaults = {}; + fnParams = util.extend({}, defaults, fnParams); + + 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( fnParams ){ + var defaults = {}; + fnParams = util.extend({}, defaults, fnParams); + + 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( fnParams ){ + var defaults = {}; + fnParams = util.extend({}, defaults, fnParams); + + 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( fnParams ){ + var defaults = {}; + fnParams = util.extend({}, defaults, fnParams); + + 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 = util.extend( {}, properties, params ); + + if( properties.duration === undefined ){ + properties.duration = 400; + } + + switch( properties.duration ){ + case 'slow': + properties.duration = 600; + break; + case 'fast': + properties.duration = 200; + break; + } + + var propertiesEmpty = true; + if( properties ){ for( var i in properties ){ // jshint ignore:line + propertiesEmpty = false; + break; + } } + + if( propertiesEmpty ){ + return new Animation( all[0], properties ); // nothing to animate + } + + if( isEles ){ + properties.style = style.getPropsList( properties.style || properties.css ); + + properties.css = undefined; + } + + if( properties.renderedPosition && isEles ){ + var rpos = properties.renderedPosition; + var pan = cy.pan(); + var zoom = cy.zoom(); + + properties.position = { + x: ( rpos.x - pan.x ) /zoom, + y: ( rpos.y - pan.y ) /zoom + }; + } + + // override pan w/ panBy if set + if( properties.panBy && isCore ){ + 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( center && isCore ){ + var centerPan = cy.getCenterPan( center.eles, properties.zoom ); + + if( centerPan ){ + properties.pan = centerPan; + } + } + + // override pan & zoom w/ fit if set + if( properties.fit && isCore ){ + var fit = properties.fit; + var fitVp = cy.getFitViewport( fit.eles || fit.boundingBox, fit.padding ); + + if( fitVp ){ + properties.pan = fitVp.pan; + properties.zoom = fitVp.zoom; + } + } + + return new Animation( all[0], properties ); + }; + }, // animate + + animate: function( fnParams ){ + var defaults = {}; + fnParams = util.extend({}, defaults, fnParams); + + 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 = util.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( fnParams ){ + var defaults = {}; + fnParams = util.extend({}, defaults, fnParams); + + 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({ + collection: this, + type: 'draw' + }); + + return this; + }; + } // stop + +}; // define + +module.exports = define; + +},{"./animation":1,"./event":42,"./is":77,"./promise":80,"./selector":81,"./util":94}],42:[function(_dereq_,module,exports){ +'use strict'; + +// ref +// https://github.com/jquery/jquery/blob/master/src/event.js + +var Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof Event) ) { + return new Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + 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; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + // util.extend( this, props ); + + // more efficient to manually copy fields we use + this.type = props.type !== undefined ? props.type : this.type; + this.cy = props.cy; + this.cyTarget = props.cyTarget; + this.cyPosition = props.cyPosition; + this.cyRenderedPosition = props.cyRenderedPosition; + this.namespace = props.namespace; + this.layout = props.layout; + this.data = props.data; + this.message = props.message; + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || Date.now(); +}; + +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(){ + return 'event'; + }, + + preventDefault: function() { + 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() { + 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() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +module.exports = Event; + +},{}],43:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('./util'); +var define = _dereq_('./define'); +var Collection = _dereq_('./collection'); +var Core = _dereq_('./core'); +var incExts = _dereq_('./extensions'); +var is = _dereq_('./is'); + +// 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; + + if( type === 'core' ){ + Core.prototype[ name ] = registrant; + + } else if( type === 'collection' ){ + Collection.prototype[ name ] = registrant; + + } else if( type === 'layout' ){ + // fill in missing layout functions in the prototype + + var Layout = function( options ){ + this.options = options; + + registrant.call( this, options ); + + // make sure layout has _private for use w/ std apis like .on() + if( !is.plainObject(this._private) ){ + this._private = {}; + } + + this._private.cy = options.cy; + this._private.listeners = []; + }; + + 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; }; + } + + if( !layoutProto.stop ){ + layoutProto.stop = function(){ + var opts = this.options; + + if( opts && opts.animate ){ + var anis = this.animations; + for( var i = 0; i < anis.length; i++ ){ + anis[i].stop(); + } + } + + this.trigger('layoutstop'); + + return this; + }; + } + + if( !layoutProto.destroy ){ + layoutProto.destroy = function(){ + return this; + }; + } + + layoutProto.on = define.on({ layout: true }); + layoutProto.one = define.on({ layout: true, unbindSelfOnTrigger: true }); + layoutProto.once = define.on({ layout: true, unbindAllBindersOnTrigger: true }); + layoutProto.off = define.off({ layout: true }); + layoutProto.trigger = define.trigger({ layout: true }); + + 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 bProto = getExtension( 'renderer', 'base' ).prototype; + var rProto = registrant.prototype; + + for( var pName in bProto ){ + var pVal = bProto[ pName ]; + var existsInR = rProto[ pName ] != null; + + if( existsInR ){ + util.error('Can not register renderer `' + name + '` since it overrides `' + pName + '` in its prototype'); + return; + } + + rProto[ pName ] = pVal; // take impl from base + } + + bProto.clientFunctions.forEach(function( name ){ + rProto[ name ] = rProto[ name ] || function(){ + util.error('Renderer does not implement `renderer.' + name + '()` on its prototype'); + }; + }); + + } + + return util.setMap({ + map: extensions, + keys: [ type, name ], + value: ext + }); +} + +function getExtension(type, name){ + return util.getMap({ + map: extensions, + keys: [ type, name ] + }); +} + +function setModule(type, name, moduleType, moduleName, registrant){ + return util.setMap({ + map: modules, + keys: [ type, name, moduleType, moduleName ], + value: registrant + }); +} + +function getModule(type, name, moduleType, moduleName){ + return util.getMap({ + map: modules, + keys: [ type, name, moduleType, moduleName ] + }); +} + +var extension = function(){ + // 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 { + util.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 ); + }); +}); + +module.exports = extension; + +},{"./collection":23,"./core":34,"./define":41,"./extensions":44,"./is":77,"./util":94}],44:[function(_dereq_,module,exports){ +'use strict'; + +module.exports = [ + { + type: 'layout', + extensions: _dereq_('./layout') + }, + + { + type: 'renderer', + extensions: _dereq_('./renderer') + } +]; + +},{"./layout":50,"./renderer":72}],45:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../../util'); +var math = _dereq_('../../math'); +var is = _dereq_('../../is'); + +var defaults = { + 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 + 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 + roots: undefined, // the roots of the trees + maximalAdjustments: 0, // how many times to try to position the nodes in a maximal way (i.e. no backtracking) + animate: false, // whether to transition the node positions + animationDuration: 500, // duration of animation in ms if enabled + animationEasing: undefined, // easing of animation if enabled + ready: undefined, // callback on layoutready + stop: undefined // callback on layoutstop +}; + +function BreadthFirstLayout( options ){ + this.options = util.extend({}, defaults, options); +} + +BreadthFirstLayout.prototype.run = function(){ + var params = this.options; + var options = params; + + var cy = params.cy; + var eles = options.eles; + var nodes = eles.nodes().not(':parent'); + var graph = eles; + + var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : { + x1: 0, y1: 0, w: cy.width(), h: cy.height() + } ); + + var roots; + if( is.elementOrCollection(options.roots) ){ + roots = options.roots; + } else if( is.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( is.string(options.roots) ){ + roots = cy.$( options.roots ); + + } else { + if( options.directed ){ + roots = nodes.roots(); + } else { + var components = []; + var unhandledNodes = nodes; + + while( unhandledNodes.length > 0 ){ + var currComp = cy.collection(); + + eles.bfs({ + roots: unhandledNodes[0], + visit: function(i, depth, node, edge, pNode){ + currComp = currComp.add( node ); + }, + directed: false + }); + + unhandledNodes = unhandledNodes.not( currComp ); + components.push( currComp ); + } + + roots = cy.collection(); + for( var i = 0; i < components.length; i++ ){ + var comp = components[i]; + var maxDegree = comp.maxDegree( false ); + var compRoots = comp.filter(function(){ + return this.degree(false) === maxDegree; + }); + + roots = roots.add( compRoots ); + } + + } + } + + + var depths = []; + var foundByBfs = {}; + var id2depth = {}; + var prevNode = {}; + var prevEdge = {}; + var successors = {}; + + // find the depths of the nodes + graph.bfs({ + roots: roots, + directed: options.directed, + visit: function(i, depth, node, edge, pNode){ + var ele = this[0]; + var id = ele.id(); + + if( !depths[depth] ){ + depths[depth] = []; + } + + depths[depth].push( ele ); + foundByBfs[ id ] = true; + id2depth[ id ] = depth; + prevNode[ id ] = pNode; + prevEdge[ id ] = edge; + + if( pNode ){ + var prevId = pNode.id(); + var succ = successors[ prevId ] = successors[ prevId ] || []; + + succ.push( node ); + } + } + }); + + // check for nodes not found by bfs + var orphanNodes = []; + for( var i = 0; i < nodes.length; i++ ){ + var ele = nodes[i]; + + if( foundByBfs[ ele.id() ] ){ + continue; + } else { + orphanNodes.push( ele ); + } + } + + // assign orphan nodes a depth from their neighborhood + var maxChecks = orphanNodes.length * 3; + var checks = 0; + while( orphanNodes.length !== 0 && checks < maxChecks ){ + var node = orphanNodes.shift(); + var neighbors = node.neighborhood().nodes(); + var assignedDepth = false; + + for( var i = 0; i < neighbors.length; i++ ){ + var depth = id2depth[ neighbors[i].id() ]; + + if( depth !== undefined ){ + depths[depth].push( node ); + assignedDepth = true; + break; + } + } + + if( !assignedDepth ){ + orphanNodes.push( node ); + } + + checks++; + } + + // assign orphan nodes that are still left to the depth of their subgraph + while( orphanNodes.length !== 0 ){ + var node = orphanNodes.shift(); + //var subgraph = graph.bfs( node ).path; + var assignedDepth = false; + + // for( var i = 0; i < subgraph.length; i++ ){ + // var depth = id2depth[ subgraph[i].id() ]; + + // if( depth !== undefined ){ + // depths[depth].push( node ); + // assignedDepth = true; + // break; + // } + // } + + if( !assignedDepth ){ // worst case if the graph really isn't tree friendly, then just dump it in 0 + if( depths.length === 0 ){ + depths.push([]); + } + + depths[0].push( node ); + } + } + + // assign the nodes a depth and index + var assignDepthsToEles = function(){ + for( var i = 0; i < depths.length; i++ ){ + var eles = depths[i]; + + for( var j = 0; j < eles.length; j++ ){ + var ele = eles[j]; + + ele._private.scratch.breadthfirst = { + depth: i, + index: j + }; + } + } + }; + assignDepthsToEles(); + + + var intersectsDepth = function( node ){ // returns true if has edges pointing in from a higher depth + var edges = node.connectedEdges(function(){ + return this.data('target') === node.id(); + }); + var thisInfo = node._private.scratch.breadthfirst; + var highestDepthOfOther = 0; + var highestOther; + for( var i = 0; i < edges.length; i++ ){ + var edge = edges[i]; + var otherNode = edge.source()[0]; + var otherInfo = otherNode._private.scratch.breadthfirst; + + if( thisInfo.depth <= otherInfo.depth && highestDepthOfOther < otherInfo.depth ){ + highestDepthOfOther = otherInfo.depth; + highestOther = otherNode; + } + } + + return highestOther; + }; + + // make maximal if so set by adjusting depths + for( var adj = 0; adj < options.maximalAdjustments; adj++ ){ + + var nDepths = depths.length; + var elesToMove = []; + for( var i = 0; i < nDepths; i++ ){ + var depth = depths[i]; + + var nDepth = depth.length; + for( var j = 0; j < nDepth; j++ ){ + var ele = depth[j]; + var info = ele._private.scratch.breadthfirst; + var intEle = intersectsDepth(ele); + + if( intEle ){ + info.intEle = intEle; + elesToMove.push( ele ); + } + } + } + + for( var i = 0; i < elesToMove.length; i++ ){ + var ele = elesToMove[i]; + var info = ele._private.scratch.breadthfirst; + var intEle = info.intEle; + var intInfo = intEle._private.scratch.breadthfirst; + + depths[ info.depth ].splice( info.index, 1 ); // remove from old depth & index + + // add to end of new depth + var newDepth = intInfo.depth + 1; + while( newDepth > depths.length - 1 ){ + depths.push([]); + } + depths[ newDepth ].push( ele ); + + info.depth = newDepth; + info.index = depths[newDepth].length - 1; + } + + assignDepthsToEles(); + } + + // find min distance we need to leave between nodes + var minDistance = 0; + if( options.avoidOverlap ){ + for( var i = 0; i < nodes.length; i++ ){ + var n = nodes[i]; + var nbb = n.boundingBox(); + var w = nbb.w; + var h = nbb.h; + + minDistance = Math.max(minDistance, w, h); + } + minDistance *= options.spacingFactor; // just to have some nice spacing + } + + // get the weighted percent for an element based on its connectivity to other levels + var cachedWeightedPercent = {}; + var getWeightedPercent = function( ele ){ + if( cachedWeightedPercent[ ele.id() ] ){ + return cachedWeightedPercent[ ele.id() ]; + } + + var eleDepth = ele._private.scratch.breadthfirst.depth; + var neighbors = ele.neighborhood().nodes().not(':parent'); + var percent = 0; + var samples = 0; + + for( var i = 0; i < neighbors.length; i++ ){ + var neighbor = neighbors[i]; + var bf = neighbor._private.scratch.breadthfirst; + var index = bf.index; + var depth = bf.depth; + var nDepth = depths[depth].length; + + if( eleDepth > depth || eleDepth === 0 ){ // only get influenced by elements above + percent += index / nDepth; + samples++; + } + } + + samples = Math.max(1, samples); + percent = percent / samples; + + if( samples === 0 ){ // so lone nodes have a "don't care" state in sorting + percent = undefined; + } + + cachedWeightedPercent[ ele.id() ] = percent; + return percent; + }; + + + // rearrange the indices in each depth level based on connectivity + + var sortFn = function(a, b){ + var apct = getWeightedPercent( a ); + var bpct = getWeightedPercent( b ); + + return apct - bpct; + }; + + for( var times = 0; times < 3; times++ ){ // do it a few times b/c the depths are dynamic and we want a more stable result + + for( var i = 0; i < depths.length; i++ ){ + depths[i] = depths[i].sort( sortFn ); + } + assignDepthsToEles(); // and update + + } + + var biggestDepthSize = 0; + for( var i = 0; i < depths.length; i++ ){ + biggestDepthSize = Math.max( depths[i].length, biggestDepthSize ); + } + + var center = { + x: bb.x1 + bb.w/2, + y: bb.x1 + bb.h/2 + }; + + var getPosition = function( ele, isBottomDepth ){ + var info = ele._private.scratch.breadthfirst; + var depth = info.depth; + var index = info.index; + var depthSize = depths[depth].length; + + var distanceX = Math.max( bb.w / (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 + }; + + if( isBottomDepth ){ + return epos; + } + + // var succs = successors[ ele.id() ]; + // if( succs ){ + // epos.x = 0; + // + // for( var i = 0 ; i < succs.length; i++ ){ + // var spos = pos[ succs[i].id() ]; + // + // epos.x += spos.x; + // } + // + // epos.x /= succs.length; + // } else { + // //debugger; + // } + + return epos; + + } else { + if( options.circle ){ + 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) + }; + + } else { + return { + x: center.x + (index + 1 - (depthSize + 1)/2) * distanceX, + y: (depth + 1) * distanceY + }; + } + } + + }; + + // get positions in reverse depth order + var pos = {}; + for( var i = depths.length - 1; i >=0; i-- ){ + var depth = depths[i]; + + for( var j = 0; j < depth.length; j++ ){ + var node = depth[j]; + + pos[ node.id() ] = getPosition( node, i === depths.length - 1 ); + } + } + + nodes.layoutPositions(this, options, function(){ + return pos[ this.id() ]; + }); + + return this; // chaining +}; + +module.exports = BreadthFirstLayout; + +},{"../../is":77,"../../math":79,"../../util":94}],46:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../../util'); +var math = _dereq_('../../math'); +var is = _dereq_('../../is'); + +var defaults = { + 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 + 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 + ready: undefined, // callback on layoutready + stop: undefined // callback on layoutstop +}; + +function CircleLayout( options ){ + this.options = util.extend({}, defaults, 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 = math.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.boundingBox(); + var w = nbb.w; + var h = nbb.h; + + minDistance = Math.max(minDistance, w, h); + } + + if( is.number(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( i, ele ){ + 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; + }; + + nodes.layoutPositions( this, options, getPos ); + + return this; // chaining +}; + +module.exports = CircleLayout; + +},{"../../is":77,"../../math":79,"../../util":94}],47:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../../util'); +var math = _dereq_('../../math'); + +var defaults = { + 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 + height: undefined, // height of layout area (overrides container height) + width: undefined, // width of layout area (overrides container width) + concentric: function(node){ // returns numeric value for each node, placing higher nodes in levels towards the centre + return node.degree(); + }, + levelWidth: function(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 + ready: undefined, // callback on layoutready + stop: undefined // callback on layoutstop +}; + +function ConcentricLayout( options ){ + this.options = util.extend({}, defaults, 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 = math.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 theta = options.startAngle; + var maxNodeSize = 0; + + for( var i = 0; i < nodes.length; i++ ){ + var node = nodes[i]; + var value; + + // calculate the node value + value = options.concentric.apply(node, [ 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.boundingBox(); + + 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 i = 0; i < nodeValues.length; i++ ){ + var val = nodeValues[i]; + + 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 i = 0; i < levels.length; i++ ){ + var level = levels[i]; + 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 i = 0; i < levels.length; i++ ){ + var level = levels[i]; + var rDelta = level.r - r; + + rDeltaMax = Math.max( rDeltaMax, rDelta ); + } + + r = 0; + for( var i = 0; i < levels.length; i++ ){ + var level = levels[i]; + + if( i === 0 ){ + r = level.r; + } + + level.r = r; + + r += rDeltaMax; + } + } + + // calculate the node positions + var pos = {}; // id => position + for( var i = 0; i < levels.length; i++ ){ + var level = levels[i]; + var dTheta = level.dTheta; + var r = level.r; + + for( var j = 0; j < level.length; j++ ){ + var val = level[j]; + var theta = options.startAngle + (clockwise ? 1 : -1) * dTheta * j; + + var p = { + x: center.x + r * Math.cos(theta), + y: center.y + r * Math.sin(theta) + }; + + pos[ val.node.id() ] = p; + } + } + + // position the nodes + nodes.layoutPositions(this, options, function(){ + var id = this.id(); + + return pos[id]; + }); + + return this; // chaining +}; + +module.exports = ConcentricLayout; + +},{"../../math":79,"../../util":94}],48:[function(_dereq_,module,exports){ +'use strict'; + +/* +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 util = _dereq_('../../util'); +var math = _dereq_('../../math'); +var Thread = _dereq_('../../thread'); +var is = _dereq_('../../is'); + +var DEBUG; + +/** + * @brief : default layout options + */ +var defaults = { + // Called on `layoutready` + ready : function() {}, + + // Called on `layoutstop` + stop : function() {}, + + // Whether to animate while running the layout + animate : true, + + // The layout animates only after this many milliseconds + // (prevents flashing on fast runs) + animationThreshold : 250, + + // Number of iterations between consecutive screen positions update + // (0 -> only updated on the end) + 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, + + // Extra spacing between components in non-compound graphs + componentSpacing : 100, + + // Node repulsion (non overlapping) multiplier + nodeRepulsion : function( node ){ return 400000; }, + + // Node repulsion (overlapping) multiplier + nodeOverlap : 10, + + // Ideal edge (non nested) length + idealEdgeLength : function( edge ){ return 10; }, + + // Divisor to compute edge forces + edgeElasticity : function( edge ){ return 100; }, + + // Nesting factor (multiplier) to compute ideal edge length for nested edges + nestingFactor : 5, + + // Gravity force (constant) + gravity : 80, + + // Maximum number of iterations to perform + numIter : 1000, + + // Initial temperature (maximum node displacement) + initialTemp : 200, + + // Cooling factor (how the temperature is reduced between consecutive iterations + coolingFactor : 0.95, + + // Lower temperature threshold (below this point the layout will end) + minTemp : 1.0, + + // Whether to use threading to speed up the layout + useMultitasking : true +}; + + +/** + * @brief : constructor + * @arg options : object containing layout options + */ +function CoseLayout(options) { + this.options = util.extend({}, defaults, options); + + this.options.layout = this; +} + + +/** + * @brief : runs the layout + */ +CoseLayout.prototype.run = function() { + var options = this.options; + var cy = options.cy; + var layout = this; + var thread = this.thread; + + if( !thread || thread.stopped() ){ + thread = this.thread = Thread({ disabled: !options.useMultitasking }); + } + + layout.stopped = false; + + layout.trigger({ 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 (true === options.randomize) { + randomizePositions(layoutInfo, cy); + // } + + var startTime = Date.now(); + var refreshRequested = false; + var refresh = function( rOpts ){ + rOpts = rOpts || {}; + + if( refreshRequested ){ + return; + } + + if( !rOpts.force && Date.now() - startTime < options.animationThreshold ){ + return; + } + + refreshRequested = true; + + util.requestAnimationFrame(function(){ + refreshPositions(layoutInfo, cy, options); + + // Fit the graph if necessary + if (true === options.fit) { + cy.fit( options.padding ); + } + + refreshRequested = false; + }); + }; + + thread.on('message', function( e ){ + var layoutNodes = e.message; + + layoutInfo.layoutNodes = layoutNodes; + refresh(); + }); + + thread.pass({ + layoutInfo: layoutInfo, + options: { + animate: options.animate, + refresh: options.refresh, + componentSpacing: options.componentSpacing, + nodeOverlap: options.nodeOverlap, + nestingFactor: options.nestingFactor, + gravity: options.gravity, + numIter: options.numIter, + initialTemp: options.initialTemp, + coolingFactor: options.coolingFactor, + minTemp: options.minTemp + } + }).run(function( pass ){ + var layoutInfo = pass.layoutInfo; + var options = pass.options; + var stopped = false; + + /** + * @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(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, options); + // Calculate gravity forces + calculateGravityForces(layoutInfo, options); + // Propagate forces from parent to child + propagateForces(layoutInfo, options); + // Update positions based on calculated forces + updatePositions(layoutInfo, options); + }; + + /** + * @brief : Computes the node repulsion forces + */ + var calculateNodeForces = function(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); + } + } + } + }; + + /** + * @brief : Compute the node repulsion forces between a pair of nodes + */ + var nodeRepulsion = function(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; + // s += "\ndirectionX: " + directionX + ", directionY: " + directionY; + + // If both centers are the same, apply a random force + if (0 === directionX && 0 === directionY) { + // s += "\nNodes have the same position."; + return; // TODO could be improved with random force + } + + 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(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(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 = {}; + do { + // Case: Vertical direction (up) + if (0 === dX && 0 < dY) { + res.x = X; + // s += "\nUp direction"; + res.y = Y + H / 2; + break; + } + + // Case: Vertical direction (down) + if (0 === dX && 0 > dY) { + res.x = X; + res.y = Y + H / 2; + // s += "\nDown direction"; + break; + } + + // 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"; + break; + } + + // 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"; + break; + } + + // 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"; + break; + } + + // 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"; + break; + } + + } while (false); + + // s += "\nClipping point found at " + res.x + ", " + res.y; + // logDebug(s); + return res; + }; + + /** + * @brief : Calculates all edge forces + */ + var calculateEdgeForces = function(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) { + return; + } + + // 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(layoutInfo, options) { + 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; + } else { + // s += ": skypped since it's too close to center"; + } + // 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(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(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(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(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(layutInfo, 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]; + 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]; + + for( var j = 0; j < c.length; j++ ){ + var n = c[j]; + + if( !n.isLocked ){ + n.positionX += x; + n.positionY += y; + } + } + + 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 mainLoop = function(i){ + if( stopped ){ + // logDebug("Layout manually stopped. Stopping computation in step " + i); + return false; + } + + // Do one step in the phisical simulation + step(layoutInfo, options, i); + + // 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 i = 0; + var loopRet; + + do { + var f = 0; + + while( f < options.refresh && i < options.numIter ){ + var loopRet = mainLoop(i); + if( !loopRet ){ break; } + + f++; + i++; + } + + if( options.animate ){ + broadcast( layoutInfo.layoutNodes ); // jshint ignore:line + } + + } while ( loopRet && i + 1 < options.numIter ); + + separateComponents( layoutInfo, options ); + + return layoutInfo; + }).then(function( layoutInfoUpdated ){ + layoutInfo.layoutNodes = layoutInfoUpdated.layoutNodes; // get the positions + + thread.stop(); + done(); + }); + + var done = function(){ + refresh({ force: true }); + + // Layout has finished + layout.one('layoutstop', options.stop); + layout.trigger({ type: 'layoutstop', layout: layout }); + }; + + 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.trigger('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(cy, layout, options) { + // Shortcut + var edges = options.eles.edges(); + var nodes = options.eles.nodes(); + + var layoutInfo = { + isCompound : cy.hasCompoundNodes(), + layoutNodes : [], + idToIndex : {}, + nodeSize : nodes.size(), + graphSet : [], + indexToGraph : [], + layoutEdges : [], + edgeSize : edges.size(), + temperature : options.initialTemp, + clientWidth : cy.width(), + clientHeight : cy.width(), + boundingBox : math.makeBoundingBox( options.boundingBox ? options.boundingBox : { + x1: 0, y1: 0, w: cy.width(), h: cy.height() + } ) + }; + + 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.boundingBox(); + + 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-left') ); + tempNode.padRight = parseFloat( n.style('padding-right') ); + tempNode.padTop = parseFloat( n.style('padding-top') ); + tempNode.padBottom = parseFloat( n.style('padding-bottom') ); + + // forces + tempNode.nodeRepulsion = is.fn( options.nodeRepulsion ) ? options.nodeRepulsion.call( n, 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 = is.fn( options.idealEdgeLength ) ? options.idealEdgeLength.call( e, e ) : options.idealEdgeLength; + var elasticity = is.fn( options.edgeElasticity ) ? options.edgeElasticity.call( e, 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(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 ancesters (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(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 = function(layoutInfo) { + /* jshint ignore:start */ + + if (!DEBUG) { + return; + } + console.debug("layoutNodes:"); + for (var i = 0; i < layoutInfo.nodeSize; i++) { + var n = layoutInfo.layoutNodes[i]; + var s = + "\nindex: " + i + + "\nId: " + n.id + + "\nChildren: " + n.children.toString() + + "\nparentId: " + n.parentId + + "\npositionX: " + n.positionX + + "\npositionY: " + n.positionY + + "\nOffsetX: " + n.offsetX + + "\nOffsetY: " + n.offsetY + + "\npadLeft: " + n.padLeft + + "\npadRight: " + n.padRight + + "\npadTop: " + n.padTop + + "\npadBottom: " + n.padBottom; + + console.debug(s); + } + + console.debug('idToIndex'); + for (var i in layoutInfo.idToIndex) { + console.debug("Id: " + i + "\nIndex: " + layoutInfo.idToIndex[i]); + } + + console.debug('Graph Set'); + var set = layoutInfo.graphSet; + for (var i = 0; i < set.length; i ++) { + console.debug("Set : " + i + ": " + set[i].toString()); + } + + var s = 'IndexToGraph'; + for (var i = 0; i < layoutInfo.indexToGraph.length; i ++) { + s += "\nIndex : " + i + " Graph: "+ layoutInfo.indexToGraph[i]; + } + console.debug(s); + + s = 'Layout Edges'; + for (var i = 0; i < layoutInfo.layoutEdges.length; i++) { + var e = layoutInfo.layoutEdges[i]; + s += "\nEdge Index: " + i + " ID: " + e.id + + " SouceID: " + e.sourceId + " TargetId: " + e.targetId + + " Ideal Length: " + e.idealLength; + } + console.debug(s); + + s = "nodeSize: " + layoutInfo.nodeSize; + s += "\nedgeSize: " + layoutInfo.edgeSize; + s += "\ntemperature: " + layoutInfo.temperature; + console.debug(s); + + return; + /* jshint ignore:end */ +}; + + +/** + * @brief : Randomizes the position of all nodes + */ +var randomizePositions = function(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; + } + } +}; + + +/** + * @brief : Updates the positions of nodes in the network + * @arg layoutInfo : LayoutInfo object + * @arg cy : Cytoscape object + * @arg options : Layout options + */ +var refreshPositions = function(layoutInfo, cy, options) { + // var s = 'Refreshing positions'; + // logDebug(s); + + var layout = options.layout; + var nodes = options.eles.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; + } + + nodes.positions(function(i, ele) { + var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[ele.data('id')]]; + // s = "Node: " + lnode.id + ". Refreshed position: (" + + // lnode.positionX + ", " + lnode.positionY + ")."; + // logDebug(s); + + 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 + }; + } + }); + + // Trigger layoutReady only on first call + if (true !== layoutInfo.ready) { + // s = 'Triggering layoutready'; + // logDebug(s); + layoutInfo.ready = true; + layout.one('layoutready', options.ready); + layout.trigger({ 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); +// } +// }; + +module.exports = CoseLayout; + +},{"../../is":77,"../../math":79,"../../thread":92,"../../util":94}],49:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../../util'); +var math = _dereq_('../../math'); + +var defaults = { + 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 + 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( 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 + ready: undefined, // callback on layoutready + stop: undefined // callback on layoutstop +}; + +function GridLayout( options ){ + this.options = util.extend({}, defaults, 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 = math.makeBoundingBox( options.boundingBox ? options.boundingBox : { + x1: 0, y1: 0, w: cy.width(), h: cy.height() + } ); + + if( bb.h === 0 || bb.w === 0){ + nodes.layoutPositions(this, options, function(){ + 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(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(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.boundingBox(); + 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(row, col){ + return cellUsed['c-' + row + '-' + col] ? true : false; + }; + + var use = function(row, col){ + cellUsed['c-' + row + '-' + col] = true; + }; + + // to keep track of current cell position + var row = 0; + var col = 0; + var moveToNextCell = function(){ + 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(i, element){ + var x, y; + + if( element.locked() || element.isFullAutoParent() ){ + 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 + +}; + +module.exports = GridLayout; + +},{"../../math":79,"../../util":94}],50:[function(_dereq_,module,exports){ +'use strict'; + +module.exports = [ + { name: 'breadthfirst', impl: _dereq_('./breadthfirst') }, + { name: 'circle', impl: _dereq_('./circle') }, + { name: 'concentric',impl: _dereq_('./concentric') }, + { name: 'cose', impl: _dereq_('./cose') }, + { name: 'grid', impl: _dereq_('./grid') }, + { name: 'null', impl: _dereq_('./null') }, + { name: 'preset', impl: _dereq_('./preset') }, + { name: 'random', impl: _dereq_('./random') } +]; + +},{"./breadthfirst":45,"./circle":46,"./concentric":47,"./cose":48,"./grid":49,"./null":51,"./preset":52,"./random":53}],51:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../../util'); + +// default layout options +var defaults = { + ready: function(){}, // on layoutready + stop: function(){} // on layoutstop +}; + +// constructor +// options : object containing layout options +function NullLayout( options ){ + this.options = util.extend({}, defaults, 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 + var cy = options.cy; // jshint ignore:line + + layout.trigger('layoutstart'); + + // puts all nodes at (0, 0) + 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.trigger('layoutready'); + + // trigger layoutstop when the layout stops (e.g. finishes) + layout.one('layoutstop', options.stop); + layout.trigger('layoutstop'); + + return this; // chaining +}; + +// called on continuous layouts to stop them before they finish +NullLayout.prototype.stop = function(){ + return this; // chaining +}; + +module.exports = NullLayout; + +},{"../../util":94}],52:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../../util'); +var is = _dereq_('../../is'); + +var defaults = { + 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 + animate: false, // whether to transition the node positions + animationDuration: 500, // duration of animation in ms if enabled + animationEasing: undefined, // easing of animation if enabled + ready: undefined, // callback on layoutready + stop: undefined // callback on layoutstop +}; + +function PresetLayout( options ){ + this.options = util.extend({}, defaults, options); +} + +PresetLayout.prototype.run = function(){ + var options = this.options; + var eles = options.eles; + + var nodes = eles.nodes(); + var posIsFn = is.fn( options.positions ); + + function getPosition(node){ + if( options.positions == null ){ + return null; + } + + if( posIsFn ){ + return options.positions.apply( node, [ node ] ); + } + + var pos = options.positions[node._private.data.id]; + + if( pos == null ){ + return null; + } + + return pos; + } + + nodes.layoutPositions(this, options, function(i, node){ + var position = getPosition(node); + + if( node.locked() || position == null ){ + return false; + } + + return position; + }); + + return this; // chaining +}; + +module.exports = PresetLayout; + +},{"../../is":77,"../../util":94}],53:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../../util'); +var math = _dereq_('../../math'); + +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 + ready: undefined, // callback on layoutready + stop: undefined // callback on layoutstop +}; + +function RandomLayout( options ){ + this.options = util.extend({}, defaults, options); +} + +RandomLayout.prototype.run = function(){ + var options = this.options; + var cy = options.cy; + var eles = options.eles; + var nodes = eles.nodes().not(':parent'); + + var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : { + x1: 0, y1: 0, w: cy.width(), h: cy.height() + } ); + + var getPos = function( i, node ){ + return { + x: bb.x1 + Math.round( Math.random() * bb.w ), + y: bb.y1 + Math.round( Math.random() * bb.h ) + }; + }; + + nodes.layoutPositions( this, options, getPos ); + + return this; // chaining +}; + +module.exports = RandomLayout; + +},{"../../math":79,"../../util":94}],54:[function(_dereq_,module,exports){ +'use strict'; + +var math = _dereq_('../../../math'); +var is = _dereq_('../../../is'); +var util = _dereq_('../../../util'); + +var BRp = {}; + +BRp.arrowShapeHeight = 0.3; + +BRp.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( x, y, size, angle, translation, 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( 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( 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( pts ){ + var ret = []; + + for( var i = 0; i < pts.length; i++ ){ + var p = pts[i]; + + ret.push( p.x, p.y ); + } + + return ret; + }; + + var defineArrowShape = function( name, defn ){ + if( is.string(defn) ){ + defn = arrowShapes[ defn ]; + } + + arrowShapes[ name ] = util.extend( { + name: name, + + points: [ + -0.15, -0.3, + 0.15, -0.3, + 0.15, 0.3, + -0.15, 0.3 + ], + + collide: function( x, y, size, angle, translation, padding ){ + var points = pointsToArr( transformPoints( this.points, size + 2*padding, angle, translation ) ); + var inside = math.pointInsidePolygonPoints( x, y, points ); + + return inside; + }, + + roughCollide: bbCollide, + + draw: function( context, size, angle, translation ){ + var points = transformPoints( this.points, size, angle, translation ); + + renderer.arrowShapeImpl('polygon')( context, points ); + }, + + spacing: function( edge ){ + return 0; + }, + + gap: function( edge ){ + return edge._private.style['width'].pfValue * 2; + } + }, defn ); + }; + + defineArrowShape( 'none', { + collide: util.falsify, + + roughCollide: util.falsify, + + draw: util.noop, + + spacing: util.zeroify, + + gap: util.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( context, size, angle, translation ){ + 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( edge ){ + return edge._private.style['width'].pfValue; + } + } ); + + + defineArrowShape( 'triangle-tee', { + points: [ + -0.15, -0.3, + 0, 0, + 0.15, -0.3, + -0.15, -0.3 + ], + + pointsTee: [ + -0.15, -0.4, + -0.15, -0.5, + 0.15, -0.5, + 0.15, -0.4 + ], + + collide: function( x, y, size, angle, translation, 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 = math.pointInsidePolygonPoints( x, y, triPts ) || math.pointInsidePolygonPoints( x, y, teePts ); + + return inside; + }, + + draw: function( context, size, angle, translation ){ + var triPts = transformPoints( this.points, size, angle, translation ); + var teePts = transformPoints( this.pointsTee, size, angle, translation ); + + renderer.arrowShapeImpl( this.name )( context, triPts, teePts ); + } + } ); + + defineArrowShape( 'vee', { + points: [ + -0.15, -0.3, + 0, 0, + 0.15, -0.3, + 0, -0.15 + ], + + gap: function( edge ){ + return edge._private.style['width'].pfValue; + } + } ); + + defineArrowShape( 'half-triangle-overshot', { + points: [ + 0, -0.25, + -0.5, -0.25, + 0.5, 0.25 + ], + + leavePathOpen: true, + + matchEdgeWidth: true + } ); + + defineArrowShape( 'circle', { + radius: 0.15, + + collide: function( x, y, size, angle, translation, 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( context, size, angle, translation ){ + renderer.arrowShapeImpl( this.name )( context, translation.x, translation.y, this.radius * size ); + }, + + spacing: function( edge ){ + return renderer.getArrowWidth(edge._private.style['width'].pfValue) + * this.radius; + } + } ); + + defineArrowShape( 'inhibitor', { + points: [ + -0.25, 0, + -0.25, -0.1, + 0.25, -0.1, + 0.25, 0 + ], + + spacing: function( edge ){ + return 1; + }, + + gap: function( edge ){ + return 1; + } + } ); + + defineArrowShape( 'tee', 'inhibitor' ); + + 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( edge ){ + return edge._private.style['width'].pfValue; + } + } ); + +}; + +module.exports = BRp; + +},{"../../../is":77,"../../../math":79,"../../../util":94}],55:[function(_dereq_,module,exports){ +'use strict'; + +var BRp = {}; + +var delEleCache = function( r ){ + r.eleEache = null; +}; + +var getEleCache = function( r ){ + if( !r.eleEache ){ + r.eleEache = { + nodes: r.cy.nodes(), + edges: r.cy.edges() + }; + } + + return r.eleEache; +}; + +BRp.getCachedElements = function(){ + return getEleCache( this ); +}; + +BRp.getCachedNodes = function(){ + return getEleCache( this ).nodes; +}; + +BRp.getCachedEdges = function(){ + return getEleCache( this ).edges; +}; + +BRp.updateElementsCache = function(){ + var r = this; + + delEleCache( r ); + + return getEleCache( r ); +}; + +module.exports = BRp; + +},{}],56:[function(_dereq_,module,exports){ +'use strict'; + +var math = _dereq_('../../../math'); +var is = _dereq_('../../../is'); +var zIndexSort = _dereq_('../../../collection/zsort'); + +var BRp = {}; + +// Project mouse +BRp.projectIntoViewport = function(clientX, clientY) { + var offsets = this.findContainerClientCoords(); + var offsetLeft = offsets[0]; + var offsetTop = offsets[1]; + + var x = clientX - offsetLeft; + var y = clientY - offsetTop; + + x -= this.cy.pan().x; y -= this.cy.pan().y; x /= this.cy.zoom(); y /= this.cy.zoom(); + return [x, y]; +}; + +BRp.findContainerClientCoords = function() { + var container = this.container; + + var bb = this.containerBB = this.containerBB || container.getBoundingClientRect(); + + return [bb.left, bb.top, bb.right - bb.left, bb.bottom - bb.top]; +}; + +BRp.invalidateContainerClientCoordsCache = function(){ + this.containerBB = null; +}; + +// Find nearest element +BRp.findNearestElement = function(x, y, visibleElementsOnly, isTouch){ + var self = this; + var r = this; + var eles = r.getCachedZSortedEles(); + var near = []; + 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; + + function checkNode(node){ + var _p = node._private; + + if( _p.style['events'].strValue === 'no' ){ return; } + + var width = node.outerWidth() + 2*nodeThreshold; + var height = node.outerHeight() + 2*nodeThreshold; + var hw = width/2; + var hh = height/2; + var pos = _p.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 visible = !visibleElementsOnly || ( node.visible() && !node.transparent() ); + + // exit early if invisible edge and must be visible + if( visibleElementsOnly && !visible ){ + return; + } + + var shape = r.nodeShapes[ self.getNodeShape(node) ]; + + if( + shape.checkPoint(x, y, 0, width, height, pos.x, pos.y) + ){ + near.push( node ); + } + + } + } + + function checkEdge(edge){ + var _p = edge._private; + + if( _p.style['events'].strValue === 'no' ){ return; } + + var rs = _p.rscratch; + var style = _p.style; + var width = style['width'].pfValue/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 inEdgeBB = false; + var sqDist; + + // exit early if invisible edge and must be visible + var passedVisibilityCheck; + var passesVisibilityCheck = function(){ + if( passedVisibilityCheck !== undefined ){ + return passedVisibilityCheck; + } + + if( !visibleElementsOnly ){ + passedVisibilityCheck = true; + return true; + } + + var visible = edge.visible() && !edge.transparent(); + if( visible ){ + passedVisibilityCheck = true; + return true; + } + + passedVisibilityCheck = false; + return false; + }; + + 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( + (inEdgeBB = math.inLineVicinity(x, y, pts[i], pts[i+1], pts[i+2], pts[i+3], width2)) + && passesVisibilityCheck() && + widthSq > ( sqDist = math.sqDistanceToFiniteLine(x, y, pts[i], pts[i+1], pts[i+2], pts[i+3]) ) + ){ + near.push( edge ); + } + } + + } 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( + (inEdgeBB = math.inBezierVicinity(x, y, pts[i], pts[i+1], pts[i+2], pts[i+3], pts[i+4], pts[i+5], width2)) + && passesVisibilityCheck() && + (widthSq > (sqDist = math.sqDistanceToQuadraticBezier(x, y, pts[i], pts[i+1], pts[i+2], pts[i+3], pts[i+4], pts[i+5])) ) + ){ + near.push( edge ); + } + } + } + + // if we're close to the edge but didn't hit it, maybe we hit its arrows + if( inEdgeBB && passesVisibilityCheck() && near.length === 0 || near[near.length - 1] !== edge ){ + var src = src || _p.source; + var tgt = tgt || _p.target; + + var eWidth = style['width'].pfValue; + var arSize = self.getArrowWidth( eWidth ); + + 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[ style[ar.name+'-arrow-shape'].value ]; + + if( + shape.roughCollide(x, y, arSize, ar.angle, { x: ar.x, y: ar.y }, edgeThreshold) + && + shape.collide(x, y, arSize, ar.angle, { x: ar.x, y: ar.y }, edgeThreshold) + ){ + near.push( edge ); + break; + } + } + } + + // 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 && near[ near.length - 1 ] === edge ){ + checkNode( src ); + checkNode( tgt ); + } + } + + function checkLabel(ele){ + var _p = ele._private; + var th = labelThreshold; + + if( _p.style['text-events'].strValue === 'no' ){ return; } + + // adjust bb w/ angle + if( _p.group === 'edges' && _p.style['edge-text-rotation'].strValue === 'autorotate' ){ + + var rstyle = _p.rstyle; + var lw = rstyle.labelWidth + 2*th; + var lh = rstyle.labelHeight + 2*th; + var lx = rstyle.labelX; + var ly = rstyle.labelY; + + var theta = _p.rscratch.labelAngle; + var cos = Math.cos( theta ); + var sin = Math.sin( theta ); + + var rotate = function( x, y ){ + x = x - lx; + y = y - ly; + + return { + x: x*cos - y*sin + lx, + y: x*sin + y*cos + ly + }; + }; + + var lx1 = lx - lw/2; + var lx2 = lx + lw/2; + var ly1 = ly - lh/2; + var ly2 = ly + lh/2; + + var px1y1 = rotate( lx1, ly1 ); + var px1y2 = rotate( lx1, ly2 ); + var px2y1 = rotate( lx2, ly1 ); + var px2y2 = rotate( lx2, ly2 ); + + var points = [ + px1y1.x, px1y1.y, + px2y1.x, px2y1.y, + px2y2.x, px2y2.y, + px1y2.x, px1y2.y + ]; + + if( math.pointInsidePolygonPoints( x, y, points ) ){ + near.push( ele ); + } + + } else { + var bb = ele.boundingBox({ + includeLabels: true, + includeNodes: false, + includeEdges: false + }); + + // adjust bb w/ threshold + bb.x1 -= th; + bb.y1 -= th; + bb.x2 += th; + bb.y2 += th; + bb.w = bb.x2 - bb.x1; + bb.h = bb.y2 - bb.y1; + + if( math.inBoundingBox( bb, x, y ) ){ + near.push( ele ); + } + } + + } + + for( var i = eles.length - 1; i >= 0; i-- ){ // reverse order for precedence + var ele = eles[i]; + var _p = ele._private; + + if( near.length > 0 ){ break; } // since we check in z-order, first found is top and best result => exit early + + if( _p.group === 'nodes' ){ + checkNode( ele ); + + } else { // then edge + checkEdge( ele ); + } + + checkLabel( ele ); + + } + + + if( near.length > 0 ){ + return near[ near.length - 1 ]; + } else { + return null; + } +}; + +// 'Give me everything from this box' +BRp.getAllInBox = function(x1, y1, x2, y2) { + var nodes = this.getCachedNodes(); + var edges = this.getCachedEdges(); + 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 = math.makeBoundingBox({ + x1: x1, y1: y1, + x2: x2, y2: y2 + }); + + for ( var i = 0; i < nodes.length; i++ ){ + var node = nodes[i]; + var nodeBb = node.boundingBox({ + includeNodes: true, + includeEdges: false, + includeLabels: false + }); + + if( math.boundingBoxesIntersect(boxBb, nodeBb) ){ + box.push(nodes[i]); + } + } + + for( var e = 0; e < edges.length; e++ ){ + var edge = edges[e]; + var _p = edge._private; + var rs = _p.rscratch; + + if( rs.startX != null && rs.startY != null && !math.inBoundingBox( boxBb, rs.startX, rs.startY ) ){ continue; } + if( rs.endX != null && rs.endY != null && !math.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( !math.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; +}; + + +/** + * Returns the shape of the given node. If the height or width of the given node + * is set to auto, the node is considered to be a compound. + * + * @param node a node + * @return {String} shape of the node + */ +BRp.getNodeShape = function( node ){ + var r = this; + var style = node._private.style; + var shape = style['shape'].value; + + if( node.isParent() ){ + if( shape === 'rectangle' || shape === 'roundrectangle' ){ + return shape; + } else { + return 'rectangle'; + } + } + + if( shape === 'polygon' ){ + var points = style['shape-polygon-points'].value; + + return r.nodeShapes.makePolygon( points ).name; + } + + return shape; +}; + +BRp.updateCachedZSortedEles = function(){ + this.getCachedZSortedEles( true ); +}; + +BRp.getCachedZSortedEles = function( forceRecalc ){ + var lastNodes = this.lastZOrderCachedNodes; + var lastEdges = this.lastZOrderCachedEdges; + var nodes = this.getCachedNodes(); + var edges = this.getCachedEdges(); + var eles = []; + + if( forceRecalc || !lastNodes || !lastEdges || lastNodes !== nodes || lastEdges !== edges ){ + //console.time('cachezorder') + + for( var i = 0; i < nodes.length; i++ ){ + var n = nodes[i]; + + if( n.animated() || (n.visible() && !n.transparent()) ){ + eles.push( n ); + } + } + + for( var i = 0; i < edges.length; i++ ){ + var e = edges[i]; + + if( e.animated() || (e.visible() && !e.transparent()) ){ + eles.push( e ); + } + } + + eles.sort( zIndexSort ); + this.cachedZSortedEles = eles; + //console.log('make cache') + + //console.timeEnd('cachezorder') + } else { + eles = this.cachedZSortedEles; + //console.log('read cache') + } + + this.lastZOrderCachedNodes = nodes; + this.lastZOrderCachedEdges = edges; + + return eles; +}; + +function pushBezierPts(edge, pts){ + var qbezierAt = function( p1, p2, p3, t ){ return math.qbezierAt(p1, p2, p3, t); }; + var _p = edge._private; + var bpts = _p.rstyle.bezierPts; + + bpts.push({ + x: qbezierAt( pts[0], pts[2], pts[4], 0.05 ), + y: qbezierAt( pts[1], pts[3], pts[5], 0.05 ) + }); + + bpts.push({ + x: qbezierAt( pts[0], pts[2], pts[4], 0.25 ), + y: qbezierAt( pts[1], pts[3], pts[5], 0.25 ) + }); + + bpts.push({ + x: qbezierAt( pts[0], pts[2], pts[4], 0.4 ), + y: qbezierAt( pts[1], pts[3], pts[5], 0.4 ) + }); + + bpts.push({ + x: qbezierAt( pts[0], pts[2], pts[4], 0.5 ), + y: qbezierAt( pts[1], pts[3], pts[5], 0.5 ) + }); + + bpts.push({ + x: qbezierAt( pts[0], pts[2], pts[4], 0.6 ), + y: qbezierAt( pts[1], pts[3], pts[5], 0.6 ) + }); + + bpts.push({ + x: qbezierAt( pts[0], pts[2], pts[4], 0.75 ), + y: qbezierAt( pts[1], pts[3], pts[5], 0.75 ) + }); + + bpts.push({ + x: qbezierAt( pts[0], pts[2], pts[4], 0.95 ), + y: qbezierAt( pts[1], pts[3], pts[5], 0.95 ) + }); +} + +BRp.projectLines = function( edge ){ + var _p = edge._private; + var rs = _p.rscratch; + var et = rs.edgeType; + + if( et === 'multibezier' || et === 'bezier' || et === 'self' || et === 'compound' ){ + var bpts = _p.rstyle.bezierPts = []; // jshint ignore:line + + for( var i = 0; i + 5 < rs.allpts.length; i += 4 ){ + pushBezierPts( 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] } + ]; + } +}; + +BRp.projectBezier = BRp.projectLines; + +BRp.recalculateNodeLabelProjection = function( node ){ + var content = node._private.style['label'].strValue; + if( !content || content.match(/^\s+$/) ){ return; } + + var textX, textY; + var nodeWidth = node.outerWidth(); + var nodeHeight = node.outerHeight(); + var nodePos = node._private.position; + var textHalign = node._private.style['text-halign'].strValue; + var textValign = node._private.style['text-valign'].strValue; + var rs = node._private.rscratch; + var rstyle = node._private.rstyle; + + switch( textHalign ){ + case 'left': + textX = nodePos.x - nodeWidth / 2; + break; + + case 'right': + textX = nodePos.x + nodeWidth / 2; + break; + + default: // e.g. center + textX = nodePos.x; + } + + switch( textValign ){ + case 'top': + textY = nodePos.y - nodeHeight / 2; + break; + + case 'bottom': + textY = nodePos.y + nodeHeight / 2; + break; + + default: // e.g. middle + textY = nodePos.y; + } + + rs.labelX = textX; + rs.labelY = textY; + rstyle.labelX = textX; + rstyle.labelY = textY; + + this.applyLabelDimensions( node ); +}; + +BRp.recalculateEdgeLabelProjection = function( edge ){ + var content = edge._private.style['label'].strValue; + if( !content || content.match(/^\s+$/) ){ return; } + + var textX, textY; + var _p = edge._private; + var rs = _p.rscratch; + //var style = _p.style; + var rstyle = _p.rstyle; + + textX = rs.midX; + textY = rs.midY; + + // add center point to style so bounding box calculations can use it + rs.labelX = textX; + rs.labelY = textY; + rstyle.labelX = textX; + rstyle.labelY = textY; + + this.applyLabelDimensions( edge ); +}; + +BRp.applyLabelDimensions = function( ele ){ + var rs = ele._private.rscratch; + var rstyle = ele._private.rstyle; + + var text = this.getLabelText( ele ); + var labelDims = this.calculateLabelDimensions( ele, text ); + + rstyle.labelWidth = labelDims.width; + rs.labelWidth = labelDims.width; + + rstyle.labelHeight = labelDims.height; + rs.labelHeight = labelDims.height; +}; + +BRp.getLabelText = function( ele ){ + var style = ele._private.style; + var text = ele._private.style['label'].strValue; + var textTransform = style['text-transform'].value; + var rscratch = ele._private.rscratch; + + if (textTransform == 'none') { + } else if (textTransform == 'uppercase') { + text = text.toUpperCase(); + } else if (textTransform == 'lowercase') { + text = text.toLowerCase(); + } + + if( style['text-wrap'].value === 'wrap' ){ + //console.log('wrap'); + + // save recalc if the label is the same as before + if( rscratch.labelWrapKey === rscratch.labelKey ){ + // console.log('wrap cache hit'); + return rscratch.labelWrapCachedText; + } + // console.log('wrap cache miss'); + + var lines = text.split('\n'); + var maxW = style['text-max-width'].pfValue; + var wrappedLines = []; + + for( var l = 0; l < lines.length; l++ ){ + var line = lines[l]; + var lineDims = this.calculateLabelDimensions( ele, line, 'line=' + line ); + var lineW = lineDims.width; + + if( lineW > maxW ){ // line is too long + var words = line.split(/\s+/); // NB: assume collapsed whitespace into single space + var subline = ''; + + for( var w = 0; w < words.length; w++ ){ + var word = words[w]; + var testLine = subline.length === 0 ? word : subline + ' ' + word; + var testDims = this.calculateLabelDimensions( ele, testLine, 'testLine=' + testLine ); + var testW = testDims.width; + + if( testW <= maxW ){ // word fits on current line + subline += word + ' '; + } else { // word starts new line + wrappedLines.push( subline ); + subline = word + ' '; + } + } + + // if there's remaining text, put it in a wrapped line + if( !subline.match(/^\s+$/) ){ + wrappedLines.push( subline ); + } + } else { // line is already short enough + wrappedLines.push( line ); + } + } // for + + rscratch.labelWrapCachedLines = wrappedLines; + rscratch.labelWrapCachedText = text = wrappedLines.join('\n'); + rscratch.labelWrapKey = rscratch.labelKey; + + // console.log(text) + } // if wrap + + return text; +}; + +BRp.calculateLabelDimensions = function( ele, text, extraKey ){ + var r = this; + var style = ele._private.style; + var fStyle = style['font-style'].strValue; + var size = style['font-size'].pfValue + 'px'; + var family = style['font-family'].strValue; + // var variant = style['font-variant'].strValue; + var weight = style['font-weight'].strValue; + + var cacheKey = ele._private.labelKey; + + if( extraKey ){ + cacheKey += '$@$' + extraKey; + } + + var cache = r.labelDimCache || (r.labelDimCache = {}); + + if( cache[cacheKey] ){ + return cache[cacheKey]; + } + + var div = this.labelCalcDiv; + + if( !div ){ + div = this.labelCalcDiv = document.createElement('div'); + document.body.appendChild( div ); + } + + var ds = div.style; + + // from ele style + ds.fontFamily = family; + ds.fontStyle = fStyle; + ds.fontSize = size; + // ds.fontVariant = variant; + ds.fontWeight = weight; + + // forced style + ds.position = 'absolute'; + ds.left = '-9999px'; + ds.top = '-9999px'; + ds.zIndex = '-1'; + ds.visibility = 'hidden'; + ds.pointerEvents = 'none'; + ds.padding = '0'; + ds.lineHeight = '1'; + + if( style['text-wrap'].value === 'wrap' ){ + ds.whiteSpace = 'pre'; // so newlines are taken into account + } else { + ds.whiteSpace = 'normal'; + } + + // put label content in div + div.textContent = text; + + cache[cacheKey] = { + width: div.clientWidth, + height: div.clientHeight + }; + + return cache[cacheKey]; +}; + +BRp.recalculateRenderedStyle = function( eles ){ + var edges = []; + var nodes = []; + var handledEdge = {}; + + for( var i = 0; i < eles.length; i++ ){ + var ele = eles[i]; + var _p = ele._private; + var style = _p.style; + var rs = _p.rscratch; + var rstyle = _p.rstyle; + var id = _p.data.id; + var bbStyleSame = rs.boundingBoxKey != null && _p.boundingBoxKey === rs.boundingBoxKey; + var labelStyleSame = rs.labelKey != null && _p.labelKey === rs.labelKey; + var styleSame = bbStyleSame && labelStyleSame; + + if( _p.group === 'nodes' ){ + var pos = _p.position; + var posSame = rstyle.nodeX != null && rstyle.nodeY != null && pos.x === rstyle.nodeX && pos.y === rstyle.nodeY; + var wSame = rstyle.nodeW != null && rstyle.nodeW === style['width'].pfValue; + var hSame = rstyle.nodeH != null && rstyle.nodeH === style['height'].pfValue; + + if( !posSame || !styleSame || !wSame || !hSame ){ + nodes.push( ele ); + } + + rstyle.nodeX = pos.x; + rstyle.nodeY = pos.y; + rstyle.nodeW = style['width'].pfValue; + rstyle.nodeH = style['height'].pfValue; + } else { // edges + + var srcPos = _p.source._private.position; + var tgtPos = _p.target._private.position; + var srcSame = rstyle.srcX != null && rstyle.srcY != null && srcPos.x === rstyle.srcX && srcPos.y === rstyle.srcY; + var tgtSame = rstyle.tgtX != null && rstyle.tgtY != null && tgtPos.x === rstyle.tgtX && tgtPos.y === rstyle.tgtY; + var positionsSame = srcSame && tgtSame; + + if( !positionsSame || !styleSame ){ + if( rs.edgeType === 'bezier' || rs.edgeType === 'straight' || rs.edgeType === 'self' || rs.edgeType === 'compound' ){ + if( !handledEdge[ id ] ){ + edges.push( ele ); + handledEdge[ id ] = true; + + var parallelEdges = ele.parallelEdges(); + for( var i = 0; i < parallelEdges.length; i++ ){ + var pEdge = parallelEdges[i]; + var pId = pEdge._private.data.id; + + if( !handledEdge[ pId ] ){ + edges.push( pEdge ); + handledEdge[ pId ] = true; + } + + } + } + } else { + edges.push( ele ); + } + } // if positions diff + + // update rstyle positions + rstyle.srcX = srcPos.x; + rstyle.srcY = srcPos.y; + rstyle.tgtX = tgtPos.x; + rstyle.tgtY = tgtPos.y; + + } // if edges + + rs.boundingBoxKey = _p.boundingBoxKey; + rs.labelKey = _p.labelKey; + } + + this.recalculateEdgeProjections( edges ); + this.recalculateLabelProjections( nodes, edges ); +}; + +BRp.recalculateLabelProjections = function( nodes, edges ){ + for( var i = 0; i < nodes.length; i++ ){ + this.recalculateNodeLabelProjection( nodes[i] ); + } + + for( var i = 0; i < edges.length; i++ ){ + this.recalculateEdgeLabelProjection( edges[i] ); + } +}; + +BRp.recalculateEdgeProjections = function( edges ){ + this.findEdgeControlPoints( edges ); +}; + + +// Find edge control points +BRp.findEdgeControlPoints = function(edges) { + if( !edges || edges.length === 0 ){ return; } + + var r = this; + var cy = r.cy; + var hasCompounds = cy.hasCompoundNodes(); + var hashTable = {}; + var pairIds = []; + var haystackEdges = []; + var autorotateEdges = []; + + // create a table of edge (src, tgt) => list of edges between them + var pairId; + for (var i = 0; i < edges.length; i++){ + var edge = edges[i]; + var _p = edge._private; + var data = _p.data; + var style = _p.style; + var curveStyle = style['curve-style'].value; + var edgeIsUnbundled = curveStyle === 'unbundled-bezier' || curveStyle === 'segments'; + + // ignore edges who are not to be displayed + // they shouldn't take up space + if( style.display.value === 'none' ){ + continue; + } + + if( style['edge-text-rotation'].strValue === 'autorotate' ){ + autorotateEdges.push( edge ); + } + + if( curveStyle === 'haystack' ){ + haystackEdges.push( edge ); + continue; + } + + var srcId = data.source; + var tgtId = data.target; + + pairId = srcId > tgtId ? + tgtId + '$-$' + srcId : + srcId + '$-$' + tgtId ; + + if( edgeIsUnbundled ){ + pairId = 'unbundled' + '$-$' + data.id; + } + + if( hashTable[pairId] == null ){ + hashTable[pairId] = []; + pairIds.push( pairId ); + } + + hashTable[pairId].push( edge ); + + if( edgeIsUnbundled ){ + hashTable[pairId].hasUnbundled = true; + } + } + + var src, tgt, src_p, tgt_p, srcPos, tgtPos, srcW, srcH, tgtW, tgtH, srcShape, tgtShape; + var vectorNormInverse; + var badBezier; + + // for each pair (src, tgt), create the ctrl pts + // Nested for loop is OK; total number of iterations for both loops = edgeCount + for (var p = 0; p < pairIds.length; p++) { + pairId = pairIds[p]; + var pairEdges = hashTable[pairId]; + + // for each pair id, the edges should be sorted by index + pairEdges.sort(function(edge1, edge2){ + return edge1._private.index - edge2._private.index; + }); + + src = pairEdges[0]._private.source; + tgt = pairEdges[0]._private.target; + + src_p = src._private; + tgt_p = tgt._private; + + // make sure src/tgt distinction is consistent + // (src/tgt in this case are just for ctrlpts and don't actually have to be true src/tgt) + if( src_p.data.id > tgt_p.data.id ){ + var temp = src; + src = tgt; + tgt = temp; + } + + srcPos = src_p.position; + tgtPos = tgt_p.position; + + srcW = src.outerWidth(); + srcH = src.outerHeight(); + + tgtW = tgt.outerWidth(); + tgtH = tgt.outerHeight(); + + srcShape = r.nodeShapes[ this.getNodeShape(src) ]; + tgtShape = r.nodeShapes[ this.getNodeShape(tgt) ]; + + badBezier = false; + + + if( (pairEdges.length > 1 && src !== tgt) || pairEdges.hasUnbundled ){ + + // 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 + ); + + // 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 midptSrcPts = { + x1: srcOutside[0], + x2: tgtOutside[0], + y1: srcOutside[1], + y2: tgtOutside[1] + }; + + var dy = ( tgtOutside[1] - srcOutside[1] ); + var dx = ( tgtOutside[0] - srcOutside[0] ); + var l = Math.sqrt( dx*dx + dy*dy ); + + var vector = { + x: dx, + y: dy + }; + + var vectorNorm = { + x: vector.x/l, + y: vector.y/l + }; + vectorNormInverse = { + x: -vectorNorm.y, + y: vectorNorm.x + }; + + + // if src intersection is inside tgt or tgt intersection is inside src, then no ctrl pts to draw + if( + 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 ) + ){ + vectorNormInverse = {}; + badBezier = true; + } + + } + + var edge; + var edge_p; + var rs; + + for (var i = 0; i < pairEdges.length; i++) { + edge = pairEdges[i]; + edge_p = edge._private; + rs = edge_p.rscratch; + + var edgeIndex1 = rs.lastEdgeIndex; + var edgeIndex2 = i; + + var numEdges1 = rs.lastNumEdges; + var numEdges2 = pairEdges.length; + + var eStyle = edge_p.style; + var style = eStyle; + var curveStyle = eStyle['curve-style'].value; + var ctrlptDists = eStyle['control-point-distances']; + var ctrlptWs = eStyle['control-point-weights']; + var bezierN = ctrlptDists && ctrlptWs ? Math.min( ctrlptDists.value.length, ctrlptWs.value.length ) : 1; + var stepSize = eStyle['control-point-step-size'].pfValue; + var ctrlptDist = ctrlptDists !== undefined ? ctrlptDists.pfValue[0] : undefined; + var ctrlptWeight = ctrlptWs.value[0]; + var edgeIsUnbundled = curveStyle === 'unbundled-bezier' || curveStyle === 'segments'; + + var swappedDirection = edge_p.source !== src; + + if( swappedDirection && edgeIsUnbundled ){ + ctrlptDist *= -1; + } + + var srcX1 = rs.lastSrcCtlPtX; + var srcX2 = srcPos.x; + var srcY1 = rs.lastSrcCtlPtY; + var srcY2 = srcPos.y; + var srcW1 = rs.lastSrcCtlPtW; + var srcW2 = src.outerWidth(); + var srcH1 = rs.lastSrcCtlPtH; + var srcH2 = src.outerHeight(); + + var tgtX1 = rs.lastTgtCtlPtX; + var tgtX2 = tgtPos.x; + var tgtY1 = rs.lastTgtCtlPtY; + var tgtY2 = tgtPos.y; + var tgtW1 = rs.lastTgtCtlPtW; + var tgtW2 = tgt.outerWidth(); + var tgtH1 = rs.lastTgtCtlPtH; + var tgtH2 = tgt.outerHeight(); + + var width1 = rs.lastW; + var width2 = eStyle['control-point-step-size'].pfValue; + + if( badBezier ){ + rs.badBezier = true; + } else { + rs.badBezier = false; + } + + if( srcX1 === srcX2 && srcY1 === srcY2 && srcW1 === srcW2 && srcH1 === srcH2 + && tgtX1 === tgtX2 && tgtY1 === tgtY2 && tgtW1 === tgtW2 && tgtH1 === tgtH2 + && width1 === width2 + && ((edgeIndex1 === edgeIndex2 && numEdges1 === numEdges2) || edgeIsUnbundled) ){ + // console.log('edge ctrl pt cache HIT') + continue; // then the control points haven't changed and we can skip calculating them + } else { + rs.lastSrcCtlPtX = srcX2; + rs.lastSrcCtlPtY = srcY2; + rs.lastSrcCtlPtW = srcW2; + rs.lastSrcCtlPtH = srcH2; + rs.lastTgtCtlPtX = tgtX2; + rs.lastTgtCtlPtY = tgtY2; + rs.lastTgtCtlPtW = tgtW2; + rs.lastTgtCtlPtH = tgtH2; + rs.lastEdgeIndex = edgeIndex2; + rs.lastNumEdges = numEdges2; + rs.lastWidth = width2; + // console.log('edge ctrl pt cache MISS') + } + + if( src === tgt ){ + // Self-edge + + rs.edgeType = 'self'; + + var j = i; + var loopDist = stepSize; + + if( edgeIsUnbundled ){ + j = 0; + loopDist = ctrlptDist; + } + + rs.ctrlpts = [ + srcPos.x, + srcPos.y - (1 + Math.pow(srcH, 1.12) / 100) * loopDist * (j / 3 + 1), + + srcPos.x - (1 + Math.pow(srcW, 1.12) / 100) * loopDist * (j / 3 + 1), + srcPos.y + ]; + + } else if( + hasCompounds && + ( src.isParent() || src.isChild() || tgt.isParent() || tgt.isChild() ) && + ( src.parents().anySame(tgt) || tgt.parents().anySame(src) ) + ){ + // Compound edge + + rs.edgeType = 'compound'; + + // because the line approximation doesn't apply for compound beziers + // (loop/self edges are already elided b/c of cheap src==tgt check) + rs.badBezier = false; + + 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 + ]; + + } else if( curveStyle === 'segments' ){ + // Segments (multiple straight lines) + + rs.edgeType = 'segments'; + rs.segpts = []; + + var segmentWs = eStyle['segment-weights'].pfValue; + var segmentDs = eStyle['segment-distances'].pfValue; + var segmentsN = Math.min( segmentWs.length, segmentDs.length ); + + for( var s = 0; s < segmentsN; s++ ){ + var w = segmentWs[s]; + var d = segmentDs[s]; + + // d = swappedDirection ? -d : d; + // + // d = Math.abs(d); + + // var w1 = !swappedDirection ? (1 - w) : w; + // var w2 = !swappedDirection ? w : (1 - w); + + var w1 = (1 - w); + var w2 = w; + + var adjustedMidpt = { + x: midptSrcPts.x1 * w1 + midptSrcPts.x2 * w2, + y: midptSrcPts.y1 * w1 + midptSrcPts.y2 * w2 + }; + + rs.segpts.push( + adjustedMidpt.x + vectorNormInverse.x * d, + adjustedMidpt.y + vectorNormInverse.y * d + ); + } + + // Straight edge + } else if ( + pairEdges.length % 2 === 1 + && i === Math.floor(pairEdges.length / 2) + && !edgeIsUnbundled + ){ + + rs.edgeType = 'straight'; + + } else { + // (Multi)bezier + + var multi = edgeIsUnbundled; + + rs.edgeType = multi ? 'multibezier' : 'bezier'; + rs.ctrlpts = []; + + for( var b = 0; b < bezierN; b++ ){ + var normctrlptDist = (0.5 - pairEdges.length / 2 + i) * stepSize; + var manctrlptDist; + var sign = math.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 = !swappedDirection || edgeIsUnbundled ? (1 - ctrlptWeight) : ctrlptWeight; + var w2 = !swappedDirection || edgeIsUnbundled ? ctrlptWeight : (1 - ctrlptWeight); + + var adjustedMidpt = { + x: midptSrcPts.x1 * w1 + midptSrcPts.x2 * w2, + y: midptSrcPts.y1 * w1 + midptSrcPts.y2 * w2 + }; + + rs.ctrlpts.push( + adjustedMidpt.x + vectorNormInverse.x * distanceFromMidpoint, + adjustedMidpt.y + vectorNormInverse.y * distanceFromMidpoint + ); + } + + } + + // find endpts for edge + this.findEndpoints( edge ); + + var badStart = !is.number( rs.startX ) || !is.number( rs.startY ); + var badAStart = !is.number( rs.arrowStartX ) || !is.number( rs.arrowStartY ); + var badEnd = !is.number( rs.endX ) || !is.number( rs.endY ); + var badAEnd = !is.number( rs.arrowEndX ) || !is.number( rs.arrowEndY ); + + var minCpADistFactor = 3; + var arrowW = this.getArrowWidth( eStyle['width'].pfValue ) * this.arrowShapeHeight; + var minCpADist = minCpADistFactor * arrowW; + + if( rs.edgeType === 'bezier' ){ + var startACpDist = math.distance( { x: rs.ctrlpts[0], y: rs.ctrlpts[1] }, { x: rs.startX, y: rs.startY } ); + var closeStartACp = startACpDist < minCpADist; + var endACpDist = math.distance( { 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 ); + } + + } + + 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.edgeType === 'bezier' ){ + rs.midX = math.qbezierAt( rs.arrowStartX, rs.ctrlpts[0], rs.arrowEndX, 0.5 ); + rs.midY = math.qbezierAt( rs.arrowStartY, rs.ctrlpts[1], rs.arrowEndY, 0.5 ); + } else 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 = math.qbezierAt( rs.allpts[m], rs.allpts[m+2], rs.allpts[m+4], mt ); + rs.midY = math.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.arrowStartX + rs.arrowEndX )/2; + rs.midY = ( rs.arrowStartY + rs.arrowEndY )/2; + + } 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 i1 = rs.segpts.length / 2 - 1; + + rs.midX = rs.segpts[i1]; + rs.midY = rs.segpts[i1+1]; + } + + + } + + this.projectLines( edge ); + this.calculateArrowAngles( edge ); + this.recalculateEdgeLabelProjection( edge ); + + } + } + + for( var i = 0; i < haystackEdges.length; i++ ){ + var edge = haystackEdges[i]; + var _p = edge._private; + var style = _p.style; + var rscratch = _p.rscratch; + var rs = rscratch; + + if( !rscratch.haystack ){ + var angle = Math.random() * 2 * Math.PI; + + rscratch.source = { + x: Math.cos(angle), + y: Math.sin(angle) + }; + + var angle = Math.random() * 2 * Math.PI; + + rscratch.target = { + x: Math.cos(angle), + y: Math.sin(angle) + }; + + } + + var src = _p.source; + var tgt = _p.target; + var srcPos = src._private.position; + var tgtPos = tgt._private.position; + var srcW = src.width(); + var tgtW = tgt.width(); + var srcH = src.height(); + var tgtH = tgt.height(); + var radius = style['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 + rscratch.edgeType = 'haystack'; + rscratch.haystack = true; + + this.projectLines( edge ); + this.calculateArrowAngles( edge ); + this.recalculateEdgeLabelProjection( edge ); + } + + for( var i = 0 ; i < autorotateEdges.length; i++ ){ + var edge = autorotateEdges[i]; + var rs = edge._private.rscratch; + + rs.labelAngle = Math.atan( rs.midDispY / rs.midDispX ); + } + + return hashTable; +}; + +var getAngleFromDisp = function( dispX, dispY ){ + return Math.atan2( dispY, dispX ) - Math.PI/2; +}; + +BRp.calculateArrowAngles = function( edge ){ + var rs = edge._private.rscratch; + var isHaystack = rs.edgeType === 'haystack'; + 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; + + var srcPos = edge.source().position(); + var tgtPos = edge.target().position(); + + 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; + } + + // source + // + + dispX = srcPos.x - startX; + dispY = srcPos.y - startY; + + 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( isSelf ){ + dispX = -1; + dispY = 1; + } else 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 ){ + 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 = math.qbezierAt( pts[p0], pts[ic], pts[p1], 0.0 ); + bp0y = math.qbezierAt( pts[p0+1], pts[ic+1], pts[p1+1], 0.0 ); + + bp1x = math.qbezierAt( pts[p0], pts[ic], pts[p1], 0.0001 ); + bp1y = math.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 = math.qbezierAt( pts[p0], pts[ic], pts[p1], 0.4999 ); + bp0y = math.qbezierAt( pts[p0+1], pts[ic+1], pts[p1+1], 0.4999 ); + + bp1x = math.qbezierAt( pts[p0], pts[ic], pts[p1], 0.5 ); + bp1y = math.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 ){ + // already ok + } 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 + // + + dispX = tgtPos.x - endX; + dispY = tgtPos.y - endY; + + rs.tgtArrowAngle = getAngleFromDisp( dispX, dispY ); +}; + + +BRp.findEndpoints = function( edge ){ + var r = this; + var intersect; + + var source = edge.source()[0]; + var target = edge.target()[0]; + + var src_p = source._private; + var tgt_p = target._private; + + var srcPos = src_p.position; + var tgtPos = tgt_p.position; + + var tgtArShape = edge._private.style['target-arrow-shape'].value; + var srcArShape = edge._private.style['source-arrow-shape'].value; + + var rs = edge._private.rscratch; + + var et = rs.edgeType; + var bezier = et === 'bezier' || et === 'multibezier' || et === 'self' || et === 'compound'; + var multi = et !== 'bezier'; + var lines = et === 'straight' || et === 'segments'; + var segments = et === 'segments'; + + var p1, p2; + + 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; + } + + intersect = r.nodeShapes[this.getNodeShape(target)].intersectLine( + tgtPos.x, + tgtPos.y, + target.outerWidth(), + target.outerHeight(), + p1[0], + p1[1], + 0 + ); + + var arrowEnd = math.shortenIntersection(intersect, p1, + r.arrowShapes[tgtArShape].spacing(edge)); + var edgeEnd = math.shortenIntersection(intersect, p1, + r.arrowShapes[tgtArShape].gap(edge)); + + rs.endX = edgeEnd[0]; + rs.endY = edgeEnd[1]; + + rs.arrowEndX = arrowEnd[0]; + rs.arrowEndY = arrowEnd[1]; + + intersect = r.nodeShapes[this.getNodeShape(source)].intersectLine( + srcPos.x, + srcPos.y, + source.outerWidth(), + source.outerHeight(), + p2[0], + p2[1], + 0 + ); + + var arrowStart = math.shortenIntersection( + intersect, p2, + r.arrowShapes[srcArShape].spacing(edge) + ); + var edgeStart = math.shortenIntersection( + intersect, p2, + r.arrowShapes[srcArShape].gap(edge) + ); + + rs.startX = edgeStart[0]; + rs.startY = edgeStart[1]; + + rs.arrowStartX = arrowStart[0]; + rs.arrowStartY = arrowStart[1]; + + if( lines ){ + if( !is.number(rs.startX) || !is.number(rs.startY) || !is.number(rs.endX) || !is.number(rs.endY) ){ + rs.badLine = true; + } else { + rs.badLine = false; + } + } +}; + +BRp.getArrowWidth = BRp.getArrowHeight = function(edgeWidth) { + var cache = this.arrowWidthCache = this.arrowWidthCache || {}; + + var cachedVal = cache[edgeWidth]; + if( cachedVal ){ + return cachedVal; + } + + cachedVal = Math.max(Math.pow(edgeWidth * 13.37, 0.9), 29); + cache[edgeWidth] = cachedVal; + + return cachedVal; +}; + +module.exports = BRp; + +},{"../../../collection/zsort":29,"../../../is":77,"../../../math":79}],57:[function(_dereq_,module,exports){ +'use strict'; + +var BRp = {}; + +BRp.getCachedImage = function(url, onLoad) { + var r = this; + var imageCache = r.imageCache = r.imageCache || {}; + + if( imageCache[url] && imageCache[url].image ){ + return imageCache[url].image; + } + + var cache = imageCache[url] = imageCache[url] || {}; + + var image = cache.image = new Image(); + image.addEventListener('load', onLoad); + image.src = url; + + return image; +}; + +module.exports = BRp; + +},{}],58:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../../../is'); +var util = _dereq_('../../../util'); + +var BaseRenderer = function(){}; +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; + + r.container = options.cy.container(); + + r.selection = [undefined, undefined, undefined, undefined, 0]; // Coordinates for selection box, plus enabled flag + + //--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.hideEdgesOnViewport = options.hideEdgesOnViewport; + r.hideLabelsOnViewport = options.hideLabelsOnViewport; + r.textureOnViewport = options.textureOnViewport; + r.wheelSensitivity = options.wheelSensitivity; + r.motionBlurEnabled = options.motionBlur; // on by default + r.forcedPixelRatio = options.pixelRatio; + r.motionBlur = true; // 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.registerNodeShapes(); + r.registerArrowShapes(); + r.load(); +}; + +BRp.notify = function(params) { + var types; + var r = this; + + if( is.array( params.type ) ){ + types = params.type; + + } else { + types = [ params.type ]; + } + + for( var i = 0; i < types.length; i++ ){ + var type = types[i]; + + switch( type ){ + case 'destroy': + r.destroy(); + return; + + case 'add': + case 'remove': + case 'load': + r.updateElementsCache(); + break; + + case 'viewport': + r.redrawHint('select', true); + break; + + case 'style': + r.updateCachedZSortedEles(); + break; + } + + if( type === 'load' || type === 'resize' ){ + r.invalidateContainerClientCoordsCache(); + r.matchCanvasSize(r.container); + } + } // for + + r.redrawHint('eles', true); + r.redrawHint('drag', true); + + this.startRenderLoop(); + + this.redraw(); +}; + +BRp.destroy = function(){ + this.destroyed = true; + + this.cy.stopAnimationLoop(); + + for( var i = 0; i < this.bindings.length; i++ ){ + var binding = this.bindings[i]; + var b = binding; + + b.target.removeEventListener(b.event, b.handler, b.useCapture); + } + + if( this.removeObserver ){ + this.removeObserver.disconnect(); + } + + if( this.labelCalcDiv ){ + try{ + document.body.removeChild(this.labelCalcDiv); + } catch(e){ + // ie10 issue #1014 + } + } +}; + +[ + _dereq_('./arrow-shapes'), + _dereq_('./cached-eles'), + _dereq_('./coord-ele-math'), + _dereq_('./images'), + _dereq_('./load-listeners'), + _dereq_('./node-shapes'), + _dereq_('./redraw') +].forEach(function( props ){ + util.extend( BRp, props ); +}); + +module.exports = BR; + +},{"../../../is":77,"../../../util":94,"./arrow-shapes":54,"./cached-eles":55,"./coord-ele-math":56,"./images":57,"./load-listeners":59,"./node-shapes":60,"./redraw":61}],59:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../../../is'); +var util = _dereq_('../../../util'); +var Event = _dereq_('../../../event'); +var Collection = _dereq_('../../../collection'); + +var BRp = {}; + +BRp.registerBinding = function(target, event, handler, useCapture){ + this.bindings.push({ + target: target, + event: event, + handler: handler, + useCapture: useCapture + }); + + target.addEventListener(event, handler, useCapture); +}; + +BRp.nodeIsDraggable = function(node) { + if (node._private.style['opacity'].value !== 0 + && node._private.style['visibility'].value == 'visible' + && node._private.style['display'].value == 'element' + && !node.locked() + && node.grabbable() ) { + + return true; + } + + return false; +}; + +BRp.load = function() { + var r = this; + + var triggerEvents = function( target, names, e, props ){ + if( target == null ){ + target = r.cy; + } + + for( var i = 0; i < names.length; i++ ){ + var name = names[i]; + + var event = Event( e, util.extend({ type: name }, props) ); + target.trigger( event ); + } + }; + + var isMultSelKeyDown = function( e ){ + return e.shiftKey || e.metaKey || e.ctrlKey; // maybe e.altKey + }; + + var getDragListIds = function(opts){ + var listHasId; + + if( opts.addToList && r.cy.hasCompoundNodes() ){ // only needed for compound graphs + if( !opts.addToList.hasId ){ // build ids lookup if doesn't already exist + opts.addToList.hasId = {}; + + for( var i = 0; i < opts.addToList.length; i++ ){ + var ele = opts.addToList[i]; + + opts.addToList.hasId[ ele.id() ] = true; + } + } + + listHasId = opts.addToList.hasId; + } + + return listHasId || {}; + }; + + // 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(node, opts){ + if( !node._private.cy.hasCompoundNodes() ){ + return; + } + + if( opts.inDragLayer == null && opts.addToList == null ){ return; } // nothing to do + + var listHasId = getDragListIds( opts ); + + var innerNodes = node.descendants(); + + for( var i = 0; i < innerNodes.size(); i++ ){ + var iNode = innerNodes[i]; + var _p = iNode._private; + + if( opts.inDragLayer ){ + _p.rscratch.inDragLayer = true; + } + + if( opts.addToList && !listHasId[ iNode.id() ] ){ + opts.addToList.push( iNode ); + listHasId[ iNode.id() ] = true; + + _p.grabbed = true; + } + + var edges = _p.edges; + for( var j = 0; opts.inDragLayer && j < edges.length; j++ ){ + edges[j]._private.rscratch.inDragLayer = true; + } + } + }; + + // adds the given nodes, and its edges to the drag layer + var addNodeToDrag = function(node, opts){ + + var _p = node._private; + var listHasId = getDragListIds( opts ); + + if( opts.inDragLayer ){ + _p.rscratch.inDragLayer = true; + } + + if( opts.addToList && !listHasId[ node.id() ] ){ + opts.addToList.push( node ); + listHasId[ node.id() ] = true; + + _p.grabbed = true; + } + + var edges = _p.edges; + for( var i = 0; opts.inDragLayer && i < edges.length; i++ ){ + edges[i]._private.rscratch.inDragLayer = true; + } + + addDescendantsToDrag( node, opts ); // always add to drag + + // also add nodes and edges related to the topmost ancestor + updateAncestorsInDragLayer( node, { + inDragLayer: opts.inDragLayer + } ); + }; + + var freeDraggedElements = function( draggedElements ){ + if( !draggedElements ){ return; } + + for (var i=0; i < draggedElements.length; i++) { + + var dEi_p = draggedElements[i]._private; + + if(dEi_p.group === 'nodes') { + dEi_p.rscratch.inDragLayer = false; + dEi_p.grabbed = false; + + var sEdges = dEi_p.edges; + for( var j = 0; j < sEdges.length; j++ ){ sEdges[j]._private.rscratch.inDragLayer = false; } + + // for compound nodes, also remove related nodes and edges from the drag layer + updateAncestorsInDragLayer(draggedElements[i], { inDragLayer: false }); + + } else if( dEi_p.group === 'edges' ){ + dEi_p.rscratch.inDragLayer = false; + } + + } + }; + + // 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(node, opts) { + + if( opts.inDragLayer == null && opts.addToList == null ){ return; } // nothing to do + + // find top-level parent + var parent = node; + + if( !node._private.cy.hasCompoundNodes() ){ + return; + } + + while( parent.parent().nonempty() ){ + parent = parent.parent()[0]; + } + + // no parent node: no nodes to add to the drag layer + if( parent == node ){ + return; + } + + var nodes = parent.descendants() + .merge( parent ) + .unmerge( node ) + .unmerge( node.descendants() ) + ; + + var edges = nodes.connectedEdges(); + + var listHasId = getDragListIds( opts ); + + for( var i = 0; i < nodes.size(); i++ ){ + if( opts.inDragLayer !== undefined ){ + nodes[i]._private.rscratch.inDragLayer = opts.inDragLayer; + } + + if( opts.addToList && !listHasId[ nodes[i].id() ] ){ + opts.addToList.push( nodes[i] ); + listHasId[ nodes[i].id() ] = true; + + nodes[i]._private.grabbed = true; + } + } + + for( var j = 0; opts.inDragLayer !== undefined && j < edges.length; j++ ) { + edges[j]._private.rscratch.inDragLayer = opts.inDragLayer; + } + }; + + if( typeof MutationObserver !== 'undefined' ){ + r.removeObserver = new MutationObserver(function( mutns ){ + 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){ + r.destroy(); + }); + } + + + + // auto resize + r.registerBinding(window, 'resize', util.debounce( function(e) { + r.invalidateContainerClientCoordsCache(); + + r.matchCanvasSize(r.container); + r.redrawHint('eles', true); + r.redraw(); + }, 100 ) ); + + var invalCtnrBBOnScroll = function(domEle){ + r.registerBinding(domEle, 'scroll', function(e){ + r.invalidateContainerClientCoordsCache(); + } ); + }; + + var bbCtnr = r.cy.container(); + + for( ;; ){ + + invalCtnrBBOnScroll( bbCtnr ); + + if( bbCtnr.parentNode ){ + bbCtnr = bbCtnr.parentNode; + } else { + break; + } + + } + + // stop right click menu from appearing on cy + r.registerBinding(r.container, 'contextmenu', function(e){ + e.preventDefault(); + }); + + var inBoxSelection = function(){ + return r.selection[4] !== 0; + }; + + // Primary key + r.registerBinding(r.container, 'mousedown', function(e) { + e.preventDefault(); + r.hoverData.capture = true; + r.hoverData.which = e.which; + + 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; + + r.hoverData.mdownPos = pos; + + var checkForTaphold = function(){ + 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.trigger( Event(e, { + type: 'taphold', + cyPosition: { x: pos[0], y: pos[1] } + }) ); + } else { + cy.trigger( Event(e, { + type: 'taphold', + cyPosition: { x: pos[0], y: pos[1] } + }) ); + } + } + + }, r.tapholdDuration); + }; + + // Right click button + if( e.which == 3 ){ + + r.hoverData.cxtStarted = true; + + var cxtEvt = Event(e, { + type: 'cxttapstart', + cyPosition: { x: pos[0], y: pos[1] } + }); + + if( near ){ + near.activate(); + near.trigger( cxtEvt ); + + r.hoverData.down = near; + } else { + cy.trigger( 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.nodeIsDraggable(near) ){ + + var grabEvent = Event(e, { + type: 'grab', + cyPosition: { x: pos[0], y: pos[1] } + }); + + if ( near.isNode() && !near.selected() ){ + + draggedElements = r.dragData.possibleDragElements = []; + addNodeToDrag( near, { addToList: draggedElements } ); + + near.trigger(grabEvent); + + } else if ( near.isNode() && near.selected() ){ + draggedElements = r.dragData.possibleDragElements = [ ]; + + var selectedNodes = cy.$(function(){ return this.isNode() && this.selected(); }); + + for( var i = 0; i < selectedNodes.length; i++ ){ + + // Only add this selected node to drag if it is draggable, eg. has nonzero opacity + if( r.nodeIsDraggable( selectedNodes[i] ) ){ + addNodeToDrag( selectedNodes[i], { addToList: draggedElements } ); + } + } + + near.trigger( grabEvent ); + } + + r.redrawHint('eles', true); + r.redrawHint('drag', true); + + } + + } + + r.hoverData.down = near; + r.hoverData.downTime = (new Date()).getTime(); + } + + triggerEvents( near, ['mousedown', 'tapstart', 'vmousedown'], e, { + cyPosition: { 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.isEdge() ){ + 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(window, 'mousemove', function(e) { + var preventDefault = false; + var capture = r.hoverData.capture; + + // save cycles if mouse events aren't to be captured + if ( !capture ){ + var containerPageCoords = r.findContainerClientCoords(); + + if (e.clientX > containerPageCoords[0] && e.clientX < containerPageCoords[0] + r.canvasWidth + && e.clientY > containerPageCoords[1] && e.clientY < containerPageCoords[1] + r.canvasHeight + ) { + // inside container bounds so OK + } else { + return; + } + + var cyContainer = r.container; + var target = e.target; + var tParent = target.parentNode; + var containerIsTarget = false; + + while( tParent ){ + if( tParent === cyContainer ){ + containerIsTarget = true; + break; + } + + tParent = tParent.parentNode; + } + + if( !containerIsTarget ){ return; } // if target is outisde cy container, then this event is not for us + } + + var cy = r.cy; + var zoom = cy.zoom(); + var pos = r.projectIntoViewport(e.clientX, e.clientY); + var select = r.selection; + + var near = null; + if( !r.hoverData.draggingEles ){ + 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 dx = select[2] - select[0]; + var dx2 = dx * dx; + var dy = select[3] - select[1]; + var dy2 = dy * dy; + var dist2 = dx2 + dy2; + var rdist2 = dist2 * zoom * zoom; + + var multSelKeyDown = isMultSelKeyDown( e ); + + r.hoverData.tapholdCancelled = true; + + var updateDragDelta = function(){ + 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, { + cyPosition: { x: pos[0], y: pos[1] } + } ); + + // trigger context drag if rmouse down + if( r.hoverData.which === 3 ){ + var cxtEvt = Event(e, { + type: 'cxtdrag', + cyPosition: { x: pos[0], y: pos[1] } + }); + + if( down ){ + down.trigger( cxtEvt ); + } else { + cy.trigger( cxtEvt ); + } + + r.hoverData.cxtDragged = true; + + if( !r.hoverData.cxtOver || near !== r.hoverData.cxtOver ){ + + if( r.hoverData.cxtOver ){ + r.hoverData.cxtOver.trigger( Event(e, { + type: 'cxtdragout', + cyPosition: { x: pos[0], y: pos[1] } + }) ); + } + + r.hoverData.cxtOver = near; + + if( near ){ + near.trigger( Event(e, { + type: 'cxtdragover', + cyPosition: { 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 ); + + 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.isEdge()) + ){ + + if( !r.hoverData.dragging && cy.boxSelectionEnabled() && ( multSelKeyDown || !cy.panningEnabled() || !cy.userPanningEnabled() ) ){ + r.data.bgActivePosistion = undefined; + r.hoverData.selecting = true; + + r.redrawHint('select', true); + r.redraw(); + + } else if( !r.hoverData.selecting && cy.panningEnabled() && cy.userPanningEnabled() ){ + r.hoverData.dragging = true; + r.hoverData.justStartedPan = true; + select[4] = 0; + + r.data.bgActivePosistion = { + x: pos[0], + y: pos[1] + }; + + r.redrawHint('select', true); + r.redraw(); + } + + if( down && down.isEdge() && down.active() ){ down.unactivate(); } + + } else { + if( down && down.isEdge() && down.active() ){ down.unactivate(); } + + if (near != last) { + + if (last) { + triggerEvents( last, ['mouseout', 'tapdragout'], e, { + cyPosition: { x: pos[0], y: pos[1] } + } ); + } + + if (near) { + triggerEvents( near, ['mouseover', 'tapdragover'], e, { + cyPosition: { x: pos[0], y: pos[1] } + } ); + } + + r.hoverData.last = near; + } + + if( down && down.isNode() && r.nodeIsDraggable(down) ){ + + if( rdist2 >= r.desktopTapThreshold2 ){ // then drag + + var justStartedDrag = !r.dragData.didDrag; + + if( justStartedDrag ) { + r.redrawHint('eles', true); + } + + r.dragData.didDrag = true; // indicate that we actually did drag the node + + var toTrigger = []; + + for( var i = 0; i < draggedElements.length; i++ ){ + var dEle = draggedElements[i]; + + // now, add the elements to the drag layer if not done already + if( !r.hoverData.draggingEles ){ + addNodeToDrag( dEle, { inDragLayer: true } ); + } + + // Locked nodes not draggable, as well as non-visible nodes + if( dEle.isNode() && r.nodeIsDraggable(dEle) && dEle.grabbed() ){ + var dPos = dEle._private.position; + + toTrigger.push( dEle ); + + if( is.number(disp[0]) && is.number(disp[1]) ){ + var updatePos = !dEle.isParent(); + + if( updatePos ){ + dPos.x += disp[0]; + dPos.y += disp[1]; + } + + if( justStartedDrag ){ + var dragDelta = r.hoverData.dragDelta; + + if( updatePos && is.number(dragDelta[0]) && is.number(dragDelta[1]) ){ + dPos.x += dragDelta[0]; + dPos.y += dragDelta[1]; + } + } + } + + } + } + + r.hoverData.draggingEles = true; + + var tcol = (Collection(cy, toTrigger)); + + tcol.updateCompoundBounds(); + tcol.trigger('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); + + r.registerBinding(window, 'mouseup', function(e) { + 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 = Event(e, { + type: 'cxttapend', + cyPosition: { x: pos[0], y: pos[1] } + }); + + if( down ){ + down.trigger( cxtEvt ); + } else { + cy.trigger( cxtEvt ); + } + + if( !r.hoverData.cxtDragged ){ + var cxtTap = Event(e, { + type: 'cxttap', + cyPosition: { x: pos[0], y: pos[1] } + }); + + if( down ){ + down.trigger( cxtTap ); + } else { + cy.trigger( cxtTap ); + } + } + + r.hoverData.cxtDragged = false; + r.hoverData.which = null; + + } else if( r.hoverData.which === 1 ) { + + // 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.$(function(){ + return this.selected(); + }).unselect(); + + if (draggedElements.length > 0) { + r.redrawHint('eles', true); + } + + r.dragData.possibleDragElements = draggedElements = []; + } + + triggerEvents( near, ['mouseup', 'tapend', 'vmouseup'], e, { + cyPosition: { x: pos[0], y: pos[1] } + } ); + + if( + !r.dragData.didDrag // didn't move a node around + && !r.hoverData.dragged // didn't pan + ){ + triggerEvents( near, ['click', 'tap', 'vclick'], e, { + cyPosition: { x: pos[0], y: pos[1] } + } ); + } + + // Single selection + if( near == down && !r.dragData.didDrag && !r.hoverData.selecting ){ + if( near != null && near._private.selectable ){ + + if( r.hoverData.dragging ){ + // if panning, don't change selection state + } else if( cy.selectionType() === 'additive' || multSelKeyDown ){ + if( near.selected() ){ + near.unselect(); + } else { + near.select(); + } + } else { + if( !multSelKeyDown ){ + cy.$(':selected').unmerge( near ).unselect(); + near.select(); + } + } + + r.redrawHint('eles', true); + } + } + + if ( r.hoverData.selecting ) { + var newlySelected = []; + var box = r.getAllInBox( select[0], select[1], select[2], select[3] ); + + r.redrawHint('select', true); + + if( box.length > 0 ) { + r.redrawHint('eles', true); + } + + for( var i = 0; i < box.length; i++ ){ + if( box[i]._private.selectable ){ + newlySelected.push( box[i] ); + } + } + + var newlySelCol = Collection( cy, newlySelected ); + + if( cy.selectionType() === 'additive' ){ + newlySelCol.select(); + } else { + if( !multSelKeyDown ){ + cy.$(':selected').unmerge( newlySelCol ).unselect(); + } + + newlySelCol.select(); + } + + // 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); + + freeDraggedElements( draggedElements ); + + if( down ){ down.trigger('free'); } + } + + } // else not right mouse + + select[4] = 0; r.hoverData.down = null; + + r.hoverData.cxtStarted = false; + r.hoverData.draggingEles = false; + r.hoverData.selecting = false; + r.dragData.didDrag = false; + r.hoverData.dragged = false; + r.hoverData.dragDelta = []; + + }, false); + + var wheelHandler = function(e) { + + + if( r.scrollingPage ){ return; } // while scrolling, ignore wheel-to-zoom + + var cy = r.cy; + var pos = r.projectIntoViewport(e.clientX, e.clientY); + var rpos = [pos[0] * cy.zoom() + cy.pan().x, + pos[1] * cy.zoom() + cy.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 = e.deltaY / -250 || e.wheelDeltaY / 1000 || 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; + } + + cy.zoom({ + level: cy.zoom() * Math.pow(10, diff), + renderedPosition: { x: rpos[0], y: rpos[1] } + }); + } + + }; + + // 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(window, 'scroll', function(e){ + r.scrollingPage = true; + + clearTimeout( r.scrollingPageTimeout ); + r.scrollingPageTimeout = setTimeout(function(){ + r.scrollingPage = false; + }, 250); + }, true); + + // Functions to help with handling mouseout/mouseover on the Cytoscape container + // Handle mouseout on Cytoscape container + r.registerBinding(r.container, 'mouseout', function(e) { + var pos = r.projectIntoViewport(e.clientX, e.clientY); + + r.cy.trigger(Event(e, { + type: 'mouseout', + cyPosition: { x: pos[0], y: pos[1] } + })); + }, false); + + r.registerBinding(r.container, 'mouseover', function(e) { + var pos = r.projectIntoViewport(e.clientX, e.clientY); + + r.cy.trigger(Event(e, { + type: 'mouseover', + cyPosition: { 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(x1, y1, x2, y2){ + return Math.sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) ); + }; + + var distanceSq = function(x1, y1, x2, y2){ + return (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1); + }; + + var touchstartHandler; + r.registerBinding(r.container, 'touchstart', touchstartHandler = function(e) { + r.touchData.capture = true; + r.data.bgActivePosistion = undefined; + + var cy = r.cy; + var nodes = r.getCachedNodes(); + var edges = r.getCachedEdges(); + 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] ){ + + // anything in the set of dragged eles should be released + var release = function( eles ){ + for( var i = 0; i < eles.length; i++ ){ + eles[i]._private.grabbed = false; + eles[i]._private.rscratch.inDragLayer = false; + if( eles[i].active() ){ eles[i].unactivate(); } + } + }; + release(nodes); + release(edges); + + 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().trigger( Event(e, { + type: 'cxttapstart', + cyPosition: { x: now[0], y: now[1] } + }) ); + r.touchData.start = near1; + + } else if( near2 && near2.isNode() ){ + near2.activate().trigger( Event(e, { + type: 'cxttapstart', + cyPosition: { x: now[0], y: now[1] } + }) ); + r.touchData.start = near2; + + } else { + cy.trigger( Event(e, { + type: 'cxttapstart', + cyPosition: { x: now[0], y: now[1] } + }) ); + r.touchData.start = null; + } + + 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]) { + + } else if (e.touches[1]) { + + } else if (e.touches[0]) { + var near = r.findNearestElement(now[0], now[1], true, true); + + if (near != null) { + near.activate(); + + r.touchData.start = near; + + if( near.isNode() && r.nodeIsDraggable(near) ){ + + var draggedEles = r.dragData.touchDragEles = []; + + r.redrawHint('eles', true); + r.redrawHint('drag', true); + + if( near.selected() ){ + // reset drag elements, since near will be added again + + var selectedNodes = cy.$(function(){ + return this.isNode() && this.selected(); + }); + + for( var k = 0; k < selectedNodes.length; k++ ){ + var selectedNode = selectedNodes[k]; + + if( r.nodeIsDraggable(selectedNode) ){ + addNodeToDrag( selectedNode, { addToList: draggedEles } ); + } + } + } else { + addNodeToDrag( near, { addToList: draggedEles } ); + } + + near.trigger( Event(e, { + type: 'grab', + cyPosition: { x: now[0], y: now[1] } + }) ); + } + } + + triggerEvents( near, ['touchstart', 'tapstart', 'vmousedown'], e, { + cyPosition: { 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 + // ----- + + for (var i=0; i= factorThresholdSq || distance2Sq >= distThresholdSq ){ + r.touchData.cxt = false; + if( r.touchData.start ){ r.touchData.start.unactivate(); r.touchData.start = null; } + r.data.bgActivePosistion = undefined; + r.redrawHint('select', true); + + var cxtEvt = Event(e, { + type: 'cxttapend', + cyPosition: { x: now[0], y: now[1] } + }); + if( r.touchData.start ){ + r.touchData.start.trigger( cxtEvt ); + } else { + cy.trigger( cxtEvt ); + } + } + + } + + // context swipe + if( capture && r.touchData.cxt ){ + var cxtEvt = Event(e, { + type: 'cxtdrag', + cyPosition: { x: now[0], y: now[1] } + }); + r.data.bgActivePosistion = undefined; + r.redrawHint('select', true); + + if( r.touchData.start ){ + r.touchData.start.trigger( cxtEvt ); + } else { + cy.trigger( 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.trigger( Event(e, { + type: 'cxtdragout', + cyPosition: { x: now[0], y: now[1] } + }) ); + } + + r.touchData.cxtOver = near; + + if( near ){ + near.trigger( Event(e, { + type: 'cxtdragover', + cyPosition: { 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(); + r.touchData.selecting = true; + + r.redrawHint('select', true); + + 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; + } + + select[4] = 1; + r.touchData.selecting = true; + + r.redraw(); + + // pinch to zoom + } else if ( capture && e.touches[1] && 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++ ){ + draggedEles[i]._private.grabbed = false; + draggedEles[i]._private.rscratch.inDragLayer = false; + } + } + + // (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( factor != 1 && 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; + + // adjust factor by the speed multiplier + // var speed = 1.5; + // if( factor > 1 ){ + // factor = (factor - 1) * speed + 1; + // } else { + // factor = 1 - (1 - factor) * speed; + // } + + // 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( r.touchData.start ){ + var draggedEles = r.dragData.touchDragEles; + + if( draggedEles ){ for( var i = 0; i < draggedEles.length; i++ ){ + var dEi_p = draggedEles[i]._private; + + dEi_p.grabbed = false; + dEi_p.rscratch.inDragLayer = false; + } } + + var start_p = r.touchData.start._private; + start_p.active = false; + start_p.grabbed = false; + start_p.rscratch.inDragLayer = false; + + r.redrawHint('drag', true); + + r.touchData.start + .trigger('free') + .trigger('unactivate') + ; + } + + cy.viewport({ + zoom: zoom2, + pan: pan2, + cancelOnFailedZoom: true + }); + + 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]) { + var start = r.touchData.start; + var last = r.touchData.last; + var near = near || r.findNearestElement(now[0], now[1], true, true); + + if( start != null ){ + e.preventDefault(); + } + + // dragging nodes + if( start != null && start._private.group == 'nodes' && r.nodeIsDraggable(start) ){ + + if( rdist2 >= r.touchTapThreshold2 ){ // then dragging can happen + var draggedEles = r.dragData.touchDragEles; + var justStartedDrag = !r.dragData.didDrag; + + for( var k = 0; k < draggedEles.length; k++ ){ + var draggedEle = draggedEles[k]; + + if( justStartedDrag ){ + addNodeToDrag( draggedEle, { inDragLayer: true } ); + } + + if( r.nodeIsDraggable(draggedEle) && draggedEle.isNode() && draggedEle.grabbed() ){ + r.dragData.didDrag = true; + var dPos = draggedEle._private.position; + var updatePos = !draggedEle.isParent(); + + if( updatePos && is.number(disp[0]) && is.number(disp[1]) ){ + dPos.x += disp[0]; + dPos.y += disp[1]; + } + + if( justStartedDrag ){ + r.redrawHint('eles', true); + + var dragDelta = r.touchData.dragDelta; + + if( updatePos && is.number(dragDelta[0]) && is.number(dragDelta[1]) ){ + dPos.x += dragDelta[0]; + dPos.y += dragDelta[1]; + } + + } + } + } + + var tcol = Collection(cy, draggedEles); + + tcol.updateCompoundBounds(); + tcol.trigger('position drag'); + + r.hoverData.draggingEles = true; + + r.redrawHint('drag', true); + + if( + r.touchData.startPosition[0] == earlier[0] + && r.touchData.startPosition[1] == earlier[1] + ){ + + r.redrawHint('eles', true); + } + + r.redraw(); + } else { // otherise 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, { + cyPosition: { x: now[0], y: now[1] } + } ); + + if (near != last) { + if (last) { last.trigger(Event(e, { type: 'tapdragout', cyPosition: { x: now[0], y: now[1] } })); } + if (near) { near.trigger(Event(e, { type: 'tapdragover', cyPosition: { x: now[0], y: now[1] } })); } + } + + r.touchData.last = near; + } + + // check to cancel taphold + for (var i=0;i r.touchTapThreshold2 ){ + + r.touchData.singleTouchMoved = true; + } + } + + // panning + if( + capture + && ( start == null || start.isEdge() ) + && cy.panningEnabled() && cy.userPanningEnabled() + ){ + + e.preventDefault(); + + if( r.swipePanning ){ + cy.panBy({ + x: disp[0] * zoom, + y: disp[1] * zoom + }); + + } else if( rdist2 >= r.touchTapThreshold2 ){ + r.swipePanning = true; + + cy.panBy({ + x: dx * zoom, + y: dy * zoom + }); + + if( start ){ + start.unactivate(); + + if( !r.data.bgActivePosistion ){ + r.data.bgActivePosistion = { + x: now[0], + y: now[1] + }; + } + + 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 0 ) { + r.redrawHint('eles', true); + } else { + r.redraw(); + } + } + + var updateStartStyle = false; + + if( start != null ){ + start._private.active = false; + updateStartStyle = true; + start.unactivate(); + } + + if (e.touches[2]) { + r.data.bgActivePosistion = undefined; + r.redrawHint('select', true); + } else if (e.touches[1]) { + + } else if (e.touches[0]) { + + // Last touch released + } 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.trigger('free'); + } + + triggerEvents( start, ['touchend', 'tapend', 'vmouseup'], e, { + cyPosition: { 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'], e, { + cyPosition: { 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; + + // 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.$(':selected').unmerge( start ).unselect(); + start.select(); + } else { + if( start.selected() ){ + start.unselect(); + } else { + start.select(); + } + } + + updateStartStyle = true; + + + r.redrawHint('eles', true); + } + + // Tap event, roughly same as mouse click event for touch + if( !r.touchData.singleTouchMoved ){ + triggerEvents( start, ['tap', 'vclick'], e, { + cyPosition: { x: now[0], y: now[1] } + } ); + } + + r.touchData.singleTouchMoved = true; + } + + for( var j = 0; j < now.length; j++ ){ earlier[j] = now[j]; } + + r.dragData.didDrag = false; // reset for next mousedown + + if( e.touches.length === 0 ){ + r.touchData.dragDelta = []; + } + + if( updateStartStyle && start ){ + start.updateStyle(false); + } + + if( e.touches.length < 2 ){ + 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( 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( e ){ + return { + event: e, + touch: makeTouch(e) + }; + }; + + var addPointer = function( e ){ + pointers.push( makePointer(e) ); + }; + + var removePointer = function( 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( e ){ + var p = pointers.filter(function( p ){ + return p.event.pointerId === e.pointerId; + })[0]; + + p.event = e; + p.touch = makeTouch(e); + }; + + var addTouchesToEvent = function( e ){ + e.touches = pointers.map(function( p ){ + return p.touch; + }); + }; + + var pointerIsMouse = function( 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 ); + }); + + } +}; + +module.exports = BRp; + +},{"../../../collection":23,"../../../event":42,"../../../is":77,"../../../util":94}],60:[function(_dereq_,module,exports){ +'use strict'; + +var math = _dereq_('../../../math'); + +var BRp = {}; + +BRp.registerNodeShapes = function(){ + var nodeShapes = this.nodeShapes = {}; + var renderer = this; + + nodeShapes['ellipse'] = { + name: 'ellipse', + + draw: function( context, centerX, centerY, width, height ){ + renderer.nodeShapeImpl( this.name )( context, centerX, centerY, width, height ); + }, + + intersectLine: function( nodeX, nodeY, width, height, x, y, padding ){ + return math.intersectLineEllipse( + x, y, + nodeX, + nodeY, + width / 2 + padding, + height / 2 + padding) + ; + }, + + checkPoint: function( x, y, padding, width, height, centerX, centerY ){ + x -= centerX; + y -= centerY; + + x /= (width / 2 + padding); + y /= (height / 2 + padding); + + return x*x + y*y <= 1; + } + }; + + function generatePolygon( name, points ){ + return ( nodeShapes[name] = { + name: name, + + points: points, + + draw: function( context, centerX, centerY, width, height ){ + renderer.nodeShapeImpl('polygon')( context, centerX, centerY, width, height, this.points ); + }, + + intersectLine: function( nodeX, nodeY, width, height, x, y, padding ){ + return math.polygonIntersectLine( + x, y, + this.points, + nodeX, + nodeY, + width / 2, height / 2, + padding) + ; + }, + + checkPoint: function( x, y, padding, width, height, centerX, centerY ){ + return math.pointInsidePolygon(x, y, nodeShapes[name].points, + centerX, centerY, width, height, [0, -1], padding) + ; + } + } ); + } + + generatePolygon( 'triangle', math.generateUnitNgonPointsFitToSquare(3, 0) ); + + generatePolygon( 'square', math.generateUnitNgonPointsFitToSquare(4, 0) ); + nodeShapes['rectangle'] = nodeShapes['square']; + + nodeShapes['roundrectangle'] = { + name: 'roundrectangle', + + points: math.generateUnitNgonPointsFitToSquare(4, 0), + + draw: function( context, centerX, centerY, width, height ){ + renderer.nodeShapeImpl( this.name )( context, centerX, centerY, width, height ); + }, + + intersectLine: function( nodeX, nodeY, width, height, x, y, padding ){ + return math.roundRectangleIntersectLine( + x, y, + nodeX, + nodeY, + width, height, + padding) + ; + }, + + // Looks like the width passed into this function is actually the total width / 2 + checkPoint: function( + x, y, padding, width, height, centerX, centerY ){ + + var cornerRadius = math.getRoundRectangleRadius(width, height); + + // Check hBox + if (math.pointInsidePolygon(x, y, this.points, + centerX, centerY, width, height - 2 * cornerRadius, [0, -1], padding) ){ + return true; + } + + // Check vBox + if (math.pointInsidePolygon(x, y, this.points, + centerX, centerY, width - 2 * cornerRadius, height, [0, -1], padding) ){ + return true; + } + + var checkInEllipse = function( x, y, centerX, centerY, width, height, padding ){ + x -= centerX; + y -= centerY; + + x /= (width / 2 + padding); + y /= (height / 2 + padding); + + return (x*x + y*y <= 1); + }; + + + // Check top left quarter circle + if (checkInEllipse(x, y, + centerX - width / 2 + cornerRadius, + centerY - height / 2 + cornerRadius, + cornerRadius * 2, cornerRadius * 2, padding) ){ + + return true; + } + + // Check top right quarter circle + if (checkInEllipse(x, y, + centerX + width / 2 - cornerRadius, + centerY - height / 2 + cornerRadius, + cornerRadius * 2, cornerRadius * 2, padding) ){ + + return true; + } + + // Check bottom right quarter circle + if (checkInEllipse(x, y, + centerX + width / 2 - cornerRadius, + centerY + height / 2 - cornerRadius, + cornerRadius * 2, cornerRadius * 2, padding) ){ + + return true; + } + + // Check bottom left quarter circle + if (checkInEllipse(x, y, + centerX - width / 2 + cornerRadius, + centerY + height / 2 - cornerRadius, + cornerRadius * 2, cornerRadius * 2, padding) ){ + + return true; + } + + return false; + } + }; + + generatePolygon( 'diamond', [ + 0, 1, + 1, 0, + 0, -1, + -1, 0 + ] ); + + generatePolygon( 'pentagon', math.generateUnitNgonPointsFitToSquare(5, 0) ); + + generatePolygon( 'hexagon', math.generateUnitNgonPointsFitToSquare(6, 0) ); + + generatePolygon( 'heptagon', math.generateUnitNgonPointsFitToSquare(7, 0) ); + + generatePolygon( 'octagon', math.generateUnitNgonPointsFitToSquare(8, 0) ); + + var star5Points = new Array(20); + { + var outerPoints = math.generateUnitNgonPoints(5, 0); + var innerPoints = math.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 redrawLimit ? minRedrawLimit : redrawLimit; + redrawLimit = redrawLimit < maxRedrawLimit ? redrawLimit : maxRedrawLimit; + + if( r.lastDrawTime === undefined ){ r.lastDrawTime = 0; } + + var nowTime = Date.now(); + var timeElapsed = nowTime - r.lastDrawTime; + var callAfterLimit = timeElapsed >= redrawLimit; + + if( !forcedContext ){ + if( !callAfterLimit || r.currentlyDrawing ){ + r.skipFrame = true; + return; + } + } + + r.requestedFrame = true; + r.currentlyDrawing = true; + r.renderOptions = options; +}; + +BRp.startRenderLoop = function(){ + var r = this; + + var renderFn = function(){ + if( r.destroyed ){ return; } + + if( r.requestedFrame && !r.skipFrame ){ + var startTime = util.performanceNow(); + + r.render( r.renderOptions ); + + var endTime = r.lastRedrawTime = util.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; + } + + r.skipFrame = false; + + util.requestAnimationFrame( renderFn ); + }; + + util.requestAnimationFrame( renderFn ); + +}; + +module.exports = BRp; + +},{"../../../util":94}],62:[function(_dereq_,module,exports){ +'use strict'; + +var CRp = {}; + +var impl; + +CRp.arrowShapeImpl = function( name ){ + return ( impl || (impl = { + 'polygon': function( context, points ){ + for( var i = 0; i < points.length; i++ ){ + var pt = points[i]; + + context.lineTo( pt.x, pt.y ); + } + }, + + 'triangle-backcurve': function( 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 ); + }, + + 'triangle-tee': function( context, trianglePoints, teePoints ){ + 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 = 0; i < teePts.length; i++ ){ + var pt = teePts[i]; + + context.lineTo( pt.x, pt.y ); + } + }, + + 'circle': function( context, rx, ry, r ){ + context.arc(rx, ry, r, 0, Math.PI * 2, false); + } + }) )[ name ]; +}; + +module.exports = CRp; + +},{}],63:[function(_dereq_,module,exports){ +'use strict'; + +var CRp = {}; + +CRp.drawEdge = function(context, edge, drawOverlayInstead) { + var rs = edge._private.rscratch; + var usePaths = this.usePaths(); + + // if bezier ctrl pts can not be calculated, then die + if( rs.badBezier || rs.badLine || isNaN( rs.allpts[0] ) ){ // iNaN in case edge is impossible and browser bugs (e.g. safari) + return; + } + + var style = edge._private.style; + + // Edge line width + if (style['width'].pfValue <= 0) { + return; + } + + var overlayPadding = style['overlay-padding'].pfValue; + var overlayOpacity = style['overlay-opacity'].value; + var overlayColor = style['overlay-color'].value; + + // Edge color & opacity + if( drawOverlayInstead ){ + + if( overlayOpacity === 0 ){ // exit early if no overlay + return; + } + + this.strokeStyle(context, overlayColor[0], overlayColor[1], overlayColor[2], overlayOpacity); + context.lineCap = 'round'; + + if( rs.edgeType == 'self' && !usePaths ){ + context.lineCap = 'butt'; + } + + } else { + var lineColor = style['line-color'].value; + + this.strokeStyle(context, lineColor[0], lineColor[1], lineColor[2], style.opacity.value); + + context.lineCap = 'butt'; + } + + var edgeWidth = style['width'].pfValue + (drawOverlayInstead ? 2 * overlayPadding : 0); + var lineStyle = drawOverlayInstead ? 'solid' : style['line-style'].value; + context.lineWidth = edgeWidth; + + var shadowBlur = style['shadow-blur'].pfValue; + var shadowOpacity = style['shadow-opacity'].value; + var shadowColor = style['shadow-color'].value; + var shadowOffsetX = style['shadow-offset-x'].pfValue; + var shadowOffsetY = style['shadow-offset-y'].pfValue; + + this.shadowStyle(context, shadowColor, drawOverlayInstead ? 0 : shadowOpacity, shadowBlur, shadowOffsetX, shadowOffsetY); + + this.drawEdgePath( + edge, + context, + rs.allpts, + lineStyle, + edgeWidth + ); + + this.drawArrowheads(context, edge, drawOverlayInstead); + + this.shadowStyle(context, 'transparent', 0); // reset for next guy + +}; + + +CRp.drawEdgePath = function(edge, context, pts, type, width) { + var rs = edge._private.rscratch; + var canvasCxt = context; + var path; + var pathCacheHit = false; + var usePaths = this.usePaths(); + + 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([ 6, 3 ]); + break; + + case 'solid': + canvasCxt.setLineDash([ ]); + break; + } + } + + if( !pathCacheHit ){ + if( context.beginPath ){ context.beginPath(); } + context.moveTo( pts[0], pts[1] ); + + switch( rs.edgeType ){ + case 'bezier': + case 'self': + case 'compound': + case 'multibezier': + if( !rs.badBezier ){ + 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': + if( !rs.badLine ){ + 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.drawArrowheads = function(context, edge, drawOverlayInstead) { + if( drawOverlayInstead ){ return; } // don't do anything for overlays + + var rs = edge._private.rscratch; + var isHaystack = rs.edgeType === 'haystack'; + + if( !isHaystack ){ + this.drawArrowhead( context, edge, 'source', rs.arrowStartX, rs.arrowStartY, rs.srcArrowAngle ); + } + + this.drawArrowhead( context, edge, 'mid-target', rs.midX, rs.midY, rs.midtgtArrowAngle ); + + this.drawArrowhead( context, edge, 'mid-source', rs.midX, rs.midY, rs.midsrcArrowAngle ); + + if( !isHaystack ){ + this.drawArrowhead( context, edge, 'target', rs.arrowEndX, rs.arrowEndY, rs.tgtArrowAngle ); + } +}; + +CRp.drawArrowhead = function( context, edge, prefix, x, y, angle ){ + if( isNaN(x) || x == null || isNaN(y) || y == null || isNaN(angle) || angle == null ){ return; } + + var self = this; + var style = edge._private.style; + var arrowShape = style[prefix + '-arrow-shape'].value; + + if( arrowShape === 'none' ){ + return; + } + + var gco = context.globalCompositeOperation; + + var arrowClearFill = style[prefix + '-arrow-fill'].value === 'hollow' ? 'both' : 'filled'; + var arrowFill = style[prefix + '-arrow-fill'].value; + + if( arrowShape === 'half-triangle-overshot' ){ + arrowFill = 'hollow'; + arrowClearFill = 'hollow'; + } + + if( style.opacity.value !== 1 || arrowFill === 'hollow' ){ // then extra clear is needed + context.globalCompositeOperation = 'destination-out'; + + self.fillStyle(context, 255, 255, 255, 1); + self.strokeStyle(context, 255, 255, 255, 1); + + self.drawArrowShape( edge, prefix, context, + arrowClearFill, style['width'].pfValue, style[prefix + '-arrow-shape'].value, + x, y, angle + ); + + context.globalCompositeOperation = gco; + } // otherwise, the opaque arrow clears it for free :) + + var color = style[prefix + '-arrow-color'].value; + self.fillStyle(context, color[0], color[1], color[2], style.opacity.value); + self.strokeStyle(context, color[0], color[1], color[2], style.opacity.value); + + self.drawArrowShape( edge, prefix, context, + arrowFill, style['width'].pfValue, style[prefix + '-arrow-shape'].value, + x, y, angle + ); +}; + +CRp.drawArrowShape = function(edge, arrowType, context, fill, edgeWidth, shape, x, y, angle) { + var r = this; + var usePaths = this.usePaths(); + var rs = edge._private.rscratch; + var pathCacheHit = false; + var path; + var canvasContext = context; + var translation = { x: x, y: y }; + var size = this.getArrowWidth( edgeWidth ); + var shapeImpl = r.arrowShapes[shape]; + + if( usePaths ){ + var pathCacheKey = size + '$' + shape + '$' + angle + '$' + x + '$' + y; + rs.arrowPathCacheKey = rs.arrowPathCacheKey || {}; + rs.arrowPathCache = rs.arrowPathCache || {}; + + var alreadyCached = rs.arrowPathCacheKey[arrowType] === pathCacheKey; + if( alreadyCached ){ + path = context = rs.arrowPathCache[arrowType]; + pathCacheHit = true; + } else { + path = context = new Path2D(); + rs.arrowPathCacheKey[arrowType] = pathCacheKey; + rs.arrowPathCache[arrowType] = path; + } + } + + if( context.beginPath ){ context.beginPath(); } + + if( !pathCacheHit ){ + shapeImpl.draw(context, size, angle, translation); + } + + if( !shapeImpl.leavePathOpen && context.closePath ){ + context.closePath(); + } + + context = canvasContext; + + if( fill === 'filled' || fill === 'both' ){ + if( usePaths ){ + context.fill( path ); + } else { + context.fill(); + } + } + + if( fill === 'hollow' || fill === 'both' ){ + context.lineWidth = ( shapeImpl.matchEdgeWidth ? edgeWidth : 1 ); + context.lineJoin = 'miter'; + + if( usePaths ){ + context.stroke( path ); + } else { + context.stroke(); + } + + } +}; + +module.exports = CRp; + +},{}],64:[function(_dereq_,module,exports){ +'use strict'; + +var CRp = {}; + +CRp.safeDrawImage = function( context, img, ix, iy, iw, ih, x, y, w, h ){ + var r = this; + + try { + context.drawImage( img, ix, iy, iw, ih, x, y, w, h ); + } catch(e){ + r.data.canvasNeedsRedraw[r.NODE] = true; + r.data.canvasNeedsRedraw[r.DRAG] = true; + + r.drawingImage = true; + + r.redraw(); + } +}; + +CRp.drawInscribedImage = function(context, img, node) { + var r = this; + var nodeX = node._private.position.x; + var nodeY = node._private.position.y; + var style = node._private.style; + var fit = style['background-fit'].value; + var xPos = style['background-position-x']; + var yPos = style['background-position-y']; + var repeat = style['background-repeat'].value; + var nodeW = node.width(); + var nodeH = node.height(); + var rs = node._private.rscratch; + var clip = style['background-clip'].value; + var shouldClip = clip === 'node'; + var imgOpacity = style['background-image-opacity'].value; + + 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 ); + + imgW = img.cachedW = img.width || img.offsetWidth; + imgH = img.cachedH = img.height || img.offsetHeight; + + document.body.removeChild( img ); + } + + var w = imgW; + var h = imgH; + + var bgW = style['background-width']; + if( bgW.value !== 'auto' ){ + if( bgW.units === '%' ){ + w = bgW.value/100 * nodeW; + } else { + w = bgW.pfValue; + } + } + + var bgH = style['background-height']; + if( bgH.value !== 'auto' ){ + if( bgH.units === '%' ){ + h = bgH.value/100 * nodeH; + } else { + h = bgH.pfValue; + } + } + + 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( nodeW/w, nodeH/h ); + + w *= scale; + h *= scale; + + } else if( fit === 'cover' ){ + var scale = Math.max( nodeW/w, nodeH/h ); + + w *= scale; + h *= scale; + } + + var x = (nodeX - nodeW/2); // left + if( xPos.units === '%' ){ + x += (nodeW - w) * xPos.value/100; + } else { + x += xPos.pfValue; + } + + var y = (nodeY - nodeH/2); // top + if( yPos.units === '%' ){ + y += (nodeH - h) * yPos.value/100; + } else { + y += yPos.pfValue; + } + + if( rs.pathCache ){ + x -= nodeX; + y -= nodeY; + + nodeX = 0; + nodeY = 0; + } + + var gAlpha = context.globalAlpha; + + context.globalAlpha = imgOpacity; + + 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, + nodeW, nodeH); + + 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, + nodeW, nodeH); + + context.translate(x, y); + context.fill(); + context.translate(-x, -y); + } + + context.globalAlpha = gAlpha; + +}; + +module.exports = CRp; + +},{}],65:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../../../is'); + +var CRp = {}; + +// Draw edge text +CRp.drawEdgeText = function(context, edge) { + var text = edge._private.style['label'].strValue; + + if( !text || text.match(/^\s+$/) ){ + return; + } + + if( this.hideEdgesOnViewport && (this.dragData.didDrag || this.pinching || this.hoverData.dragging || this.data.wheel || this.swipePanning) ){ return; } // save cycles on pinching + + var computedSize = edge._private.style['font-size'].pfValue * edge.cy().zoom(); + var minSize = edge._private.style['min-zoomed-font-size'].pfValue; + + if( computedSize < minSize ){ + return; + } + + // Calculate text draw position + + context.textAlign = 'center'; + context.textBaseline = 'middle'; + + var rs = edge._private.rscratch; + if( !is.number( rs.labelX ) || !is.number( rs.labelY ) ){ return; } // no pos => label can't be rendered + + var style = edge._private.style; + var autorotate = style['edge-text-rotation'].strValue === 'autorotate'; + var theta; + + if( autorotate ){ + theta = rs.labelAngle; + + context.translate(rs.labelX, rs.labelY); + context.rotate(theta); + + this.drawText(context, edge, 0, 0); + + context.rotate(-theta); + context.translate(-rs.labelX, -rs.labelY); + } else { + this.drawText(context, edge, rs.labelX, rs.labelY); + } + +}; + +// Draw node text +CRp.drawNodeText = function(context, node) { + var text = node._private.style['label'].strValue; + + if ( !text || text.match(/^\s+$/) ) { + return; + } + + var computedSize = node._private.style['font-size'].pfValue * node.cy().zoom(); + var minSize = node._private.style['min-zoomed-font-size'].pfValue; + + if( computedSize < minSize ){ + return; + } + + // this.recalculateNodeLabelProjection( node ); + + var textHalign = node._private.style['text-halign'].strValue; + var textValign = node._private.style['text-valign'].strValue; + var rs = node._private.rscratch; + if( !is.number( rs.labelX ) || !is.number( rs.labelY ) ){ return; } // no pos => label can't be rendered + + switch( textHalign ){ + case 'left': + context.textAlign = 'right'; + break; + + case 'right': + context.textAlign = 'left'; + break; + + default: // e.g. center + context.textAlign = 'center'; + } + + switch( textValign ){ + case 'top': + context.textBaseline = 'bottom'; + break; + + case 'bottom': + context.textBaseline = 'top'; + break; + + default: // e.g. center + context.textBaseline = 'middle'; + } + + this.drawText(context, node, rs.labelX, rs.labelY); +}; + +CRp.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.setupTextStyle = function( context, element ){ + // Font style + var parentOpacity = element.effectiveOpacity(); + var style = element._private.style; + var labelStyle = style['font-style'].strValue; + var labelSize = style['font-size'].pfValue + 'px'; + var labelFamily = style['font-family'].strValue; + var labelWeight = style['font-weight'].strValue; + var opacity = style['text-opacity'].value * style['opacity'].value * parentOpacity; + var outlineOpacity = style['text-outline-opacity'].value * opacity; + var color = style['color'].value; + var outlineColor = style['text-outline-color'].value; + var shadowBlur = style['text-shadow-blur'].pfValue; + var shadowOpacity = style['text-shadow-opacity'].value; + var shadowColor = style['text-shadow-color'].value; + var shadowOffsetX = style['text-shadow-offset-x'].pfValue; + var shadowOffsetY = style['text-shadow-offset-y'].pfValue; + + var fontCacheKey = element._private.fontKey; + var cache = this.getFontCache(context); + + if( cache.key !== fontCacheKey ){ + context.font = labelStyle + ' ' + labelWeight + ' ' + labelSize + ' ' + labelFamily; + + cache.key = fontCacheKey; + } + + var text = this.getLabelText( element ); + + // Calculate text draw position based on text alignment + + // so text outlines aren't jagged + context.lineJoin = 'round'; + + this.fillStyle(context, color[0], color[1], color[2], opacity); + + this.strokeStyle(context, outlineColor[0], outlineColor[1], outlineColor[2], outlineOpacity); + + this.shadowStyle(context, shadowColor, shadowOpacity, shadowBlur, shadowOffsetX, shadowOffsetY); + + return text; +}; + +function roundRect(ctx, x, y, width, height, radius) { + var radius = radius || 5; + 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(); + ctx.fill(); +} + +// Draw text +CRp.drawText = function(context, element, textX, textY) { + var _p = element._private; + var style = _p.style; + var rstyle = _p.rstyle; + var rscratch = _p.rscratch; + var parentOpacity = element.effectiveOpacity(); + if( parentOpacity === 0 || style['text-opacity'].value === 0){ return; } + + var text = this.setupTextStyle( context, element ); + var halign = style['text-halign'].value; + var valign = style['text-valign'].value; + + if( element.isEdge() ){ + halign = 'center'; + valign = 'center'; + } + + if( element.isNode() ){ + var pLeft = style['padding-left'].pfValue; + var pRight = style['padding-right'].pfValue; + var pTop = style['padding-top'].pfValue; + var pBottom = style['padding-bottom'].pfValue; + + textX += pLeft/2; + textX -= pRight/2; + + textY += pTop/2; + textY -= pBottom/2; + } + + if ( text != null && !isNaN(textX) && !isNaN(textY)) { + var backgroundOpacity = style['text-background-opacity'].value; + var borderOpacity = style['text-border-opacity'].value; + var textBorderWidth = style['text-border-width'].pfValue; + + if( backgroundOpacity > 0 || (textBorderWidth > 0 && borderOpacity > 0) ){ + var margin = 4 + textBorderWidth/2; + + if (element.isNode()) { + //Move textX, textY to include the background margins + if (valign === 'top') { + textY -= margin; + } else if (valign === 'bottom') { + textY += margin; + } + if (halign === 'left') { + textX -= margin; + } else if (halign === 'right') { + textX += margin; + } + } + + var bgWidth = rstyle.labelWidth; + var bgHeight = rstyle.labelHeight; + var bgX = textX; + + if (halign) { + if (halign == 'center') { + bgX = bgX - bgWidth / 2; + } else if (halign == 'left') { + bgX = bgX- bgWidth; + } + } + + var bgY = textY; + + if (element.isNode()) { + if (valign == 'top') { + bgY = bgY - bgHeight; + } else if (valign == 'center') { + bgY = bgY- bgHeight / 2; + } + } else { + bgY = bgY - bgHeight / 2; + } + + if (style['edge-text-rotation'].strValue === 'autorotate') { + textY = 0; + bgWidth += 4; + bgX = textX - bgWidth / 2; + bgY = textY - bgHeight / 2; + } else { + // Adjust with border width & margin + bgX -= margin; + bgY -= margin; + bgHeight += margin*2; + bgWidth += margin*2; + } + + if( backgroundOpacity > 0 ){ + var textFill = context.fillStyle; + var textBackgroundColor = style['text-background-color'].value; + + context.fillStyle = 'rgba(' + textBackgroundColor[0] + ',' + textBackgroundColor[1] + ',' + textBackgroundColor[2] + ',' + backgroundOpacity * parentOpacity + ')'; + var styleShape = style['text-background-shape'].strValue; + if (styleShape == 'roundrectangle') { + roundRect(context, bgX, bgY, bgWidth, bgHeight, 2); + } else { + context.fillRect(bgX,bgY,bgWidth,bgHeight); + } + context.fillStyle = textFill; + } + + if( textBorderWidth > 0 && borderOpacity > 0 ){ + var textStroke = context.strokeStyle; + var textLineWidth = context.lineWidth; + var textBorderColor = style['text-border-color'].value; + var textBorderStyle = style['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; + } + } + + context.strokeRect(bgX,bgY,bgWidth,bgHeight); + + if( textBorderStyle === 'double' ){ + var whiteWidth = textBorderWidth/2; + + context.strokeRect(bgX+whiteWidth,bgY+whiteWidth,bgWidth-whiteWidth*2,bgHeight-whiteWidth*2); + } + + if( context.setLineDash ){ // for very outofdate browsers + context.setLineDash([ ]); + } + context.lineWidth = textLineWidth; + context.strokeStyle = textStroke; + } + + } + + var lineWidth = 2 * style['text-outline-width'].pfValue; // *2 b/c the stroke is drawn centred on the middle + + if( lineWidth > 0 ){ + context.lineWidth = lineWidth; + } + + if( style['text-wrap'].value === 'wrap' ){ + var lines = rscratch.labelWrapCachedLines; + var lineHeight = rstyle.labelHeight / lines.length; + + switch( valign ){ + case 'top': + textY -= (lines.length - 1) * lineHeight; + break; + + case 'bottom': + // nothing required + break; + + default: + case 'center': + textY -= (lines.length - 1) * lineHeight / 2; + } + + 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 ); + } + + + this.shadowStyle(context, 'transparent', 0); // reset for next guy + } +}; + + +module.exports = CRp; + +},{"../../../is":77}],66:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../../../is'); + +var CRp = {}; + +// Draw node +CRp.drawNode = function(context, node, drawOverlayInstead) { + + var r = this; + var nodeWidth, nodeHeight; + var style = node._private.style; + var rs = node._private.rscratch; + var _p = node._private; + var pos = _p.position; + + if( !is.number(pos.x) || !is.number(pos.y) ){ + return; // can't draw node with undefined position + } + + var usePaths = this.usePaths(); + var canvasContext = context; + var path; + var pathCacheHit = false; + + var overlayPadding = style['overlay-padding'].pfValue; + var overlayOpacity = style['overlay-opacity'].value; + var overlayColor = style['overlay-color'].value; + + if( drawOverlayInstead && overlayOpacity === 0 ){ // exit early if drawing overlay but none to draw + return; + } + + var parentOpacity = node.effectiveOpacity(); + if( parentOpacity === 0 ){ return; } + + nodeWidth = node.width() + style['padding-left'].pfValue + style['padding-right'].pfValue; + nodeHeight = node.height() + style['padding-top'].pfValue + style['padding-bottom'].pfValue; + + context.lineWidth = style['border-width'].pfValue; + + if( drawOverlayInstead === undefined || !drawOverlayInstead ){ + + var url = style['background-image'].value[2] || + style['background-image'].value[1]; + var image; + + if (url !== undefined) { + + // get image, and if not loaded then ask to redraw when later loaded + image = this.getCachedImage(url, function(){ + r.data.canvasNeedsRedraw[r.NODE] = true; + r.data.canvasNeedsRedraw[r.DRAG] = true; + + r.drawingImage = true; + + r.redraw(); + }); + + var prevBging = _p.backgrounding; + _p.backgrounding = !image.complete; + + if( prevBging !== _p.backgrounding ){ // update style b/c :backgrounding state changed + node.updateStyle( false ); + } + } + + // Node color & opacity + + var bgColor = style['background-color'].value; + var borderColor = style['border-color'].value; + var borderStyle = style['border-style'].value; + + this.fillStyle(context, bgColor[0], bgColor[1], bgColor[2], style['background-opacity'].value * parentOpacity); + + this.strokeStyle(context, borderColor[0], borderColor[1], borderColor[2], style['border-opacity'].value * parentOpacity); + + var shadowBlur = style['shadow-blur'].pfValue; + var shadowOpacity = style['shadow-opacity'].value; + var shadowColor = style['shadow-color'].value; + var shadowOffsetX = style['shadow-offset-x'].pfValue; + var shadowOffsetY = style['shadow-offset-y'].pfValue; + + this.shadowStyle(context, shadowColor, shadowOpacity, shadowBlur, shadowOffsetX, shadowOffsetY); + + context.lineJoin = 'miter'; // so borders are square with the node shape + + 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; + } + } + + + var styleShape = style['shape'].strValue; + + if( usePaths ){ + var pathCacheKey = styleShape + '$' + nodeWidth +'$' + nodeHeight; + + context.translate( pos.x, pos.y ); + + if( rs.pathCacheKey === pathCacheKey ){ + path = context = rs.pathCache; + pathCacheHit = true; + } else { + path = context = new Path2D(); + rs.pathCacheKey = pathCacheKey; + rs.pathCache = path; + } + } + + if( !pathCacheHit ){ + + var npos = pos; + + if( usePaths ){ + npos = { + x: 0, + y: 0 + }; + } + + r.nodeShapes[this.getNodeShape(node)].draw( + context, + npos.x, + npos.y, + nodeWidth, + nodeHeight); + } + + context = canvasContext; + + if( usePaths ){ + context.fill( path ); + } else { + context.fill(); + } + + this.shadowStyle(context, 'transparent', 0); // reset for next guy + + if (url !== undefined) { + if( image.complete ){ + this.drawInscribedImage(context, image, node); + } + } + + var darkness = style['background-blacken'].value; + var borderWidth = style['border-width'].pfValue; + + if( this.hasPie(node) ){ + this.drawPie( context, node, parentOpacity ); + + // redraw path for blacken and border + if( darkness !== 0 || borderWidth !== 0 ){ + + if( !usePaths ){ + r.nodeShapes[this.getNodeShape(node)].draw( + context, + pos.x, + pos.y, + nodeWidth, + nodeHeight); + } + } + } + + if( darkness > 0 ){ + this.fillStyle(context, 0, 0, 0, darkness); + + if( usePaths ){ + context.fill( path ); + } else { + context.fill(); + } + + } else if( darkness < 0 ){ + this.fillStyle(context, 255, 255, 255, -darkness); + + if( usePaths ){ + context.fill( path ); + } else { + context.fill(); + } + } + + // Border width, draw border + if (borderWidth > 0) { + + if( usePaths ){ + context.stroke( path ); + } else { + context.stroke(); + } + + if( borderStyle === 'double' ){ + context.lineWidth = style['border-width'].pfValue/3; + + var gco = context.globalCompositeOperation; + context.globalCompositeOperation = 'destination-out'; + + if( usePaths ){ + context.stroke( path ); + } else { + context.stroke(); + } + + context.globalCompositeOperation = gco; + } + + } + + if( usePaths ){ + context.translate( -pos.x, -pos.y ); + } + + // reset in case we changed the border style + if( context.setLineDash ){ // for very outofdate browsers + context.setLineDash([ ]); + } + + // draw the overlay + } else { + + if( overlayOpacity > 0 ){ + this.fillStyle(context, overlayColor[0], overlayColor[1], overlayColor[2], overlayOpacity); + + r.nodeShapes['roundrectangle'].draw( + context, + node._private.position.x, + node._private.position.y, + nodeWidth + overlayPadding * 2, + nodeHeight + overlayPadding * 2 + ); + + context.fill(); + } + } + +}; + +// does the node have at least one pie piece? +CRp.hasPie = function(node){ + node = node[0]; // ensure ele ref + + return node._private.hasPie; +}; + +CRp.drawPie = function( context, node, nodeOpacity ){ + node = node[0]; // ensure ele ref + + var _p = node._private; + var cyStyle = node.cy().style(); + var style = _p.style; + var pieSize = style['pie-size']; + var nodeW = node.width(); + var nodeH = node.height(); + var x = _p.position.x; + var y = _p.position.y; + 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.value / 100; + } else if( pieSize.pfValue !== undefined ){ + radius = pieSize.pfValue / 2; + } + + for( var i = 1; i <= cyStyle.pieBackgroundN; i++ ){ // 1..N + var size = style['pie-' + i + '-background-size'].value; + var color = style['pie-' + i + '-background-color'].value; + var opacity = style['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.fillStyle(context, color[0], color[1], color[2], opacity); + + context.fill(); + + lastPercent += percent; + } + +}; + + +module.exports = CRp; + +},{"../../../is":77}],67:[function(_dereq_,module,exports){ +'use strict'; + +var CRp = {}; + +var util = _dereq_('../../../util'); +var math = _dereq_('../../../math'); + +var motionBlurDelay = 100; + +// var isFirefox = typeof InstallTrigger !== 'undefined'; + +CRp.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; +}; + +CRp.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.fillStyle = 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.strokeStyle = 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.shadowStyle = function(context, color, opacity, blur, offsetX, offsetY){ + var zoom = this.cy.zoom(); + + var cache = this.paintCache(context); + + // don't make expensive changes to the shadow style if it's not used + if( cache.shadowOpacity === 0 && opacity === 0 ){ + return; + } + + cache.shadowOpacity = opacity; + + if (opacity > 0) { + context.shadowBlur = blur * zoom; + context.shadowColor = "rgba(" + color[0] + "," + color[1] + "," + color[2] + "," + opacity + ")"; + context.shadowOffsetX = offsetX * zoom; + context.shadowOffsetY = offsetY * zoom; + } else { + context.shadowBlur = 0; + context.shadowColor = "transparent"; + } +}; + +// Resize canvas +CRp.matchCanvasSize = function(container) { + var r = this; + var data = r.data; + var width = container.clientWidth; + var height = container.clientHeight; + 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]; + + if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) { + + 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]; + + if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) { + + 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.renderTo = function( cxt, zoom, pan, pxRatio ){ + this.render({ + forcedContext: cxt, + forcedZoom: zoom, + forcedPan: pan, + drawAllLayers: true, + forcedPxRatio: pxRatio + }); +}; + +CRp.render = function( options ) { + options = options || util.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 && r.motionBlurTimeout ){ + clearTimeout( r.motionBlurTimeout ); + } + + if( motionBlur ){ + if( r.mbFrames == null ){ + r.mbFrames = 0; + } + + if( !r.drawingImage ){ // image loading frames don't count towards motion blur blurry frames + 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 edges = r.getCachedEdges(); + var coreStyle = cy.style()._private.coreStyle; + + 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 = { + drag: { + nodes: [], + edges: [], + eles: [] + }, + nondrag: { + nodes: [], + edges: [], + eles: [] + } + }; + + function mbclear( context, x, y, w, h ){ + var gco = context.globalCompositeOperation; + + context.globalCompositeOperation = 'destination-out'; + r.fillStyle( 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; + + var bb; + + if( !r.textureCache ){ + r.textureCache = {}; + + bb = r.textureCache.bb = cy.elements().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; + bb = r.textureCache.bb; + + 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 = coreStyle['outside-texture-bg-color'].value; + var outsideBgOpacity = coreStyle['outside-texture-bg-opacity'].value; + r.fillStyle( 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 vpManip = (r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming || r.hoverData.draggingEles); + var hideEdges = r.hideEdgesOnViewport && vpManip; + var hideLabels = r.hideLabelsOnViewport && vpManip; + + if (needDraw[r.DRAG] || needDraw[r.NODE] || drawAllLayers || drawOnlyNodeLayer) { + if( hideEdges ){ + } else { + r.findEdgeControlPoints(edges); + } + + var zEles = r.getCachedZSortedEles(); + var extent = cy.extent(); + + for (var i = 0; i < zEles.length; i++) { + var ele = zEles[i]; + var list; + var bb = forcedContext ? null : ele.boundingBox(); + var insideExtent = forcedContext ? true : math.boundingBoxesIntersect( extent, bb ); + + if( !insideExtent ){ continue; } // no need to render + + if ( ele._private.rscratch.inDragLayer ) { + list = eles.drag; + } else { + list = eles.nondrag; + } + + list.eles.push( ele ); + } + + } + + + function drawElements( list, context ){ + var eles = list.eles; + + for( var i = 0; i < eles.length; i++ ){ + var ele = eles[i]; + + if( ele.isNode() ){ + r.drawNode(context, ele); + + if( !hideLabels ){ + r.drawNodeText(context, ele); + } + + r.drawNode(context, ele, true); + } else if( !hideEdges ) { + r.drawEdge(context, ele); + + if( !hideLabels ){ + r.drawEdgeText(context, ele); + } + + r.drawEdge(context, ele, true); + } + + + } + + } + + 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 ); + drawElements(eles.nondrag, context); + + 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 ); + drawElements(eles.drag, context); + + 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 = coreStyle['selection-box-border-width'].value / zoom; + + context.lineWidth = borderWidth; + context.fillStyle = "rgba(" + + coreStyle['selection-box-color'].value[0] + "," + + coreStyle['selection-box-color'].value[1] + "," + + coreStyle['selection-box-color'].value[2] + "," + + coreStyle['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(" + + coreStyle['selection-box-border-color'].value[0] + "," + + coreStyle['selection-box-border-color'].value[1] + "," + + coreStyle['selection-box-border-color'].value[2] + "," + + coreStyle['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(" + + coreStyle['active-bg-color'].value[0] + "," + + coreStyle['active-bg-color'].value[1] + "," + + coreStyle['active-bg-color'].value[2] + "," + + coreStyle['active-bg-opacity'].value + ")"; + + context.beginPath(); + context.arc(pos.x, pos.y, coreStyle['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( 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.currentlyDrawing = 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); + } + + r.drawingImage = false; + + + if( !forcedContext && !r.initrender ){ + r.initrender = true; + cy.trigger('initrender'); + } + + if( !forcedContext ){ + cy.triggerOnRender(); + } + +}; + +module.exports = CRp; + +},{"../../../math":79,"../../../util":94}],68:[function(_dereq_,module,exports){ +'use strict'; + + var math = _dereq_('../../../math'); + + var CRp = {}; + + // @O Polygon drawing + CRp.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(); + }; + + // Round rectangle drawing + CRp.drawRoundRectanglePath = function( + context, x, y, width, height, radius) { + + var halfWidth = width / 2; + var halfHeight = height / 2; + var cornerRadius = math.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(); + }; + + 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.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(); + }; + +module.exports = CRp; + +},{"../../../math":79}],69:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../../../is'); + +var CRp = {}; + +CRp.createBuffer = function(w, h) { + var buffer = document.createElement('canvas'); + buffer.width = w; + buffer.height = h; + + return [buffer, buffer.getContext('2d')]; +}; + +CRp.bufferCanvasImage = function( options ){ + var cy = this.cy; + var bb = cy.elements().boundingBox(); + var width = options.full ? Math.ceil(bb.w) : this.container.clientWidth; + var height = options.full ? Math.ceil(bb.h) : this.container.clientHeight; + var scale = 1; + + if( options.scale !== undefined ){ + width *= options.scale; + height *= options.scale; + + scale = options.scale; + } else if( is.number(options.maxWidth) || is.number(options.maxHeight) ){ + var maxScaleW = Infinity; + var maxScaleH = Infinity; + + if( is.number(options.maxWidth) ){ + maxScaleW = scale * options.maxWidth / width; + } + + if( is.number(options.maxHeight) ){ + maxScaleH = scale * options.maxHeight / height; + } + + scale = Math.min( maxScaleW, maxScaleH ); + + width *= scale; + height *= scale; + } + + var buffCanvas = document.createElement('canvas'); + + 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 ); + + if( options.bg ){ + buffCxt.fillStyle = options.bg; + buffCxt.rect( 0, 0, width, height ); + buffCxt.fill(); + } + + buffCxt.globalCompositeOperation = 'source-over'; + + if( options.full ){ // draw the full bounds of the graph + this.render({ + forcedContext: buffCxt, + drawAllLayers: true, + forcedZoom: scale, + forcedPan: { x: -bb.x1*scale, y: -bb.y1*scale }, + forcedPxRatio: 1 + }); + } else { // draw the current view + var cyPan = cy.pan(); + var pan = { + x: cyPan.x * scale, + y: cyPan.y * scale + }; + var zoom = cy.zoom() * scale; + + this.render({ + forcedContext: buffCxt, + drawAllLayers: true, + forcedZoom: zoom, + forcedPan: pan, + forcedPxRatio: 1 + }); + } + } + + return buffCanvas; +}; + +CRp.png = function( options ){ + return this.bufferCanvasImage( options ).toDataURL('image/png'); +}; + +CRp.jpg = function( options ){ + return this.bufferCanvasImage( options ).toDataURL('image/jpeg'); +}; + +module.exports = CRp; + +},{"../../../is":77}],70:[function(_dereq_,module,exports){ +/* +The canvas renderer was written by Yue Dong. + +Modifications tracked on Github. +*/ + +'use strict'; + +var util = _dereq_('../../../util'); +var is = _dereq_('../../../is'); + +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) + }; + + r.data.canvasContainer = document.createElement('div'); + var containerStyle = r.data.canvasContainer.style; + r.data.canvasContainer.setAttribute('style', '-webkit-tap-highlight-color: rgba(0,0,0,0);'); + containerStyle.position = 'relative'; + containerStyle.zIndex = '0'; + containerStyle.overflow = 'hidden'; + + var container = options.cy.container(); + container.appendChild( r.data.canvasContainer ); + container.setAttribute('style', ( container.getAttribute('style') || '' ) + '-webkit-tap-highlight-color: rgba(0,0,0,0);'); + + for (var i = 0; i < CRp.CANVAS_LAYERS; i++) { + var canvas = r.data.canvases[i] = document.createElement('canvas'); + r.data.contexts[i] = canvas.getContext('2d'); + canvas.setAttribute( 'style', '-webkit-user-select: none; -moz-user-select: -moz-none; user-select: none; -webkit-tap-highlight-color: rgba(0,0,0,0); outline-style: none;' + ( is.ms() ? ' -ms-touch-action: none; touch-action: none; ' : '' ) ); + 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'); + 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; +} + +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; +}; + +[ + _dereq_('./arrow-shapes'), + _dereq_('./drawing-edges'), + _dereq_('./drawing-images'), + _dereq_('./drawing-label-text'), + _dereq_('./drawing-nodes'), + _dereq_('./drawing-redraw'), + _dereq_('./drawing-shapes'), + _dereq_('./export-image'), + _dereq_('./node-shapes') +].forEach(function( props ){ + util.extend( CRp, props ); +}); + +module.exports = CR; + +},{"../../../is":77,"../../../util":94,"./arrow-shapes":62,"./drawing-edges":63,"./drawing-images":64,"./drawing-label-text":65,"./drawing-nodes":66,"./drawing-redraw":67,"./drawing-shapes":68,"./export-image":69,"./node-shapes":71}],71:[function(_dereq_,module,exports){ +'use strict'; + +var CRp = {}; + +var impl; + +CRp.nodeShapeImpl = function( name ){ + var self = this; + + return ( impl || (impl = { + 'ellipse': function( context, centerX, centerY, width, height ){ + self.drawEllipsePath( context, centerX, centerY, width, height ); + }, + + 'polygon': function( context, centerX, centerY, width, height, points ){ + self.drawPolygonPath( context, centerX, centerY, width, height, points ); + }, + + 'roundrectangle': function( context, centerX, centerY, width, height ){ + self.drawRoundRectanglePath( context, centerX, centerY, width, height, 10 ); + } + }) )[ name ]; +}; + +module.exports = CRp; + +},{}],72:[function(_dereq_,module,exports){ +'use strict'; + +module.exports = [ + { name: 'null', impl: _dereq_('./null') }, + { name: 'base', impl: _dereq_('./base') }, + { name: 'canvas', impl: _dereq_('./canvas') } +]; + +},{"./base":58,"./canvas":70,"./null":73}],73:[function(_dereq_,module,exports){ +'use strict'; + +function NullRenderer(options){ + this.options = options; + this.notifications = 0; // for testing +} + +var noop = function(){}; + +NullRenderer.prototype = { + recalculateRenderedStyle: noop, + notify: function(){ this.notifications++; }, + init: noop +}; + +module.exports = NullRenderer; + +},{}],74:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('./is'); +var util = _dereq_('./util'); +var Thread = _dereq_('./thread'); +var Promise = _dereq_('./promise'); +var define = _dereq_('./define'); + +var Fabric = function( N ){ + if( !(this instanceof Fabric) ){ + return new Fabric( N ); + } + + this._private = { + pass: [] + }; + + var defN = 4; + + if( is.number(N) ){ + // then use the specified number of threads + } if( typeof navigator !== 'undefined' && navigator.hardwareConcurrency != null ){ + N = navigator.hardwareConcurrency; + } else { + try{ + N = _dereq_('os').cpus().length; + } catch( err ){ + N = defN; + } + } // TODO could use an estimation here but would the additional expense be worth it? + + for( var i = 0; i < N; i++ ){ + this[i] = new Thread(); + } + + this.length = N; +}; + +var fabfn = Fabric.prototype; // short alias + +util.extend(fabfn, { + + instanceString: function(){ return 'fabric'; }, + + // require fn in all threads + require: function( fn, as ){ + for( var i = 0; i < this.length; i++ ){ + var thread = this[i]; + + thread.require( fn, as ); + } + + return this; + }, + + // get a random thread + random: function(){ + var i = Math.round( (this.length - 1) * Math.random() ); + var thread = this[i]; + + return thread; + }, + + // run on random thread + run: function( fn ){ + var pass = this._private.pass.shift(); + + return this.random().pass( pass ).run( fn ); + }, + + // sends a random thread a message + message: function( m ){ + return this.random().message( m ); + }, + + // send all threads a message + broadcast: function( m ){ + for( var i = 0; i < this.length; i++ ){ + var thread = this[i]; + + thread.message( m ); + } + + return this; // chaining + }, + + // stop all threads + stop: function(){ + for( var i = 0; i < this.length; i++ ){ + var thread = this[i]; + + thread.stop(); + } + + return this; // chaining + }, + + // pass data to be used with .spread() etc. + pass: function( data ){ + var pass = this._private.pass; + + if( is.array(data) ){ + pass.push( data ); + } else { + throw 'Only arrays may be used with fabric.pass()'; + } + + return this; // chaining + }, + + spreadSize: function(){ + var subsize = Math.ceil( this._private.pass[0].length / this.length ); + + subsize = Math.max( 1, subsize ); // don't pass less than one ele to each thread + + return subsize; + }, + + // split the data into slices to spread the data equally among threads + spread: function( fn ){ + var self = this; + var _p = self._private; + var subsize = self.spreadSize(); // number of pass eles to handle in each thread + var pass = _p.pass.shift().concat([]); // keep a copy + var runPs = []; + + for( var i = 0; i < this.length; i++ ){ + var thread = this[i]; + var slice = pass.splice( 0, subsize ); + + var runP = thread.pass( slice ).run( fn ); + + runPs.push( runP ); + + var doneEarly = pass.length === 0; + if( doneEarly ){ break; } + } + + return Promise.all( runPs ).then(function( thens ){ + var postpass = []; + var p = 0; + + // fill postpass with the total result joined from all threads + for( var i = 0; i < thens.length; i++ ){ + var then = thens[i]; // array result from thread i + + for( var j = 0; j < then.length; j++ ){ + var t = then[j]; // array element + + postpass[ p++ ] = t; + } + } + + return postpass; + }); + }, + + // parallel version of array.map() + map: function( fn ){ + var self = this; + + self.require( fn, '_$_$_fabmap' ); + + return self.spread(function( split ){ + var mapped = []; + var origResolve = resolve; // jshint ignore:line + + resolve = function( val ){ // jshint ignore:line + mapped.push( val ); + }; + + for( var i = 0; i < split.length; i++ ){ + var oldLen = mapped.length; + var ret = _$_$_fabmap( split[i] ); // jshint ignore:line + var nothingInsdByResolve = oldLen === mapped.length; + + if( nothingInsdByResolve ){ + mapped.push( ret ); + } + } + + resolve = origResolve; // jshint ignore:line + + return mapped; + }); + + }, + + // parallel version of array.filter() + filter: function( fn ){ + var _p = this._private; + var pass = _p.pass[0]; + + return this.map( fn ).then(function( include ){ + var ret = []; + + for( var i = 0; i < pass.length; i++ ){ + var datum = pass[i]; + var incDatum = include[i]; + + if( incDatum ){ + ret.push( datum ); + } + } + + return ret; + }); + }, + + // sorts the passed array using a divide and conquer strategy + sort: function( cmp ){ + var self = this; + var P = this._private.pass[0].length; + var subsize = this.spreadSize(); + + cmp = cmp || function( a, b ){ // default comparison function + if( a < b ){ + return -1; + } else if( a > b ){ + return 1; + } + + return 0; + }; + + self.require( cmp, '_$_$_cmp' ); + + return self.spread(function( split ){ // sort each split normally + var sortedSplit = split.sort( _$_$_cmp ); // jshint ignore:line + resolve( sortedSplit ); // jshint ignore:line + + }).then(function( joined ){ + // do all the merging in the main thread to minimise data transfer + + // TODO could do merging in separate threads but would incur add'l cost of data transfer + // for each level of the merge + + var merge = function( i, j, max ){ + // don't overflow array + j = Math.min( j, P ); + max = Math.min( max, P ); + + // left and right sides of merge + var l = i; + var r = j; + + var sorted = []; + + for( var k = l; k < max; k++ ){ + + var eleI = joined[i]; + var eleJ = joined[j]; + + if( i < r && ( j >= max || cmp(eleI, eleJ) <= 0 ) ){ + sorted.push( eleI ); + i++; + } else { + sorted.push( eleJ ); + j++; + } + + } + + // in the array proper, put the sorted values + for( var k = 0; k < sorted.length; k++ ){ // kth sorted item + var index = l + k; + + joined[ index ] = sorted[k]; + } + }; + + for( var splitL = subsize; splitL < P; splitL *= 2 ){ // merge until array is "split" as 1 + + for( var i = 0; i < P; i += 2*splitL ){ + merge( i, i + splitL, i + 2*splitL ); + } + + } + + return joined; + }); + } + + +}); + +var defineRandomPasser = function( opts ){ + opts = opts || {}; + + return function( fn, arg1 ){ + var pass = this._private.pass.shift(); + + return this.random().pass( pass )[ opts.threadFn ]( fn, arg1 ); + }; +}; + +util.extend(fabfn, { + randomMap: defineRandomPasser({ threadFn: 'map' }), + + reduce: defineRandomPasser({ threadFn: 'reduce' }), + + reduceRight: defineRandomPasser({ threadFn: 'reduceRight' }) +}); + +// aliases +var fn = fabfn; +fn.promise = fn.run; +fn.terminate = fn.halt = fn.stop; +fn.include = fn.require; + +// pull in event apis +util.extend(fabfn, { + on: define.on(), + one: define.on({ unbindSelfOnTrigger: true }), + off: define.off(), + trigger: define.trigger() +}); + +define.eventAliasesOn( fabfn ); + +module.exports = Fabric; + +},{"./define":41,"./is":77,"./promise":80,"./thread":92,"./util":94,"os":undefined}],75:[function(_dereq_,module,exports){ +'use strict'; +/* jshint ignore:start */ + +// 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, _j, _len, _ref, _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, i, 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 (i = _j = 0, _ref1 = min(n, array.length); 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 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) { + if (typeof define === 'function' && define.amd) { + return define([], factory); + } else if (typeof exports === 'object') { + return module.exports = factory(); + } else { + return root.Heap = factory(); + } + })(this, function() { + return Heap; + }); + +}).call(this); + +/* jshint ignore:end */ + +},{}],76:[function(_dereq_,module,exports){ +'use strict'; + +var window = _dereq_('./window'); +var is = _dereq_('./is'); +var Core = _dereq_('./core'); +var extension = _dereq_('./extension'); +var registerJquery = _dereq_('./jquery-plugin'); +var Stylesheet = _dereq_('./stylesheet'); +var Thread = _dereq_('./thread'); +var Fabric = _dereq_('./fabric'); + +var cytoscape = function( options ){ // jshint ignore:line + // if no options specified, use default + if( options === undefined ){ + options = {}; + } + + // create instance + if( is.plainObject( options ) ){ + return new Core( options ); + } + + // allow for registration of extensions + else if( is.string( options ) ) { + return extension.apply(extension, arguments); + } +}; + +// replaced by build system +cytoscape.version = '2.5.4'; + +// try to register w/ jquery +if( window && window.jQuery ){ + registerJquery( window.jQuery, cytoscape ); +} + +// expose register api +cytoscape.registerJquery = function( jQuery ){ + registerJquery( jQuery, cytoscape ); +}; + +// expose public apis (mostly for extensions) +cytoscape.stylesheet = cytoscape.Stylesheet = Stylesheet; +cytoscape.thread = cytoscape.Thread = Thread; +cytoscape.fabric = cytoscape.Fabric = Fabric; + +module.exports = cytoscape; + +},{"./core":34,"./extension":43,"./fabric":74,"./is":77,"./jquery-plugin":78,"./stylesheet":91,"./thread":92,"./window":100}],77:[function(_dereq_,module,exports){ +'use strict'; + +var window = _dereq_('./window'); +var navigator = window ? window.navigator : null; + +var typeofstr = typeof ''; +var typeofobj = typeof {}; +var typeoffn = typeof function(){}; +var typeofhtmlele = typeof HTMLElement; + +var instanceStr = function( obj ){ + return obj && obj.instanceString && is.fn( obj.instanceString ) ? obj.instanceString() : null; +}; + +var is = { + defined: function(obj){ + return obj != null; // not undefined or null + }, + + string: function(obj){ + return obj != null && typeof obj == typeofstr; + }, + + fn: function(obj){ + return obj != null && typeof obj === typeoffn; + }, + + array: function(obj){ + return Array.isArray ? Array.isArray(obj) : obj != null && obj instanceof Array; + }, + + plainObject: function(obj){ + return obj != null && typeof obj === typeofobj && !is.array(obj) && obj.constructor === Object; + }, + + object: function(obj){ + return obj != null && typeof obj === typeofobj; + }, + + number: function(obj){ + return obj != null && typeof obj === typeof 1 && !isNaN(obj); + }, + + integer: function( obj ){ + return is.number(obj) && Math.floor(obj) === obj; + }, + + bool: function(obj){ + return obj != null && typeof obj === typeof true; + }, + + htmlElement: function(obj){ + if( 'undefined' === typeofhtmlele ){ + return undefined; + } else { + return null != obj && obj instanceof HTMLElement; + } + }, + + elementOrCollection: function(obj){ + return is.element(obj) || is.collection(obj); + }, + + element: function(obj){ + return instanceStr(obj) === 'collection' && obj._private.single; + }, + + collection: function(obj){ + return instanceStr(obj) === 'collection' && !obj._private.single; + }, + + core: function(obj){ + return instanceStr(obj) === 'core'; + }, + + style: function(obj){ + return instanceStr(obj) === 'style'; + }, + + stylesheet: function(obj){ + return instanceStr(obj) === 'stylesheet'; + }, + + event: function(obj){ + return instanceStr(obj) === 'event'; + }, + + thread: function(obj){ + return instanceStr(obj) === 'thread'; + }, + + fabric: function(obj){ + return instanceStr(obj) === 'fabric'; + }, + + emptyString: function(obj){ + if( !obj ){ // null is empty + return true; + } else if( is.string(obj) ){ + if( obj === '' || obj.match(/^\s+$/) ){ + return true; // empty string is empty + } + } + + return false; // otherwise, we don't know what we've got + }, + + nonemptyString: function(obj){ + if( obj && is.string(obj) && obj !== '' && !obj.match(/^\s+$/) ){ + return true; + } + + return false; + }, + + domElement: function(obj){ + if( typeof HTMLElement === 'undefined' ){ + return false; // we're not in a browser so it doesn't matter + } else { + return obj instanceof HTMLElement; + } + }, + + boundingBox: function(obj){ + return is.plainObject(obj) && + is.number(obj.x1) && is.number(obj.x2) && + is.number(obj.y1) && is.number(obj.y2) + ; + }, + + promise: function(obj){ + return is.object(obj) && is.fn(obj.then); + }, + + touch: function(){ + return window && ( ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch ); + }, + + gecko: function(){ + return typeof InstallTrigger !== 'undefined' || ('MozAppearance' in document.documentElement.style); + }, + + webkit: function(){ + return typeof webkitURL !== 'undefined' || ('WebkitAppearance' in document.documentElement.style); + }, + + chromium: function(){ + return typeof chrome !== 'undefined'; + }, + + khtml: function(){ + return navigator && navigator.vendor.match(/kde/i); // probably a better way to detect this... + }, + + khtmlEtc: function(){ + return is.khtml() || is.webkit() || is.chromium(); + }, + + ms: function(){ + return navigator && navigator.userAgent.match(/msie|trident|edge/i); // probably a better way to detect this... + }, + + windows: function(){ + return navigator && navigator.appVersion.match(/Win/i); + }, + + mac: function(){ + return navigator && navigator.appVersion.match(/Mac/i); + }, + + linux: function(){ + return navigator && navigator.appVersion.match(/Linux/i); + }, + + unix: function(){ + return navigator && navigator.appVersion.match(/X11/i); + } +}; + +module.exports = is; + +},{"./window":100}],78:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('./is'); + +var cyReg = function( $ele ){ + var d = $ele[0]._cyreg = $ele[0]._cyreg || {}; + + return d; +}; + +var registerJquery = function( $, cytoscape ){ + if( !$ ){ return; } // no jquery => don't need this + + if( $.fn.cytoscape ){ return; } // already registered + + // allow calls on a jQuery selector by proxying calls to $.cytoscape + // e.g. $("#foo").cytoscape(options) => $.cytoscape(options) on #foo + $.fn.cytoscape = function(opts){ + var $this = $(this); + + // get object + if( opts === 'get' ){ + return cyReg( $this ).cy; + } + + // bind to ready + else if( is.fn(opts) ){ + + var ready = opts; + var cy = cyReg( $this ).cy; + + if( cy && cy.isReady() ){ // already ready so just trigger now + cy.trigger('ready', [], ready); + + } else { // not yet ready, so add to readies list + var data = cyReg( $this ); + var readies = data.readies = data.readies || []; + + readies.push( ready ); + } + + } + + // proxy to create instance + else if( is.plainObject(opts) ){ + return $this.each(function(){ + var options = $.extend({}, opts, { + container: $(this)[0] + }); + + cytoscape(options); + }); + } + }; + + // allow access to the global cytoscape object under jquery for legacy reasons + $.cytoscape = cytoscape; + + // use short alias (cy) if not already defined + if( $.fn.cy == null && $.cy == null ){ + $.fn.cy = $.fn.cytoscape; + $.cy = $.cytoscape; + } +}; + +module.exports = registerJquery; + +},{"./is":77}],79:[function(_dereq_,module,exports){ +'use strict'; + +var math = {}; + +math.signum = function(x){ + if( x > 0 ){ + return 1; + } else if( x < 0 ){ + return -1; + } else { + return 0; + } +}; + +math.distance = function( p1, p2 ){ + return Math.sqrt( math.sqDistance(p1, p2) ); +}; + +math.sqDistance = function( p1, p2 ){ + var dx = p2.x - p1.x; + var dy = p2.y - p1.y; + + return dx*dx + dy*dy; +}; + +// from http://en.wikipedia.org/wiki/Bézier_curve#Quadratic_curves +math.qbezierAt = function(p0, p1, p2, t){ + return (1 - t)*(1 - t)*p0 + 2*(1 - t)*t*p1 + t*t*p2; +}; + +math.qbezierPtAt = function(p0, p1, p2, t){ + return { + x: math.qbezierAt( p0.x, p1.x, p2.x, t ), + y: math.qbezierAt( p0.y, p1.y, p2.y, t ) + }; +}; + +// makes a full bb (x1, y1, x2, y2, w, h) from implicit params +math.makeBoundingBox = function( bb ){ + 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 + }; + } + } +}; + +math.boundingBoxesIntersect = function( 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; +}; + +math.inBoundingBox = function( bb, x, y ){ + return bb.x1 <= x && x <= bb.x2 && bb.y1 <= y && y <= bb.y2; +}; + +math.pointInBoundingBox = function( bb, pt ){ + return this.inBoundingBox( bb, pt.x, pt.y ); +}; + +math.roundRectangleIntersectLine = function( + x, y, nodeX, nodeY, width, height, padding) { + + var cornerRadius = this.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 = this.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 = this.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 = this.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 = this.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 = this.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 = this.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 = this.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 = this.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 +}; + +math.inLineVicinity = function(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; +}; + +math.inBezierVicinity = function( + 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; + } + +}; + +math.solveCubic = function(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 + + 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; +}; + +math.sqDistanceToQuadraticBezier = function( + 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 + this.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 closestParam; + + 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; + closestParam = params[i]; + } + } else { + minDistanceSquared = distSquared; + closestParam = params[i]; + } + } + + return minDistanceSquared; +}; + +math.sqDistanceToFiniteLine = function(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; +}; + +math.pointInsidePolygonPoints = function(x, y, points){ + var x1, y1, x2, y2; + var y3; + + // Intersect with vertical line through (x, y) + var up = 0; + var 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; + } +}; + +math.pointInsidePolygon = function( + x, y, basePoints, centerX, centerY, width, height, direction, padding) { + + //var direction = arguments[6]; + 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 = this.expandPolygon( + transformedPoints, + -padding); + + points = this.joinLines(expandedLineSet); + } else { + points = transformedPoints; + } + + return math.pointInsidePolygonPoints( x, y, points ); +}; + +math.joinLines = function(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 = this.finiteLinesIntersect( + currentLineStartX, currentLineStartY, + currentLineEndX, currentLineEndY, + nextLineStartX, nextLineStartY, + nextLineEndX, nextLineEndY, + true); + + vertices[i * 2] = intersection[0]; + vertices[i * 2 + 1] = intersection[1]; + } + + return vertices; +}; + +math.expandPolygon = function(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; +}; + +math.intersectLineEllipse = function( + 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]; +}; + +// Returns intersections of increasing distance from line's start point +math.intersectLineCircle = function( + x1, y1, x2, y2, centerX, centerY, radius) { + + // Calculate d, direction vector of line + var d = [x2 - x1, y2 - y1]; // Direction vector of line + var c = [centerX, centerY]; // Center of circle + 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]; + } + +}; + +math.findCircleNearPoint = function(centerX, centerY, + radius, farX, farY) { + + var displacementX = farX - centerX; + var displacementY = farY - centerY; + var distance = Math.sqrt(displacementX * displacementX + + displacementY * displacementY); + + var unitDisplacementX = displacementX / distance; + var unitDisplacementY = displacementY / distance; + + return [centerX + unitDisplacementX * radius, + centerY + unitDisplacementY * radius]; +}; + +math.findMaxSqDistanceToOrigin = function(points) { + var maxSqDistance = 0.000001; + var sqDistance; + + for (var i = 0; i < points.length / 2; i++) { + + sqDistance = points[i * 2] * points[i * 2] + + points[i * 2 + 1] * points[i * 2 + 1]; + + if (sqDistance > maxSqDistance) { + maxSqDistance = sqDistance; + } + } + + return maxSqDistance; +}; + +math.finiteLinesIntersect = function( + x1, y1, x2, y2, x3, y3, x4, y4, infiniteLines) { + + var ua_t = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3); + var ub_t = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3); + var u_b = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1); + + if (u_b !== 0) { + var ua = ua_t / u_b; + var ub = ub_t / u_b; + + if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) { + return [x1 + ua * (x2 - x1), y1 + ua * (y2 - y1)]; + + } else { + if (!infiniteLines) { + return []; + } else { + return [x1 + ua * (x2 - x1), y1 + ua * (y2 - y1)]; + } + } + } else { + if (ua_t === 0 || ub_t === 0) { + + // Parallel, coincident lines. Check if overlap + + // Check endpoint of second line + if ([x1, x2, x4].sort()[1] === x4) { + return [x4, y4]; + } + + // Check start point of second line + if ([x1, x2, x3].sort()[1] === x3) { + return [x3, y3]; + } + + // Endpoint of first line + if ([x3, x4, x2].sort()[1] === x2) { + return [x2, y2]; + } + + return []; + } else { + + // Parallel, non-coincident + return []; + } + } +}; + +math.polygonIntersectLine = function( + x, y, basePoints, centerX, centerY, width, height, padding) { + + var intersections = []; + var intersection; + + var transformedPoints = new Array(basePoints.length); + + 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; + } + + var points; + + if (padding > 0) { + var expandedLineSet = math.expandPolygon( + transformedPoints, + -padding); + + points = math.joinLines(expandedLineSet); + } else { + points = transformedPoints; + } + // var points = transformedPoints; + + var currentX, currentY, nextX, nextY; + + for (var i = 0; i < points.length / 2; i++) { + + currentX = points[i * 2]; + currentY = points[i * 2 + 1]; + + if (i < points.length / 2 - 1) { + nextX = points[(i + 1) * 2]; + nextY = points[(i + 1) * 2 + 1]; + } else { + nextX = points[0]; + nextY = points[1]; + } + + intersection = this.finiteLinesIntersect( + x, y, centerX, centerY, + currentX, currentY, + nextX, nextY); + + if (intersection.length !== 0) { + intersections.push(intersection[0], intersection[1]); + } + } + + return intersections; +}; + +math.shortenIntersection = function( + 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]]; +}; + +math.generateUnitNgonPointsFitToSquare = function(sides, rotationRadians) { + var points = math.generateUnitNgonPoints(sides, rotationRadians); + points = math.fitPolygonToSquare(points); + + return points; +}; + +math.fitPolygonToSquare = function(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 i = 0; i < sides; i++){ + x = points[2 * i] = points[2 * i] * sx; + y = points[2 * i + 1] = points[2 * i + 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 i = 0; i < sides; i++){ + y = points[2 * i + 1] = points[2 * i + 1] + (-1 -minY); + } + } + + return points; +}; + +math.generateUnitNgonPoints = function(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; + // console.log(nodeShapes['square']); + startAngle += rotationRadians; + + var points = new Array(sides * 2); + + var currentAngle, x, y; + for (var i = 0; i < sides; i++) { + currentAngle = i * increment + startAngle; + + x = points[2 * i] = Math.cos(currentAngle);// * (1 + i/2); + y = points[2 * i + 1] = Math.sin(-currentAngle);// * (1 + i/2); + } + + return points; +}; + +math.getRoundRectangleRadius = function(width, height) { + + // Set the default radius, unless half of width or height is smaller than default + return Math.min(width / 4, height / 4, 8); +}; + +module.exports = math; + +},{}],80:[function(_dereq_,module,exports){ +// internal, minimal Promise impl s.t. apis can return promises in old envs +// based on thenable (http://github.com/rse/thenable) + +'use strict'; + +/* 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 (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 (value) { return deliver(this, STATE_FULFILLED, "fulfillValue", value); }, + reject: function (value) { return deliver(this, STATE_REJECTED, "rejectReason", value); }, + + /* "The then Method" [Promises/A+ 1.1, 1.2, 2.2] */ + then: function (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 (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 (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 (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 () { + 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 (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 (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] */ +}; + +// use native promises where possible +var Promise = typeof Promise === 'undefined' ? api : Promise; + +// so we always have Promise.all() +Promise.all = Promise.all || function( ps ){ + return new Promise(function( resolveAll, rejectAll ){ + var vals = new Array( ps.length ); + var doneCount = 0; + + var fulfill = function( 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.then != null; + + if( isPromise ){ + p.then(function( val ){ + fulfill( i, val ); + }, function( err ){ + rejectAll( err ); + }); + } else { + var val = p; + fulfill( i, val ); + } + })( i ); + } + + }); +}; + +module.exports = Promise; + +},{}],81:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('./is'); +var util = _dereq_('./util'); + +var Selector = function( onlyThisGroup, selector ){ + + if( !(this instanceof Selector) ){ + return new Selector(onlyThisGroup, selector); + } + + if( selector === undefined && onlyThisGroup !== undefined ){ + selector = onlyThisGroup; + onlyThisGroup = undefined; + } + + var self = this; + + self._private = { + selectorText: null, + invalid: true + }; + + if( !selector || ( is.string(selector) && selector.match(/^\s*$/) ) ){ + + if( onlyThisGroup == null ){ + // ignore + self.length = 0; + } else { + self[0] = newQuery(); + self[0].group = onlyThisGroup; + self.length = 1; + } + + } else if( is.elementOrCollection( selector ) ){ + var collection = selector.collection(); + + self[0] = newQuery(); + self[0].collection = collection; + self.length = 1; + + } else if( is.fn( selector ) ) { + self[0] = newQuery(); + self[0].filter = selector; + self.length = 1; + + } else if( is.string( selector ) ){ + + // the current subject in the query + var currentSubject = null; + + // storage for parsed queries + var newQuery = function(){ + return { + classes: [], + colonSelectors: [], + data: [], + group: null, + ids: [], + meta: [], + + // fake selectors + collection: null, // a collection to match against + filter: null, // filter function + + // these are defined in the upward direction rather than down (e.g. child) + // because we need to go up in Selector.filter() + parent: null, // parent query obj + ancestor: null, // ancestor query obj + subject: null, // defines subject in compound query (subject query obj; points to self if subject) + + // use these only when subject has been defined + child: null, + descendant: null + }; + }; + + // tokens in the query language + var tokens = { + metaChar: '[\\!\\"\\#\\$\\%\\&\\\'\\(\\)\\*\\+\\,\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]', // chars we need to escape in var 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: util.regex.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: '\\$' + }; + tokens.variable = '(?:[\\w-]|(?:\\\\'+ tokens.metaChar +'))+'; // a variable name + tokens.value = tokens.string + '|' + tokens.number; // a value literal, either a string or number + tokens.className = tokens.variable; // a class name (follows variable conventions) + tokens.id = tokens.variable; // an element id (follows variable conventions) + + // 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(str){ + return str.replace(new RegExp('\\\\(' + tokens.metaChar + ')', 'g'), function(match, $1, offset, original){ + return $1; + }); + }; + + // add @ variants to comparatorOp + var ops = tokens.comparatorOp.split('|'); + for( var i = 0; i < ops.length; i++ ){ + var op = ops[i]; + tokens.comparatorOp += '|@' + op; + } + + // add ! variants to comparatorOp + var ops = tokens.comparatorOp.split('|'); + for( var i = 0; i < ops.length; i++ ){ + var 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; + } + + // 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 self[i] --- you can use the reference to `this` in the populate function; + // - you need to check the query objects in Selector.filter() for it actually filter properly, but that's pretty straight forward + // - when you add something here, also add to Selector.toString() + var exprs = [ + { + name: 'group', + query: true, + regex: '(node|edge|\\*)', + populate: function( group ){ + this.group = group == "*" ? group : group + 's'; + } + }, + + { + name: 'state', + query: true, + // NB: if one colon selector is a substring of another from its start, place the longer one first + // e.g. :foobar|:foo + regex: '(:selected|:unselected|:locked|:unlocked|:visible|:hidden|:transparent|:grabbed|:free|:removed|:inside|:grabbable|:ungrabbable|:animated|:unanimated|:selectable|:unselectable|:orphan|:nonorphan|:parent|:child|:loop|:simple|:active|:inactive|:touch|:backgrounding|:nonbackgrounding)', + populate: function( state ){ + this.colonSelectors.push( state ); + } + }, + + { + name: 'id', + query: true, + regex: '\\#('+ tokens.id +')', + populate: function( id ){ + this.ids.push( cleanMetaChars(id) ); + } + }, + + { + name: 'className', + query: true, + regex: '\\.('+ tokens.className +')', + populate: function( className ){ + this.classes.push( cleanMetaChars(className) ); + } + }, + + { + name: 'dataExists', + query: true, + regex: '\\[\\s*('+ tokens.variable +')\\s*\\]', + populate: function( variable ){ + this.data.push({ + field: cleanMetaChars(variable) + }); + } + }, + + { + name: 'dataCompare', + query: true, + regex: '\\[\\s*('+ tokens.variable +')\\s*('+ tokens.comparatorOp +')\\s*('+ tokens.value +')\\s*\\]', + populate: function( variable, comparatorOp, value ){ + var valueIsString = new RegExp('^' + tokens.string + '$').exec(value) != null; + + if( valueIsString ){ + value = value.substring(1, value.length - 1); + } else { + value = parseFloat(value); + } + + this.data.push({ + field: cleanMetaChars(variable), + operator: comparatorOp, + value: value + }); + } + }, + + { + name: 'dataBool', + query: true, + regex: '\\[\\s*('+ tokens.boolOp +')\\s*('+ tokens.variable +')\\s*\\]', + populate: function( boolOp, variable ){ + this.data.push({ + field: cleanMetaChars(variable), + operator: boolOp + }); + } + }, + + { + name: 'metaCompare', + query: true, + regex: '\\[\\[\\s*('+ tokens.meta +')\\s*('+ tokens.comparatorOp +')\\s*('+ tokens.number +')\\s*\\]\\]', + populate: function( meta, comparatorOp, number ){ + this.meta.push({ + field: cleanMetaChars(meta), + operator: comparatorOp, + value: parseFloat(number) + }); + } + }, + + { + name: 'nextQuery', + separator: true, + regex: tokens.separator, + populate: function(){ + // go on to next query + self[++i] = newQuery(); + currentSubject = null; + } + }, + + { + name: 'child', + separator: true, + regex: tokens.child, + populate: function(){ + // this query is the parent of the following query + var childQuery = newQuery(); + childQuery.parent = this; + childQuery.subject = currentSubject; + + // we're now populating the child query with expressions that follow + self[i] = childQuery; + } + }, + + { + name: 'descendant', + separator: true, + regex: tokens.descendant, + populate: function(){ + // this query is the ancestor of the following query + var descendantQuery = newQuery(); + descendantQuery.ancestor = this; + descendantQuery.subject = currentSubject; + + // we're now populating the descendant query with expressions that follow + self[i] = descendantQuery; + } + }, + + { + name: 'subject', + modifier: true, + regex: tokens.subject, + populate: function(){ + if( currentSubject != null && this.subject != this ){ + util.error('Redefinition of subject in selector `' + selector + '`'); + return false; + } + + currentSubject = this; + this.subject = this; + } + + } + ]; + + self._private.selectorText = selector; + var remaining = selector; + var i = 0; + + // of all the expressions, find the first match in the remaining text + var consumeExpr = function( expectation ){ + var expr; + var match; + var name; + + for( var j = 0; j < exprs.length; j++ ){ + var e = exprs[j]; + var n = e.name; + + // ignore this expression if it doesn't meet the expectation function + if( is.fn( expectation ) && !expectation(n, e) ){ continue; } + + var m = remaining.match(new RegExp( '^' + e.regex )); + + 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 + }; + }; + + // consume all leading whitespace + var consumeWhitespace = function(){ + var match = remaining.match(/^\s+/); + + if( match ){ + var consumed = match[0]; + remaining = remaining.substring( consumed.length ); + } + }; + + self[0] = newQuery(); // get started + + consumeWhitespace(); // get rid of leading whitespace + for(;;){ + var check = consumeExpr(); + + if( check.expr == null ){ + util.error('The selector `'+ selector +'`is invalid'); + return; + } else { + var args = []; + for(var j = 1; j < check.match.length; j++){ + args.push( check.match[j] ); + } + + // let the token populate the selector object (i.e. in self[i]) + var ret = check.expr.populate.apply( self[i], args ); + + if( ret === false ){ return; } // exit if population failed + } + + // we're done when there's nothing left to parse + if( remaining.match(/^\s*$/) ){ + break; + } + } + + self.length = i + 1; + + // adjust references for subject + for(var j = 0; j < self.length; j++){ + var query = self[j]; + + if( query.subject != null ){ + // go up the tree until we reach the subject + for(;;){ + if( query.subject == query ){ break; } // done if subject is self + + if( query.parent != null ){ // swap parent/child reference + var parent = query.parent; + var child = query; + + child.parent = null; + parent.child = child; + + query = parent; // go up the tree + } else if( query.ancestor != null ){ // swap ancestor/descendant + var ancestor = query.ancestor; + var descendant = query; + + descendant.ancestor = null; + ancestor.descendant = descendant; + + query = ancestor; // go up the tree + } else { + util.error('When adjusting references for the selector `'+ query +'`, neither parent nor ancestor was found'); + break; + } + } // for + + self[j] = query.subject; // subject should be the root query + } // if + } // for + + // make sure for each query that the subject group matches the implicit group if any + if( onlyThisGroup != null ){ + for(var j = 0; j < self.length; j++){ + if( self[j].group != null && self[j].group != onlyThisGroup ){ + util.error('Group `'+ self[j].group +'` conflicts with implicit group `'+ onlyThisGroup +'` in selector `'+ selector +'`'); + return; + } + + self[j].group = onlyThisGroup; // set to implicit group + } + } + + } else { + util.error('A selector must be created from a string; found ' + selector); + return; + } + + self._private.invalid = false; + +}; + +var selfn = Selector.prototype; + +selfn.size = function(){ + return this.length; +}; + +selfn.eq = function(i){ + return this[i]; +}; + +var queryMatches = function(query, element){ + // check group + if( query.group != null && query.group != '*' && query.group != element._private.group ){ + return false; + } + + var cy = element.cy(); + + // check colon selectors + var allColonSelectorsMatch = true; + for(var k = 0; k < query.colonSelectors.length; k++){ + var sel = query.colonSelectors[k]; + + switch(sel){ + case ':selected': + allColonSelectorsMatch = element.selected(); + break; + case ':unselected': + allColonSelectorsMatch = !element.selected(); + break; + case ':selectable': + allColonSelectorsMatch = element.selectable(); + break; + case ':unselectable': + allColonSelectorsMatch = !element.selectable(); + break; + case ':locked': + allColonSelectorsMatch = element.locked(); + break; + case ':unlocked': + allColonSelectorsMatch = !element.locked(); + break; + case ':visible': + allColonSelectorsMatch = element.visible(); + break; + case ':hidden': + allColonSelectorsMatch = !element.visible(); + break; + case ':transparent': + allColonSelectorsMatch = element.transparent(); + break; + case ':grabbed': + allColonSelectorsMatch = element.grabbed(); + break; + case ':free': + allColonSelectorsMatch = !element.grabbed(); + break; + case ':removed': + allColonSelectorsMatch = element.removed(); + break; + case ':inside': + allColonSelectorsMatch = !element.removed(); + break; + case ':grabbable': + allColonSelectorsMatch = element.grabbable(); + break; + case ':ungrabbable': + allColonSelectorsMatch = !element.grabbable(); + break; + case ':animated': + allColonSelectorsMatch = element.animated(); + break; + case ':unanimated': + allColonSelectorsMatch = !element.animated(); + break; + case ':parent': + allColonSelectorsMatch = element.isNode() && element.children().nonempty(); + break; + case ':child': + case ':nonorphan': + allColonSelectorsMatch = element.isNode() && element.parent().nonempty(); + break; + case ':orphan': + allColonSelectorsMatch = element.isNode() && element.parent().empty(); + break; + case ':loop': + allColonSelectorsMatch = element.isEdge() && element.data('source') === element.data('target'); + break; + case ':simple': + allColonSelectorsMatch = element.isEdge() && element.data('source') !== element.data('target'); + break; + case ':active': + allColonSelectorsMatch = element.active(); + break; + case ':inactive': + allColonSelectorsMatch = !element.active(); + break; + case ':touch': + allColonSelectorsMatch = is.touch(); + break; + case ':backgrounding': + allColonSelectorsMatch = element.backgrounding(); + break; + case ':nonbackgrounding': + allColonSelectorsMatch = !element.backgrounding(); + break; + } + + if( !allColonSelectorsMatch ) break; + } + if( !allColonSelectorsMatch ) return false; + + // check id + var allIdsMatch = true; + for(var k = 0; k < query.ids.length; k++){ + var id = query.ids[k]; + var actualId = element._private.data.id; + + allIdsMatch = allIdsMatch && (id == actualId); + + if( !allIdsMatch ) break; + } + if( !allIdsMatch ) return false; + + // check classes + var allClassesMatch = true; + for(var k = 0; k < query.classes.length; k++){ + var cls = query.classes[k]; + + allClassesMatch = allClassesMatch && element.hasClass(cls); + + if( !allClassesMatch ) break; + } + if( !allClassesMatch ) return false; + + // generic checking for data/metadata + var operandsMatch = function(params){ + var allDataMatches = true; + for(var k = 0; k < query[params.name].length; k++){ + var data = query[params.name][k]; + var operator = data.operator; + var value = data.value; + var field = data.field; + var matches; + + if( operator != null && value != null ){ + + var fieldVal = params.fieldValue(field); + var fieldStr = !is.string(fieldVal) && !is.number(fieldVal) ? '' : '' + fieldVal; + var valStr = '' + value; + + var caseInsensitive = false; + if( operator.indexOf('@') >= 0 ){ + fieldStr = fieldStr.toLowerCase(); + valStr = valStr.toLowerCase(); + + operator = operator.replace('@', ''); + caseInsensitive = true; + } + + var notExpr = false; + var handledNotExpr = false; + if( operator.indexOf('!') >= 0 ){ + operator = operator.replace('!', ''); + notExpr = true; + } + + // if we're doing a case insensitive comparison, then we're using a STRING comparison + // even if we're comparing numbers + if( caseInsensitive ){ + value = valStr.toLowerCase(); + fieldVal = fieldStr.toLowerCase(); + } + + switch(operator){ + case '*=': + matches = fieldStr.search(valStr) >= 0; + break; + case '$=': + matches = new RegExp(valStr + '$').exec(fieldStr) != null; + break; + case '^=': + matches = new RegExp('^' + valStr).exec(fieldStr) != null; + break; + case '=': + matches = fieldVal === value; + break; + case '!=': + matches = fieldVal !== value; + break; + case '>': + matches = !notExpr ? fieldVal > value : fieldVal <= value; + handledNotExpr = true; + break; + case '>=': + matches = !notExpr ? fieldVal >= value : fieldVal < value; + handledNotExpr = true; + break; + case '<': + matches = !notExpr ? fieldVal < value : fieldVal >= value; + handledNotExpr = true; + break; + case '<=': + matches = !notExpr ? fieldVal <= value : fieldVal > value; + handledNotExpr = true; + break; + default: + matches = false; + break; + + } + } else if( operator != null ){ + switch(operator){ + case '?': + matches = params.fieldTruthy(field); + break; + case '!': + matches = !params.fieldTruthy(field); + break; + case '^': + matches = params.fieldUndefined(field); + break; + } + } else { + matches = !params.fieldUndefined(field); + } + + if( notExpr && !handledNotExpr ){ + matches = !matches; + handledNotExpr = true; + } + + if( !matches ){ + allDataMatches = false; + break; + } + } // for + + return allDataMatches; + }; // operandsMatch + + // check data matches + var allDataMatches = operandsMatch({ + name: 'data', + fieldValue: function(field){ + return element._private.data[field]; + }, + fieldRef: function(field){ + return 'element._private.data.' + field; + }, + fieldUndefined: function(field){ + return element._private.data[field] === undefined; + }, + fieldTruthy: function(field){ + if( element._private.data[field] ){ + return true; + } + return false; + } + }); + + if( !allDataMatches ){ + return false; + } + + // check metadata matches + var allMetaMatches = operandsMatch({ + name: 'meta', + fieldValue: function(field){ + return element[field](); + }, + fieldRef: function(field){ + return 'element.' + field + '()'; + }, + fieldUndefined: function(field){ + return element[field]() == null; + }, + fieldTruthy: function(field){ + if( element[field]() ){ + return true; + } + return false; + } + }); + + if( !allMetaMatches ){ + return false; + } + + // check collection + if( query.collection != null ){ + var matchesAny = query.collection._private.ids[ element.id() ] != null; + + if( !matchesAny ){ + return false; + } + } + + // check filter function + if( query.filter != null && element.collection().filter( query.filter ).size() === 0 ){ + return false; + } + + + // check parent/child relations + var confirmRelations = function( query, elements ){ + if( query != null ){ + var matches = false; + + if( !cy.hasCompoundNodes() ){ + return false; + } + + elements = elements(); // make elements functional so we save cycles if query == null + + // query must match for at least one element (may be recursive) + for(var i = 0; i < elements.length; i++){ + if( queryMatches( query, elements[i] ) ){ + matches = true; + break; + } + } + + return matches; + } else { + return true; + } + }; + + if (! confirmRelations(query.parent, function(){ + return element.parent(); + }) ){ return false; } + + if (! confirmRelations(query.ancestor, function(){ + return element.parents(); + }) ){ return false; } + + if (! confirmRelations(query.child, function(){ + return element.children(); + }) ){ return false; } + + if (! confirmRelations(query.descendant, function(){ + return element.descendants(); + }) ){ return false; } + + // we've reached the end, so we've matched everything for this query + return true; +}; // queryMatches + +// filter an existing collection +selfn.filter = function(collection){ + var self = this; + var cy = collection.cy(); + + // don't bother trying if it's invalid + if( self._private.invalid ){ + return cy.collection(); + } + + var selectorFunction = function(i, element){ + for(var j = 0; j < self.length; j++){ + var query = self[j]; + + if( queryMatches(query, element) ){ + return true; + } + } + + return false; + }; + + if( self._private.selectorText == null ){ + selectorFunction = function(){ return true; }; + } + + var filteredCollection = collection.filter( selectorFunction ); + + return filteredCollection; +}; // filter + +// does selector match a single element? +selfn.matches = function(ele){ + var self = this; + + // don't bother trying if it's invalid + if( self._private.invalid ){ + return false; + } + + for(var j = 0; j < self.length; j++){ + var query = self[j]; + + if( queryMatches(query, ele) ){ + return true; + } + } + + return false; +}; // filter + +// ith query to string +selfn.toString = selfn.selector = function(){ + + var str = ''; + + var clean = function(obj, isValue){ + if( is.string(obj) ){ + return isValue ? '"' + obj + '"' : obj; + } + return ''; + }; + + var queryToString = function(query){ + var str = ''; + + if( query.subject === query ){ + str += '$'; + } + + var group = clean(query.group); + str += group.substring(0, group.length - 1); + + for(var j = 0; j < query.data.length; j++){ + var data = query.data[j]; + + if( data.value ){ + str += '[' + data.field + clean(data.operator) + clean(data.value, true) + ']'; + } else { + str += '[' + clean(data.operator) + data.field + ']'; + } + } + + for(var j = 0; j < query.meta.length; j++){ + var meta = query.meta[j]; + str += '[[' + meta.field + clean(meta.operator) + clean(meta.value, true) + ']]'; + } + + for(var j = 0; j < query.colonSelectors.length; j++){ + var sel = query.colonSelectors[i]; + str += sel; + } + + for(var j = 0; j < query.ids.length; j++){ + var sel = '#' + query.ids[i]; + str += sel; + } + + for(var j = 0; j < query.classes.length; j++){ + var sel = '.' + query.classes[j]; + str += sel; + } + + if( query.parent != null ){ + str = queryToString( query.parent ) + ' > ' + str; + } + + if( query.ancestor != null ){ + str = queryToString( query.ancestor ) + ' ' + str; + } + + if( query.child != null ){ + str += ' > ' + queryToString( query.child ); + } + + if( query.descendant != null ){ + str += ' ' + queryToString( query.descendant ); + } + + return str; + }; + + for(var i = 0; i < this.length; i++){ + var query = this[i]; + + str += queryToString( query ); + + if( this.length > 1 && i < this.length - 1 ){ + str += ', '; + } + } + + return str; +}; + +module.exports = Selector; + +},{"./is":77,"./util":94}],82:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../util'); +var is = _dereq_('../is'); + +var styfn = {}; + +// (potentially expensive calculation) +// apply the style to the element based on +// - its bypass +// - what selectors match it +styfn.apply = function( eles ){ + var self = this; + + if( self._private.newStyle ){ // clear style caches + this._private.contextStyles = {}; + this._private.propDiffs = {}; + } + + for( var ie = 0; ie < eles.length; ie++ ){ + var ele = eles[ie]; + var cxtMeta = self.getContextMeta( ele ); + var cxtStyle = self.getContextStyle( cxtMeta ); + var app = self.applyContextStyle( cxtMeta, cxtStyle, ele ); + + self.updateTransitions( ele, app.diffProps ); + self.updateStyleHints( ele ); + + } // for elements + + self._private.newStyle = false; +}; + +styfn.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] === 't'; + var newHasCxt = newCxtKey[i] === 't'; + var cxtHasDiffed = oldHasCxt !== newHasCxt; + var cxtHasMappedProps = cxt.mappedProperties.length > 0; + + if( cxtHasDiffed || cxtHasMappedProps ){ + var props; + + 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] === 't'; + + 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.getContextMeta = function( ele ){ + var self = this; + var cxtKey = ''; + var diffProps; + var prevKey = ele._private.styleCxtKey || ''; + + if( self._private.newStyle ){ + prevKey = ''; // since we need to apply all style if a fresh stylesheet + } + + // 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 += 't'; + } else { + cxtKey += 'f'; + } + } // for context + + diffProps = self.getPropertiesDiff( prevKey, cxtKey ); + + ele._private.styleCxtKey = cxtKey; + + return { + key: cxtKey, + diffPropNames: diffProps + }; +}; + +// gets a computed ele style object based on matched contexts +styfn.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] === 't'; + + if( !hasCxt ){ continue; } + + for( var j = 0; j < cxt.properties.length; j++ ){ + var prop = cxt.properties[j]; + var styProp = style[ prop.name ] = prop; + + styProp.context = cxt; + } + } + + cxtStyles[cxtKey] = style; + return style; +}; + +styfn.applyContextStyle = function( cxtMeta, cxtStyle, ele ){ + var self = this; + var diffProps = cxtMeta.diffPropNames; + var retDiffProps = {}; + + for( var i = 0; i < diffProps.length; i++ ){ + var diffPropName = diffProps[i]; + var cxtProp = cxtStyle[ diffPropName ]; + var eleProp = ele._private.style[ diffPropName ]; + + // save cycles when the context prop doesn't need to be applied + if( !cxtProp || eleProp === cxtProp ){ continue; } + + var retDiffProp = retDiffProps[ diffPropName ] = { + prev: eleProp + }; + + self.applyParsedProperty( ele, cxtProp ); + + retDiffProp.next = ele._private.style[ diffPropName ]; + + if( retDiffProp.next && retDiffProp.next.bypass ){ + retDiffProp.next = retDiffProp.next.bypassed; + } + } + + return { + diffProps: retDiffProps + }; +}; + +styfn.updateStyleHints = function(ele){ + var _p = ele._private; + var self = this; + var style = _p.style; + + if( ele.removed() ){ return; } + + // set whether has pie or not; for greater efficiency + var hasPie = false; + if( _p.group === 'nodes' && self._private.hasPie ){ + for( var i = 1; i <= self.pieBackgroundN; i++ ){ // 1..N + var size = _p.style['pie-' + i + '-background-size'].value; + + if( size > 0 ){ + hasPie = true; + break; + } + } + } + + _p.hasPie = hasPie; + + var transform = style['text-transform'].strValue; + var content = style['label'].strValue; + var fStyle = style['font-style'].strValue; + var size = style['font-size'].pfValue + 'px'; + var family = style['font-family'].strValue; + // var variant = style['font-variant'].strValue; + var weight = style['font-weight'].strValue; + var valign = style['text-valign'].strValue; + var halign = style['text-valign'].strValue; + var oWidth = style['text-outline-width'].pfValue; + var wrap = style['text-wrap'].strValue; + var wrapW = style['text-max-width'].pfValue; + _p.labelKey = fStyle +'$'+ size +'$'+ family +'$'+ weight +'$'+ content +'$'+ transform +'$'+ valign +'$'+ halign +'$'+ oWidth + '$' + wrap + '$' + wrapW; + _p.fontKey = fStyle +'$'+ weight +'$'+ size +'$'+ family; + + var width = style['width'].pfValue; + var height = style['height'].pfValue; + var borderW = style['border-width'].pfValue; + _p.boundingBoxKey = width +'$'+ height +'$'+ borderW; + + if( ele._private.group === 'edges' ){ + var cpss = style['control-point-step-size'].pfValue; + var cpd = style['control-point-distances'] ? style['control-point-distances'].pfValue.join('_') : undefined; + var cpw = style['control-point-weights'].value.join('_'); + var curve = style['curve-style'].strValue; + var sd = style['segment-distances'] ? style['segment-distances'].pfValue.join('_') : undefined; + var sw = style['segment-weights'].value.join('_'); + + _p.boundingBoxKey += '$'+ cpss +'$'+ cpd +'$'+ cpw +'$'+ sd +'$'+ sw +'$'+ curve; + } + + _p.styleKey = Date.now(); +}; + +// 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.applyParsedProperty = function( ele, parsedProp ){ + var self = this; + var prop = parsedProp; + var style = ele._private.style; + var fieldVal, 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; + + // can't apply auto to width or height unless it's a parent node + if( (parsedProp.name === 'height' || parsedProp.name === 'width') && ele.isNode() ){ + if( parsedProp.value === 'auto' && !ele.isParent() ){ + return false; + } else if( parsedProp.value !== 'auto' && ele.isParent() ){ + prop = parsedProp = this.parse( parsedProp.name, 'auto', propIsBypass ); + } + } + + // check if we need to delete the current bypass + if( propIsBypass && prop.deleteBypass ){ // then this property is just here to indicate we need to delete + var currentProp = style[ prop.name ]; + + // can only delete if the current prop is a bypass and it points to the property it was overriding + if( !currentProp ){ + return true; // property is already not defined + } else if( currentProp.bypass && currentProp.bypassed ){ // 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 ] = currentProp.bypassed; + return true; + + } else { + return false; // we're unsuccessful deleting the bypass + } + } + + var printMappingErr = function(){ + util.error('Do not assign mappings to elements without corresponding data (e.g. ele `'+ ele.id() +'` 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: + case types.mapLayoutData: + case types.mapScratch: + + var isLayout = prop.mapped === types.mapLayoutData; + var isScratch = prop.mapped === types.mapScratch; + + // flatten the field (e.g. data.foo.bar) + var fields = prop.field.split("."); + var fieldVal; + + if( isScratch || isLayout ){ + fieldVal = _p.scratch; + } else { + fieldVal = _p.data; + } + + for( var i = 0; i < fields.length && fieldVal; i++ ){ + var field = fields[i]; + fieldVal = fieldVal[ field ]; + } + + var percent; + if( !is.number(fieldVal) ){ // then keep the mapping but assume 0% for now + percent = 0; + } else { + percent = (fieldVal - prop.fieldMin) / (prop.fieldMax - prop.fieldMin); + } + + // 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, true ); + + } else { + return false; // can only map to colours and numbers + } + + if( !flatProp ){ // if we can't flatten the property, then use the origProp so we still keep the mapping itself + flatProp = this.parse( prop.name, origProp.strValue, prop.bypass, true ); + } + + if( !flatProp ){ printMappingErr(); } + 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: + case types.layoutData: + case types.scratch: + var isLayout = prop.mapped === types.layoutData; + var isScratch = prop.mapped === types.scratch; + + // flatten the field (e.g. data.foo.bar) + var fields = prop.field.split("."); + var fieldVal; + + if( isScratch || isLayout ){ + fieldVal = _p.scratch; + } else { + fieldVal = _p.data; + } + + if( fieldVal ){ for( var i = 0; i < fields.length; i++ ){ + var field = fields[i]; + fieldVal = fieldVal[ field ]; + } } + + flatProp = this.parse( prop.name, fieldVal, prop.bypass, true ); + + if( !flatProp ){ // if we can't flatten the property, then use the origProp so we still keep the mapping itself + var flatPropVal = origProp ? origProp.strValue : ''; + + flatProp = this.parse( prop.name, flatPropVal, prop.bypass, true ); + } + + if( !flatProp ){ printMappingErr(); } + 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 = fn( ele ); + + flatProp = this.parse( prop.name, fnRetVal, prop.bypass, true ); + flatProp.mapping = 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; + } + } + + return true; +}; + +// updates the visual style for all elements (useful for manual style modification after init) +styfn.update = function(){ + var cy = this._private.cy; + var eles = cy.elements(); + + eles.updateStyle(); +}; + +// just update the functional properties (i.e. mappings) in the elements' +// styles (less expensive than recalculation) +styfn.updateMappers = function( eles ){ + var self = this; + + for( var i = 0; i < eles.length; i++ ){ // for each ele + var ele = eles[i]; + var style = ele._private.style; + + for( var j = 0; j < self.properties.length; j++ ){ // for each prop + var prop = self.properties[j]; + var propInStyle = style[ prop.name ]; + + if( propInStyle && propInStyle.mapping ){ + var mapping = propInStyle.mapping; + this.applyParsedProperty( ele, mapping ); // reapply the mapping property + } + } + + this.updateStyleHints( ele ); + } +}; + +// diffProps : { name => { prev, next } } +styfn.updateTransitions = function( ele, diffProps, isBypass ){ + var self = this; + var _p = ele._private; + var style = _p.style; + var props = style['transition-property'].value; + var duration = style['transition-duration'].pfValue; + var delay = style['transition-delay'].pfValue; + var css = {}; + + if( props.length > 0 && duration > 0 ){ + + // build up the style to animate towards + var anyPrev = false; + for( var i = 0; i < props.length; i++ ){ + var prop = props[i]; + var styProp = style[ 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; + var initDt = 0.000001; // delta time % value for initVal (allows animating out of init zero opacity) + + if( !fromProp ){ continue; } + + // consider px values + if( is.number( fromProp.pfValue ) && is.number( toProp.pfValue ) ){ + diff = toProp.pfValue - fromProp.pfValue; // nonzero is truthy + initVal = fromProp.pfValue + initDt * diff; + + // consider numerical values + } else if( is.number( fromProp.value ) && is.number( toProp.value ) ){ + diff = toProp.value - fromProp.value; // nonzero is truthy + initVal = fromProp.value + initDt * diff; + + // consider colour values + } else if( is.array( fromProp.value ) && is.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 ){ + css[ 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; + + ele.stop(); + + if( delay > 0 ){ + ele.delay( delay ); + } + + ele.animate({ + css: css + }, { + duration: duration, + easing: style['transition-timing-function'].value, + queue: false, + complete: function(){ + if( !isBypass ){ + self.removeBypasses( ele, props ); + } + + _p.transitioning = false; + } + }); + + } else if( _p.transitioning ){ + ele.stop(); + + this.removeBypasses( ele, props ); + + _p.transitioning = false; + } +}; + +module.exports = styfn; + +},{"../is":77,"../util":94}],83:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../is'); +var util = _dereq_('../util'); + +var styfn = {}; + +// 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.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( is.string(name) ){ // then parse the single property + var parsedProp = this.parse(name, value, true); + + if( parsedProp ){ + props.push( parsedProp ); + } + } else if( is.plainObject(name) ){ // then parse each property + var specifiedProps = name; + updateTransitions = value; + + for( var i = 0; i < self.properties.length; i++ ){ + var prop = self.properties[i]; + var name = prop.name; + var value = specifiedProps[ name ]; + + if( value === undefined ){ // try camel case name too + value = specifiedProps[ util.dash2camel(name) ]; + } + + if( value !== undefined ){ + var parsedProp = this.parse(name, value, true); + + if( parsedProp ){ + props.push( parsedProp ); + } + } + } + } 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 i = 0; i < eles.length; i++ ){ // for each ele + var ele = eles[i]; + var style = ele._private.style; + var diffProps = {}; + var diffProp; + + for( var j = 0; j < props.length; j++ ){ // for each prop + var prop = props[j]; + + if( updateTransitions ){ + var prevProp = style[ prop.name ]; + diffProp = diffProps[ prop.name ] = { prev: prevProp }; + } + + ret = this.applyParsedProperty( ele, prop ) || ret; + + if( updateTransitions ){ + diffProp.next = style[ 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.overrideBypass = function( eles, name, value ){ + name = util.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; + + if( !prop.bypass ){ // need a bypass if one doesn't exist + this.applyBypass( ele, name, value ); + continue; + } + + 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; + } + } +}; + +styfn.removeAllBypasses = function( eles, updateTransitions ){ + return this.removeBypasses( eles, this.propertyNames, updateTransitions ); +}; + +styfn.removeBypasses = function( eles, props, updateTransitions ){ + var isBypass = true; + + for( var j = 0; j < eles.length; j++ ){ + var ele = eles[j]; + var diffProps = {}; + var style = ele._private.style; + + for( var i = 0; i < props.length; i++ ){ + var name = props[i]; + var prop = this.properties[ name ]; + var value = ''; // empty => remove bypass + var parsedProp = this.parse(name, value, true); + var prevProp = style[ prop.name ]; + var diffProp = diffProps[ prop.name ] = { prev: prevProp }; + + this.applyParsedProperty(ele, parsedProp); + + diffProp.next = style[ prop.name ]; + } // for props + + this.updateStyleHints( ele ); + + if( updateTransitions ){ + this.updateTransitions( ele, diffProps, isBypass ); + } + } // for eles +}; + +module.exports = styfn; + +},{"../is":77,"../util":94}],84:[function(_dereq_,module,exports){ +'use strict'; + +var window = _dereq_('../window'); + +var styfn = {}; + +// gets what an em size corresponds to in pixels relative to a dom element +styfn.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.containerCss = function( propName ){ + var cy = this._private.cy; + var domElement = cy.container(); + + if( window && domElement && window.getComputedStyle ){ + return window.getComputedStyle(domElement).getPropertyValue( propName ); + } +}; + +module.exports = styfn; + +},{"../window":100}],85:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../util'); +var is = _dereq_('../is'); + +var styfn = {}; + +// gets the rendered style for an element +styfn.getRenderedStyle = function( ele ){ + return this.getRawStyle( ele, true ); +}; + +// gets the raw style for an element +styfn.getRawStyle = function( ele, isRenderedVal ){ + var self = this; + var 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 ){ + rstyle[ prop.name ] = val; + rstyle[ util.dash2camel(prop.name) ] = val; + } + } + + return rstyle; + } +}; + +styfn.getStylePropertyValue = function( ele, propName, isRenderedVal ){ + var self = this; + var ele = ele[0]; // insure it's an element + + if( ele ){ + var style = ele._private.style; + var prop = self.properties[ propName ]; + var type = prop.type; + var styleProp = style[ prop.name ]; + var zoom = ele.cy().zoom(); + + if( styleProp ){ + var units = styleProp.units ? type.implicitUnits || 'px' : null; + var val = units ? [].concat( styleProp.pfValue ).map(function( pfValue ){ + return ( pfValue * (isRenderedVal ? zoom : 1) ) + units; + }).join(' ') : styleProp.strValue; + + return val; + } + } +}; + +// gets the value style for an element (useful for things like animations) +styfn.getValueStyle = function( ele ){ + var self = this; + var rstyle = {}; + var style; + var isEle = is.element(ele); + + if( isEle ){ + style = ele._private.style; + } else { + style = ele; // just passed the style itself + } + + if( style ){ + for( var i = 0; i < self.properties.length; i++ ){ + var prop = self.properties[i]; + var styleProp = style[ prop.name ] || style[ util.dash2camel(prop.name) ]; + + if( styleProp !== undefined ){ // then make a prop of it + if( is.plainObject( styleProp ) ){ + styleProp = this.parse( prop.name, styleProp.strValue ); + } else { + styleProp = this.parse( prop.name, styleProp ); + } + } + + if( styleProp ){ + rstyle[ prop.name ] = styleProp; + rstyle[ util.dash2camel(prop.name) ] = styleProp; + } + } + } + + return rstyle; +}; + +styfn.getPropsList = function( propsObj ){ + var self = this; + var rstyle = []; + var style = propsObj; + var props = self.properties; + + if( style ){ + for( var name in style ){ + var val = style[name]; + var prop = props[name] || props[ util.camel2dash(name) ]; + var styleProp = this.parse( prop.name, val ); + + rstyle.push( styleProp ); + } + } + + return rstyle; +}; + +module.exports = styfn; + +},{"../is":77,"../util":94}],86:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../is'); +var util = _dereq_('../util'); +var Selector = _dereq_('../selector'); + +var Style = function( cy ){ + + if( !(this instanceof Style) ){ + return new Style(cy); + } + + if( !is.core(cy) ){ + util.error('A style must have a core reference'); + return; + } + + this._private = { + cy: cy, + coreStyle: {}, + newStyle: true + }; + + this.length = 0; + + this.addDefaultStylesheet(); +}; + +var styfn = Style.prototype; + +styfn.instanceString = function(){ + return 'style'; +}; + +// remove all contexts +styfn.clear = function(){ + for( var i = 0; i < this.length; i++ ){ + this[i] = undefined; + } + this.length = 0; + this._private.newStyle = true; + + return this; // chaining +}; + +styfn.resetToDefault = function(){ + this.clear(); + this.addDefaultStylesheet(); + + return this; +}; + +// builds a style object for the 'core' selector +styfn.core = function(){ + return this._private.coreStyle; +}; + +// 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; + + switch( args.length ){ + case 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[ util.dash2camel(prop.name) ]; + } + + if( mapVal !== undefined ){ + this.cssRule( prop.name, mapVal ); + } + } + + break; + + case 2: + this.cssRule( args[0], args[1] ); + break; + + default: + break; // 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 +}; + +// 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 ); +}; + +[ + _dereq_('./apply'), + _dereq_('./bypass'), + _dereq_('./container'), + _dereq_('./get-for-ele'), + _dereq_('./json'), + _dereq_('./string-sheet'), + _dereq_('./properties'), + _dereq_('./parse') +].forEach(function( props ){ + util.extend( styfn, props ); +}); + + +Style.types = styfn.types; +Style.properties = styfn.properties; + +module.exports = Style; + +},{"../is":77,"../selector":81,"../util":94,"./apply":82,"./bypass":83,"./container":84,"./get-for-ele":85,"./json":87,"./parse":88,"./properties":89,"./string-sheet":90}],87:[function(_dereq_,module,exports){ +'use strict'; + +var styfn = {}; + +styfn.applyFromJson = 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; + + style.selector( selector ); // apply selector + + for( var name in props ){ + var value = props[name]; + + style.css( name, value ); // apply property + } + } + + return style; +}; + +// accessible cy.style() function +styfn.fromJson = function( json ){ + var style = this; + + style.resetToDefault(); + style.applyFromJson( json ); + + return style; +}; + +// get json from cy.style() api +styfn.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; +}; + +module.exports = styfn; + +},{}],88:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../util'); +var is = _dereq_('../is'); + +var styfn = {}; + +// a caching layer for property parsing +styfn.parse = function( name, value, propIsBypass, propIsFlat ){ + var argHash = [ name, value, propIsBypass, propIsFlat ].join('$'); + var propCache = this.propCache = this.propCache || {}; + var ret; + var impl = parseImpl.bind( this ); + + if( !(ret = propCache[argHash]) ){ + ret = propCache[argHash] = impl( name, value, propIsBypass, propIsFlat ); + } + + // always need a copy since props are mutated later in their lifecycles + ret = util.copy( ret ); + + if( ret ){ + ret.value = util.copy( ret.value ); // because it could be an array, e.g. colour + } + + return ret; +}; + +// 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 +var parseImpl = function( name, value, propIsBypass, propIsFlat ){ + var self = this; + + name = util.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 || value === null ){ return null; } // can't assign null + + // the property may be an alias + if( property.alias ){ + property = property.pointsTo; + name = property.name; + } + + var valueIsString = is.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( is.fn(value) ){ + return { + name: name, + value: value, + strValue: 'fn', + mapped: types.fn, + bypass: propIsBypass + }; + } + + // check if value is mapped + var data, mapData, layoutData, mapLayoutData, scratch, mapScratch; + if( !valueIsString || propIsFlat ){ + // then don't bother to do the expensive regex checks + + } else if( + ( data = new RegExp( types.data.regex ).exec( value ) ) || + ( layoutData = new RegExp( types.layoutData.regex ).exec( value ) ) || + ( scratch = new RegExp( types.scratch.regex ).exec( value ) ) + ){ + if( propIsBypass ){ return false; } // mappers not allowed in bypass + + var mapped; + if( data ){ + mapped = types.data; + } else if( layoutData ){ + mapped = types.layoutData; + } else { + mapped = types.scratch; + } + + data = data || layoutData || scratch; + + return { + name: name, + value: data, + strValue: '' + value, + mapped: mapped, + field: data[1], + bypass: propIsBypass + }; + + } else if( + ( mapData = new RegExp( types.mapData.regex ).exec( value ) ) || + ( mapLayoutData = new RegExp( types.mapLayoutData.regex ).exec( value ) ) || + ( mapScratch = new RegExp( types.mapScratch.regex ).exec( value ) ) + ){ + if( propIsBypass ){ return false; } // mappers not allowed in bypass + if( type.multiple ){ return false; } // impossible to map to num + + var mapped; + if( mapData ){ + mapped = types.mapData; + } else if( mapLayoutData ){ + mapped = types.mapLayoutData; + } else { + mapped = types.mapScratch; + } + + mapData = mapData || mapLayoutData || mapScratch; + + // 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.value === valueMax.value ){ + return false; // 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( is.array(value) ){ + vals = value; + } else { + vals = [ value ]; + } + + if( type.evenMultiple && vals.length % 2 !== 0 ){ return null; } + + var valArr = vals.map(function( v ){ + var p = self.parse( name, v, propIsBypass, 'multiple' ); + + if( p.pfValue != null ){ + return p.pfValue; + } else { + return p.value; + } + }); + + return { + name: name, + value: valArr, + pfValue: valArr, + strValue: valArr.join(' '), + bypass: propIsBypass, + units: type.number && !type.unitless ? type.implicitUnits || 'px' : undefined + }; + } + + // several types also allow enums + var checkEnums = function(){ + 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( '^(' + util.regex.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 && !is.integer(value) ){ + return null; + } + + // check value is within range + if( (type.min !== undefined && value < type.min) + || (type.max !== undefined && 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 : value * Math.PI/180; + } + + return ret; + + } else if( type.propList ) { + + var props = []; + var propsStr = '' + value; + + if( propsStr === 'none' ){ + // leave empty + + } else { // go over each prop + + var propsSplit = propsStr.split(','); + for( var i = 0; i < propsSplit.length; i++ ){ + var propName = propsSplit[i].trim(); + + if( self.properties[propName] ){ + props.push( propName ); + } + } + + 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 = util.color2tuple( value ); + + if( !tuple ){ return null; } + + return { + name: name, + value: tuple, + strValue: '' + value, + bypass: propIsBypass, + roundValue: true + }; + + } 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 i = 0; i < regexes.length; i++ ){ + var regex = new RegExp( regexes[i] ); // make a regex from the type string + var m = regex.exec( value ); + + if( m ){ // regex matches + return { + name: name, + value: 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 + } + +}; + +module.exports = styfn; + +},{"../is":77,"../util":94}],89:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../util'); + +var styfn = {}; + +(function(){ + var number = util.regex.number; + var rgba = util.regex.rgbaNoBackRefs; + var hsla = util.regex.hslaNoBackRefs; + var hex3 = util.regex.hex3; + var hex6 = util.regex.hex6; + var data = function( prefix ){ return '^' + prefix + '\\s*\\(\\s*([\\w\\.]+)\\s*\\)$'; }; + var mapData = function( prefix ){ + var mapArg = number + '|\\w+|' + rgba + '|' + hsla + '|' + hex3 + '|' + hex6; + return '^' + prefix + '\\s*\\(([\\w\\.]+)\\s*\\,\\s*(' + number + ')\\s*\\,\\s*(' + number + ')\\s*,\\s*(' + mapArg + ')\\s*\\,\\s*(' + mapArg + ')\\)$'; + }; + + // each visual style property has a type and needs to be validated according to it + styfn.types = { + time: { number: true, min: 0, units: 's|ms', implicitUnits: 'ms' }, + percent: { number: true, min: 0, max: 100, units: '%', implicitUnits: '%' }, + zeroOneNumber: { number: true, min: 0, max: 1, unitless: true }, + nOneOneNumber: { number: true, min: -1, max: 1, unitless: true }, + nonNegativeInt: { number: true, min: 0, integer: true, unitless: true }, + position: { enums: ['parent', 'origin'] }, + nodeSize: { number: true, min: 0, enums: ['auto', 'label'] }, + number: { number: true, unitless: true }, + numbers: { number: true, unitless: true, multiple: true }, + size: { number: true, min: 0 }, + bidirectionalSize: { number: true }, // allows negative + bidirectionalSizes: { number: true, multiple: true }, // allows negative + bgSize: { number: true, min: 0, allowPercent: true }, + bgWH: { number: true, min: 0, allowPercent: true, enums: ['auto'] }, + bgPos: { number: true, allowPercent: true }, + bgRepeat: { enums: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat'] }, + bgFit: { enums: ['none', 'contain', 'cover'] }, + bgClip: { enums: ['none', 'node'] }, + color: { color: true }, + bool: { enums: ['yes', 'no'] }, + lineStyle: { enums: ['solid', 'dotted', 'dashed'] }, + borderStyle: { enums: ['solid', 'dotted', 'dashed', 'double'] }, + curveStyle: { enums: ['bezier', 'unbundled-bezier', 'haystack', 'segments'] }, + fontFamily: { regex: '^([\\w- \\"]+(?:\\s*,\\s*[\\w- \\"]+)*)$' }, + fontVariant: { enums: ['small-caps', 'normal'] }, + 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'] }, + textBackgroundShape: { enums: ['rectangle', 'roundrectangle']}, + nodeShape: { enums: ['rectangle', 'roundrectangle', 'ellipse', 'triangle', 'square', 'pentagon', 'hexagon', 'heptagon', 'octagon', 'star', 'diamond', 'vee', 'rhomboid', 'polygon'] }, + compoundIncludeLabels: { enums: ['include', 'exclude'] }, + arrowShape: { enums: ['tee', 'triangle', 'triangle-tee', 'triangle-backcurve', 'half-triangle-overshot', 'vee', 'square', 'circle', 'diamond', 'none'] }, + arrowFill: { enums: ['filled', 'hollow'] }, + display: { enums: ['element', 'none'] }, + visibility: { enums: ['hidden', 'visible'] }, + valign: { enums: ['top', 'center', 'bottom'] }, + halign: { enums: ['left', 'center', 'right'] }, + 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: { regex: '^url\\s*\\(\\s*([^\\s]+)\\s*\\s*\\)|none|(.+)$' }, + propList: { propList: true }, + angle: { number: true, units: 'deg|rad', implicitUnits: 'rad' }, + textRotation: { enums: ['none', 'autorotate'] }, + polygonPointList: { number: true, multiple: true, evenMultiple: true, min: -1, max: 1, unitless: true }, + easing: { + regexes: [ + '^(spring)\\s*\\(\\s*(' + number + ')\\s*,\\s*(' + number + ')\\s*\\)$', + '^(cubic-bezier)\\s*\\(\\s*(' + number + ')\\s*,\\s*(' + number + ')\\s*,\\s*(' + number + ')\\s*,\\s*(' + number + ')\\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' + ] + } + }; + + // define visual style properties + var t = styfn.types; + var props = styfn.properties = [ + // labels + { name: 'text-valign', type: t.valign }, + { name: 'text-halign', type: t.halign }, + { name: 'color', type: t.color }, + { name: 'label', type: t.text }, + { name: 'text-outline-color', type: t.color }, + { name: 'text-outline-width', type: t.size }, + { name: 'text-outline-opacity', type: t.zeroOneNumber }, + { name: 'text-opacity', type: t.zeroOneNumber }, + { name: 'text-background-color', type: t.color }, + { name: 'text-background-opacity', type: t.zeroOneNumber }, + { name: 'text-border-opacity', type: t.zeroOneNumber }, + { name: 'text-border-color', type: t.color }, + { name: 'text-border-width', type: t.size }, + { name: 'text-border-style', type: t.borderStyle }, + { name: 'text-background-shape', type: t.textBackgroundShape}, + // { name: 'text-decoration', type: t.textDecoration }, // not supported in canvas + { name: 'text-transform', type: t.textTransform }, + { name: 'text-wrap', type: t.textWrap }, + { name: 'text-max-width', type: t.size }, + { name: 'text-events', type: t.bool }, + + // { name: 'text-rotation', type: t.angle }, // TODO disabled b/c rotation breaks bounding boxes + { name: 'font-family', type: t.fontFamily }, + { name: 'font-style', type: t.fontStyle }, + // { name: 'font-variant', type: t.fontVariant }, // not useful + { name: 'font-weight', type: t.fontWeight }, + { name: 'font-size', type: t.size }, + { name: 'min-zoomed-font-size', type: t.size }, + { name: 'edge-text-rotation', type: t.textRotation }, + + // behaviour + { name: 'events', type: t.bool }, + + // visibility + { name: 'display', type: t.display }, + { name: 'visibility', type: t.visibility }, + { name: 'opacity', type: t.zeroOneNumber }, + { name: 'z-index', type: t.nonNegativeInt }, + + // overlays + { name: 'overlay-padding', type: t.size }, + { name: 'overlay-color', type: t.color }, + { name: 'overlay-opacity', type: t.zeroOneNumber }, + + // shadows + { name: 'shadow-blur', type: t.size }, + { name: 'shadow-color', type: t.color }, + { name: 'shadow-opacity', type: t.zeroOneNumber }, + { name: 'shadow-offset-x', type: t.bidirectionalSize }, + { name: 'shadow-offset-y', type: t.bidirectionalSize }, + + // label shadows + { name: 'text-shadow-blur', type: t.size }, + { name: 'text-shadow-color', type: t.color }, + { name: 'text-shadow-opacity', type: t.zeroOneNumber }, + { name: 'text-shadow-offset-x', type: t.bidirectionalSize }, + { name: 'text-shadow-offset-y', type: t.bidirectionalSize }, + + // transition anis + { 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 }, + + // node body + { name: 'height', type: t.nodeSize }, + { name: 'width', type: t.nodeSize }, + { name: 'shape', type: t.nodeShape }, + { name: 'shape-polygon-points', type: t.polygonPointList }, + { name: 'background-color', type: t.color }, + { name: 'background-opacity', type: t.zeroOneNumber }, + { name: 'background-blacken', type: t.nOneOneNumber }, + { name: 'padding-left', type: t.size }, + { name: 'padding-right', type: t.size }, + { name: 'padding-top', type: t.size }, + { name: 'padding-bottom', type: t.size }, + + // node border + { name: 'border-color', type: t.color }, + { name: 'border-opacity', type: t.zeroOneNumber }, + { name: 'border-width', type: t.size }, + { name: 'border-style', type: t.borderStyle }, + + // node background images + { name: 'background-image', type: t.url }, + { name: 'background-image-opacity', type: t.zeroOneNumber }, + { name: 'background-position-x', type: t.bgPos }, + { name: 'background-position-y', type: t.bgPos }, + { 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 }, + + // compound props + { name: 'position', type: t.position }, + { name: 'compound-sizing-wrt-labels', type: t.compoundIncludeLabels }, + + // edge line + { name: 'line-style', type: t.lineStyle }, + { name: 'line-color', type: t.color }, + { name: 'curve-style', type: t.curveStyle }, + { name: 'haystack-radius', type: t.zeroOneNumber }, + { name: 'control-point-step-size', type: t.size }, + { name: 'control-point-distances', type: t.bidirectionalSizes }, + { name: 'control-point-weights', type: t.numbers }, + { name: 'segment-distances', type: t.bidirectionalSizes }, + { name: 'segment-weights', type: t.numbers }, + + // these are just for the 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 } + ]; + + // define aliases + var aliases = styfn.aliases = [ + { name: 'content', pointsTo: 'label' }, + { name: 'control-point-distance', pointsTo: 'control-point-distances' }, + { name: 'control-point-weight', pointsTo: 'control-point-weights' } + ]; + + // pie backgrounds for nodes + styfn.pieBackgroundN = 16; // because the pie properties are numbered, give access to a constant N (for renderer use) + props.push({ name: 'pie-size', type: t.bgSize }); + for( var i = 1; i <= styfn.pieBackgroundN; i++ ){ + props.push({ name: 'pie-'+i+'-background-color', type: t.color }); + props.push({ name: 'pie-'+i+'-background-size', type: t.percent }); + props.push({ name: 'pie-'+i+'-background-opacity', type: t.zeroOneNumber }); + } + + // edge arrows + var arrowPrefixes = styfn.arrowPrefixes = ['source', 'mid-source', 'target', 'mid-target']; + [ + { name: 'arrow-shape', type: t.arrowShape }, + { name: 'arrow-color', type: t.color }, + { name: 'arrow-fill', type: t.arrowFill } + ].forEach(function( prop ){ + arrowPrefixes.forEach(function( prefix ){ + var name = prefix + '-' + prop.name; + var type = prop.type; + + props.push({ name: name, type: type }); + }); + }, {}); + + // list of property names + styfn.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 i = 0; i < aliases.length; i++ ){ + var alias = aliases[i]; + 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 + } +})(); + +// adds the default stylesheet to the current style +styfn.addDefaultStylesheet = function(){ + // fill the style with the default stylesheet + this + .selector('node, edge') // common properties + .css( util.extend( { + 'events': 'yes', + 'text-events': 'no', + 'text-valign': 'top', + 'text-halign': 'center', + '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-max-width': 9999, + 'text-background-color': '#000', + 'text-background-opacity': 0, + 'text-border-opacity': 0, + 'text-border-width': 0, + 'text-border-style': 'solid', + 'text-border-color':'#000', + 'text-background-shape':'rectangle', + 'font-family': 'Helvetica Neue, Helvetica, sans-serif', + 'font-style': 'normal', + // 'font-variant': fontVariant, + 'font-weight': 'normal', + 'font-size': 16, + 'min-zoomed-font-size': 0, + 'edge-text-rotation': 'none', + 'visibility': 'visible', + 'display': 'element', + 'opacity': 1, + 'z-index': 0, + 'label': '', + 'overlay-opacity': 0, + 'overlay-color': '#000', + 'overlay-padding': 10, + 'shadow-opacity': 0, + 'shadow-color': '#000', + 'shadow-blur': 10, + 'shadow-offset-x': 0, + 'shadow-offset-y': 0, + 'text-shadow-opacity': 0, + 'text-shadow-color': '#000', + 'text-shadow-blur': 5, + 'text-shadow-offset-x': 0, + 'text-shadow-offset-y': 0, + 'transition-property': 'none', + 'transition-duration': 0, + 'transition-delay': 0, + 'transition-timing-function': 'linear', + + // node props + 'background-blacken': 0, + 'background-color': '#888', + 'background-opacity': 1, + 'background-image': 'none', + 'background-image-opacity': 1, + 'background-position-x': '50%', + 'background-position-y': '50%', + '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', + 'height': 30, + 'width': 30, + 'shape': 'ellipse', + 'shape-polygon-points': '-1, -1, 1, -1, 1, 1, -1, 1', + + // compound props + 'padding-top': 0, + 'padding-bottom': 0, + 'padding-left': 0, + 'padding-right': 0, + 'position': 'origin', + 'compound-sizing-wrt-labels': 'include' + }, { + // 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.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': '#ddd', + 'control-point-step-size': 40, + 'control-point-weights': 0.5, + 'segment-weights': 0.5, + 'segment-distances': 20, + 'curve-style': 'bezier', + 'haystack-radius': 0.8 + }, [ + { name: 'arrow-shape', value: 'none' }, + { name: 'arrow-color', value: '#ddd' }, + { name: 'arrow-fill', value: 'filled' } + ].reduce(function( css, prop ){ + styfn.arrowPrefixes.forEach(function( prefix ){ + var name = prefix + '-' + prop.name; + var val = prop.value; + + css[ name ] = val; + }); + + return css; + }, {}) ) ) + .selector('$node > node') // compound (parent) node properties + .css({ + 'width': 'auto', + 'height': 'auto', + 'shape': 'rectangle', + 'padding-top': 10, + 'padding-right': 10, + 'padding-left': 10, + 'padding-bottom': 10 + }) + .selector('edge') // just edge properties + .css({ + 'width': 1 + }) + .selector(':active') + .css({ + 'overlay-color': 'black', + 'overlay-padding': 10, + 'overlay-opacity': 0.25 + }) + .selector('core') // just core properties + .css({ + '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 + }) + ; + + this.defaultLength = this.length; +}; + +module.exports = styfn; + +},{"../util":94}],90:[function(_dereq_,module,exports){ +'use strict'; + +var util = _dereq_('../util'); +var Selector = _dereq_('../selector'); + +var styfn = {}; + +styfn.applyFromString = 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 = ''; + } + } + + while(true){ + var nothingLeftToParse = remaining.match(/^\s*$/); + if( nothingLeftToParse ){ break; } + + var selAndBlock = remaining.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/); + + if( !selAndBlock ){ + util.error('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._private.invalid ){ + util.error('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 = []; + + while(true){ + var nothingLeftToParse = blockRem.match(/^\s*$/); + if( nothingLeftToParse ){ break; } + + var propAndVal = blockRem.match(/^\s*(.+?)\s*:\s*(.+?)\s*;/); + + if( !propAndVal ){ + util.error('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 ){ + util.error('Skipping property: Invalid property name in: ' + propAndValStr); + + // skip this property in the block + removePropAndValFromRem(); + continue; + } + + var parsedProp = style.parse( propStr, valStr ); + + if( !parsedProp ){ + util.error('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.fromString = function( string ){ + var style = this; + + style.resetToDefault(); + style.applyFromString( string ); + + return style; +}; + +module.exports = styfn; + +},{"../selector":81,"../util":94}],91:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('./is'); +var util = _dereq_('./util'); +var Style = _dereq_('./style'); + +// a dummy stylesheet object that doesn't need a reference to the core +// (useful for init) +var Stylesheet = function(){ + 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( is.string(name) ){ + this[i].properties.push({ + name: name, + value: value + }); + } else if( is.plainObject(name) ){ + var map = name; + + for( var j = 0; j < Style.properties.length; j++ ){ + var prop = Style.properties[j]; + var mapVal = map[ prop.name ]; + + if( mapVal === undefined ){ // also try camel case name + mapVal = map[ util.dash2camel(prop.name) ]; + } + + if( mapVal !== undefined ){ + 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); + + 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; +}; + +module.exports = Stylesheet; + +},{"./is":77,"./style":86,"./util":94}],92:[function(_dereq_,module,exports){ +// cross-env thread/worker +// NB : uses (heavyweight) processes on nodejs so best not to create too many threads + +'use strict'; + +var window = _dereq_('./window'); +var util = _dereq_('./util'); +var Promise = _dereq_('./promise'); +var Event = _dereq_('./event'); +var define = _dereq_('./define'); +var is = _dereq_('./is'); + +var Thread = function( opts ){ + if( !(this instanceof Thread) ){ + return new Thread( opts ); + } + + var _p = this._private = { + requires: [], + files: [], + queue: null, + pass: [], + disabled: false + }; + + if( is.plainObject(opts) ){ + if( opts.disabled != null ){ + _p.disabled = !!opts.disabled; + } + } + +}; + +var thdfn = Thread.prototype; // short alias + +var stringifyFieldVal = function( val ){ + var valStr = is.fn( val ) ? val.toString() : "JSON.parse('" + JSON.stringify(val) + "')"; + + return valStr; +}; + +// allows for requires with prototypes and subobjs etc +var fnAsRequire = function( fn ){ + var req; + var fnName; + + if( is.object(fn) && fn.fn ){ // manual fn + req = fnAs( fn.fn, fn.name ); + fnName = fn.name; + fn = fn.fn; + } else if( is.fn(fn) ){ // auto fn + req = fn.toString(); + fnName = fn.name; + } else if( is.string(fn) ){ // stringified fn + req = fn; + } else if( is.object(fn) ){ // plain object + if( fn.proto ){ + req = ''; + } else { + req = fn.name + ' = {};'; + } + + fnName = fn.name; + fn = fn.obj; + } + + req += '\n'; + + var protoreq = function( val, subname ){ + if( val.prototype ){ + var protoNonempty = false; + for( var prop in val.prototype ){ protoNonempty = true; break; } // jshint ignore:line + + if( protoNonempty ){ + req += fnAsRequire( { + name: subname, + obj: val, + proto: true + }, val ); + } + } + }; + + // pull in prototype + if( fn.prototype && fnName != null ){ + + for( var name in fn.prototype ){ + var protoStr = ''; + + var val = fn.prototype[ name ]; + var valStr = stringifyFieldVal( val ); + var subname = fnName + '.prototype.' + name; + + protoStr += subname + ' = ' + valStr + ';\n'; + + if( protoStr ){ + req += protoStr; + } + + protoreq( val, subname ); // subobject with prototype + } + + } + + // pull in properties for obj/fns + if( !is.string(fn) ){ for( var name in fn ){ + var propsStr = ''; + + if( fn.hasOwnProperty(name) ){ + var val = fn[ name ]; + var valStr = stringifyFieldVal( val ); + var subname = fnName + '["' + name + '"]'; + + propsStr += subname + ' = ' + valStr + ';\n'; + } + + if( propsStr ){ + req += propsStr; + } + + protoreq( val, subname ); // subobject with prototype + } } + + return req; +}; + +var isPathStr = function( str ){ + return is.string(str) && str.match(/\.js$/); +}; + +util.extend(thdfn, { + + instanceString: function(){ return 'thread'; }, + + require: function( fn, as ){ + var requires = this._private.requires; + + if( isPathStr(fn) ){ + this._private.files.push( fn ); + + return this; + } + + if( as ){ + if( is.fn(fn) ){ + fn = { name: as, fn: fn }; + } else { + fn = { name: as, obj: fn }; + } + } else { + if( is.fn(fn) ){ + if( !fn.name ){ + throw 'The function name could not be automatically determined. Use thread.require( someFunction, "someFunction" )'; + } + + fn = { name: fn.name, fn: fn }; + } + } + + requires.push( fn ); + + return this; // chaining + }, + + pass: function( data ){ + this._private.pass.push( data ); + + return this; // chaining + }, + + run: function( fn, pass ){ // fn used like main() + var self = this; + var _p = this._private; + pass = pass || _p.pass.shift(); + + if( _p.stopped ){ + throw 'Attempted to run a stopped thread! Start a new thread or do not stop the existing thread and reuse it.'; + } + + if( _p.running ){ + return ( _p.queue = _p.queue.then(function(){ // inductive step + return self.run( fn, pass ); + }) ); + } + + var useWW = window != null && !_p.disabled; + var useNode = !window && typeof module !== 'undefined' && !_p.disabled; + + self.trigger('run'); + + var runP = new Promise(function( resolve, reject ){ + + _p.running = true; + + var threadTechAlreadyExists = _p.ran; + + var fnImplStr = is.string( fn ) ? fn : fn.toString(); + + // worker code to exec + var fnStr = '\n' + ( _p.requires.map(function( r ){ + return fnAsRequire( r ); + }) ).concat( _p.files.map(function( f ){ + if( useWW ){ + var wwifyFile = function( file ){ + if( file.match(/^\.\//) || file.match(/^\.\./) ){ + return window.location.origin + window.location.pathname + file; + } else if( file.match(/^\//) ){ + return window.location.origin + '/' + file; + } + return file; + }; + + return 'importScripts("' + wwifyFile(f) + '");'; + } else if( useNode ) { + return 'eval( require("fs").readFileSync("' + f + '", { encoding: "utf8" }) );'; + } else { + throw 'External file `' + f + '` can not be required without any threading technology.'; + } + }) ).concat([ + '( function(){', + 'var ret = (' + fnImplStr + ')(' + JSON.stringify(pass) + ');', + 'if( ret !== undefined ){ resolve(ret); }', // assume if ran fn returns defined value (incl. null), that we want to resolve to it + '} )()\n' + ]).join('\n'); + + // because we've now consumed the requires, empty the list so we don't dupe on next run() + _p.requires = []; + _p.files = []; + + if( useWW ){ + var fnBlob, fnUrl; + + // add normalised thread api functions + if( !threadTechAlreadyExists ){ + var fnPre = fnStr + ''; + + fnStr = [ + 'function _ref_(o){ return eval(o); };', + 'function broadcast(m){ return message(m); };', // alias + 'function message(m){ postMessage(m); };', + 'function listen(fn){', + ' self.addEventListener("message", function(m){ ', + ' if( typeof m === "object" && (m.data.$$eval || m.data === "$$start") ){', + ' } else { ', + ' fn( m.data );', + ' }', + ' });', + '};', + 'self.addEventListener("message", function(m){ if( m.data.$$eval ){ eval( m.data.$$eval ); } });', + 'function resolve(v){ postMessage({ $$resolve: v }); };', + 'function reject(v){ postMessage({ $$reject: v }); };' + ].join('\n'); + + fnStr += fnPre; + + fnBlob = new Blob([ fnStr ], { + type: 'application/javascript' + }); + fnUrl = window.URL.createObjectURL( fnBlob ); + } + // create webworker and let it exec the serialised code + var ww = _p.webworker = _p.webworker || new Worker( fnUrl ); + + if( threadTechAlreadyExists ){ // then just exec new run() code + ww.postMessage({ + $$eval: fnStr + }); + } + + // worker messages => events + var cb; + ww.addEventListener('message', cb = function( m ){ + var isObject = is.object(m) && is.object( m.data ); + + if( isObject && ('$$resolve' in m.data) ){ + ww.removeEventListener('message', cb); // done listening b/c resolve() + + resolve( m.data.$$resolve ); + } else if( isObject && ('$$reject' in m.data) ){ + ww.removeEventListener('message', cb); // done listening b/c reject() + + reject( m.data.$$reject ); + } else { + self.trigger( new Event(m, { type: 'message', message: m.data }) ); + } + }, false); + + if( !threadTechAlreadyExists ){ + ww.postMessage('$$start'); // start up the worker + } + + } else if( useNode ){ + // create a new process + + if( !_p.child ){ + _p.child = ( _dereq_('child_process').fork( _dereq_('path').join(__dirname, 'thread-node-fork') ) ); + } + + var child = _p.child; + + // child process messages => events + var cb; + child.on('message', cb = function( m ){ + if( is.object(m) && ('$$resolve' in m) ){ + child.removeListener('message', cb); // done listening b/c resolve() + + resolve( m.$$resolve ); + } else if( is.object(m) && ('$$reject' in m) ){ + child.removeListener('message', cb); // done listening b/c reject() + + reject( m.$$reject ); + } else { + self.trigger( new Event({}, { type: 'message', message: m }) ); + } + }); + + // ask the child process to eval the worker code + child.send({ + $$eval: fnStr + }); + + } else { // use a fallback mechanism using a timeout + + var promiseResolve = resolve; + var promiseReject = reject; + + var timer = _p.timer = _p.timer || { + + listeners: [], + + exec: function(){ + // as a string so it can't be mangled by minifiers and processors + fnStr = [ + 'function _ref_(o){ return eval(o); };', + 'function broadcast(m){ return message(m); };', + 'function message(m){ self.trigger( new Event({}, { type: "message", message: m }) ); };', + 'function listen(fn){ timer.listeners.push( fn ); };', + 'function resolve(v){ promiseResolve(v); };', + 'function reject(v){ promiseReject(v); };' + ].join('\n') + fnStr; + + // the .run() code + eval( fnStr ); // jshint ignore:line + }, + + message: function( m ){ + var ls = timer.listeners; + + for( var i = 0; i < ls.length; i++ ){ + var fn = ls[i]; + + fn( m ); + } + } + + }; + + timer.exec(); + } + + }).then(function( v ){ + _p.running = false; + _p.ran = true; + + self.trigger('ran'); + + return v; + }); + + if( _p.queue == null ){ + _p.queue = runP; // i.e. first step of inductive promise chain (for queue) + } + + return runP; + }, + + // send the thread a message + message: function( m ){ + var _p = this._private; + + if( _p.webworker ){ + _p.webworker.postMessage( m ); + } + + if( _p.child ){ + _p.child.send( m ); + } + + if( _p.timer ){ + _p.timer.message( m ); + } + + return this; // chaining + }, + + stop: function(){ + var _p = this._private; + + if( _p.webworker ){ + _p.webworker.terminate(); + } + + if( _p.child ){ + _p.child.kill(); + } + + if( _p.timer ){ + // nothing we can do if we've run a timeout + } + + _p.stopped = true; + + return this.trigger('stop'); // chaining + }, + + stopped: function(){ + return this._private.stopped; + } + +}); + +// turns a stringified function into a (re)named function +var fnAs = function( fn, name ){ + var fnStr = fn.toString(); + fnStr = fnStr.replace(/function\s*?\S*?\s*?\(/, 'function ' + name + '('); + + return fnStr; +}; + +var defineFnal = function( opts ){ + opts = opts || {}; + + return function fnalImpl( fn, arg1 ){ + var fnStr = fnAs( fn, '_$_$_' + opts.name ); + + this.require( fnStr ); + + return this.run( [ + 'function( data ){', + ' var origResolve = resolve;', + ' var res = [];', + ' ', + ' resolve = function( val ){', + ' res.push( val );', + ' };', + ' ', + ' var ret = data.' + opts.name + '( _$_$_' + opts.name + ( arguments.length > 1 ? ', ' + JSON.stringify(arg1) : '' ) + ' );', + ' ', + ' resolve = origResolve;', + ' resolve( res.length > 0 ? res : ret );', + '}' + ].join('\n') ); + }; +}; + +util.extend(thdfn, { + reduce: defineFnal({ name: 'reduce' }), + + reduceRight: defineFnal({ name: 'reduceRight' }), + + map: defineFnal({ name: 'map' }) +}); + +// aliases +var fn = thdfn; +fn.promise = fn.run; +fn.terminate = fn.halt = fn.stop; +fn.include = fn.require; + +// pull in event apis +util.extend(thdfn, { + on: define.on(), + one: define.on({ unbindSelfOnTrigger: true }), + off: define.off(), + trigger: define.trigger() +}); + +define.eventAliasesOn( thdfn ); + +module.exports = Thread; + +},{"./define":41,"./event":42,"./is":77,"./promise":80,"./util":94,"./window":100,"child_process":undefined,"path":undefined}],93:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../is'); + +module.exports = { + // get [r, g, b] from #abc or #aabbcc + hex2tuple: function( 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) + hsl2tuple: function( 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("^" + this.regex.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) + rgb2tuple: function( rgb ){ + var ret; + + var m = new RegExp("^" + this.regex.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; + }, + + colorname2tuple: function( color ){ + return this.colors[ color.toLowerCase() ]; + }, + + color2tuple: function( color ){ + return ( is.array(color) ? color : null ) + || this.colorname2tuple(color) + || this.hex2tuple(color) + || this.rgb2tuple(color) + || this.hsl2tuple(color); + }, + + 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] + } +}; + +},{"../is":77}],94:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../is'); +var math = _dereq_('../math'); + +var util = { + + falsify: function(){ return false; }, + + zeroify: function(){ return 0; }, + + noop: function(){}, + + /* jshint ignore:start */ + error: function( msg ){ + if( console.error ){ + console.error.apply( console, arguments ); + + if( console.trace ){ console.trace(); } + } else { + console.log.apply( console, arguments ); + + if( console.trace ){ console.trace(); } + } + }, + /* jshint ignore:end */ + + clone: function( obj ){ + return this.extend( {}, obj ); + }, + + // gets a shallow copy of the argument + copy: function( obj ){ + if( obj == null ){ + return obj; + } if( is.array(obj) ){ + return obj.slice(); + } else if( is.plainObject(obj) ){ + return this.clone( obj ); + } else { + return obj; + } + } + +}; + +util.makeBoundingBox = math.makeBoundingBox.bind( math ); + +util._staticEmptyObject = {}; + +util.staticEmptyObject = function(){ + return util._staticEmptyObject; +}; + +util.extend = Object.assign != null ? Object.assign : function( tgt ){ + var args = arguments; + + for( var i = 1; i < args.length; i++ ){ + var obj = args[i]; + + for( var k in obj ){ + tgt[k] = obj[k]; + } + } + + return tgt; +}; + +[ + _dereq_('./colors'), + _dereq_('./maps'), + { memoize: _dereq_('./memoize') }, + _dereq_('./regex'), + _dereq_('./strings'), + _dereq_('./timing') +].forEach(function( req ){ + util.extend( util, req ); +}); + +module.exports = util; + +},{"../is":77,"../math":79,"./colors":93,"./maps":95,"./memoize":96,"./regex":97,"./strings":98,"./timing":99}],95:[function(_dereq_,module,exports){ +'use strict'; + +var is = _dereq_('../is'); + +module.exports = { + // has anything been set in the map + mapEmpty: function( map ){ + var empty = true; + + if( map != null ){ + for(var i in map){ // jshint ignore:line + empty = false; + break; + } + } + + return empty; + }, + + // pushes to the array at the end of a map (map may not be built) + pushMap: function( options ){ + var array = this.getMap(options); + + if( array == null ){ // if empty, put initial array + this.setMap( this.extend({}, options, { + value: [ options.value ] + }) ); + } else { + array.push( options.value ); + } + }, + + // sets the value in a map (map may not be built) + setMap: function( options ){ + var obj = options.map; + var key; + var keys = options.keys; + var l = keys.length; + + for(var i = 0; i < l; i++){ + var key = keys[i]; + + if( is.plainObject( key ) ){ + this.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 + getMap: function( 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( is.plainObject( key ) ){ + this.error('Tried to get map with object key'); + } + + obj = obj[key]; + + if( obj == null ){ + return obj; + } + } + + return obj; + }, + + // deletes the entry in the map + deleteMap: function( options ){ + var obj = options.map; + var keys = options.keys; + var l = keys.length; + var keepChildren = options.keepChildren; + + for(var i = 0; i < l; i++){ + var key = keys[i]; + + if( is.plainObject( key ) ){ + this.error('Tried to delete map with object key'); + } + + var lastKey = i === options.keys.length - 1; + if( lastKey ){ + + if( keepChildren ){ // then only delete child fields not in keepChildren + for( var child in obj ){ + if( !keepChildren[child] ){ + obj[child] = undefined; + } + } + } else { + obj[key] = undefined; + } + + } else { + obj = obj[key]; + } + } + } +}; + +},{"../is":77}],96:[function(_dereq_,module,exports){ +'use strict'; + +module.exports = function memoize( fn, keyFn ){ + var self = this; + var cache = {}; + + if( !keyFn ){ + keyFn = function(){ + if( arguments.length === 1 ){ + return arguments[0]; + } + + var args = []; + + for( var i = 0; i < arguments.length; i++ ){ + args.push( arguments[i] ); + } + + return args.join('$'); + }; + } + + return function memoizedFn(){ + var args = arguments; + var ret; + var k = keyFn.apply( self, args ); + + if( !(ret = cache[k]) ){ + ret = cache[k] = fn.apply( self, args ); + } + + return ret; + }; +}; + +},{}],97:[function(_dereq_,module,exports){ +'use strict'; + +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}"; + +module.exports = { + regex: { + number: number, + rgba: rgba, + rgbaNoBackRefs: rgbaNoBackRefs, + hsla: hsla, + hslaNoBackRefs: hslaNoBackRefs, + hex3: hex3, + hex6: hex6 + } +}; + +},{}],98:[function(_dereq_,module,exports){ +'use strict'; + +var memoize = _dereq_('./memoize'); +var is = _dereq_('../is'); + +module.exports = { + + camel2dash: memoize( function( str ){ + return str.replace(/([A-Z])/g, function( v ){ + return '-' + v.toLowerCase(); + }); + } ), + + dash2camel: memoize( function( str ){ + return str.replace(/(-\w)/g, function( v ){ + return v[1].toUpperCase(); + }); + } ), + + capitalize: function(str){ + if( is.emptyString(str) ){ + return str; + } + + return str.charAt(0).toUpperCase() + str.substring(1); + } + +}; + +},{"../is":77,"./memoize":96}],99:[function(_dereq_,module,exports){ +'use strict'; + +var window = _dereq_('../window'); +var is = _dereq_('../is'); +var performance = window ? window.performance : null; + +var util = {}; + +var raf = !window ? null : ( window.requestAnimationFrame || window.mozRequestAnimationFrame || + window.webkitRequestAnimationFrame || window.msRequestAnimationFrame ); + +raf = raf || function( fn ){ + if( fn ){ + setTimeout(function(){ + fn( pnow() ); + }, 1000/60); + } +}; + +util.requestAnimationFrame = function(fn){ + raf( fn ); +}; + +var pnow = performance && performance.now ? function(){ return performance.now(); } : function(){ return Date.now(); }; + +util.performanceNow = pnow; + +// ported lodash throttle function +util.throttle = function(func, wait, options) { + var leading = true, + trailing = true; + + if (options === false) { + leading = false; + } else if (is.plainObject(options)) { + leading = 'leading' in options ? options.leading : leading; + trailing = 'trailing' in options ? options.trailing : trailing; + } + options = options || {}; + options.leading = leading; + options.maxWait = wait; + options.trailing = trailing; + + return util.debounce(func, wait, options); +}; + +util.now = function(){ + return Date.now(); +}; + +util.debounce = function(func, wait, options) { // ported lodash debounce function + var util = this; + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; + + if (!is.fn(func)) { + return; + } + wait = Math.max(0, wait) || 0; + if (options === true) { + var leading = true; + trailing = false; + } else if (is.plainObject(options)) { + leading = options.leading; + maxWait = 'maxWait' in options && (Math.max(wait, options.maxWait) || 0); + trailing = 'trailing' in options ? options.trailing : trailing; + } + var delayed = function() { + var remaining = wait - (util.now() - stamp); + if (remaining <= 0) { + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + var isCalled = trailingCall; + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = util.now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + } else { + timeoutId = setTimeout(delayed, remaining); + } + }; + + var maxDelayed = function() { + if (timeoutId) { + clearTimeout(timeoutId); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (trailing || (maxWait !== wait)) { + lastCalled = util.now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + }; + + return function() { + args = arguments; + stamp = util.now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + return result; + }; +}; + +module.exports = util; + +},{"../is":77,"../window":100}],100:[function(_dereq_,module,exports){ +module.exports = ( typeof window === 'undefined' ? null : window ); + +},{}]},{},[76])(76) +}); + + +//# sourceMappingURL=cytoscape.js.map diff --git a/dependencies/cytoscape.js-2.5.4/cytoscape.js.map b/dependencies/cytoscape.js-2.5.4/cytoscape.js.map new file mode 100644 index 0000000..175b202 --- /dev/null +++ b/dependencies/cytoscape.js-2.5.4/cytoscape.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["node_modules/browserify/node_modules/browser-pack/_prelude.js","src/animation.js","src/collection/algorithms/a-star.js","src/collection/algorithms/bellman-ford.js","src/collection/algorithms/betweenness-centrality.js","src/collection/algorithms/bfs-dfs.js","src/collection/algorithms/closeness-centrality.js","src/collection/algorithms/degree-centrality.js","src/collection/algorithms/floyd-warshall.js","src/collection/algorithms/index.js","src/collection/algorithms/kerger-stein.js","src/collection/algorithms/page-rank.js","src/collection/animation.js","src/collection/class.js","src/collection/comparators.js","src/collection/compounds.js","src/collection/data.js","src/collection/degree.js","src/collection/dimensions.js","src/collection/element.js","src/collection/events.js","src/collection/filter.js","src/collection/group.js","src/collection/index.js","src/collection/iteration.js","src/collection/layout.js","src/collection/style.js","src/collection/switch-functions.js","src/collection/traversing.js","src/collection/zsort.js","src/core/add-remove.js","src/core/animation.js","src/core/events.js","src/core/export.js","src/core/index.js","src/core/layout.js","src/core/notification.js","src/core/renderer.js","src/core/search.js","src/core/style.js","src/core/viewport.js","src/define.js","src/event.js","src/extension.js","src/extensions/index.js","src/extensions/layout/breadthfirst.js","src/extensions/layout/circle.js","src/extensions/layout/concentric.js","src/extensions/layout/cose.js","src/extensions/layout/grid.js","src/extensions/layout/index.js","src/extensions/layout/null.js","src/extensions/layout/preset.js","src/extensions/layout/random.js","src/extensions/renderer/base/arrow-shapes.js","src/extensions/renderer/base/cached-eles.js","src/extensions/renderer/base/coord-ele-math.js","src/extensions/renderer/base/images.js","src/extensions/renderer/base/index.js","src/extensions/renderer/base/load-listeners.js","src/extensions/renderer/base/node-shapes.js","src/extensions/renderer/base/redraw.js","src/extensions/renderer/canvas/arrow-shapes.js","src/extensions/renderer/canvas/drawing-edges.js","src/extensions/renderer/canvas/drawing-images.js","src/extensions/renderer/canvas/drawing-label-text.js","src/extensions/renderer/canvas/drawing-nodes.js","src/extensions/renderer/canvas/drawing-redraw.js","src/extensions/renderer/canvas/drawing-shapes.js","src/extensions/renderer/canvas/export-image.js","src/extensions/renderer/canvas/index.js","src/extensions/renderer/canvas/node-shapes.js","src/extensions/renderer/index.js","src/extensions/renderer/null/index.js","src/fabric.js","src/heap.js","src/index.js","src/is.js","src/jquery-plugin.js","src/math.js","src/promise.js","src/selector.js","src/style/apply.js","src/style/bypass.js","src/style/container.js","src/style/get-for-ele.js","src/style/index.js","src/style/json.js","src/style/parse.js","src/style/properties.js","src/style/string-sheet.js","src/stylesheet.js","src/thread.js","src/util/colors.js","src/util/index.js","src/util/maps.js","src/util/memoize.js","src/util/regex.js","src/util/strings.js","src/util/timing.js","src/window.js"],"names":[],"mappings":"AAAA;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3OA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3LA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5KA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtoBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChXA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnrBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxSA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7bA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzjBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACfA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChdA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9GA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3hBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxyBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACvGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtMA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzyCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChqDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC9JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACn1DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3OA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrRA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzJA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7XA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACnUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxpBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7HA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACjUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5XA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC/CA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACpLA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACp4BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7MA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACl4BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3kBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACtKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzKA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC3DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClZA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC1IA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC7FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACheA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrSA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AChFA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACrHA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AClCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACxBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AC5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;ACzJA;AACA","file":"cytoscape.js","sourceRoot":"/source/","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o 0) {\n var minPos = findMin(openSet, fScore);\n var cMin = cy.getElementById( openSet[minPos] );\n steps++;\n\n // If we've found our goal, then we are done\n if (cMin.id() == target.id()) {\n var rPath = reconstructPath(source.id(), target.id(), cameFrom, []);\n rPath.reverse();\n return {\n found : true,\n distance : gScore[cMin.id()],\n path : eles.spawn(rPath),\n steps : steps\n };\n }\n\n // Add cMin to processed nodes\n closedSet.push(cMin.id());\n // Remove cMin from boundary nodes\n openSet.splice(minPos, 1);\n\n // Update scores for neighbors of cMin\n // Take into account if graph is directed or not\n var vwEdges = cMin.connectedEdges();\n if( directed ){ vwEdges = vwEdges.stdFilter(function(ele){ return ele.data('source') === cMin.id(); }); }\n vwEdges = vwEdges.intersect(edges);\n\n for (var i = 0; i < vwEdges.length; i++) {\n var e = vwEdges[i];\n var w = e.connectedNodes().stdFilter(function(n){ return n.id() !== cMin.id(); }).intersect(nodes);\n\n // if node is in closedSet, ignore it\n if (closedSet.indexOf(w.id()) != -1) {\n continue;\n }\n\n // New tentative score for node w\n var tempScore = gScore[cMin.id()] + weightFn.apply(e, [e]);\n\n // Update gScore for node w if:\n // w not present in openSet\n // OR\n // tentative gScore is less than previous value\n\n // w not in openSet\n if (openSet.indexOf(w.id()) == -1) {\n gScore[w.id()] = tempScore;\n fScore[w.id()] = tempScore + heuristic(w);\n openSet.push(w.id()); // Add node to openSet\n cameFrom[w.id()] = cMin.id();\n cameFromEdge[w.id()] = e.id();\n continue;\n }\n // w already in openSet, but with greater gScore\n if (tempScore < gScore[w.id()]) {\n gScore[w.id()] = tempScore;\n fScore[w.id()] = tempScore + heuristic(w);\n cameFrom[w.id()] = cMin.id();\n }\n\n } // End of neighbors update\n\n } // End of main loop\n\n // If we've reached here, then we've not reached our goal\n return {\n found : false,\n distance : undefined,\n path : undefined,\n steps : steps\n };\n }\n\n}); // elesfn\n\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../../is');\nvar util = require('../../util');\n\nvar elesfn = ({\n\n // Implemented from pseudocode from wikipedia\n bellmanFord: function(options) {\n var eles = this;\n\n options = options || {};\n\n // Weight function - optional\n if (options.weight != null && is.fn(options.weight)) {\n var weightFn = options.weight;\n } else {\n // If not specified, assume each edge has equal weight (1)\n var weightFn = function(e) {return 1;};\n }\n\n // directed - optional\n if (options.directed != null) {\n var directed = options.directed;\n } else {\n var directed = false;\n }\n\n // root - mandatory!\n if (options.root != null) {\n if (is.string(options.root)) {\n // use it as a selector, e.g. \"#rootID\n var source = this.filter(options.root)[0];\n } else {\n var source = options.root[0];\n }\n } else {\n return undefined;\n }\n\n var cy = this._private.cy;\n var edges = this.edges().stdFilter(function(e){ return !e.isLoop(); });\n var nodes = this.nodes();\n var numNodes = nodes.length;\n\n // mapping: node id -> position in nodes array\n var id2position = {};\n for (var i = 0; i < numNodes; i++) {\n id2position[nodes[i].id()] = i;\n }\n\n // Initializations\n var cost = [];\n var predecessor = [];\n var predEdge = [];\n\n for (var i = 0; i < numNodes; i++) {\n if (nodes[i].id() === source.id()) {\n cost[i] = 0;\n } else {\n cost[i] = Infinity;\n }\n predecessor[i] = undefined;\n }\n\n // Edges relaxation\n var flag = false;\n for (var i = 1; i < numNodes; i++) {\n flag = false;\n for (var e = 0; e < edges.length; e++) {\n var sourceIndex = id2position[edges[e].source().id()];\n var targetIndex = id2position[edges[e].target().id()];\n var weight = weightFn.apply(edges[e], [edges[e]]);\n\n var temp = cost[sourceIndex] + weight;\n if (temp < cost[targetIndex]) {\n cost[targetIndex] = temp;\n predecessor[targetIndex] = sourceIndex;\n predEdge[targetIndex] = edges[e];\n flag = true;\n }\n\n // If undirected graph, we need to take into account the 'reverse' edge\n if (!directed) {\n var temp = cost[targetIndex] + weight;\n if (temp < cost[sourceIndex]) {\n cost[sourceIndex] = temp;\n predecessor[sourceIndex] = targetIndex;\n predEdge[sourceIndex] = edges[e];\n flag = true;\n }\n }\n }\n\n if (!flag) {\n break;\n }\n }\n\n if (flag) {\n // Check for negative weight cycles\n for (var e = 0; e < edges.length; e++) {\n var sourceIndex = id2position[edges[e].source().id()];\n var targetIndex = id2position[edges[e].target().id()];\n var weight = weightFn.apply(edges[e], [edges[e]]);\n\n if (cost[sourceIndex] + weight < cost[targetIndex]) {\n util.error(\"Graph contains a negative weight cycle for Bellman-Ford\");\n return { pathTo: undefined,\n distanceTo: undefined,\n hasNegativeWeightCycle: true};\n }\n }\n }\n\n // Build result object\n var position2id = [];\n for (var i = 0; i < numNodes; i++) {\n position2id.push(nodes[i].id());\n }\n\n\n var res = {\n distanceTo : function(to) {\n if (is.string(to)) {\n // to is a selector string\n var toId = (cy.filter(to)[0]).id();\n } else {\n // to is a node\n var toId = to.id();\n }\n\n return cost[id2position[toId]];\n },\n\n pathTo : function(to) {\n\n var reconstructPathAux = function(predecessor, fromPos, toPos, position2id, acumPath, predEdge) {\n for(;;){\n // Add toId to path\n acumPath.push( cy.getElementById(position2id[toPos]) );\n acumPath.push( predEdge[toPos] );\n\n if (fromPos === toPos) {\n // reached starting node\n return acumPath;\n }\n\n // If no path exists, discart acumulated path and return undefined\n var predPos = predecessor[toPos];\n if (typeof predPos === \"undefined\") {\n return undefined;\n }\n\n toPos = predPos;\n }\n\n };\n\n if (is.string(to)) {\n // to is a selector string\n var toId = (cy.filter(to)[0]).id();\n } else {\n // to is a node\n var toId = to.id();\n }\n var path = [];\n\n // This returns a reversed path\n var res = reconstructPathAux(predecessor,\n id2position[source.id()],\n id2position[toId],\n position2id,\n path,\n predEdge);\n\n // Get it in the correct order and return it\n if (res != null) {\n res.reverse();\n }\n\n return eles.spawn(res);\n },\n\n hasNegativeWeightCycle: false\n };\n\n return res;\n\n } // bellmanFord\n\n}); // elesfn\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../../is');\n\nvar elesfn = ({\n\n // Implemented from the algorithm in the paper \"On Variants of Shortest-Path Betweenness Centrality and their Generic Computation\" by Ulrik Brandes\n betweennessCentrality: function (options) {\n options = options || {};\n\n // Weight - optional\n if (options.weight != null && is.fn(options.weight)) {\n var weightFn = options.weight;\n var weighted = true;\n } else {\n var weighted = false;\n }\n\n // Directed - default false\n if (options.directed != null && is.bool(options.directed)) {\n var directed = options.directed;\n } else {\n var directed = false;\n }\n\n var priorityInsert = function (queue, ele) {\n queue.unshift(ele);\n for (var i = 0; d[queue[i]] < d[queue[i + 1]] && i < queue.length - 1; i++) {\n var tmp = queue[i];\n queue[i] = queue[i + 1];\n queue[i + 1] = tmp;\n }\n };\n\n var cy = this._private.cy;\n\n // starting\n var V = this.nodes();\n var A = {};\n var C = {};\n\n // A contains the neighborhoods of every node\n for (var i = 0; i < V.length; i++) {\n if (directed) {\n A[V[i].id()] = V[i].outgoers(\"node\"); // get outgoers of every node\n } else {\n A[V[i].id()] = V[i].openNeighborhood(\"node\"); // get neighbors of every node\n }\n }\n\n // C contains the betweenness values\n for (var i = 0; i < V.length; i++) {\n C[V[i].id()] = 0;\n }\n\n for (var s = 0; s < V.length; s++) {\n var S = []; // stack\n var P = {};\n var g = {};\n var d = {};\n var Q = []; // queue\n\n // init dictionaries\n for (var i = 0; i < V.length; i++) {\n P[V[i].id()] = [];\n g[V[i].id()] = 0;\n d[V[i].id()] = Number.POSITIVE_INFINITY;\n }\n\n g[V[s].id()] = 1; // sigma\n d[V[s].id()] = 0; // distance to s\n\n Q.unshift(V[s].id());\n\n while (Q.length > 0) {\n var v = Q.pop();\n S.push(v);\n if (weighted) {\n A[v].forEach(function (w) {\n if (cy.$('#' + v).edgesTo(w).length > 0) {\n var edge = cy.$('#' + v).edgesTo(w)[0];\n } else {\n var edge = w.edgesTo('#' + v)[0];\n }\n\n var edgeWeight = weightFn.apply(edge, [edge]);\n\n if (d[w.id()] > d[v] + edgeWeight) {\n d[w.id()] = d[v] + edgeWeight;\n if (Q.indexOf(w.id()) < 0) { //if w is not in Q\n priorityInsert(Q, w.id());\n } else { // update position if w is in Q\n Q.splice(Q.indexOf(w.id()), 1);\n priorityInsert(Q, w.id());\n }\n g[w.id()] = 0;\n P[w.id()] = [];\n }\n if (d[w.id()] == d[v] + edgeWeight) {\n g[w.id()] = g[w.id()] + g[v];\n P[w.id()].push(v);\n }\n });\n } else {\n A[v].forEach(function (w) {\n if (d[w.id()] == Number.POSITIVE_INFINITY) {\n Q.unshift(w.id());\n d[w.id()] = d[v] + 1;\n }\n if (d[w.id()] == d[v] + 1) {\n g[w.id()] = g[w.id()] + g[v];\n P[w.id()].push(v);\n }\n });\n }\n }\n\n var e = {};\n for (var i = 0; i < V.length; i++) {\n e[V[i].id()] = 0;\n }\n\n while (S.length > 0) {\n var w = S.pop();\n P[w].forEach(function (v) {\n e[v] = e[v] + (g[v] / g[w]) * (1 + e[w]);\n if (w != V[s].id())\n C[w] = C[w] + e[w];\n });\n }\n }\n\n var max = 0;\n for (var key in C) {\n if (max < C[key])\n max = C[key];\n }\n\n var ret = {\n betweenness: function (node) {\n if (is.string(node)) {\n var node = (cy.filter(node)[0]).id();\n } else {\n var node = node.id();\n }\n\n return C[node];\n },\n\n betweennessNormalized: function (node) {\n if (is.string(node)) {\n var node = (cy.filter(node)[0]).id();\n } else {\n var node = node.id();\n }\n\n return C[node] / max;\n }\n };\n\n // alias\n ret.betweennessNormalised = ret.betweennessNormalized;\n\n return ret;\n } // betweennessCentrality\n\n}); // elesfn\n\n// nice, short mathemathical alias\nelesfn.bc = elesfn.betweennessCentrality;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../../is');\nvar Heap = require('../../heap');\n\nvar defineSearch = function( params ){\n params = {\n bfs: params.bfs || !params.dfs,\n dfs: params.dfs || !params.bfs\n };\n\n // from pseudocode on wikipedia\n return function searchFn( roots, fn, directed ){\n var options;\n var std;\n var thisArg;\n if( is.plainObject(roots) && !is.elementOrCollection(roots) ){\n options = roots;\n roots = options.roots || options.root;\n fn = options.visit;\n directed = options.directed;\n std = options.std;\n thisArg = options.thisArg;\n }\n\n directed = arguments.length === 2 && !is.fn(fn) ? fn : directed;\n fn = is.fn(fn) ? fn : function(){};\n\n var cy = this._private.cy;\n var v = roots = is.string(roots) ? this.filter(roots) : roots;\n var Q = [];\n var connectedNodes = [];\n var connectedBy = {};\n var id2depth = {};\n var V = {};\n var j = 0;\n var found;\n var nodes = this.nodes();\n var edges = this.edges();\n\n // enqueue v\n for( var i = 0; i < v.length; i++ ){\n if( v[i].isNode() ){\n Q.unshift( v[i] );\n\n if( params.bfs ){\n V[ v[i].id() ] = true;\n\n connectedNodes.push( v[i] );\n }\n\n id2depth[ v[i].id() ] = 0;\n }\n }\n\n while( Q.length !== 0 ){\n var v = params.bfs ? Q.shift() : Q.pop();\n\n if( params.dfs ){\n if( V[ v.id() ] ){ continue; }\n\n V[ v.id() ] = true;\n\n connectedNodes.push( v );\n }\n\n var depth = id2depth[ v.id() ];\n var prevEdge = connectedBy[ v.id() ];\n var prevNode = prevEdge == null ? undefined : prevEdge.connectedNodes().not( v )[0];\n var ret;\n\n if( std ){\n ret = fn.call(thisArg, v, prevEdge, prevNode, j++, depth);\n } else {\n ret = fn.call(v, j++, depth, v, prevEdge, prevNode);\n }\n\n if( ret === true ){\n found = v;\n break;\n }\n\n if( ret === false ){\n break;\n }\n\n var vwEdges = v.connectedEdges(directed ? function(){ return this.data('source') === v.id(); } : undefined).intersect( edges );\n for( var i = 0; i < vwEdges.length; i++ ){\n var e = vwEdges[i];\n var w = e.connectedNodes(function(){ return this.id() !== v.id(); }).intersect( nodes );\n\n if( w.length !== 0 && !V[ w.id() ] ){\n w = w[0];\n\n Q.push( w );\n\n if( params.bfs ){\n V[ w.id() ] = true;\n\n connectedNodes.push( w );\n }\n\n connectedBy[ w.id() ] = e;\n\n id2depth[ w.id() ] = id2depth[ v.id() ] + 1;\n }\n }\n\n }\n\n var connectedEles = [];\n\n for( var i = 0; i < connectedNodes.length; i++ ){\n var node = connectedNodes[i];\n var edge = connectedBy[ node.id() ];\n\n if( edge ){\n connectedEles.push( edge );\n }\n\n connectedEles.push( node );\n }\n\n return {\n path: cy.collection( connectedEles, { unique: true } ),\n found: cy.collection( found )\n };\n };\n};\n\n// search, spanning trees, etc\nvar elesfn = ({\n\n breadthFirstSearch: defineSearch({ bfs: true }),\n depthFirstSearch: defineSearch({ dfs: true }),\n\n // kruskal's algorithm (finds min spanning tree, assuming undirected graph)\n // implemented from pseudocode from wikipedia\n kruskal: function( weightFn ){\n var cy = this.cy();\n\n weightFn = is.fn(weightFn) ? weightFn : function(){ return 1; }; // if not specified, assume each edge has equal weight (1)\n\n function findSet(ele){\n for( var i = 0; i < forest.length; i++ ){\n var eles = forest[i];\n\n if( eles.anySame(ele) ){\n return {\n eles: eles,\n index: i\n };\n }\n }\n }\n\n var A = cy.collection(cy, []);\n var forest = [];\n var nodes = this.nodes();\n\n for( var i = 0; i < nodes.length; i++ ){\n forest.push( nodes[i].collection() );\n }\n\n var edges = this.edges();\n var S = edges.toArray().sort(function(a, b){\n var weightA = weightFn.call(a, a);\n var weightB = weightFn.call(b, b);\n\n return weightA - weightB;\n });\n\n for(var i = 0; i < S.length; i++){\n var edge = S[i];\n var u = edge.source()[0];\n var v = edge.target()[0];\n var setU = findSet(u);\n var setV = findSet(v);\n\n if( setU.index !== setV.index ){\n A = A.add( edge );\n\n // combine forests for u and v\n forest[ setU.index ] = setU.eles.add( setV.eles );\n forest.splice( setV.index, 1 );\n }\n }\n\n return nodes.add( A );\n\n },\n\n dijkstra: function( root, weightFn, directed ){\n var options;\n if( is.plainObject(root) && !is.elementOrCollection(root) ){\n options = root;\n root = options.root;\n weightFn = options.weight;\n directed = options.directed;\n }\n\n var cy = this._private.cy;\n weightFn = is.fn(weightFn) ? weightFn : function(){ return 1; }; // if not specified, assume each edge has equal weight (1)\n\n var source = is.string(root) ? this.filter(root)[0] : root[0];\n var dist = {};\n var prev = {};\n var knownDist = {};\n\n var edges = this.edges().filter(function(){ return !this.isLoop(); });\n var nodes = this.nodes();\n\n var getDist = function(node){\n return dist[ node.id() ];\n };\n\n var setDist = function(node, d){\n dist[ node.id() ] = d;\n\n Q.updateItem( node );\n };\n\n var Q = new Heap(function( a, b ){\n return getDist(a) - getDist(b);\n });\n\n for( var i = 0; i < nodes.length; i++ ){\n var node = nodes[i];\n\n dist[ node.id() ] = node.same( source ) ? 0 : Infinity;\n Q.push( node );\n }\n\n var distBetween = function(u, v){\n var uvs = ( directed ? u.edgesTo(v) : u.edgesWith(v) ).intersect(edges);\n var smallestDistance = Infinity;\n var smallestEdge;\n\n for( var i = 0; i < uvs.length; i++ ){\n var edge = uvs[i];\n var weight = weightFn.apply( edge, [edge] );\n\n if( weight < smallestDistance || !smallestEdge ){\n smallestDistance = weight;\n smallestEdge = edge;\n }\n }\n\n return {\n edge: smallestEdge,\n dist: smallestDistance\n };\n };\n\n while( Q.size() > 0 ){\n var u = Q.pop();\n var smalletsDist = getDist(u);\n var uid = u.id();\n\n knownDist[uid] = smalletsDist;\n\n if( smalletsDist === Math.Infinite ){\n break;\n }\n\n var neighbors = u.neighborhood().intersect(nodes);\n for( var i = 0; i < neighbors.length; i++ ){\n var v = neighbors[i];\n var vid = v.id();\n var vDist = distBetween(u, v);\n\n var alt = smalletsDist + vDist.dist;\n\n if( alt < getDist(v) ){\n setDist(v, alt);\n\n prev[ vid ] = {\n node: u,\n edge: vDist.edge\n };\n }\n } // for\n } // while\n\n return {\n distanceTo: function(node){\n var target = is.string(node) ? nodes.filter(node)[0] : node[0];\n\n return knownDist[ target.id() ];\n },\n\n pathTo: function(node){\n var target = is.string(node) ? nodes.filter(node)[0] : node[0];\n var S = [];\n var u = target;\n\n if( target.length > 0 ){\n S.unshift( target );\n\n while( prev[ u.id() ] ){\n var p = prev[ u.id() ];\n\n S.unshift( p.edge );\n S.unshift( p.node );\n\n u = p.node;\n }\n }\n\n return cy.collection( S );\n }\n };\n }\n});\n\n// nice, short mathemathical alias\nelesfn.bfs = elesfn.breadthFirstSearch;\nelesfn.dfs = elesfn.depthFirstSearch;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../../is');\n\nvar elesfn = ({\n\n closenessCentralityNormalized: function (options) {\n options = options || {};\n\n var cy = this.cy();\n\n var harmonic = options.harmonic;\n if( harmonic === undefined ){\n harmonic = true;\n }\n\n var closenesses = {};\n var maxCloseness = 0;\n var nodes = this.nodes();\n var fw = this.floydWarshall({ weight: options.weight, directed: options.directed });\n\n // Compute closeness for every node and find the maximum closeness\n for(var i = 0; i < nodes.length; i++){\n var currCloseness = 0;\n for (var j = 0; j < nodes.length; j++) {\n if (i != j) {\n var d = fw.distance(nodes[i], nodes[j]);\n\n if( harmonic ){\n currCloseness += 1 / d;\n } else {\n currCloseness += d;\n }\n }\n }\n\n if( !harmonic ){\n currCloseness = 1 / currCloseness;\n }\n\n if (maxCloseness < currCloseness){\n maxCloseness = currCloseness;\n }\n\n closenesses[nodes[i].id()] = currCloseness;\n }\n\n return {\n closeness: function (node) {\n if (is.string(node)) {\n // from is a selector string\n var node = (cy.filter(node)[0]).id();\n } else {\n // from is a node\n var node = node.id();\n }\n\n return closenesses[node] / maxCloseness;\n }\n };\n },\n\n // Implemented from pseudocode from wikipedia\n closenessCentrality: function (options) {\n options = options || {};\n\n // root - mandatory!\n if (options.root != null) {\n if (is.string(options.root)) {\n // use it as a selector, e.g. \"#rootID\n var root = this.filter(options.root)[0];\n } else {\n var root = options.root[0];\n }\n } else {\n return undefined;\n }\n\n // weight - optional\n if (options.weight != null && is.fn(options.weight)) {\n var weight = options.weight;\n } else {\n var weight = function(){return 1;};\n }\n\n // directed - optional\n if (options.directed != null && is.bool(options.directed)) {\n var directed = options.directed;\n } else {\n var directed = false;\n }\n\n var harmonic = options.harmonic;\n if( harmonic === undefined ){\n harmonic = true;\n }\n\n // we need distance from this node to every other node\n var dijkstra = this.dijkstra({\n root: root,\n weight: weight,\n directed: directed\n });\n var totalDistance = 0;\n\n var nodes = this.nodes();\n for (var i = 0; i < nodes.length; i++){\n if (nodes[i].id() != root.id()){\n var d = dijkstra.distanceTo(nodes[i]);\n\n if( harmonic ){\n totalDistance += 1 / d;\n } else {\n totalDistance += d;\n }\n }\n }\n\n return harmonic ? totalDistance : 1 / totalDistance;\n } // closenessCentrality\n\n}); // elesfn\n\n// nice, short mathemathical alias\nelesfn.cc = elesfn.closenessCentrality;\nelesfn.ccn = elesfn.closenessCentralityNormalised = elesfn.closenessCentralityNormalized;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../../is');\nvar util = require('../../util');\n\nvar elesfn = ({\n\n degreeCentralityNormalized: function (options) {\n options = options || {};\n\n var cy = this.cy();\n\n // directed - optional\n if (options.directed != null) {\n var directed = options.directed;\n } else {\n var directed = false;\n }\n\n var nodes = this.nodes();\n var numNodes = nodes.length;\n\n if (!directed) {\n var degrees = {};\n var maxDegree = 0;\n\n for (var i = 0; i < numNodes; i++) {\n var node = nodes[i];\n // add current node to the current options object and call degreeCentrality\n var currDegree = this.degreeCentrality(util.extend({}, options, {root: node}));\n if (maxDegree < currDegree.degree)\n maxDegree = currDegree.degree;\n\n degrees[node.id()] = currDegree.degree;\n }\n\n return {\n degree: function (node) {\n if (is.string(node)) {\n // from is a selector string\n var node = (cy.filter(node)[0]).id();\n } else {\n // from is a node\n var node = node.id();\n }\n\n return degrees[node] / maxDegree;\n }\n };\n } else {\n var indegrees = {};\n var outdegrees = {};\n var maxIndegree = 0;\n var maxOutdegree = 0;\n\n for (var i = 0; i < numNodes; i++) {\n var node = nodes[i];\n // add current node to the current options object and call degreeCentrality\n var currDegree = this.degreeCentrality(util.extend({}, options, {root: node}));\n\n if (maxIndegree < currDegree.indegree)\n maxIndegree = currDegree.indegree;\n\n if (maxOutdegree < currDegree.outdegree)\n maxOutdegree = currDegree.outdegree;\n\n indegrees[node.id()] = currDegree.indegree;\n outdegrees[node.id()] = currDegree.outdegree;\n }\n\n return {\n indegree: function (node) {\n if (is.string(node)) {\n // from is a selector string\n var node = (cy.filter(node)[0]).id();\n } else {\n // from is a node\n var node = node.id();\n }\n\n return indegrees[node] / maxIndegree;\n },\n outdegree: function (node) {\n if (is.string(node)) {\n // from is a selector string\n var node = (cy.filter(node)[0]).id();\n } else {\n // from is a node\n var node = node.id();\n }\n\n return outdegrees[node] / maxOutdegree;\n }\n\n };\n }\n\n }, // degreeCentralityNormalized\n\n // Implemented from the algorithm in Opsahl's paper\n // \"Node centrality in weighted networks: Generalizing degree and shortest paths\"\n // check the heading 2 \"Degree\"\n degreeCentrality: function (options) {\n options = options || {};\n\n var callingEles = this;\n\n // root - mandatory!\n if (options != null && options.root != null) {\n var root = is.string(options.root) ? this.filter(options.root)[0] : options.root[0];\n } else {\n return undefined;\n }\n\n // weight - optional\n if (options.weight != null && is.fn(options.weight)) {\n var weightFn = options.weight;\n } else {\n // If not specified, assume each edge has equal weight (1)\n var weightFn = function (e) {\n return 1;\n };\n }\n\n // directed - optional\n if (options.directed != null) {\n var directed = options.directed;\n } else {\n var directed = false;\n }\n\n // alpha - optional\n if (options.alpha != null && is.number(options.alpha)) {\n var alpha = options.alpha;\n } else {\n alpha = 0;\n }\n\n\n if (!directed) {\n var connEdges = root.connectedEdges().intersection( callingEles );\n var k = connEdges.length;\n var s = 0;\n\n // Now, sum edge weights\n for (var i = 0; i < connEdges.length; i++) {\n var edge = connEdges[i];\n s += weightFn.apply(edge, [edge]);\n }\n\n return {\n degree: Math.pow(k, 1 - alpha) * Math.pow(s, alpha)\n };\n } else {\n var incoming = root.connectedEdges('edge[target = \"' + root.id() + '\"]').intersection( callingEles );\n var outgoing = root.connectedEdges('edge[source = \"' + root.id() + '\"]').intersection( callingEles );\n var k_in = incoming.length;\n var k_out = outgoing.length;\n var s_in = 0;\n var s_out = 0;\n\n // Now, sum incoming edge weights\n for (var i = 0; i < incoming.length; i++) {\n var edge = incoming[i];\n s_in += weightFn.apply(edge, [edge]);\n }\n\n // Now, sum outgoing edge weights\n for (var i = 0; i < outgoing.length; i++) {\n var edge = outgoing[i];\n s_out += weightFn.apply(edge, [edge]);\n }\n\n return {\n indegree: Math.pow(k_in, 1 - alpha) * Math.pow(s_in, alpha),\n outdegree: Math.pow(k_out, 1 - alpha) * Math.pow(s_out, alpha)\n };\n }\n } // degreeCentrality\n\n}); // elesfn\n\n// nice, short mathemathical alias\nelesfn.dc = elesfn.degreeCentrality;\nelesfn.dcn = elesfn.degreeCentralityNormalised = elesfn.degreeCentralityNormalized;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../../is');\n\nvar elesfn = ({\n\n // Implemented from pseudocode from wikipedia\n floydWarshall: function(options) {\n options = options || {};\n\n var cy = this.cy();\n\n // Weight function - optional\n if (options.weight != null && is.fn(options.weight)) {\n var weightFn = options.weight;\n } else {\n // If not specified, assume each edge has equal weight (1)\n var weightFn = function(e) {return 1;};\n }\n\n // directed - optional\n if (options.directed != null) {\n var directed = options.directed;\n } else {\n var directed = false;\n }\n\n var edges = this.edges().stdFilter(function(e){ return !e.isLoop(); });\n var nodes = this.nodes();\n var numNodes = nodes.length;\n\n // mapping: node id -> position in nodes array\n var id2position = {};\n for (var i = 0; i < numNodes; i++) {\n id2position[nodes[i].id()] = i;\n }\n\n // Initialize distance matrix\n var dist = [];\n for (var i = 0; i < numNodes; i++) {\n var newRow = new Array(numNodes);\n for (var j = 0; j < numNodes; j++) {\n if (i == j) {\n newRow[j] = 0;\n } else {\n newRow[j] = Infinity;\n }\n }\n dist.push(newRow);\n }\n\n // Initialize matrix used for path reconstruction\n // Initialize distance matrix\n var next = [];\n var edgeNext = [];\n\n var initMatrix = function(next){\n for (var i = 0; i < numNodes; i++) {\n var newRow = new Array(numNodes);\n for (var j = 0; j < numNodes; j++) {\n newRow[j] = undefined;\n }\n next.push(newRow);\n }\n };\n\n initMatrix(next);\n initMatrix(edgeNext);\n\n // Process edges\n for (var i = 0; i < edges.length ; i++) {\n var sourceIndex = id2position[edges[i].source().id()];\n var targetIndex = id2position[edges[i].target().id()];\n var weight = weightFn.apply(edges[i], [edges[i]]);\n\n // Check if already process another edge between same 2 nodes\n if (dist[sourceIndex][targetIndex] > weight) {\n dist[sourceIndex][targetIndex] = weight;\n next[sourceIndex][targetIndex] = targetIndex;\n edgeNext[sourceIndex][targetIndex] = edges[i];\n }\n }\n\n // If undirected graph, process 'reversed' edges\n if (!directed) {\n for (var i = 0; i < edges.length ; i++) {\n var sourceIndex = id2position[edges[i].target().id()];\n var targetIndex = id2position[edges[i].source().id()];\n var weight = weightFn.apply(edges[i], [edges[i]]);\n\n // Check if already process another edge between same 2 nodes\n if (dist[sourceIndex][targetIndex] > weight) {\n dist[sourceIndex][targetIndex] = weight;\n next[sourceIndex][targetIndex] = targetIndex;\n edgeNext[sourceIndex][targetIndex] = edges[i];\n }\n }\n }\n\n // Main loop\n for (var k = 0; k < numNodes; k++) {\n for (var i = 0; i < numNodes; i++) {\n for (var j = 0; j < numNodes; j++) {\n if (dist[i][k] + dist[k][j] < dist[i][j]) {\n dist[i][j] = dist[i][k] + dist[k][j];\n next[i][j] = next[i][k];\n }\n }\n }\n }\n\n // Build result object\n var position2id = [];\n for (var i = 0; i < numNodes; i++) {\n position2id.push(nodes[i].id());\n }\n\n var res = {\n distance: function(from, to) {\n if (is.string(from)) {\n // from is a selector string\n var fromId = (cy.filter(from)[0]).id();\n } else {\n // from is a node\n var fromId = from.id();\n }\n\n if (is.string(to)) {\n // to is a selector string\n var toId = (cy.filter(to)[0]).id();\n } else {\n // to is a node\n var toId = to.id();\n }\n\n return dist[id2position[fromId]][id2position[toId]];\n },\n\n path: function(from, to) {\n var reconstructPathAux = function(from, to, next, position2id, edgeNext) {\n if (from === to) {\n return cy.getElementById( position2id[from] );\n }\n if (next[from][to] === undefined) {\n return undefined;\n }\n\n var path = [ cy.getElementById(position2id[from]) ];\n var prev = from;\n while (from !== to) {\n prev = from;\n from = next[from][to];\n\n var edge = edgeNext[prev][from];\n path.push( edge );\n\n path.push( cy.getElementById(position2id[from]) );\n }\n return path;\n };\n\n if (is.string(from)) {\n // from is a selector string\n var fromId = (cy.filter(from)[0]).id();\n } else {\n // from is a node\n var fromId = from.id();\n }\n\n if (is.string(to)) {\n // to is a selector string\n var toId = (cy.filter(to)[0]).id();\n } else {\n // to is a node\n var toId = to.id();\n }\n\n var pathArr = reconstructPathAux(id2position[fromId],\n id2position[toId],\n next,\n position2id,\n edgeNext);\n\n return cy.collection( pathArr );\n }\n };\n\n return res;\n\n } // floydWarshall\n\n}); // elesfn\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar util = require('../../util');\n\nvar elesfn = {};\n\n[\n require('./bfs-dfs'),\n require('./a-star'),\n require('./floyd-warshall'),\n require('./bellman-ford'),\n require('./kerger-stein'),\n require('./page-rank'),\n require('./degree-centrality'),\n require('./closeness-centrality'),\n require('./betweenness-centrality')\n].forEach(function( props ){\n util.extend( elesfn, props );\n});\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar util = require('../../util');\n\nvar elesfn = ({\n\n // Computes the minimum cut of an undirected graph\n // Returns the correct answer with high probability\n kargerStein: function(options) {\n var eles = this;\n\n options = options || {};\n\n // Function which colapses 2 (meta) nodes into one\n // Updates the remaining edge lists\n // Receives as a paramater the edge which causes the collapse\n var colapse = function(edgeIndex, nodeMap, remainingEdges) {\n var edgeInfo = remainingEdges[edgeIndex];\n var sourceIn = edgeInfo[1];\n var targetIn = edgeInfo[2];\n var partition1 = nodeMap[sourceIn];\n var partition2 = nodeMap[targetIn];\n\n // Delete all edges between partition1 and partition2\n var newEdges = remainingEdges.filter(function(edge) {\n if (nodeMap[edge[1]] === partition1 && nodeMap[edge[2]] === partition2) {\n return false;\n }\n if (nodeMap[edge[1]] === partition2 && nodeMap[edge[2]] === partition1) {\n return false;\n }\n return true;\n });\n\n // All edges pointing to partition2 should now point to partition1\n for (var i = 0; i < newEdges.length; i++) {\n var edge = newEdges[i];\n if (edge[1] === partition2) { // Check source\n newEdges[i] = edge.slice(0);\n newEdges[i][1] = partition1;\n } else if (edge[2] === partition2) { // Check target\n newEdges[i] = edge.slice(0);\n newEdges[i][2] = partition1;\n }\n }\n\n // Move all nodes from partition2 to partition1\n for (var i = 0; i < nodeMap.length; i++) {\n if (nodeMap[i] === partition2) {\n nodeMap[i] = partition1;\n }\n }\n\n return newEdges;\n };\n\n\n // Contracts a graph until we reach a certain number of meta nodes\n var contractUntil = function(metaNodeMap,\n remainingEdges,\n size,\n sizeLimit) {\n // Stop condition\n if (size <= sizeLimit) {\n return remainingEdges;\n }\n\n // Choose an edge randomly\n var edgeIndex = Math.floor((Math.random() * remainingEdges.length));\n\n // Colapse graph based on edge\n var newEdges = colapse(edgeIndex, metaNodeMap, remainingEdges);\n\n return contractUntil(metaNodeMap,\n newEdges,\n size - 1,\n sizeLimit);\n };\n\n var cy = this._private.cy;\n var edges = this.edges().stdFilter(function(e){ return !e.isLoop(); });\n var nodes = this.nodes();\n var numNodes = nodes.length;\n var numEdges = edges.length;\n var numIter = Math.ceil(Math.pow(Math.log(numNodes) / Math.LN2, 2));\n var stopSize = Math.floor(numNodes / Math.sqrt(2));\n\n if (numNodes < 2) {\n util.error(\"At least 2 nodes are required for Karger-Stein algorithm\");\n return undefined;\n }\n\n // Create numerical identifiers for each node\n // mapping: node id -> position in nodes array\n // for reverse mapping, simply use nodes array\n var id2position = {};\n for (var i = 0; i < numNodes; i++) {\n id2position[nodes[i].id()] = i;\n }\n\n // Now store edge destination as indexes\n // Format for each edge (edge index, source node index, target node index)\n var edgeIndexes = [];\n for (var i = 0; i < numEdges; i++) {\n var e = edges[i];\n edgeIndexes.push([i, id2position[e.source().id()], id2position[e.target().id()]]);\n }\n\n // We will store the best cut found here\n var minCutSize = Infinity;\n var minCut;\n\n // Initial meta node partition\n var originalMetaNode = [];\n for (var i = 0; i < numNodes; i++) {\n originalMetaNode.push(i);\n }\n\n // Main loop\n for (var iter = 0; iter <= numIter; iter++) {\n // Create new meta node partition\n var metaNodeMap = originalMetaNode.slice(0);\n\n // Contract until stop point (stopSize nodes)\n var edgesState = contractUntil(metaNodeMap, edgeIndexes, numNodes, stopSize);\n\n // Create a copy of the colapsed nodes state\n var metaNodeMap2 = metaNodeMap.slice(0);\n\n // Run 2 iterations starting in the stop state\n var res1 = contractUntil(metaNodeMap, edgesState, stopSize, 2);\n var res2 = contractUntil(metaNodeMap2, edgesState, stopSize, 2);\n\n // Is any of the 2 results the best cut so far?\n if (res1.length <= res2.length && res1.length < minCutSize) {\n minCutSize = res1.length;\n minCut = [res1, metaNodeMap];\n } else if (res2.length <= res1.length && res2.length < minCutSize) {\n minCutSize = res2.length;\n minCut = [res2, metaNodeMap2];\n }\n } // end of main loop\n\n\n // Construct result\n var resEdges = (minCut[0]).map(function(e){ return edges[e[0]]; });\n var partition1 = [];\n var partition2 = [];\n\n // traverse metaNodeMap for best cut\n var witnessNodePartition = minCut[1][0];\n for (var i = 0; i < minCut[1].length; i++) {\n var partitionId = minCut[1][i];\n if (partitionId === witnessNodePartition) {\n partition1.push(nodes[i]);\n } else {\n partition2.push(nodes[i]);\n }\n }\n\n var ret = {\n cut: eles.spawn(cy, resEdges),\n partition1: eles.spawn(partition1),\n partition2: eles.spawn(partition2)\n };\n\n return ret;\n }\n}); // elesfn\n\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../../is');\n\nvar elesfn = ({\n\n pageRank: function(options) {\n options = options || {};\n\n var normalizeVector = function(vector) {\n var length = vector.length;\n\n // First, get sum of all elements\n var total = 0;\n for (var i = 0; i < length; i++) {\n total += vector[i];\n }\n\n // Now, divide each by the sum of all elements\n for (var i = 0; i < length; i++) {\n vector[i] = vector[i] / total;\n }\n };\n\n // dampingFactor - optional\n if (options != null &&\n options.dampingFactor != null) {\n var dampingFactor = options.dampingFactor;\n } else {\n var dampingFactor = 0.8; // Default damping factor\n }\n\n // desired precision - optional\n if (options != null &&\n options.precision != null) {\n var epsilon = options.precision;\n } else {\n var epsilon = 0.000001; // Default precision\n }\n\n // Max number of iterations - optional\n if (options != null &&\n options.iterations != null) {\n var numIter = options.iterations;\n } else {\n var numIter = 200; // Default number of iterations\n }\n\n // Weight function - optional\n if (options != null &&\n options.weight != null &&\n is.fn(options.weight)) {\n var weightFn = options.weight;\n } else {\n // If not specified, assume each edge has equal weight (1)\n var weightFn = function(e) {return 1;};\n }\n\n var cy = this._private.cy;\n var edges = this.edges().stdFilter(function(e){ return !e.isLoop(); });\n var nodes = this.nodes();\n var numNodes = nodes.length;\n var numEdges = edges.length;\n\n // Create numerical identifiers for each node\n // mapping: node id -> position in nodes array\n // for reverse mapping, simply use nodes array\n var id2position = {};\n for (var i = 0; i < numNodes; i++) {\n id2position[nodes[i].id()] = i;\n }\n\n // Construct transposed adjacency matrix\n // First lets have a zeroed matrix of the right size\n // We'll also keep track of the sum of each column\n var matrix = [];\n var columnSum = [];\n var additionalProb = (1 - dampingFactor) / numNodes;\n\n // Create null matric\n for (var i = 0; i < numNodes; i++) {\n var newRow = [];\n for (var j = 0; j < numNodes; j++) {\n newRow.push(0.0);\n }\n matrix.push(newRow);\n columnSum.push(0.0);\n }\n\n // Now, process edges\n for (var i = 0; i < numEdges; i++) {\n var edge = edges[i];\n var s = id2position[edge.source().id()];\n var t = id2position[edge.target().id()];\n var w = weightFn.apply(edge, [edge]);\n\n // Update matrix\n matrix[t][s] += w;\n\n // Update column sum\n columnSum[s] += w;\n }\n\n // Add additional probability based on damping factor\n // Also, take into account columns that have sum = 0\n var p = 1.0 / numNodes + additionalProb; // Shorthand\n // Traverse matrix, column by column\n for (var j = 0; j < numNodes; j++) {\n if (columnSum[j] === 0) {\n // No 'links' out from node jth, assume equal probability for each possible node\n for (var i = 0; i < numNodes; i++) {\n matrix[i][j] = p;\n }\n } else {\n // Node jth has outgoing link, compute normalized probabilities\n for (var i = 0; i < numNodes; i++) {\n matrix[i][j] = matrix[i][j] / columnSum[j] + additionalProb;\n }\n }\n }\n\n // Compute dominant eigenvector using power method\n var eigenvector = [];\n var nullVector = [];\n var previous;\n\n // Start with a vector of all 1's\n // Also, initialize a null vector which will be used as shorthand\n for (var i = 0; i < numNodes; i++) {\n eigenvector.push(1.0);\n nullVector.push(0.0);\n }\n\n for (var iter = 0; iter < numIter; iter++) {\n // New array with all 0's\n var temp = nullVector.slice(0);\n\n // Multiply matrix with previous result\n for (var i = 0; i < numNodes; i++) {\n for (var j = 0; j < numNodes; j++) {\n temp[i] += matrix[i][j] * eigenvector[j];\n }\n }\n\n normalizeVector(temp);\n previous = eigenvector;\n eigenvector = temp;\n\n var diff = 0;\n // Compute difference (squared module) of both vectors\n for (var i = 0; i < numNodes; i++) {\n diff += Math.pow(previous[i] - eigenvector[i], 2);\n }\n\n // If difference is less than the desired threshold, stop iterating\n if (diff < epsilon) {\n break;\n }\n }\n\n // Construct result\n var res = {\n rank : function(node) {\n if (is.string(node)) {\n // is a selector string\n var nodeId = (cy.filter(node)[0]).id();\n } else {\n // is a node object\n var nodeId = node.id();\n }\n return eigenvector[id2position[nodeId]];\n }\n };\n\n\n return res;\n } // pageRank\n\n}); // elesfn\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar define = require('../define');\n\nvar elesfn = ({\n animate: define.animate(),\n animation: define.animation(),\n animated: define.animated(),\n clearQueue: define.clearQueue(),\n delay: define.delay(),\n delayAnimation: define.delayAnimation(),\n stop: define.stop()\n});\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar util = require('../util');\n\nvar elesfn = ({\n classes: function( classes ){\n classes = classes.match(/\\S+/g) || [];\n var self = this;\n var changed = [];\n var classesMap = {};\n\n // fill in classes map\n for( var i = 0; i < classes.length; i++ ){\n var cls = classes[i];\n\n classesMap[ cls ] = true;\n }\n\n // check and update each ele\n for( var j = 0; j < self.length; j++ ){\n var ele = self[j];\n var _p = ele._private;\n var eleClasses = _p.classes;\n var changedEle = false;\n\n // check if ele has all of the passed classes\n for( var i = 0; i < classes.length; i++ ){\n var cls = classes[i];\n var eleHasClass = eleClasses[ cls ];\n\n if( !eleHasClass ){\n changedEle = true;\n break;\n }\n }\n\n // check if ele has classes outside of those passed\n if( !changedEle ){ for( var eleCls in eleClasses ){\n var eleHasClass = eleClasses[ eleCls ];\n var specdClass = classesMap[ eleCls ]; // i.e. this class is passed to the function\n\n if( eleHasClass && !specdClass ){\n changedEle = true;\n break;\n }\n } }\n\n if( changedEle ){\n _p.classes = util.copy( classesMap );\n\n changed.push( ele );\n }\n }\n\n // trigger update style on those eles that had class changes\n if( changed.length > 0 ){\n this.spawn(changed)\n .updateStyle()\n .trigger('class')\n ;\n }\n\n return self;\n },\n\n addClass: function( classes ){\n return this.toggleClass( classes, true );\n },\n\n hasClass: function( className ){\n var ele = this[0];\n return ( ele != null && ele._private.classes[className] ) ? true : false;\n },\n\n toggleClass: function( classesStr, toggle ){\n var classes = classesStr.match(/\\S+/g) || [];\n var self = this;\n var changed = []; // eles who had classes changed\n\n for( var i = 0, il = self.length; i < il; i++ ){\n var ele = self[i];\n var changedEle = false;\n\n for( var j = 0; j < classes.length; j++ ){\n var cls = classes[j];\n var eleClasses = ele._private.classes;\n var hasClass = eleClasses[cls];\n var shouldAdd = toggle || (toggle === undefined && !hasClass);\n\n if( shouldAdd ){\n eleClasses[cls] = true;\n\n if( !hasClass && !changedEle ){\n changed.push(ele);\n changedEle = true;\n }\n } else { // then remove\n eleClasses[cls] = false;\n\n if( hasClass && !changedEle ){\n changed.push(ele);\n changedEle = true;\n }\n }\n\n } // for j classes\n } // for i eles\n\n // trigger update style on those eles that had class changes\n if( changed.length > 0 ){\n this.spawn(changed)\n .updateStyle()\n .trigger('class')\n ;\n }\n\n return self;\n },\n\n removeClass: function( classes ){\n return this.toggleClass( classes, false );\n },\n\n flashClass: function( classes, duration ){\n var self = this;\n\n if( duration == null ){\n duration = 250;\n } else if( duration === 0 ){\n return self; // nothing to do really\n }\n\n self.addClass( classes );\n setTimeout(function(){\n self.removeClass( classes );\n }, duration);\n\n return self;\n }\n});\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar elesfn = ({\n allAre: function( selector ){\n return this.filter(selector).length === this.length;\n },\n\n is: function( selector ){\n return this.filter(selector).length > 0;\n },\n\n some: function( fn, thisArg ){\n for( var i = 0; i < this.length; i++ ){\n var ret = !thisArg ? fn( this[i], i, this ) : fn.apply( thisArg, [ this[i], i, this ] );\n\n if( ret ){\n return true;\n }\n }\n\n return false;\n },\n\n every: function( fn, thisArg ){\n for( var i = 0; i < this.length; i++ ){\n var ret = !thisArg ? fn( this[i], i, this ) : fn.apply( thisArg, [ this[i], i, this ] );\n\n if( !ret ){\n return false;\n }\n }\n\n return true;\n },\n\n same: function( collection ){\n collection = this.cy().collection( collection );\n\n // cheap extra check\n if( this.length !== collection.length ){\n return false;\n }\n\n return this.intersect( collection ).length === this.length;\n },\n\n anySame: function( collection ){\n collection = this.cy().collection( collection );\n\n return this.intersect( collection ).length > 0;\n },\n\n allAreNeighbors: function( collection ){\n collection = this.cy().collection( collection );\n\n return this.neighborhood().intersect( collection ).length === collection.length;\n }\n});\n\nelesfn.allAreNeighbours = elesfn.allAreNeighbors;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar elesfn = ({\n parent: function( selector ){\n var parents = [];\n var cy = this._private.cy;\n\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n var parent = cy.getElementById( ele._private.data.parent );\n\n if( parent.size() > 0 ){\n parents.push( parent );\n }\n }\n\n return this.spawn( parents, { unique: true } ).filter( selector );\n },\n\n parents: function( selector ){\n var parents = [];\n\n var eles = this.parent();\n while( eles.nonempty() ){\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n parents.push( ele );\n }\n\n eles = eles.parent();\n }\n\n return this.spawn( parents, { unique: true } ).filter( selector );\n },\n\n commonAncestors: function( selector ){\n var ancestors;\n\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n var parents = ele.parents();\n\n ancestors = ancestors || parents;\n\n ancestors = ancestors.intersect( parents ); // current list must be common with current ele parents set\n }\n\n return ancestors.filter( selector );\n },\n\n orphans: function( selector ){\n return this.stdFilter(function( ele ){\n return ele.isNode() && ele.parent().empty();\n }).filter( selector );\n },\n\n nonorphans: function( selector ){\n return this.stdFilter(function( ele ){\n return ele.isNode() && ele.parent().nonempty();\n }).filter( selector );\n },\n\n children: function( selector ){\n var children = [];\n\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n children = children.concat( ele._private.children );\n }\n\n return this.spawn( children, { unique: true } ).filter( selector );\n },\n\n siblings: function( selector ){\n return this.parent().children().not( this ).filter( selector );\n },\n\n isParent: function(){\n var ele = this[0];\n\n if( ele ){\n return ele._private.children.length !== 0;\n }\n },\n\n isChild: function(){\n var ele = this[0];\n\n if( ele ){\n return ele._private.data.parent !== undefined && ele.parent().length !== 0;\n }\n },\n\n descendants: function( selector ){\n var elements = [];\n\n function add( eles ){\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n\n elements.push( ele );\n\n if( ele.children().nonempty() ){\n add( ele.children() );\n }\n }\n }\n\n add( this.children() );\n\n return this.spawn( elements, { unique: true } ).filter( selector );\n }\n});\n\n// aliases\nelesfn.ancestors = elesfn.parents;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar define = require('../define');\nvar fn, elesfn;\n\nfn = elesfn = ({\n\n data: define.data({\n field: 'data',\n bindingEvent: 'data',\n allowBinding: true,\n allowSetting: true,\n settingEvent: 'data',\n settingTriggersEvent: true,\n triggerFnName: 'trigger',\n allowGetting: true,\n immutableKeys: {\n 'id': true,\n 'source': true,\n 'target': true,\n 'parent': true\n },\n updateStyle: true\n }),\n\n removeData: define.removeData({\n field: 'data',\n event: 'data',\n triggerFnName: 'trigger',\n triggerEvent: true,\n immutableKeys: {\n 'id': true,\n 'source': true,\n 'target': true,\n 'parent': true\n },\n updateStyle: true\n }),\n\n scratch: define.data({\n field: 'scratch',\n bindingEvent: 'scratch',\n allowBinding: true,\n allowSetting: true,\n settingEvent: 'scratch',\n settingTriggersEvent: true,\n triggerFnName: 'trigger',\n allowGetting: true,\n updateStyle: true\n }),\n\n removeScratch: define.removeData({\n field: 'scratch',\n event: 'scratch',\n triggerFnName: 'trigger',\n triggerEvent: true,\n updateStyle: true\n }),\n\n rscratch: define.data({\n field: 'rscratch',\n allowBinding: false,\n allowSetting: true,\n settingTriggersEvent: false,\n allowGetting: true\n }),\n\n removeRscratch: define.removeData({\n field: 'rscratch',\n triggerEvent: false\n }),\n\n id: function(){\n var ele = this[0];\n\n if( ele ){\n return ele._private.data.id;\n }\n }\n\n});\n\n// aliases\nfn.attr = fn.data;\nfn.removeAttr = fn.removeData;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar util = require('../util');\n\nvar elesfn = {};\n\nfunction defineDegreeFunction(callback){\n return function( includeLoops ){\n var self = this;\n\n if( includeLoops === undefined ){\n includeLoops = true;\n }\n\n if( self.length === 0 ){ return; }\n\n if( self.isNode() && !self.removed() ){\n var degree = 0;\n var node = self[0];\n var connectedEdges = node._private.edges;\n\n for( var i = 0; i < connectedEdges.length; i++ ){\n var edge = connectedEdges[i];\n\n if( !includeLoops && edge.isLoop() ){\n continue;\n }\n\n degree += callback( node, edge );\n }\n\n return degree;\n } else {\n return;\n }\n };\n}\n\nutil.extend(elesfn, {\n degree: defineDegreeFunction(function(node, edge){\n if( edge.source().same( edge.target() ) ){\n return 2;\n } else {\n return 1;\n }\n }),\n\n indegree: defineDegreeFunction(function(node, edge){\n if( edge.target().same(node) ){\n return 1;\n } else {\n return 0;\n }\n }),\n\n outdegree: defineDegreeFunction(function(node, edge){\n if( edge.source().same(node) ){\n return 1;\n } else {\n return 0;\n }\n })\n});\n\nfunction defineDegreeBoundsFunction(degreeFn, callback){\n return function( includeLoops ){\n var ret;\n var nodes = this.nodes();\n\n for( var i = 0; i < nodes.length; i++ ){\n var ele = nodes[i];\n var degree = ele[degreeFn]( includeLoops );\n if( degree !== undefined && (ret === undefined || callback(degree, ret)) ){\n ret = degree;\n }\n }\n\n return ret;\n };\n}\n\nutil.extend(elesfn, {\n minDegree: defineDegreeBoundsFunction('degree', function(degree, min){\n return degree < min;\n }),\n\n maxDegree: defineDegreeBoundsFunction('degree', function(degree, max){\n return degree > max;\n }),\n\n minIndegree: defineDegreeBoundsFunction('indegree', function(degree, min){\n return degree < min;\n }),\n\n maxIndegree: defineDegreeBoundsFunction('indegree', function(degree, max){\n return degree > max;\n }),\n\n minOutdegree: defineDegreeBoundsFunction('outdegree', function(degree, min){\n return degree < min;\n }),\n\n maxOutdegree: defineDegreeBoundsFunction('outdegree', function(degree, max){\n return degree > max;\n })\n});\n\nutil.extend(elesfn, {\n totalDegree: function( includeLoops ){\n var total = 0;\n var nodes = this.nodes();\n\n for( var i = 0; i < nodes.length; i++ ){\n total += nodes[i].degree( includeLoops );\n }\n\n return total;\n }\n});\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar define = require('../define');\nvar is = require('../is');\nvar util = require('../util');\nvar fn, elesfn;\n\nfn = elesfn = ({\n\n position: define.data({\n field: 'position',\n bindingEvent: 'position',\n allowBinding: true,\n allowSetting: true,\n settingEvent: 'position',\n settingTriggersEvent: true,\n triggerFnName: 'rtrigger',\n allowGetting: true,\n validKeys: ['x', 'y'],\n onSet: function( eles ){\n var updatedEles = eles.updateCompoundBounds();\n updatedEles.rtrigger('position');\n },\n canSet: function( ele ){\n return !ele.locked() && !ele.isParent();\n }\n }),\n\n // position but no notification to renderer\n silentPosition: define.data({\n field: 'position',\n bindingEvent: 'position',\n allowBinding: false,\n allowSetting: true,\n settingEvent: 'position',\n settingTriggersEvent: false,\n triggerFnName: 'trigger',\n allowGetting: true,\n validKeys: ['x', 'y'],\n onSet: function( eles ){\n eles.updateCompoundBounds();\n },\n canSet: function( ele ){\n return !ele.locked() && !ele.isParent();\n }\n }),\n\n positions: function( pos, silent ){\n if( is.plainObject(pos) ){\n this.position(pos);\n\n } else if( is.fn(pos) ){\n var fn = pos;\n\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n\n var pos = fn.apply(ele, [i, ele]);\n\n if( pos && !ele.locked() && !ele.isParent() ){\n var elePos = ele._private.position;\n elePos.x = pos.x;\n elePos.y = pos.y;\n }\n }\n\n var updatedEles = this.updateCompoundBounds();\n var toTrigger = updatedEles.length > 0 ? this.add( updatedEles ) : this;\n\n if( silent ){\n toTrigger.trigger('position');\n } else {\n toTrigger.rtrigger('position');\n }\n }\n\n return this; // chaining\n },\n\n silentPositions: function( pos ){\n return this.positions( pos, true );\n },\n\n // get/set the rendered (i.e. on screen) positon of the element\n renderedPosition: function( dim, val ){\n var ele = this[0];\n var cy = this.cy();\n var zoom = cy.zoom();\n var pan = cy.pan();\n var rpos = is.plainObject( dim ) ? dim : undefined;\n var setting = rpos !== undefined || ( val !== undefined && is.string(dim) );\n\n if( ele && ele.isNode() ){ // must have an element and must be a node to return position\n if( setting ){\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n\n if( val !== undefined ){ // set one dimension\n ele._private.position[dim] = ( val - pan[dim] )/zoom;\n } else if( rpos !== undefined ){ // set whole position\n ele._private.position = {\n x: ( rpos.x - pan.x ) /zoom,\n y: ( rpos.y - pan.y ) /zoom\n };\n }\n }\n\n this.rtrigger('position');\n } else { // getting\n var pos = ele._private.position;\n rpos = {\n x: pos.x * zoom + pan.x,\n y: pos.y * zoom + pan.y\n };\n\n if( dim === undefined ){ // then return the whole rendered position\n return rpos;\n } else { // then return the specified dimension\n return rpos[ dim ];\n }\n }\n } else if( !setting ){\n return undefined; // for empty collection case\n }\n\n return this; // chaining\n },\n\n // get/set the position relative to the parent\n relativePosition: function( dim, val ){\n var ele = this[0];\n var cy = this.cy();\n var ppos = is.plainObject( dim ) ? dim : undefined;\n var setting = ppos !== undefined || ( val !== undefined && is.string(dim) );\n var hasCompoundNodes = cy.hasCompoundNodes();\n\n if( ele && ele.isNode() ){ // must have an element and must be a node to return position\n if( setting ){\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n var parent = hasCompoundNodes ? ele.parent() : null;\n var hasParent = parent && parent.length > 0;\n var relativeToParent = hasParent;\n\n if( hasParent ){\n parent = parent[0];\n }\n\n var origin = relativeToParent ? parent._private.position : { x: 0, y: 0 };\n\n if( val !== undefined ){ // set one dimension\n ele._private.position[dim] = val + origin[dim];\n } else if( ppos !== undefined ){ // set whole position\n ele._private.position = {\n x: ppos.x + origin.x,\n y: ppos.y + origin.y\n };\n }\n }\n\n this.rtrigger('position');\n\n } else { // getting\n var pos = ele._private.position;\n var parent = hasCompoundNodes ? ele.parent() : null;\n var hasParent = parent && parent.length > 0;\n var relativeToParent = hasParent;\n\n if( hasParent ){\n parent = parent[0];\n }\n\n var origin = relativeToParent ? parent._private.position : { x: 0, y: 0 };\n\n ppos = {\n x: pos.x - origin.x,\n y: pos.y - origin.y\n };\n\n if( dim === undefined ){ // then return the whole rendered position\n return ppos;\n } else { // then return the specified dimension\n return ppos[ dim ];\n }\n }\n } else if( !setting ){\n return undefined; // for empty collection case\n }\n\n return this; // chaining\n },\n\n renderedBoundingBox: function( options ){\n var bb = this.boundingBox( options );\n var cy = this.cy();\n var zoom = cy.zoom();\n var pan = cy.pan();\n\n var x1 = bb.x1 * zoom + pan.x;\n var x2 = bb.x2 * zoom + pan.x;\n var y1 = bb.y1 * zoom + pan.y;\n var y2 = bb.y2 * zoom + pan.y;\n\n return {\n x1: x1,\n x2: x2,\n y1: y1,\n y2: y2,\n w: x2 - x1,\n h: y2 - y1\n };\n },\n\n updateCompoundBounds: function(){\n var cy = this.cy();\n\n if( !cy.styleEnabled() || !cy.hasCompoundNodes() ){ return cy.collection(); } // save cycles for non compound graphs or when style disabled\n\n var updated = [];\n\n function update( parent ){\n var children = parent.children();\n var style = parent._private.style;\n var includeLabels = style['compound-sizing-wrt-labels'].value === 'include';\n var bb = children.boundingBox({ includeLabels: includeLabels, includeEdges: true });\n var padding = {\n top: style['padding-top'].pfValue,\n bottom: style['padding-bottom'].pfValue,\n left: style['padding-left'].pfValue,\n right: style['padding-right'].pfValue\n };\n var pos = parent._private.position;\n var didUpdate = false;\n\n if( style['width'].value === 'auto' ){\n parent._private.autoWidth = bb.w;\n pos.x = (bb.x1 + bb.x2 - padding.left + padding.right)/2;\n didUpdate = true;\n }\n\n if( style['height'].value === 'auto' ){\n parent._private.autoHeight = bb.h;\n pos.y = (bb.y1 + bb.y2 - padding.top + padding.bottom)/2;\n didUpdate = true;\n }\n\n if( didUpdate ){\n updated.push( parent );\n }\n }\n\n // go up, level by level\n var eles = this.parent();\n while( eles.nonempty() ){\n\n // update each parent node in this level\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n\n update( ele );\n }\n\n // next level\n eles = eles.parent();\n }\n\n // return changed\n return this.spawn( updated );\n },\n\n // get the bounding box of the elements (in raw model position)\n boundingBox: function( options ){\n var eles = this;\n var cy = eles._private.cy;\n var cy_p = cy._private;\n var styleEnabled = cy_p.styleEnabled;\n\n options = options || util.staticEmptyObject();\n\n var includeNodes = options.includeNodes === undefined ? true : options.includeNodes;\n var includeEdges = options.includeEdges === undefined ? true : options.includeEdges;\n var includeLabels = options.includeLabels === undefined ? true : options.includeLabels;\n\n // recalculate projections etc\n if( styleEnabled ){\n cy_p.renderer.recalculateRenderedStyle( this );\n }\n\n var x1 = Infinity;\n var x2 = -Infinity;\n var y1 = Infinity;\n var y2 = -Infinity;\n\n // find bounds of elements\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var _p = ele._private;\n var style = _p.style;\n var display = styleEnabled ? _p.style['display'].value : 'element';\n var isNode = _p.group === 'nodes';\n var ex1, ex2, ey1, ey2, x, y;\n var includedEle = false;\n\n if( display === 'none' ){ continue; } // then ele doesn't take up space\n\n if( isNode && includeNodes ){\n includedEle = true;\n\n var pos = _p.position;\n x = pos.x;\n y = pos.y;\n var w = ele.outerWidth();\n var halfW = w/2;\n var h = ele.outerHeight();\n var halfH = h/2;\n\n // handle node dimensions\n /////////////////////////\n\n ex1 = x - halfW;\n ex2 = x + halfW;\n ey1 = y - halfH;\n ey2 = y + halfH;\n\n x1 = ex1 < x1 ? ex1 : x1;\n x2 = ex2 > x2 ? ex2 : x2;\n y1 = ey1 < y1 ? ey1 : y1;\n y2 = ey2 > y2 ? ey2 : y2;\n\n } else if( ele.isEdge() && includeEdges ){\n includedEle = true;\n\n var n1 = _p.source;\n var n1_p = n1._private;\n var n1pos = n1_p.position;\n\n var n2 = _p.target;\n var n2_p = n2._private;\n var n2pos = n2_p.position;\n\n\n // handle edge dimensions (rough box estimate)\n //////////////////////////////////////////////\n\n var rstyle = _p.rstyle || {};\n var w = 0;\n var wHalf = 0;\n\n if( styleEnabled ){\n w = style['width'].pfValue;\n wHalf = w/2;\n }\n\n ex1 = n1pos.x;\n ex2 = n2pos.x;\n ey1 = n1pos.y;\n ey2 = n2pos.y;\n\n if( ex1 > ex2 ){\n var temp = ex1;\n ex1 = ex2;\n ex2 = temp;\n }\n\n if( ey1 > ey2 ){\n var temp = ey1;\n ey1 = ey2;\n ey2 = temp;\n }\n\n // take into account edge width\n ex1 -= wHalf;\n ex2 += wHalf;\n ey1 -= wHalf;\n ey2 += wHalf;\n\n x1 = ex1 < x1 ? ex1 : x1;\n x2 = ex2 > x2 ? ex2 : x2;\n y1 = ey1 < y1 ? ey1 : y1;\n y2 = ey2 > y2 ? ey2 : y2;\n\n // handle points along edge (sanity check)\n //////////////////////////////////////////\n\n if( styleEnabled ){\n var pts = rstyle.bezierPts || rstyle.linePts || [];\n\n for( var j = 0; j < pts.length; j++ ){\n var pt = pts[j];\n\n ex1 = pt.x - wHalf;\n ex2 = pt.x + wHalf;\n ey1 = pt.y - wHalf;\n ey2 = pt.y + wHalf;\n\n x1 = ex1 < x1 ? ex1 : x1;\n x2 = ex2 > x2 ? ex2 : x2;\n y1 = ey1 < y1 ? ey1 : y1;\n y2 = ey2 > y2 ? ey2 : y2;\n }\n }\n\n // precise haystacks (sanity check)\n ///////////////////////////////////\n\n if( styleEnabled && style['curve-style'].strValue === 'haystack' ){\n var hpts = rstyle.haystackPts;\n\n ex1 = hpts[0].x;\n ey1 = hpts[0].y;\n ex2 = hpts[1].x;\n ey2 = hpts[1].y;\n\n if( ex1 > ex2 ){\n var temp = ex1;\n ex1 = ex2;\n ex2 = temp;\n }\n\n if( ey1 > ey2 ){\n var temp = ey1;\n ey1 = ey2;\n ey2 = temp;\n }\n\n x1 = ex1 < x1 ? ex1 : x1;\n x2 = ex2 > x2 ? ex2 : x2;\n y1 = ey1 < y1 ? ey1 : y1;\n y2 = ey2 > y2 ? ey2 : y2;\n }\n\n } // edges\n\n\n // handle label dimensions\n //////////////////////////\n\n if( styleEnabled ){\n\n var _p = ele._private;\n var style = _p.style;\n var rstyle = _p.rstyle;\n var label = style['label'].strValue;\n var fontSize = style['font-size'];\n var halign = style['text-halign'];\n var valign = style['text-valign'];\n var labelWidth = rstyle.labelWidth;\n var labelHeight = rstyle.labelHeight;\n var labelX = rstyle.labelX;\n var labelY = rstyle.labelY;\n var isEdge = ele.isEdge();\n var autorotate = style['edge-text-rotation'].strValue === 'autorotate';\n\n if( includeLabels && label && fontSize && labelHeight != null && labelWidth != null && labelX != null && labelY != null && halign && valign ){\n var lh = labelHeight;\n var lw = labelWidth;\n var lx1, lx2, ly1, ly2;\n\n if( isEdge ){\n lx1 = labelX - lw/2;\n lx2 = labelX + lw/2;\n ly1 = labelY - lh/2;\n ly2 = labelY + lh/2;\n\n if( autorotate ){\n var theta = _p.rscratch.labelAngle;\n var cos = Math.cos( theta );\n var sin = Math.sin( theta );\n\n var rotate = function( x, y ){\n x = x - labelX;\n y = y - labelY;\n\n return {\n x: x*cos - y*sin + labelX,\n y: x*sin + y*cos + labelY\n };\n };\n\n var px1y1 = rotate( lx1, ly1 );\n var px1y2 = rotate( lx1, ly2 );\n var px2y1 = rotate( lx2, ly1 );\n var px2y2 = rotate( lx2, ly2 );\n\n lx1 = Math.min( px1y1.x, px1y2.x, px2y1.x, px2y2.x );\n lx2 = Math.max( px1y1.x, px1y2.x, px2y1.x, px2y2.x );\n ly1 = Math.min( px1y1.y, px1y2.y, px2y1.y, px2y2.y );\n ly2 = Math.max( px1y1.y, px1y2.y, px2y1.y, px2y2.y );\n }\n } else {\n switch( halign.value ){\n case 'left':\n lx1 = labelX - lw;\n lx2 = labelX;\n break;\n\n case 'center':\n lx1 = labelX - lw/2;\n lx2 = labelX + lw/2;\n break;\n\n case 'right':\n lx1 = labelX;\n lx2 = labelX + lw;\n break;\n }\n\n switch( valign.value ){\n case 'top':\n ly1 = labelY - lh;\n ly2 = labelY;\n break;\n\n case 'center':\n ly1 = labelY - lh/2;\n ly2 = labelY + lh/2;\n break;\n\n case 'bottom':\n ly1 = labelY;\n ly2 = labelY + lh;\n break;\n }\n }\n\n x1 = lx1 < x1 ? lx1 : x1;\n x2 = lx2 > x2 ? lx2 : x2;\n y1 = ly1 < y1 ? ly1 : y1;\n y2 = ly2 > y2 ? ly2 : y2;\n }\n } // style enabled for labels\n } // for\n\n var noninf = function(x){\n if( x === Infinity || x === -Infinity ){\n return 0;\n }\n\n return x;\n };\n\n x1 = noninf(x1);\n x2 = noninf(x2);\n y1 = noninf(y1);\n y2 = noninf(y2);\n\n return {\n x1: x1,\n x2: x2,\n y1: y1,\n y2: y2,\n w: x2 - x1,\n h: y2 - y1\n };\n }\n});\n\nvar defineDimFns = function( opts ){\n opts.uppercaseName = util.capitalize( opts.name );\n opts.autoName = 'auto' + opts.uppercaseName;\n opts.labelName = 'label' + opts.uppercaseName;\n opts.outerName = 'outer' + opts.uppercaseName;\n opts.uppercaseOuterName = util.capitalize( opts.outerName );\n\n fn[ opts.name ] = function dimImpl(){\n var ele = this[0];\n var _p = ele._private;\n var cy = _p.cy;\n var styleEnabled = cy._private.styleEnabled;\n\n if( ele ){\n if( styleEnabled ){\n var d = _p.style[ opts.name ];\n\n switch( d.strValue ){\n case 'auto':\n return _p[ opts.autoName ] || 0;\n case 'label':\n return _p.rstyle[ opts.labelName ] || 0;\n default:\n return d.pfValue;\n }\n } else {\n return 1;\n }\n }\n };\n\n fn[ 'outer' + opts.uppercaseName ] = function outerDimImpl(){\n var ele = this[0];\n var _p = ele._private;\n var cy = _p.cy;\n var styleEnabled = cy._private.styleEnabled;\n\n if( ele ){\n if( styleEnabled ){\n var style = _p.style;\n var dim = ele[ opts.name ]();\n var border = style['border-width'].pfValue;\n var padding = style[ opts.paddings[0] ].pfValue + style[ opts.paddings[1] ].pfValue;\n\n return dim + border + padding;\n } else {\n return 1;\n }\n }\n };\n\n fn[ 'rendered' + opts.uppercaseName ] = function renderedDimImpl(){\n var ele = this[0];\n\n if( ele ){\n var d = ele[ opts.name ]();\n return d * this.cy().zoom();\n }\n };\n\n fn[ 'rendered' + opts.uppercaseOuterName ] = function renderedOuterDimImpl(){\n var ele = this[0];\n\n if( ele ){\n var od = ele[ opts.outerName ]();\n return od * this.cy().zoom();\n }\n };\n};\n\ndefineDimFns({\n name: 'width',\n paddings: ['padding-left', 'padding-right']\n});\n\ndefineDimFns({\n name: 'height',\n paddings: ['padding-top', 'padding-bottom']\n});\n\n// aliases\nfn.modelPosition = fn.point = fn.position;\nfn.modelPositions = fn.points = fn.positions;\nfn.renderedPoint = fn.renderedPosition;\nfn.relativePoint = fn.relativePosition;\nfn.boundingbox = fn.boundingBox;\nfn.renderedBoundingbox = fn.renderedBoundingBox;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar util = require('../util');\nvar is = require('../is');\n\n// represents a node or an edge\nvar Element = function(cy, params, restore){\n if( !(this instanceof Element) ){\n return new Element(cy, params, restore);\n }\n\n var self = this;\n restore = (restore === undefined || restore ? true : false);\n\n if( cy === undefined || params === undefined || !is.core(cy) ){\n util.error('An element must have a core reference and parameters set');\n return;\n }\n\n var group = params.group;\n\n // try to automatically infer the group if unspecified\n if( group == null ){\n if( params.data.source != null && params.data.target != null ){\n group = 'edges';\n } else {\n group = 'nodes';\n }\n }\n\n // validate group\n if( group !== 'nodes' && group !== 'edges' ){\n util.error('An element must be of type `nodes` or `edges`; you specified `' + group + '`');\n return;\n }\n\n // make the element array-like, just like a collection\n this.length = 1;\n this[0] = this;\n\n // NOTE: when something is added here, add also to ele.json()\n this._private = {\n cy: cy,\n single: true, // indicates this is an element\n data: params.data || {}, // data object\n position: params.position || {}, // (x, y) position pair\n autoWidth: undefined, // width and height of nodes calculated by the renderer when set to special 'auto' value\n autoHeight: undefined,\n listeners: [], // array of bound listeners\n group: group, // string; 'nodes' or 'edges'\n style: {}, // properties as set by the style\n rstyle: {}, // properties for style sent from the renderer to the core\n styleCxts: [], // applied style contexts from the styler\n removed: true, // whether it's inside the vis; true if removed (set true here since we call restore)\n selected: params.selected ? true : false, // whether it's selected\n selectable: params.selectable === undefined ? true : ( params.selectable ? true : false ), // whether it's selectable\n locked: params.locked ? true : false, // whether the element is locked (cannot be moved)\n grabbed: false, // whether the element is grabbed by the mouse; renderer sets this privately\n grabbable: params.grabbable === undefined ? true : ( params.grabbable ? true : false ), // whether the element can be grabbed\n active: false, // whether the element is active from user interaction\n classes: {}, // map ( className => true )\n animation: { // object for currently-running animations\n current: [],\n queue: []\n },\n rscratch: {}, // object in which the renderer can store information\n scratch: params.scratch || {}, // scratch objects\n edges: [], // array of connected edges\n children: [] // array of children\n };\n\n // renderedPosition overrides if specified\n if( params.renderedPosition ){\n var rpos = params.renderedPosition;\n var pan = cy.pan();\n var zoom = cy.zoom();\n\n this._private.position = {\n x: (rpos.x - pan.x)/zoom,\n y: (rpos.y - pan.y)/zoom\n };\n }\n\n if( is.string(params.classes) ){\n var classes = params.classes.split(/\\s+/);\n for( var i = 0, l = classes.length; i < l; i++ ){\n var cls = classes[i];\n if( !cls || cls === '' ){ continue; }\n\n self._private.classes[cls] = true;\n }\n }\n\n if( params.style || params.css ){\n cy.style().applyBypass( this, params.style || params.css );\n }\n\n if( restore === undefined || restore ){\n this.restore();\n }\n\n};\n\nmodule.exports = Element;\n","'use strict';\n\nvar define = require('../define');\n\nvar elesfn = ({\n on: define.on(), // .on( events [, selector] [, data], handler)\n one: define.on({ unbindSelfOnTrigger: true }),\n once: define.on({ unbindAllBindersOnTrigger: true }),\n off: define.off(), // .off( events [, selector] [, handler] )\n trigger: define.trigger(), // .trigger( events [, extraParams] )\n\n rtrigger: function(event, extraParams){ // for internal use only\n if( this.length === 0 ){ return; } // empty collections don't need to notify anything\n\n // notify renderer\n this.cy().notify({\n type: event,\n collection: this\n });\n\n this.trigger(event, extraParams);\n return this;\n }\n});\n\n// aliases:\ndefine.eventAliasesOn( elesfn );\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../is');\nvar Selector = require('../selector');\n\nvar elesfn = ({\n nodes: function( selector ){\n return this.filter(function(i, element){\n return element.isNode();\n }).filter(selector);\n },\n\n edges: function( selector ){\n return this.filter(function(i, element){\n return element.isEdge();\n }).filter(selector);\n },\n\n filter: function( filter ){\n if( is.fn(filter) ){\n var elements = [];\n\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n\n if( filter.apply(ele, [i, ele]) ){\n elements.push(ele);\n }\n }\n\n return this.spawn(elements);\n\n } else if( is.string(filter) || is.elementOrCollection(filter) ){\n return Selector(filter).filter(this);\n\n } else if( filter === undefined ){\n return this;\n }\n\n return this.spawn(); // if not handled by above, give 'em an empty collection\n },\n\n not: function( toRemove ){\n if( !toRemove ){\n return this;\n } else {\n\n if( is.string( toRemove ) ){\n toRemove = this.filter( toRemove );\n }\n\n var elements = [];\n\n for( var i = 0; i < this.length; i++ ){\n var element = this[i];\n\n var remove = toRemove._private.ids[ element.id() ];\n if( !remove ){\n elements.push( element );\n }\n }\n\n return this.spawn( elements );\n }\n\n },\n\n absoluteComplement: function(){\n var cy = this._private.cy;\n\n return cy.elements().not( this );\n },\n\n intersect: function( other ){\n // if a selector is specified, then filter by it instead\n if( is.string(other) ){\n var selector = other;\n return this.filter( selector );\n }\n\n var elements = [];\n var col1 = this;\n var col2 = other;\n var col1Smaller = this.length < other.length;\n // var ids1 = col1Smaller ? col1._private.ids : col2._private.ids;\n var ids2 = col1Smaller ? col2._private.ids : col1._private.ids;\n var col = col1Smaller ? col1 : col2;\n\n for( var i = 0; i < col.length; i++ ){\n var id = col[i]._private.data.id;\n var ele = ids2[ id ];\n\n if( ele ){\n elements.push( ele );\n }\n }\n\n return this.spawn( elements );\n },\n\n xor: function( other ){\n var cy = this._private.cy;\n\n if( is.string(other) ){\n other = cy.$( other );\n }\n\n var elements = [];\n var col1 = this;\n var col2 = other;\n\n var add = function( col, other ){\n\n for( var i = 0; i < col.length; i++ ){\n var ele = col[i];\n var id = ele._private.data.id;\n var inOther = other._private.ids[ id ];\n\n if( !inOther ){\n elements.push( ele );\n }\n }\n\n };\n\n add( col1, col2 );\n add( col2, col1 );\n\n return this.spawn( elements );\n },\n\n diff: function( other ){\n var cy = this._private.cy;\n\n if( is.string(other) ){\n other = cy.$( other );\n }\n\n var left = [];\n var right = [];\n var both = [];\n var col1 = this;\n var col2 = other;\n\n var add = function( col, other, retEles ){\n\n for( var i = 0; i < col.length; i++ ){\n var ele = col[i];\n var id = ele._private.data.id;\n var inOther = other._private.ids[ id ];\n\n if( inOther ){\n both.push( ele );\n } else {\n retEles.push( ele );\n }\n }\n\n };\n\n add( col1, col2, left );\n add( col2, col1, right );\n\n return {\n left: this.spawn( left, { unique: true } ),\n right: this.spawn( right, { unique: true } ),\n both: this.spawn( both, { unique: true } )\n };\n },\n\n add: function( toAdd ){\n var cy = this._private.cy;\n\n if( !toAdd ){\n return this;\n }\n\n if( is.string(toAdd) ){\n var selector = toAdd;\n toAdd = cy.elements(selector);\n }\n\n var elements = [];\n\n for( var i = 0; i < this.length; i++ ){\n elements.push( this[i] );\n }\n\n for( var i = 0; i < toAdd.length; i++ ){\n\n var add = !this._private.ids[ toAdd[i].id() ];\n if( add ){\n elements.push( toAdd[i] );\n }\n }\n\n return this.spawn(elements);\n },\n\n // in place merge on calling collection\n merge: function( toAdd ){\n var _p = this._private;\n var cy = _p.cy;\n\n if( !toAdd ){\n return this;\n }\n\n if( is.string(toAdd) ){\n var selector = toAdd;\n toAdd = cy.elements(selector);\n }\n\n for( var i = 0; i < toAdd.length; i++ ){\n var toAddEle = toAdd[i];\n var id = toAddEle.id();\n var add = !_p.ids[ id ];\n\n if( add ){\n var index = this.length++;\n\n this[ index ] = toAddEle;\n _p.ids[ id ] = toAddEle;\n _p.indexes[ id ] = index;\n }\n }\n\n return this; // chaining\n },\n\n // remove single ele in place in calling collection\n unmergeOne: function( ele ){\n ele = ele[0];\n\n var _p = this._private;\n var id = ele.id();\n var i = _p.indexes[ id ];\n\n if( i == null ){\n return this; // no need to remove\n }\n\n // remove ele\n this[i] = undefined;\n _p.ids[ id ] = undefined;\n _p.indexes[ id ] = undefined;\n\n var unmergedLastEle = i === this.length - 1;\n\n // replace empty spot with last ele in collection\n if( this.length > 1 && !unmergedLastEle ){\n var lastEleI = this.length - 1;\n var lastEle = this[ lastEleI ];\n\n this[ lastEleI ] = undefined;\n this[i] = lastEle;\n _p.indexes[ lastEle.id() ] = i;\n }\n\n // the collection is now 1 ele smaller\n this.length--;\n\n return this;\n },\n\n // remove eles in place on calling collection\n unmerge: function( toRemove ){\n var cy = this._private.cy;\n\n if( !toRemove ){\n return this;\n }\n\n if( is.string(toRemove) ){\n var selector = toRemove;\n toRemove = cy.elements(selector);\n }\n\n for( var i = 0; i < toRemove.length; i++ ){\n this.unmergeOne( toRemove[i] );\n }\n\n return this; // chaining\n },\n\n map: function( mapFn, thisArg ){\n var arr = [];\n var eles = this;\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var ret = thisArg ? mapFn.apply( thisArg, [ele, i, eles] ) : mapFn( ele, i, eles );\n\n arr.push( ret );\n }\n\n return arr;\n },\n\n stdFilter: function( fn, thisArg ){\n var filterEles = [];\n var eles = this;\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var include = thisArg ? fn.apply( thisArg, [ele, i, eles] ) : fn( ele, i, eles );\n\n if( include ){\n filterEles.push( ele );\n }\n }\n\n return this.spawn( filterEles );\n },\n\n max: function( valFn, thisArg ){\n var max = -Infinity;\n var maxEle;\n var eles = this;\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var val = thisArg ? valFn.apply( thisArg, [ ele, i, eles ] ) : valFn( ele, i, eles );\n\n if( val > max ){\n max = val;\n maxEle = ele;\n }\n }\n\n return {\n value: max,\n ele: maxEle\n };\n },\n\n min: function( valFn, thisArg ){\n var min = Infinity;\n var minEle;\n var eles = this;\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var val = thisArg ? valFn.apply( thisArg, [ ele, i, eles ] ) : valFn( ele, i, eles );\n\n if( val < min ){\n min = val;\n minEle = ele;\n }\n }\n\n return {\n value: min,\n ele: minEle\n };\n }\n});\n\n// aliases\nvar fn = elesfn;\nfn['u'] = fn['|'] = fn['+'] = fn.union = fn.or = fn.add;\nfn['\\\\'] = fn['!'] = fn['-'] = fn.difference = fn.relativeComplement = fn.subtract = fn.not;\nfn['n'] = fn['&'] = fn['.'] = fn.and = fn.intersection = fn.intersect;\nfn['^'] = fn['(+)'] = fn['(-)'] = fn.symmetricDifference = fn.symdiff = fn.xor;\nfn.fnFilter = fn.filterFn = fn.stdFilter;\nfn.complement = fn.abscomp = fn.absoluteComplement;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar elesfn = ({\n isNode: function(){\n return this.group() === 'nodes';\n },\n\n isEdge: function(){\n return this.group() === 'edges';\n },\n\n isLoop: function(){\n return this.isEdge() && this.source().id() === this.target().id();\n },\n\n isSimple: function(){\n return this.isEdge() && this.source().id() !== this.target().id();\n },\n\n group: function(){\n var ele = this[0];\n\n if( ele ){\n return ele._private.group;\n }\n }\n});\n\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar util = require('../util');\nvar is = require('../is');\n\nvar Element = require('./element');\n\n// factory for generating edge ids when no id is specified for a new element\nvar idFactory = {\n prefix: 'ele',\n id: 0,\n generate: function(cy, element, tryThisId){\n var json = is.element( element ) ? element._private : element;\n var id = tryThisId != null ? tryThisId : this.prefix + this.id;\n\n if( cy.getElementById(id).empty() ){\n this.id++; // we've used the current id, so move it up\n } else { // otherwise keep trying successive unused ids\n while( !cy.getElementById(id).empty() ){\n id = this.prefix + ( ++this.id );\n }\n }\n\n return id;\n }\n};\n\n// represents a set of nodes, edges, or both together\nvar Collection = function(cy, elements, options){\n if( !(this instanceof Collection) ){\n return new Collection(cy, elements, options);\n }\n\n if( cy === undefined || !is.core(cy) ){\n util.error('A collection must have a reference to the core');\n return;\n }\n\n var ids = {};\n var indexes = {};\n var createdElements = false;\n\n if( !elements ){\n elements = [];\n } else if( elements.length > 0 && is.plainObject( elements[0] ) && !is.element( elements[0] ) ){\n createdElements = true;\n\n // make elements from json and restore all at once later\n var eles = [];\n var elesIds = {};\n\n for( var i = 0, l = elements.length; i < l; i++ ){\n var json = elements[i];\n\n if( json.data == null ){\n json.data = {};\n }\n\n var data = json.data;\n\n // make sure newly created elements have valid ids\n if( data.id == null ){\n data.id = idFactory.generate( cy, json );\n } else if( cy.getElementById( data.id ).length !== 0 || elesIds[ data.id ] ){\n continue; // can't create element if prior id already exists\n }\n\n var ele = new Element( cy, json, false );\n eles.push( ele );\n elesIds[ data.id ] = true;\n }\n\n elements = eles;\n }\n\n this.length = 0;\n\n for( var i = 0, l = elements.length; i < l; i++ ){\n var element = elements[i];\n if( !element ){ continue; }\n\n var id = element._private.data.id;\n\n if( !options || (options.unique && !ids[ id ] ) ){\n ids[ id ] = element;\n indexes[ id ] = this.length;\n\n this[ this.length ] = element;\n this.length++;\n }\n }\n\n this._private = {\n cy: cy,\n ids: ids,\n indexes: indexes\n };\n\n // restore the elements if we created them from json\n if( createdElements ){\n this.restore();\n }\n};\n\n// Functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n// keep the prototypes in sync (an element has the same functions as a collection)\n// and use elefn and elesfn as shorthands to the prototypes\nvar elesfn = Element.prototype = Collection.prototype;\n\nelesfn.instanceString = function(){\n return 'collection';\n};\n\nelesfn.spawn = function( cy, eles, opts ){\n if( !is.core(cy) ){ // cy is optional\n opts = eles;\n eles = cy;\n cy = this.cy();\n }\n\n return new Collection( cy, eles, opts );\n};\n\nelesfn.cy = function(){\n return this._private.cy;\n};\n\nelesfn.element = function(){\n return this[0];\n};\n\nelesfn.collection = function(){\n if( is.collection(this) ){\n return this;\n } else { // an element\n return new Collection( this._private.cy, [this] );\n }\n};\n\nelesfn.unique = function(){\n return new Collection( this._private.cy, this, { unique: true } );\n};\n\nelesfn.getElementById = function( id ){\n var cy = this._private.cy;\n var ele = this._private.ids[ id ];\n\n return ele ? ele : new Collection(cy); // get ele or empty collection\n};\n\nelesfn.json = function( obj ){\n var ele = this.element();\n var cy = this.cy();\n\n if( ele == null && obj ){ return this; } // can't set to no eles\n\n if( ele == null ){ return undefined; } // can't get from no eles\n\n var p = ele._private;\n\n if( is.plainObject(obj) ){ // set\n\n cy.startBatch();\n\n if( obj.data ){\n ele.data( obj.data );\n }\n\n if( obj.position ){\n ele.position( obj.position );\n }\n\n // ignore group -- immutable\n\n var checkSwitch = function( k, trueFnName, falseFnName ){\n var obj_k = obj[k];\n\n if( obj_k != null && obj_k !== p[k] ){\n if( obj_k ){\n ele[ trueFnName ]();\n } else {\n ele[ falseFnName ]();\n }\n }\n };\n\n checkSwitch( 'removed', 'remove', 'restore' );\n\n checkSwitch( 'selected', 'select', 'unselect' );\n\n checkSwitch( 'selectable', 'selectify', 'unselectify' );\n\n checkSwitch( 'locked', 'lock', 'unlock' );\n\n checkSwitch( 'grabbable', 'grabify', 'ungrabify' );\n\n if( obj.classes != null ){\n ele.classes( obj.classes );\n }\n\n cy.endBatch();\n\n return this;\n\n } else if( obj === undefined ){ // get\n\n var json = {\n data: util.copy( p.data ),\n position: util.copy( p.position ),\n group: p.group,\n removed: p.removed,\n selected: p.selected,\n selectable: p.selectable,\n locked: p.locked,\n grabbable: p.grabbable,\n classes: null\n };\n\n var classes = [];\n for( var cls in p.classes ){\n if( p.classes[cls] ){\n classes.push(cls);\n }\n }\n json.classes = classes.join(' ');\n\n return json;\n }\n};\n\nelesfn.jsons = function(){\n var jsons = [];\n\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n var json = ele.json();\n\n jsons.push( json );\n }\n\n return jsons;\n};\n\nelesfn.clone = function(){\n var cy = this.cy();\n var elesArr = [];\n\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n var json = ele.json();\n var clone = new Element(cy, json, false); // NB no restore\n\n elesArr.push( clone );\n }\n\n return new Collection( cy, elesArr );\n};\nelesfn.copy = elesfn.clone;\n\nelesfn.restore = function( notifyRenderer ){\n var self = this;\n var restored = [];\n var cy = self.cy();\n\n if( notifyRenderer === undefined ){\n notifyRenderer = true;\n }\n\n // create arrays of nodes and edges, since we need to\n // restore the nodes first\n var elements = [];\n var nodes = [], edges = [];\n var numNodes = 0;\n var numEdges = 0;\n for( var i = 0, l = self.length; i < l; i++ ){\n var ele = self[i];\n\n // keep nodes first in the array and edges after\n if( ele.isNode() ){ // put to front of array if node\n nodes.push( ele );\n numNodes++;\n } else { // put to end of array if edge\n edges.push( ele );\n numEdges++;\n }\n }\n\n elements = nodes.concat( edges );\n\n // now, restore each element\n for( var i = 0, l = elements.length; i < l; i++ ){\n var ele = elements[i];\n\n if( !ele.removed() ){\n // don't need to do anything\n continue;\n }\n\n var _private = ele._private;\n var data = _private.data;\n\n // set id and validate\n if( data.id === undefined ){\n data.id = idFactory.generate( cy, ele );\n\n } else if( is.number(data.id) ){\n data.id = '' + data.id; // now it's a string\n\n } else if( is.emptyString(data.id) || !is.string(data.id) ){\n util.error('Can not create element with invalid string ID `' + data.id + '`');\n\n // can't create element if it has empty string as id or non-string id\n continue;\n } else if( cy.getElementById( data.id ).length !== 0 ){\n util.error('Can not create second element with ID `' + data.id + '`');\n\n // can't create element if one already has that id\n continue;\n }\n\n var id = data.id; // id is finalised, now let's keep a ref\n\n if( ele.isNode() ){ // extra checks for nodes\n var node = ele;\n var pos = _private.position;\n\n // make sure the nodes have a defined position\n\n if( pos.x == null ){\n pos.x = 0;\n }\n\n if( pos.y == null ){\n pos.y = 0;\n }\n }\n\n if( ele.isEdge() ){ // extra checks for edges\n\n var edge = ele;\n var fields = ['source', 'target'];\n var fieldsLength = fields.length;\n var badSourceOrTarget = false;\n for(var j = 0; j < fieldsLength; j++){\n\n var field = fields[j];\n var val = data[field];\n\n if( is.number(val) ){\n val = data[field] = '' + data[field]; // now string\n }\n\n if( val == null || val === '' ){\n // can't create if source or target is not defined properly\n util.error('Can not create edge `' + id + '` with unspecified ' + field);\n badSourceOrTarget = true;\n } else if( cy.getElementById(val).empty() ){\n // can't create edge if one of its nodes doesn't exist\n util.error('Can not create edge `' + id + '` with nonexistant ' + field + ' `' + val + '`');\n badSourceOrTarget = true;\n }\n }\n\n if( badSourceOrTarget ){ continue; } // can't create this\n\n var src = cy.getElementById( data.source );\n var tgt = cy.getElementById( data.target );\n\n src._private.edges.push( edge );\n tgt._private.edges.push( edge );\n\n edge._private.source = src;\n edge._private.target = tgt;\n\n } // if is edge\n\n // create mock ids map for element so it can be used like collections\n _private.ids = {};\n _private.ids[ id ] = ele;\n\n _private.removed = false;\n cy.addToPool( ele );\n\n restored.push( ele );\n } // for each element\n\n // do compound node sanity checks\n for( var i = 0; i < numNodes; i++ ){ // each node\n var node = elements[i];\n var data = node._private.data;\n\n if( is.number(data.parent) ){ // then automake string\n data.parent = '' + data.parent;\n }\n\n var parentId = data.parent;\n\n var specifiedParent = parentId != null;\n\n if( specifiedParent ){\n var parent = cy.getElementById( parentId );\n\n if( parent.empty() ){\n // non-existant parent; just remove it\n data.parent = undefined;\n } else {\n var selfAsParent = false;\n var ancestor = parent;\n while( !ancestor.empty() ){\n if( node.same(ancestor) ){\n // mark self as parent and remove from data\n selfAsParent = true;\n data.parent = undefined; // remove parent reference\n\n // exit or we loop forever\n break;\n }\n\n ancestor = ancestor.parent();\n }\n\n if( !selfAsParent ){\n // connect with children\n parent[0]._private.children.push( node );\n node._private.parent = parent[0];\n\n // let the core know we have a compound graph\n cy._private.hasCompoundNodes = true;\n }\n } // else\n } // if specified parent\n } // for each node\n\n restored = new Collection( cy, restored );\n if( restored.length > 0 ){\n\n var toUpdateStyle = restored.add( restored.connectedNodes() ).add( restored.parent() );\n toUpdateStyle.updateStyle( notifyRenderer );\n\n if( notifyRenderer ){\n restored.rtrigger('add');\n } else {\n restored.trigger('add');\n }\n }\n\n return self; // chainability\n};\n\nelesfn.removed = function(){\n var ele = this[0];\n return ele && ele._private.removed;\n};\n\nelesfn.inside = function(){\n var ele = this[0];\n return ele && !ele._private.removed;\n};\n\nelesfn.remove = function( notifyRenderer ){\n var self = this;\n var removed = [];\n var elesToRemove = [];\n var elesToRemoveIds = {};\n var cy = self._private.cy;\n\n if( notifyRenderer === undefined ){\n notifyRenderer = true;\n }\n\n // add connected edges\n function addConnectedEdges(node){\n var edges = node._private.edges;\n for( var i = 0; i < edges.length; i++ ){\n add( edges[i] );\n }\n }\n\n\n // add descendant nodes\n function addChildren(node){\n var children = node._private.children;\n\n for( var i = 0; i < children.length; i++ ){\n add( children[i] );\n }\n }\n\n function add( ele ){\n var alreadyAdded = elesToRemoveIds[ ele.id() ];\n if( alreadyAdded ){\n return;\n } else {\n elesToRemoveIds[ ele.id() ] = true;\n }\n\n if( ele.isNode() ){\n elesToRemove.push( ele ); // nodes are removed last\n\n addConnectedEdges( ele );\n addChildren( ele );\n } else {\n elesToRemove.unshift( ele ); // edges are removed first\n }\n }\n\n // make the list of elements to remove\n // (may be removing more than specified due to connected edges etc)\n\n for( var i = 0, l = self.length; i < l; i++ ){\n var ele = self[i];\n\n add( ele );\n }\n\n function removeEdgeRef(node, edge){\n var connectedEdges = node._private.edges;\n for( var j = 0; j < connectedEdges.length; j++ ){\n var connectedEdge = connectedEdges[j];\n\n if( edge === connectedEdge ){\n connectedEdges.splice( j, 1 );\n break;\n }\n }\n }\n\n function removeChildRef(parent, ele){\n ele = ele[0];\n parent = parent[0];\n var children = parent._private.children;\n\n for( var j = 0; j < children.length; j++ ){\n if( children[j][0] === ele[0] ){\n children.splice(j, 1);\n break;\n }\n }\n }\n\n for( var i = 0; i < elesToRemove.length; i++ ){\n var ele = elesToRemove[i];\n\n // mark as removed\n ele._private.removed = true;\n\n // remove from core pool\n cy.removeFromPool( ele );\n\n // add to list of removed elements\n removed.push( ele );\n\n if( ele.isEdge() ){ // remove references to this edge in its connected nodes\n var src = ele.source()[0];\n var tgt = ele.target()[0];\n\n removeEdgeRef( src, ele );\n removeEdgeRef( tgt, ele );\n\n } else { // remove reference to parent\n var parent = ele.parent();\n\n if( parent.length !== 0 ){\n removeChildRef(parent, ele);\n }\n }\n }\n\n // check to see if we have a compound graph or not\n var elesStillInside = cy._private.elements;\n cy._private.hasCompoundNodes = false;\n for( var i = 0; i < elesStillInside.length; i++ ){\n var ele = elesStillInside[i];\n\n if( ele.isParent() ){\n cy._private.hasCompoundNodes = true;\n break;\n }\n }\n\n var removedElements = new Collection( this.cy(), removed );\n if( removedElements.size() > 0 ){\n // must manually notify since trigger won't do this automatically once removed\n\n if( notifyRenderer ){\n this.cy().notify({\n type: 'remove',\n collection: removedElements\n });\n }\n\n removedElements.trigger('remove');\n }\n\n // check for empty remaining parent nodes\n var checkedParentId = {};\n for( var i = 0; i < elesToRemove.length; i++ ){\n var ele = elesToRemove[i];\n var isNode = ele._private.group === 'nodes';\n var parentId = ele._private.data.parent;\n\n if( isNode && parentId !== undefined && !checkedParentId[ parentId ] ){\n checkedParentId[ parentId ] = true;\n var parent = cy.getElementById( parentId );\n\n if( parent && parent.length !== 0 && !parent._private.removed && parent.children().length === 0 ){\n parent.updateStyle();\n }\n }\n }\n\n return new Collection( cy, removed );\n};\n\nelesfn.move = function( struct ){\n var cy = this._private.cy;\n\n if( struct.source !== undefined || struct.target !== undefined ){\n var srcId = struct.source;\n var tgtId = struct.target;\n var srcExists = cy.getElementById( srcId ).length > 0;\n var tgtExists = cy.getElementById( tgtId ).length > 0;\n\n if( srcExists || tgtExists ){\n var jsons = this.jsons();\n\n this.remove();\n\n for( var i = 0; i < jsons.length; i++ ){\n var json = jsons[i];\n\n if( json.group === 'edges' ){\n if( srcExists ){ json.data.source = srcId; }\n if( tgtExists ){ json.data.target = tgtId; }\n }\n }\n\n return cy.add( jsons );\n }\n\n } else if( struct.parent !== undefined ){ // move node to new parent\n var parentId = struct.parent;\n var parentExists = parentId === null || cy.getElementById( parentId ).length > 0;\n\n if( parentExists ){\n var jsons = this.jsons();\n var descs = this.descendants();\n var descsEtc = descs.merge( descs.add(this).connectedEdges() );\n\n this.remove(); // NB: also removes descendants and their connected edges\n\n for( var i = 0; i < this.length; i++ ){\n var json = jsons[i];\n\n if( json.group === 'nodes' ){\n json.data.parent = parentId === null ? undefined : parentId;\n }\n }\n }\n\n return cy.add( jsons ).merge( descsEtc.restore() );\n }\n\n return this; // if nothing done\n};\n\n[\n require('./algorithms'),\n require('./animation'),\n require('./class'),\n require('./comparators'),\n require('./compounds'),\n require('./data'),\n require('./degree'),\n require('./dimensions'),\n require('./events'),\n require('./filter'),\n require('./group'),\n require('./index'),\n require('./iteration'),\n require('./layout'),\n require('./style'),\n require('./switch-functions'),\n require('./traversing')\n].forEach(function( props ){\n util.extend( elesfn, props );\n});\n\nmodule.exports = Collection;\n","'use strict';\n\nvar is = require('../is');\nvar zIndexSort = require('./zsort');\n\nvar elesfn = ({\n each: function(fn){\n if( is.fn(fn) ){\n for(var i = 0; i < this.length; i++){\n var ele = this[i];\n var ret = fn.apply( ele, [ i, ele ] );\n\n if( ret === false ){ break; } // exit each early on return false\n }\n }\n return this;\n },\n\n forEach: function(fn, thisArg){\n if( is.fn(fn) ){\n\n for(var i = 0; i < this.length; i++){\n var ele = this[i];\n var ret = thisArg ? fn.apply( thisArg, [ ele, i, this ] ) : fn( ele, i, this );\n\n if( ret === false ){ break; } // exit each early on return false\n }\n }\n\n return this;\n },\n\n toArray: function(){\n var array = [];\n\n for(var i = 0; i < this.length; i++){\n array.push( this[i] );\n }\n\n return array;\n },\n\n slice: function(start, end){\n var array = [];\n var thisSize = this.length;\n\n if( end == null ){\n end = thisSize;\n }\n\n if( start == null ){\n start = 0;\n }\n\n if( start < 0 ){\n start = thisSize + start;\n }\n\n if( end < 0 ){\n end = thisSize + end;\n }\n\n for(var i = start; i >= 0 && i < end && i < thisSize; i++){\n array.push( this[i] );\n }\n\n return this.spawn(array);\n },\n\n size: function(){\n return this.length;\n },\n\n eq: function(i){\n return this[i] || this.spawn();\n },\n\n first: function(){\n return this[0] || this.spawn();\n },\n\n last: function(){\n return this[ this.length - 1 ] || this.spawn();\n },\n\n empty: function(){\n return this.length === 0;\n },\n\n nonempty: function(){\n return !this.empty();\n },\n\n sort: function( sortFn ){\n if( !is.fn( sortFn ) ){\n return this;\n }\n\n var sorted = this.toArray().sort( sortFn );\n\n return this.spawn(sorted);\n },\n\n sortByZIndex: function(){\n return this.sort( zIndexSort );\n },\n\n zDepth: function(){\n var ele = this[0];\n if( !ele ){ return undefined; }\n\n // var cy = ele.cy();\n var _p = ele._private;\n var group = _p.group;\n\n if( group === 'nodes' ){\n var depth = _p.data.parent ? ele.parents().size() : 0;\n\n if( !ele.isParent() ){\n return Number.MAX_VALUE; // childless nodes always on top\n }\n\n return depth;\n } else {\n var src = _p.source;\n var tgt = _p.target;\n var srcDepth = src.zDepth();\n var tgtDepth = tgt.zDepth();\n\n return Math.max( srcDepth, tgtDepth, 0 ); // depth of deepest parent\n }\n }\n});\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../is');\nvar util = require('../util');\n\nvar elesfn = ({\n\n // using standard layout options, apply position function (w/ or w/o animation)\n layoutPositions: function( layout, options, fn ){\n var nodes = this.nodes();\n var cy = this.cy();\n\n layout.trigger({ type: 'layoutstart', layout: layout });\n\n layout.animations = [];\n\n if( options.animate ){\n for( var i = 0; i < nodes.length; i++ ){\n var node = nodes[i];\n var lastNode = i === nodes.length - 1;\n\n var newPos = fn.call( node, i, node );\n var pos = node.position();\n\n if( !is.number(pos.x) || !is.number(pos.y) ){\n node.silentPosition({ x: 0, y: 0 });\n }\n\n var ani = node.animation({\n position: newPos,\n duration: options.animationDuration,\n easing: options.animationEasing,\n step: !lastNode ? undefined : function(){\n if( options.fit ){\n cy.fit( options.eles, options.padding );\n }\n },\n complete: !lastNode ? undefined : function(){\n if( options.zoom != null ){\n cy.zoom( options.zoom );\n }\n\n if( options.pan ){\n cy.pan( options.pan );\n }\n\n if( options.fit ){\n cy.fit( options.eles, options.padding );\n }\n\n layout.one('layoutstop', options.stop);\n layout.trigger({ type: 'layoutstop', layout: layout });\n }\n });\n\n layout.animations.push( ani );\n\n ani.play();\n }\n\n layout.one('layoutready', options.ready);\n layout.trigger({ type: 'layoutready', layout: layout });\n } else {\n nodes.positions( fn );\n\n if( options.fit ){\n cy.fit( options.eles, options.padding );\n }\n\n if( options.zoom != null ){\n cy.zoom( options.zoom );\n }\n\n if( options.pan ){\n cy.pan( options.pan );\n }\n\n layout.one('layoutready', options.ready);\n layout.trigger({ type: 'layoutready', layout: layout });\n\n layout.one('layoutstop', options.stop);\n layout.trigger({ type: 'layoutstop', layout: layout });\n }\n\n return this; // chaining\n },\n\n layout: function( options ){\n var cy = this.cy();\n\n cy.layout( util.extend({}, options, {\n eles: this\n }) );\n\n return this;\n },\n\n makeLayout: function( options ){\n var cy = this.cy();\n\n return cy.makeLayout( util.extend({}, options, {\n eles: this\n }) );\n }\n\n});\n\n// aliases:\nelesfn.createLayout = elesfn.makeLayout;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../is');\n\nvar elesfn = ({\n\n // fully updates (recalculates) the style for the elements\n updateStyle: function( notifyRenderer ){\n var cy = this._private.cy;\n\n if( !cy.styleEnabled() ){ return this; }\n\n if( cy._private.batchingStyle ){\n var bEles = cy._private.batchStyleEles;\n\n bEles.merge( this );\n\n return this; // chaining and exit early when batching\n }\n\n var style = cy.style();\n notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false;\n\n style.apply( this );\n\n var updatedCompounds = this.updateCompoundBounds();\n var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;\n\n if( notifyRenderer ){\n toNotify.rtrigger('style'); // let renderer know we changed style\n } else {\n toNotify.trigger('style'); // just fire the event\n }\n return this; // chaining\n },\n\n // just update the mappers in the elements' styles; cheaper than eles.updateStyle()\n updateMappers: function( notifyRenderer ){\n var cy = this._private.cy;\n var style = cy.style();\n notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false;\n\n if( !cy.styleEnabled() ){ return this; }\n\n style.updateMappers( this );\n\n var updatedCompounds = this.updateCompoundBounds();\n var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;\n\n if( notifyRenderer ){\n toNotify.rtrigger('style'); // let renderer know we changed style\n } else {\n toNotify.trigger('style'); // just fire the event\n }\n return this; // chaining\n },\n\n // get the specified css property as a rendered value (i.e. on-screen value)\n // or get the whole rendered style if no property specified (NB doesn't allow setting)\n renderedCss: function( property ){\n var cy = this.cy();\n if( !cy.styleEnabled() ){ return this; }\n\n var ele = this[0];\n\n if( ele ){\n var renstyle = ele.cy().style().getRenderedStyle( ele );\n\n if( property === undefined ){\n return renstyle;\n } else {\n return renstyle[ property ];\n }\n }\n },\n\n // read the calculated css style of the element or override the style (via a bypass)\n css: function( name, value ){\n var cy = this.cy();\n\n if( !cy.styleEnabled() ){ return this; }\n\n var updateTransitions = false;\n var style = cy.style();\n\n if( is.plainObject(name) ){ // then extend the bypass\n var props = name;\n style.applyBypass( this, props, updateTransitions );\n\n var updatedCompounds = this.updateCompoundBounds();\n var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;\n toNotify.rtrigger('style'); // let the renderer know we've updated style\n\n } else if( is.string(name) ){\n\n if( value === undefined ){ // then get the property from the style\n var ele = this[0];\n\n if( ele ){\n return style.getStylePropertyValue( ele, name );\n } else { // empty collection => can't get any value\n return;\n }\n\n } else { // then set the bypass with the property value\n style.applyBypass( this, name, value, updateTransitions );\n\n var updatedCompounds = this.updateCompoundBounds();\n var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;\n toNotify.rtrigger('style'); // let the renderer know we've updated style\n }\n\n } else if( name === undefined ){\n var ele = this[0];\n\n if( ele ){\n return style.getRawStyle( ele );\n } else { // empty collection => can't get any value\n return;\n }\n }\n\n return this; // chaining\n },\n\n removeCss: function( names ){\n var cy = this.cy();\n\n if( !cy.styleEnabled() ){ return this; }\n\n var updateTransitions = false;\n var style = cy.style();\n var eles = this;\n\n if( names === undefined ){\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n\n style.removeAllBypasses( ele, updateTransitions );\n }\n } else {\n names = names.split(/\\s+/);\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n\n style.removeBypasses( ele, names, updateTransitions );\n }\n }\n\n var updatedCompounds = this.updateCompoundBounds();\n var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;\n toNotify.rtrigger('style'); // let the renderer know we've updated style\n\n return this; // chaining\n },\n\n show: function(){\n this.css('display', 'element');\n return this; // chaining\n },\n\n hide: function(){\n this.css('display', 'none');\n return this; // chaining\n },\n\n visible: function(){\n var cy = this.cy();\n if( !cy.styleEnabled() ){ return true; }\n\n var ele = this[0];\n var hasCompoundNodes = cy.hasCompoundNodes();\n\n if( ele ){\n var style = ele._private.style;\n\n if(\n style['visibility'].value !== 'visible'\n || style['display'].value !== 'element'\n ){\n return false;\n }\n\n if( ele._private.group === 'nodes' ){\n if( !hasCompoundNodes ){ return true; }\n\n var parents = ele._private.data.parent ? ele.parents() : null;\n\n if( parents ){\n for( var i = 0; i < parents.length; i++ ){\n var parent = parents[i];\n var pStyle = parent._private.style;\n var pVis = pStyle['visibility'].value;\n var pDis = pStyle['display'].value;\n\n if( pVis !== 'visible' || pDis !== 'element' ){\n return false;\n }\n }\n }\n\n return true;\n } else {\n var src = ele._private.source;\n var tgt = ele._private.target;\n\n return src.visible() && tgt.visible();\n }\n\n }\n },\n\n hidden: function(){\n var ele = this[0];\n\n if( ele ){\n return !ele.visible();\n }\n },\n\n effectiveOpacity: function(){\n var cy = this.cy();\n if( !cy.styleEnabled() ){ return 1; }\n\n var hasCompoundNodes = cy.hasCompoundNodes();\n var ele = this[0];\n\n if( ele ){\n var _p = ele._private;\n var parentOpacity = _p.style.opacity.value;\n\n if( !hasCompoundNodes ){ return parentOpacity; }\n\n var parents = !_p.data.parent ? null : ele.parents();\n\n if( parents ){\n for( var i = 0; i < parents.length; i++ ){\n var parent = parents[i];\n var opacity = parent._private.style.opacity.value;\n\n parentOpacity = opacity * parentOpacity;\n }\n }\n\n return parentOpacity;\n }\n },\n\n transparent: function(){\n var cy = this.cy();\n if( !cy.styleEnabled() ){ return false; }\n\n var ele = this[0];\n var hasCompoundNodes = ele.cy().hasCompoundNodes();\n\n if( ele ){\n if( !hasCompoundNodes ){\n return ele._private.style.opacity.value === 0;\n } else {\n return ele.effectiveOpacity() === 0;\n }\n }\n },\n\n isFullAutoParent: function(){\n var cy = this.cy();\n if( !cy.styleEnabled() ){ return false; }\n\n var ele = this[0];\n\n if( ele ){\n var autoW = ele._private.style['width'].value === 'auto';\n var autoH = ele._private.style['height'].value === 'auto';\n\n return ele.isParent() && autoW && autoH;\n }\n },\n\n backgrounding: function(){\n var cy = this.cy();\n if( !cy.styleEnabled() ){ return false; }\n\n var ele = this[0];\n\n return ele._private.backgrounding ? true : false;\n }\n\n});\n\n\nelesfn.bypass = elesfn.style = elesfn.css;\nelesfn.renderedStyle = elesfn.renderedCss;\nelesfn.removeBypass = elesfn.removeStyle = elesfn.removeCss;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar elesfn = {};\n\nfunction defineSwitchFunction(params){\n return function(){\n var args = arguments;\n var changedEles = [];\n\n // e.g. cy.nodes().select( data, handler )\n if( args.length === 2 ){\n var data = args[0];\n var handler = args[1];\n this.bind( params.event, data, handler );\n }\n\n // e.g. cy.nodes().select( handler )\n else if( args.length === 1 ){\n var handler = args[0];\n this.bind( params.event, handler );\n }\n\n // e.g. cy.nodes().select()\n else if( args.length === 0 ){\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n var able = !params.ableField || ele._private[params.ableField];\n var changed = ele._private[params.field] != params.value;\n\n if( params.overrideAble ){\n var overrideAble = params.overrideAble(ele);\n\n if( overrideAble !== undefined ){\n able = overrideAble;\n\n if( !overrideAble ){ return this; } // to save cycles assume not able for all on override\n }\n }\n\n if( able ){\n ele._private[params.field] = params.value;\n\n if( changed ){\n changedEles.push( ele );\n }\n }\n }\n\n var changedColl = this.spawn( changedEles );\n changedColl.updateStyle(); // change of state => possible change of style\n changedColl.trigger( params.event );\n }\n\n return this;\n };\n}\n\nfunction defineSwitchSet( params ){\n elesfn[ params.field ] = function(){\n var ele = this[0];\n\n if( ele ){\n if( params.overrideField ){\n var val = params.overrideField(ele);\n\n if( val !== undefined ){\n return val;\n }\n }\n\n return ele._private[ params.field ];\n }\n };\n\n elesfn[ params.on ] = defineSwitchFunction({\n event: params.on,\n field: params.field,\n ableField: params.ableField,\n overrideAble: params.overrideAble,\n value: true\n });\n\n elesfn[ params.off ] = defineSwitchFunction({\n event: params.off,\n field: params.field,\n ableField: params.ableField,\n overrideAble: params.overrideAble,\n value: false\n });\n}\n\ndefineSwitchSet({\n field: 'locked',\n overrideField: function(ele){\n return ele.cy().autolock() ? true : undefined;\n },\n on: 'lock',\n off: 'unlock'\n});\n\ndefineSwitchSet({\n field: 'grabbable',\n overrideField: function(ele){\n return ele.cy().autoungrabify() ? false : undefined;\n },\n on: 'grabify',\n off: 'ungrabify'\n});\n\ndefineSwitchSet({\n field: 'selected',\n ableField: 'selectable',\n overrideAble: function(ele){\n return ele.cy().autounselectify() ? false : undefined;\n },\n on: 'select',\n off: 'unselect'\n});\n\ndefineSwitchSet({\n field: 'selectable',\n overrideField: function(ele){\n return ele.cy().autounselectify() ? false : undefined;\n },\n on: 'selectify',\n off: 'unselectify'\n});\n\nelesfn.deselect = elesfn.unselect;\n\nelesfn.grabbed = function(){\n var ele = this[0];\n if( ele ){\n return ele._private.grabbed;\n }\n};\n\ndefineSwitchSet({\n field: 'active',\n on: 'activate',\n off: 'unactivate'\n});\n\nelesfn.inactive = function(){\n var ele = this[0];\n if( ele ){\n return !ele._private.active;\n }\n};\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar util = require('../util');\nvar is = require('../is');\n\nvar elesfn = {};\n\nutil.extend(elesfn, {\n // get the root nodes in the DAG\n roots: function( selector ){\n var eles = this;\n var roots = [];\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n if( !ele.isNode() ){\n continue;\n }\n\n var hasEdgesPointingIn = ele.connectedEdges(function(){\n return this.data('target') === ele.id() && this.data('source') !== ele.id();\n }).length > 0;\n\n if( !hasEdgesPointingIn ){\n roots.push( ele );\n }\n }\n\n return this.spawn( roots, { unique: true } ).filter( selector );\n },\n\n // get the leaf nodes in the DAG\n leaves: function( selector ){\n var eles = this;\n var leaves = [];\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n if( !ele.isNode() ){\n continue;\n }\n\n var hasEdgesPointingOut = ele.connectedEdges(function(){\n return this.data('source') === ele.id() && this.data('target') !== ele.id();\n }).length > 0;\n\n if( !hasEdgesPointingOut ){\n leaves.push( ele );\n }\n }\n\n return this.spawn( leaves, { unique: true } ).filter( selector );\n },\n\n // normally called children in graph theory\n // these nodes =edges=> outgoing nodes\n outgoers: function( selector ){\n var eles = this;\n var oEles = [];\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var eleId = ele.id();\n\n if( !ele.isNode() ){ continue; }\n\n var edges = ele._private.edges;\n for( var j = 0; j < edges.length; j++ ){\n var edge = edges[j];\n var srcId = edge._private.data.source;\n var tgtId = edge._private.data.target;\n\n if( srcId === eleId && tgtId !== eleId ){\n oEles.push( edge );\n oEles.push( edge.target()[0] );\n }\n }\n }\n\n return this.spawn( oEles, { unique: true } ).filter( selector );\n },\n\n // aka DAG descendants\n successors: function( selector ){\n var eles = this;\n var sEles = [];\n var sElesIds = {};\n\n for(;;){\n var outgoers = eles.outgoers();\n\n if( outgoers.length === 0 ){ break; } // done if no outgoers left\n\n var newOutgoers = false;\n for( var i = 0; i < outgoers.length; i++ ){\n var outgoer = outgoers[i];\n var outgoerId = outgoer.id();\n\n if( !sElesIds[ outgoerId ] ){\n sElesIds[ outgoerId ] = true;\n sEles.push( outgoer );\n newOutgoers = true;\n }\n }\n\n if( !newOutgoers ){ break; } // done if touched all outgoers already\n\n eles = outgoers;\n }\n\n return this.spawn( sEles, { unique: true } ).filter( selector );\n },\n\n // normally called parents in graph theory\n // these nodes <=edges= incoming nodes\n incomers: function( selector ){\n var eles = this;\n var oEles = [];\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var eleId = ele.id();\n\n if( !ele.isNode() ){ continue; }\n\n var edges = ele._private.edges;\n for( var j = 0; j < edges.length; j++ ){\n var edge = edges[j];\n var srcId = edge._private.data.source;\n var tgtId = edge._private.data.target;\n\n if( tgtId === eleId && srcId !== eleId ){\n oEles.push( edge );\n oEles.push( edge.source()[0] );\n }\n }\n }\n\n return this.spawn( oEles, { unique: true } ).filter( selector );\n },\n\n // aka DAG ancestors\n predecessors: function( selector ){\n var eles = this;\n var pEles = [];\n var pElesIds = {};\n\n for(;;){\n var incomers = eles.incomers();\n\n if( incomers.length === 0 ){ break; } // done if no incomers left\n\n var newIncomers = false;\n for( var i = 0; i < incomers.length; i++ ){\n var incomer = incomers[i];\n var incomerId = incomer.id();\n\n if( !pElesIds[ incomerId ] ){\n pElesIds[ incomerId ] = true;\n pEles.push( incomer );\n newIncomers = true;\n }\n }\n\n if( !newIncomers ){ break; } // done if touched all incomers already\n\n eles = incomers;\n }\n\n return this.spawn( pEles, { unique: true } ).filter( selector );\n }\n});\n\n\n// Neighbourhood functions\n//////////////////////////\n\nutil.extend(elesfn, {\n neighborhood: function(selector){\n var elements = [];\n var nodes = this.nodes();\n\n for( var i = 0; i < nodes.length; i++ ){ // for all nodes\n var node = nodes[i];\n var connectedEdges = node.connectedEdges();\n\n // for each connected edge, add the edge and the other node\n for( var j = 0; j < connectedEdges.length; j++ ){\n var edge = connectedEdges[j];\n var src = edge._private.source;\n var tgt = edge._private.target;\n var otherNode = node === src ? tgt : src;\n\n // need check in case of loop\n if( otherNode.length > 0 ){\n elements.push( otherNode[0] ); // add node 1 hop away\n }\n\n // add connected edge\n elements.push( edge[0] );\n }\n\n }\n\n return ( this.spawn( elements, { unique: true } ) ).filter( selector );\n },\n\n closedNeighborhood: function(selector){\n return this.neighborhood().add( this ).filter( selector );\n },\n\n openNeighborhood: function(selector){\n return this.neighborhood( selector );\n }\n});\n\n// aliases\nelesfn.neighbourhood = elesfn.neighborhood;\nelesfn.closedNeighbourhood = elesfn.closedNeighborhood;\nelesfn.openNeighbourhood = elesfn.openNeighborhood;\n\n// Edge functions\n/////////////////\n\nutil.extend(elesfn, {\n source: function( selector ){\n var ele = this[0];\n var src;\n\n if( ele ){\n src = ele._private.source;\n }\n\n return src && selector ? src.filter( selector ) : src;\n },\n\n target: function( selector ){\n var ele = this[0];\n var tgt;\n\n if( ele ){\n tgt = ele._private.target;\n }\n\n return tgt && selector ? tgt.filter( selector ) : tgt;\n },\n\n sources: defineSourceFunction({\n attr: 'source'\n }),\n\n targets: defineSourceFunction({\n attr: 'target'\n })\n});\n\nfunction defineSourceFunction( params ){\n return function( selector ){\n var sources = [];\n\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n var src = ele._private[ params.attr ];\n\n if( src ){\n sources.push( src );\n }\n }\n\n return this.spawn( sources, { unique: true } ).filter( selector );\n };\n}\n\nutil.extend(elesfn, {\n edgesWith: defineEdgesWithFunction(),\n\n edgesTo: defineEdgesWithFunction({\n thisIs: 'source'\n })\n});\n\nfunction defineEdgesWithFunction( params ){\n\n return function edgesWithImpl( otherNodes ){\n var elements = [];\n var cy = this._private.cy;\n var p = params || {};\n\n // get elements if a selector is specified\n if( is.string(otherNodes) ){\n otherNodes = cy.$( otherNodes );\n }\n\n var thisIds = this._private.ids;\n var otherIds = otherNodes._private.ids;\n\n for( var h = 0; h < otherNodes.length; h++ ){\n var edges = otherNodes[h]._private.edges;\n\n for( var i = 0; i < edges.length; i++ ){\n var edge = edges[i];\n var edgeData = edge._private.data;\n var thisToOther = thisIds[ edgeData.source ] && otherIds[ edgeData.target ];\n var otherToThis = otherIds[ edgeData.source ] && thisIds[ edgeData.target ];\n var edgeConnectsThisAndOther = thisToOther || otherToThis;\n\n if( !edgeConnectsThisAndOther ){ continue; }\n\n if( p.thisIs ){\n if( p.thisIs === 'source' && !thisToOther ){ continue; }\n\n if( p.thisIs === 'target' && !otherToThis ){ continue; }\n }\n\n elements.push( edge );\n }\n }\n\n return this.spawn( elements, { unique: true } );\n };\n}\n\nutil.extend(elesfn, {\n connectedEdges: function( selector ){\n var retEles = [];\n\n var eles = this;\n for( var i = 0; i < eles.length; i++ ){\n var node = eles[i];\n if( !node.isNode() ){ continue; }\n\n var edges = node._private.edges;\n\n for( var j = 0; j < edges.length; j++ ){\n var edge = edges[j];\n retEles.push( edge );\n }\n }\n\n return this.spawn( retEles, { unique: true } ).filter( selector );\n },\n\n connectedNodes: function( selector ){\n var retEles = [];\n\n var eles = this;\n for( var i = 0; i < eles.length; i++ ){\n var edge = eles[i];\n if( !edge.isEdge() ){ continue; }\n\n retEles.push( edge.source()[0] );\n retEles.push( edge.target()[0] );\n }\n\n return this.spawn( retEles, { unique: true } ).filter( selector );\n },\n\n parallelEdges: defineParallelEdgesFunction(),\n\n codirectedEdges: defineParallelEdgesFunction({\n codirected: true\n })\n});\n\nfunction defineParallelEdgesFunction(params){\n var defaults = {\n codirected: false\n };\n params = util.extend({}, defaults, params);\n\n return function( selector ){\n var elements = [];\n var edges = this.edges();\n var p = params;\n\n // look at all the edges in the collection\n for( var i = 0; i < edges.length; i++ ){\n var edge1 = edges[i];\n var src1 = edge1.source()[0];\n var srcid1 = src1.id();\n var tgt1 = edge1.target()[0];\n var tgtid1 = tgt1.id();\n var srcEdges1 = src1._private.edges;\n\n // look at edges connected to the src node of this edge\n for( var j = 0; j < srcEdges1.length; j++ ){\n var edge2 = srcEdges1[j];\n var edge2data = edge2._private.data;\n var tgtid2 = edge2data.target;\n var srcid2 = edge2data.source;\n\n var codirected = tgtid2 === tgtid1 && srcid2 === srcid1;\n var oppdirected = srcid1 === tgtid2 && tgtid1 === srcid2;\n\n if( (p.codirected && codirected) || (!p.codirected && (codirected || oppdirected)) ){\n elements.push( edge2 );\n }\n }\n }\n\n return this.spawn( elements, { unique: true } ).filter( selector );\n };\n\n}\n\n// Misc functions\n/////////////////\n\nutil.extend(elesfn, {\n components: function(){\n var cy = this.cy();\n var visited = cy.collection();\n var unvisited = this.nodes();\n var components = [];\n\n var visitInComponent = function( node, component ){\n visited.merge( node );\n unvisited.unmerge( node );\n component.merge( node );\n };\n\n do {\n var component = cy.collection();\n components.push( component );\n\n var root = unvisited[0];\n visitInComponent( root, component );\n\n this.bfs({\n directed: false,\n roots: root,\n visit: function( i, depth, v, e, u ){\n visitInComponent( v, component );\n }\n });\n\n } while( unvisited.length > 0 );\n\n return components.map(function( component ){\n return component.closedNeighborhood(); // add the edges\n });\n }\n});\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar zIndexSort = function( a, b ){\n var cy = a.cy();\n var a_p = a._private;\n var b_p = b._private;\n var zDiff = a_p.style['z-index'].value - b_p.style['z-index'].value;\n var depthA = 0;\n var depthB = 0;\n var hasCompoundNodes = cy.hasCompoundNodes();\n var aIsNode = a_p.group === 'nodes';\n var aIsEdge = a_p.group === 'edges';\n var bIsNode = b_p.group === 'nodes';\n var bIsEdge = b_p.group === 'edges';\n\n // no need to calculate element depth if there is no compound node\n if( hasCompoundNodes ){\n depthA = a.zDepth();\n depthB = b.zDepth();\n }\n\n var depthDiff = depthA - depthB;\n var sameDepth = depthDiff === 0;\n\n if( sameDepth ){\n\n if( aIsNode && bIsEdge ){\n return 1; // 'a' is a node, it should be drawn later\n\n } else if( aIsEdge && bIsNode ){\n return -1; // 'a' is an edge, it should be drawn first\n\n } else { // both nodes or both edges\n if( zDiff === 0 ){ // same z-index => compare indices in the core (order added to graph w/ last on top)\n return a_p.index - b_p.index;\n } else {\n return zDiff;\n }\n }\n\n // elements on different level\n } else {\n return depthDiff; // deeper element should be drawn later\n }\n\n};\n\nmodule.exports = zIndexSort;\n","'use strict';\n\nvar is = require('../is');\nvar util = require('../util');\nvar Collection = require('../collection');\nvar Element = require('../collection/element');\nvar window = require('../window');\nvar document = window ? window.document : null;\nvar NullRenderer = require('../extensions/renderer/null');\n\nvar corefn = {\n add: function(opts){\n\n var elements;\n var cy = this;\n\n // add the elements\n if( is.elementOrCollection(opts) ){\n var eles = opts;\n\n if( eles._private.cy === cy ){ // same instance => just restore\n elements = eles.restore();\n\n } else { // otherwise, copy from json\n var jsons = [];\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n jsons.push( ele.json() );\n }\n\n elements = new Collection( cy, jsons );\n }\n }\n\n // specify an array of options\n else if( is.array(opts) ){\n var jsons = opts;\n\n elements = new Collection(cy, jsons);\n }\n\n // specify via opts.nodes and opts.edges\n else if( is.plainObject(opts) && (is.array(opts.nodes) || is.array(opts.edges)) ){\n var elesByGroup = opts;\n var jsons = [];\n\n var grs = ['nodes', 'edges'];\n for( var i = 0, il = grs.length; i < il; i++ ){\n var group = grs[i];\n var elesArray = elesByGroup[group];\n\n if( is.array(elesArray) ){\n\n for( var j = 0, jl = elesArray.length; j < jl; j++ ){\n var json = util.extend( { group: group }, elesArray[j] );\n\n jsons.push( json );\n }\n }\n }\n\n elements = new Collection(cy, jsons);\n }\n\n // specify options for one element\n else {\n var json = opts;\n elements = (new Element( cy, json )).collection();\n }\n\n return elements;\n },\n\n remove: function(collection){\n if( is.elementOrCollection(collection) ){\n collection = collection;\n } else if( is.string(collection) ){\n var selector = collection;\n collection = this.$( selector );\n }\n\n return collection.remove();\n },\n\n load: function(elements, onload, ondone){\n var cy = this;\n\n cy.notifications(false);\n\n // remove old elements\n var oldEles = cy.elements();\n if( oldEles.length > 0 ){\n oldEles.remove();\n }\n\n if( elements != null ){\n if( is.plainObject(elements) || is.array(elements) ){\n cy.add( elements );\n }\n }\n\n cy.one('layoutready', function(e){\n cy.notifications(true);\n cy.trigger(e); // we missed this event by turning notifications off, so pass it on\n\n cy.notify({\n type: 'load',\n collection: cy.elements()\n });\n\n cy.one('load', onload);\n cy.trigger('load');\n }).one('layoutstop', function(){\n cy.one('done', ondone);\n cy.trigger('done');\n });\n\n var layoutOpts = util.extend({}, cy._private.options.layout);\n layoutOpts.eles = cy.$();\n\n cy.layout( layoutOpts );\n\n return this;\n }\n};\n\nmodule.exports = corefn;\n","'use strict';\n\nvar define = require('../define');\nvar util = require('../util');\nvar is = require('../is');\n\nvar corefn = ({\n\n // pull in animation functions\n animate: define.animate(),\n animation: define.animation(),\n animated: define.animated(),\n clearQueue: define.clearQueue(),\n delay: define.delay(),\n delayAnimation: define.delayAnimation(),\n stop: define.stop(),\n\n addToAnimationPool: function( eles ){\n var cy = this;\n\n if( !cy.styleEnabled() ){ return; } // save cycles when no style used\n\n cy._private.aniEles.merge( eles );\n },\n\n stopAnimationLoop: function(){\n this._private.animationsRunning = false;\n },\n\n startAnimationLoop: function(){\n var cy = this;\n\n cy._private.animationsRunning = true;\n\n if( !cy.styleEnabled() ){ return; } // save cycles when no style used\n\n // NB the animation loop will exec in headless environments if style enabled\n // and explicit cy.destroy() is necessary to stop the loop\n\n function globalAnimationStep(){\n if( !cy._private.animationsRunning ){ return; }\n\n util.requestAnimationFrame(function(now){\n handleElements(now);\n globalAnimationStep();\n });\n }\n\n globalAnimationStep(); // first call\n\n function handleElements( now ){\n var eles = cy._private.aniEles;\n var doneEles = [];\n\n function handleElement( ele, isCore ){\n var _p = ele._private;\n var current = _p.animation.current;\n var queue = _p.animation.queue;\n var ranAnis = false;\n\n // if nothing currently animating, get something from the queue\n if( current.length === 0 ){\n var next = queue.shift();\n\n if( next ){\n current.push( next );\n }\n }\n\n var callbacks = function( callbacks ){\n for( var j = callbacks.length - 1; j >= 0; j-- ){\n var cb = callbacks[j];\n\n cb();\n }\n\n callbacks.splice( 0, callbacks.length );\n };\n\n // step and remove if done\n for( var i = current.length - 1; i >= 0; i-- ){\n var ani = current[i];\n var ani_p = ani._private;\n\n if( ani_p.stopped ){\n current.splice( i, 1 );\n\n ani_p.hooked = false;\n ani_p.playing = false;\n ani_p.started = false;\n\n callbacks( ani_p.frames );\n\n continue;\n }\n\n if( !ani_p.playing && !ani_p.applying ){ continue; }\n\n // an apply() while playing shouldn't do anything\n if( ani_p.playing && ani_p.applying ){\n ani_p.applying = false;\n }\n\n if( !ani_p.started ){\n startAnimation( ele, ani, now );\n }\n\n step( ele, ani, now, isCore );\n\n if( ani_p.applying ){\n ani_p.applying = false;\n }\n\n callbacks( ani_p.frames );\n\n if( ani.completed() ){\n current.splice(i, 1);\n\n ani_p.hooked = false;\n ani_p.playing = false;\n ani_p.started = false;\n\n callbacks( ani_p.completes );\n }\n\n ranAnis = true;\n }\n\n if( !isCore && current.length === 0 && queue.length === 0 ){\n doneEles.push( ele );\n }\n\n return ranAnis;\n } // handleElement\n\n // handle all eles\n var ranEleAni = false;\n for( var e = 0; e < eles.length; e++ ){\n var ele = eles[e];\n var handledThisEle = handleElement( ele );\n\n ranEleAni = ranEleAni || handledThisEle;\n } // each element\n\n var ranCoreAni = handleElement( cy, true );\n\n // notify renderer\n if( ranEleAni || ranCoreAni ){\n var toNotify;\n\n if( eles.length > 0 ){\n var updatedEles = eles.updateCompoundBounds();\n toNotify = updatedEles.length > 0 ? eles.add( updatedEles ) : eles;\n }\n\n cy.notify({\n type: 'draw',\n collection: toNotify\n });\n }\n\n // remove elements from list of currently animating if its queues are empty\n eles.unmerge( doneEles );\n\n } // handleElements\n\n function startAnimation( self, ani, now ){\n var isCore = is.core( self );\n var isEles = !isCore;\n var ele = self;\n var style = cy._private.style;\n var ani_p = ani._private;\n\n if( isEles ){\n var pos = ele._private.position;\n\n ani_p.startPosition = ani_p.startPosition || {\n x: pos.x,\n y: pos.y\n };\n\n ani_p.startStyle = ani_p.startStyle || style.getValueStyle( ele );\n }\n\n if( isCore ){\n var pan = cy._private.pan;\n\n ani_p.startPan = ani_p.startPan || {\n x: pan.x,\n y: pan.y\n };\n\n ani_p.startZoom = ani_p.startZoom != null ? ani_p.startZoom : cy._private.zoom;\n }\n\n ani_p.started = true;\n ani_p.startTime = now - ani_p.progress * ani_p.duration;\n }\n\n function step( self, ani, now, isCore ){\n var style = cy._private.style;\n var isEles = !isCore;\n var _p = self._private;\n var ani_p = ani._private;\n var pEasing = ani_p.easing;\n var startTime = ani_p.startTime;\n\n if( !ani_p.easingImpl ){\n\n if( pEasing == null ){ // use default\n ani_p.easingImpl = easings['linear'];\n\n } else { // then define w/ name\n var easingVals;\n\n if( is.string( pEasing ) ){\n var easingProp = style.parse('transition-timing-function', pEasing);\n\n easingVals = easingProp.value;\n\n } else { // then assume preparsed array\n easingVals = pEasing;\n }\n\n var name, args;\n\n if( is.string( easingVals ) ){\n name = easingVals;\n args = [];\n } else {\n name = easingVals[1];\n args = easingVals.slice(2).map(function(n){ return +n; });\n }\n\n if( args.length > 0 ){ // create with args\n if( name === 'spring' ){\n args.push( ani_p.duration ); // need duration to generate spring\n }\n\n ani_p.easingImpl = easings[ name ].apply( null, args );\n } else { // static impl by name\n ani_p.easingImpl = easings[ name ];\n }\n }\n\n }\n\n var easing = ani_p.easingImpl;\n var percent;\n\n if( ani_p.duration === 0 ){\n percent = 1;\n } else {\n percent = (now - startTime) / ani_p.duration;\n }\n\n if( ani_p.applying ){\n percent = ani_p.progress;\n }\n\n if( percent < 0 ){\n percent = 0;\n } else if( percent > 1 ){\n percent = 1;\n }\n\n if( ani_p.delay == null ){ // then update\n\n var startPos = ani_p.startPosition;\n var endPos = ani_p.position;\n var pos = _p.position;\n if( endPos && isEles ){\n if( valid( startPos.x, endPos.x ) ){\n pos.x = ease( startPos.x, endPos.x, percent, easing );\n }\n\n if( valid( startPos.y, endPos.y ) ){\n pos.y = ease( startPos.y, endPos.y, percent, easing );\n }\n }\n\n var startPan = ani_p.startPan;\n var endPan = ani_p.pan;\n var pan = _p.pan;\n var animatingPan = endPan != null && isCore;\n if( animatingPan ){\n if( valid( startPan.x, endPan.x ) ){\n pan.x = ease( startPan.x, endPan.x, percent, easing );\n }\n\n if( valid( startPan.y, endPan.y ) ){\n pan.y = ease( startPan.y, endPan.y, percent, easing );\n }\n\n self.trigger('pan');\n }\n\n var startZoom = ani_p.startZoom;\n var endZoom = ani_p.zoom;\n var animatingZoom = endZoom != null && isCore;\n if( animatingZoom ){\n if( valid( startZoom, endZoom ) ){\n _p.zoom = ease( startZoom, endZoom, percent, easing );\n }\n\n self.trigger('zoom');\n }\n\n if( animatingPan || animatingZoom ){\n self.trigger('viewport');\n }\n\n var props = ani_p.style;\n if( props && isEles ){\n\n for( var i = 0; i < props.length; i++ ){\n var prop = props[i];\n var name = prop.name;\n var end = prop;\n\n var start = ani_p.startStyle[ name ];\n var easedVal = ease( start, end, percent, easing );\n\n style.overrideBypass( self, name, easedVal );\n } // for props\n\n } // if\n\n }\n\n if( is.fn(ani_p.step) ){\n ani_p.step.apply( self, [ now ] );\n }\n\n ani_p.progress = percent;\n\n return percent;\n }\n\n function valid(start, end){\n if( start == null || end == null ){\n return false;\n }\n\n if( is.number(start) && is.number(end) ){\n return true;\n } else if( (start) && (end) ){\n return true;\n }\n\n return false;\n }\n\n // assumes p0 = 0, p3 = 1\n function evalCubicBezier( p1, p2, t ){\n var one_t = 1 - t;\n var tsq = t*t;\n\n return ( 3 * one_t * one_t * t * p1 ) + ( 3 * one_t * tsq * p2 ) + tsq * t;\n }\n\n function cubicBezier( p1, p2 ){\n return function( start, end, percent ){\n return start + (end - start) * evalCubicBezier( p1, p2, percent );\n };\n }\n\n /* Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */\n /* 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\n then adjusts the time delta -- using the relation between actual time and duration -- to calculate the path for the duration-constrained animation. */\n var generateSpringRK4 = (function () {\n function springAccelerationForState (state) {\n return (-state.tension * state.x) - (state.friction * state.v);\n }\n\n function springEvaluateStateWithDerivative (initialState, dt, derivative) {\n var state = {\n x: initialState.x + derivative.dx * dt,\n v: initialState.v + derivative.dv * dt,\n tension: initialState.tension,\n friction: initialState.friction\n };\n\n return { dx: state.v, dv: springAccelerationForState(state) };\n }\n\n function springIntegrateState (state, dt) {\n var a = {\n dx: state.v,\n dv: springAccelerationForState(state)\n },\n b = springEvaluateStateWithDerivative(state, dt * 0.5, a),\n c = springEvaluateStateWithDerivative(state, dt * 0.5, b),\n d = springEvaluateStateWithDerivative(state, dt, c),\n dxdt = 1.0 / 6.0 * (a.dx + 2.0 * (b.dx + c.dx) + d.dx),\n dvdt = 1.0 / 6.0 * (a.dv + 2.0 * (b.dv + c.dv) + d.dv);\n\n state.x = state.x + dxdt * dt;\n state.v = state.v + dvdt * dt;\n\n return state;\n }\n\n return function springRK4Factory (tension, friction, duration) {\n\n var initState = {\n x: -1,\n v: 0,\n tension: null,\n friction: null\n },\n path = [0],\n time_lapsed = 0,\n tolerance = 1 / 10000,\n DT = 16 / 1000,\n have_duration, dt, last_state;\n\n tension = parseFloat(tension) || 500;\n friction = parseFloat(friction) || 20;\n duration = duration || null;\n\n initState.tension = tension;\n initState.friction = friction;\n\n have_duration = duration !== null;\n\n /* Calculate the actual time it takes for this animation to complete with the provided conditions. */\n if (have_duration) {\n /* Run the simulation without a duration. */\n time_lapsed = springRK4Factory(tension, friction);\n /* Compute the adjusted time delta. */\n dt = time_lapsed / duration * DT;\n } else {\n dt = DT;\n }\n\n while (true) {\n /* Next/step function .*/\n last_state = springIntegrateState(last_state || initState, dt);\n /* Store the position. */\n path.push(1 + last_state.x);\n time_lapsed += 16;\n /* If the change threshold is reached, break. */\n if (!(Math.abs(last_state.x) > tolerance && Math.abs(last_state.v) > tolerance)) {\n break;\n }\n }\n\n /* If duration is not defined, return the actual time required for completing this animation. Otherwise, return a closure that holds the\n computed path and returns a snapshot of the position according to a given percentComplete. */\n return !have_duration ? time_lapsed : function(percentComplete) { return path[ (percentComplete * (path.length - 1)) | 0 ]; };\n };\n }());\n\n var easings = {\n 'linear': function( start, end, percent ){\n return start + (end - start) * percent;\n },\n\n // default easings\n 'ease': cubicBezier( 0.25, 0.1, 0.25, 1 ),\n 'ease-in': cubicBezier( 0.42, 0, 1, 1 ),\n 'ease-out': cubicBezier( 0, 0, 0.58, 1 ),\n 'ease-in-out': cubicBezier( 0.42, 0, 0.58, 1 ),\n\n // sine\n 'ease-in-sine': cubicBezier( 0.47, 0, 0.745, 0.715 ),\n 'ease-out-sine': cubicBezier( 0.39, 0.575, 0.565, 1 ),\n 'ease-in-out-sine': cubicBezier( 0.445, 0.05, 0.55, 0.95 ),\n\n // quad\n 'ease-in-quad': cubicBezier( 0.55, 0.085, 0.68, 0.53 ),\n 'ease-out-quad': cubicBezier( 0.25, 0.46, 0.45, 0.94 ),\n 'ease-in-out-quad': cubicBezier( 0.455, 0.03, 0.515, 0.955 ),\n\n // cubic\n 'ease-in-cubic': cubicBezier( 0.55, 0.055, 0.675, 0.19 ),\n 'ease-out-cubic': cubicBezier( 0.215, 0.61, 0.355, 1 ),\n 'ease-in-out-cubic': cubicBezier( 0.645, 0.045, 0.355, 1 ),\n\n // quart\n 'ease-in-quart': cubicBezier( 0.895, 0.03, 0.685, 0.22 ),\n 'ease-out-quart': cubicBezier( 0.165, 0.84, 0.44, 1 ),\n 'ease-in-out-quart': cubicBezier( 0.77, 0, 0.175, 1 ),\n\n // quint\n 'ease-in-quint': cubicBezier( 0.755, 0.05, 0.855, 0.06 ),\n 'ease-out-quint': cubicBezier( 0.23, 1, 0.32, 1 ),\n 'ease-in-out-quint': cubicBezier( 0.86, 0, 0.07, 1 ),\n\n // expo\n 'ease-in-expo': cubicBezier( 0.95, 0.05, 0.795, 0.035 ),\n 'ease-out-expo': cubicBezier( 0.19, 1, 0.22, 1 ),\n 'ease-in-out-expo': cubicBezier( 1, 0, 0, 1 ),\n\n // circ\n 'ease-in-circ': cubicBezier( 0.6, 0.04, 0.98, 0.335 ),\n 'ease-out-circ': cubicBezier( 0.075, 0.82, 0.165, 1 ),\n 'ease-in-out-circ': cubicBezier( 0.785, 0.135, 0.15, 0.86 ),\n\n\n // user param easings...\n\n 'spring': function( tension, friction, duration ){\n var spring = generateSpringRK4( tension, friction, duration );\n\n return function( start, end, percent ){\n return start + (end - start) * spring( percent );\n };\n },\n\n 'cubic-bezier': function( x1, y1, x2, y2 ){\n return cubicBezier( x1, y1, x2, y2 );\n }\n };\n\n function ease( startProp, endProp, percent, easingFn ){\n if( percent < 0 ){\n percent = 0;\n } else if( percent > 1 ){\n percent = 1;\n }\n\n var start, end;\n\n if( startProp.pfValue != null || startProp.value != null ){\n start = startProp.pfValue != null ? startProp.pfValue : startProp.value;\n } else {\n start = startProp;\n }\n\n if( endProp.pfValue != null || endProp.value != null ){\n end = endProp.pfValue != null ? endProp.pfValue : endProp.value;\n } else {\n end = endProp;\n }\n\n if( is.number(start) && is.number(end) ){\n return easingFn( start, end, percent );\n\n } else if( is.array(start) && is.array(end) ){\n var easedArr = [];\n\n for( var i = 0; i < end.length; i++ ){\n var si = start[i];\n var ei = end[i];\n\n if( si != null && ei != null ){\n var val = easingFn(si, ei, percent);\n\n if( startProp.roundValue ){ val = Math.round( val ); }\n\n easedArr.push( val );\n } else {\n easedArr.push( ei );\n }\n }\n\n return easedArr;\n }\n\n return undefined;\n }\n\n }\n\n});\n\nmodule.exports = corefn;\n","'use strict';\n\nvar define = require('../define');\n\nvar corefn = ({\n on: define.on(), // .on( events [, selector] [, data], handler)\n one: define.on({ unbindSelfOnTrigger: true }),\n once: define.on({ unbindAllBindersOnTrigger: true }),\n off: define.off(), // .off( events [, selector] [, handler] )\n trigger: define.trigger() // .trigger( events [, extraParams] )\n});\n\ndefine.eventAliasesOn( corefn );\n\nmodule.exports = corefn;\n","'use strict';\n\nvar corefn = ({\n\n png: function( options ){\n var renderer = this._private.renderer;\n options = options || {};\n\n return renderer.png( options );\n },\n\n jpg: function( options ){\n var renderer = this._private.renderer;\n options = options || {};\n\n options.bg = options.bg || '#fff';\n\n return renderer.jpg( options );\n }\n\n});\n\ncorefn.jpeg = corefn.jpg;\n\nmodule.exports = corefn;\n","'use strict';\n\nvar window = require('../window');\nvar util = require('../util');\nvar Collection = require('../collection');\nvar is = require('../is');\nvar Promise = require('../promise');\nvar define = require('../define');\n\nvar Core = function( opts ){\n if( !(this instanceof Core) ){\n return new Core(opts);\n }\n var cy = this;\n\n opts = util.extend({}, opts);\n\n var container = opts.container;\n\n // allow for passing a wrapped jquery object\n // e.g. cytoscape({ container: $('#cy') })\n if( container && !is.htmlElement( container ) && is.htmlElement( container[0] ) ){\n container = container[0];\n }\n\n var reg = container ? container._cyreg : null; // e.g. already registered some info (e.g. readies) via jquery\n reg = reg || {};\n\n if( reg && reg.cy ){\n reg.cy.destroy();\n\n reg = {}; // old instance => replace reg completely\n }\n\n var readies = reg.readies = reg.readies || [];\n\n if( container ){ container._cyreg = reg; } // make sure container assoc'd reg points to this cy\n reg.cy = cy;\n\n var head = window !== undefined && container !== undefined && !opts.headless;\n var options = opts;\n options.layout = util.extend( { name: head ? 'grid' : 'null' }, options.layout );\n options.renderer = util.extend( { name: head ? 'canvas' : 'null' }, options.renderer );\n\n var defVal = function( def, val, altVal ){\n if( val !== undefined ){\n return val;\n } else if( altVal !== undefined ){\n return altVal;\n } else {\n return def;\n }\n };\n\n var _p = this._private = {\n container: container, // html dom ele container\n ready: false, // whether ready has been triggered\n initrender: false, // has initrender has been triggered\n options: options, // cached options\n elements: [], // array of elements\n id2index: {}, // element id => index in elements array\n listeners: [], // list of listeners\n onRenders: [], // rendering listeners\n aniEles: Collection(this), // elements being animated\n scratch: {}, // scratch object for core\n layout: null,\n renderer: null,\n notificationsEnabled: true, // whether notifications are sent to the renderer\n minZoom: 1e-50,\n maxZoom: 1e50,\n zoomingEnabled: defVal(true, options.zoomingEnabled),\n userZoomingEnabled: defVal(true, options.userZoomingEnabled),\n panningEnabled: defVal(true, options.panningEnabled),\n userPanningEnabled: defVal(true, options.userPanningEnabled),\n boxSelectionEnabled: defVal(true, options.boxSelectionEnabled),\n autolock: defVal(false, options.autolock, options.autolockNodes),\n autoungrabify: defVal(false, options.autoungrabify, options.autoungrabifyNodes),\n autounselectify: defVal(false, options.autounselectify),\n styleEnabled: options.styleEnabled === undefined ? head : options.styleEnabled,\n zoom: is.number(options.zoom) ? options.zoom : 1,\n pan: {\n x: is.plainObject(options.pan) && is.number(options.pan.x) ? options.pan.x : 0,\n y: is.plainObject(options.pan) && is.number(options.pan.y) ? options.pan.y : 0\n },\n animation: { // object for currently-running animations\n current: [],\n queue: []\n },\n hasCompoundNodes: false,\n deferredExecQueue: []\n };\n\n // set selection type\n var selType = options.selectionType;\n if( selType === undefined || (selType !== 'additive' && selType !== 'single') ){\n // then set default\n\n _p.selectionType = 'single';\n } else {\n _p.selectionType = selType;\n }\n\n // init zoom bounds\n if( is.number(options.minZoom) && is.number(options.maxZoom) && options.minZoom < options.maxZoom ){\n _p.minZoom = options.minZoom;\n _p.maxZoom = options.maxZoom;\n } else if( is.number(options.minZoom) && options.maxZoom === undefined ){\n _p.minZoom = options.minZoom;\n } else if( is.number(options.maxZoom) && options.minZoom === undefined ){\n _p.maxZoom = options.maxZoom;\n }\n\n var loadExtData = function( next ){\n var anyIsPromise = false;\n\n for( var i = 0; i < extData.length; i++ ){\n var datum = extData[i];\n\n if( is.promise(datum) ){\n anyIsPromise = true;\n break;\n }\n }\n\n if( anyIsPromise ){\n return Promise.all( extData ).then( next ); // load all data asynchronously, then exec rest of init\n } else {\n next( extData ); // exec synchronously for convenience\n }\n };\n\n // create the renderer\n cy.initRenderer( util.extend({\n hideEdgesOnViewport: options.hideEdgesOnViewport,\n hideLabelsOnViewport: options.hideLabelsOnViewport,\n textureOnViewport: options.textureOnViewport,\n wheelSensitivity: is.number(options.wheelSensitivity) && options.wheelSensitivity > 0 ? options.wheelSensitivity : 1,\n motionBlur: options.motionBlur === undefined ? true : options.motionBlur, // on by default\n motionBlurOpacity: options.motionBlurOpacity === undefined ? 0.05 : options.motionBlurOpacity,\n pixelRatio: is.number(options.pixelRatio) && options.pixelRatio > 0 ? options.pixelRatio : undefined,\n desktopTapThreshold: options.desktopTapThreshold === undefined ? 4 : options.desktopTapThreshold,\n touchTapThreshold: options.touchTapThreshold === undefined ? 8 : options.touchTapThreshold\n }, options.renderer) );\n\n var extData = [ options.style, options.elements ];\n loadExtData(function( thens ){\n var initStyle = thens[0];\n var initEles = thens[1];\n\n // init style\n if( _p.styleEnabled ){\n cy.setStyle( initStyle );\n }\n\n // trigger the passed function for the `initrender` event\n if( options.initrender ){\n cy.on('initrender', options.initrender);\n cy.on('initrender', function(){\n _p.initrender = true;\n });\n }\n\n // initial load\n cy.load(initEles, function(){ // onready\n cy.startAnimationLoop();\n _p.ready = true;\n\n // if a ready callback is specified as an option, the bind it\n if( is.fn( options.ready ) ){\n cy.on('ready', options.ready);\n }\n\n // bind all the ready handlers registered before creating this instance\n for( var i = 0; i < readies.length; i++ ){\n var fn = readies[i];\n cy.on('ready', fn);\n }\n 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\n\n cy.trigger('ready');\n }, options.done);\n\n });\n};\n\nvar corefn = Core.prototype; // short alias\n\nutil.extend(corefn, {\n instanceString: function(){\n return 'core';\n },\n\n isReady: function(){\n return this._private.ready;\n },\n\n ready: function( fn ){\n if( this.isReady() ){\n this.trigger('ready', [], fn); // just calls fn as though triggered via ready event\n } else {\n this.on('ready', fn);\n }\n\n return this;\n },\n\n initrender: function(){\n return this._private.initrender;\n },\n\n destroy: function(){\n var cy = this;\n\n cy.stopAnimationLoop();\n\n cy.notify({ type: 'destroy' }); // destroy the renderer\n\n var domEle = cy.container();\n if( domEle ){\n domEle._cyreg = null;\n\n while( domEle.childNodes.length > 0 ){\n domEle.removeChild( domEle.childNodes[0] );\n }\n }\n\n return cy;\n },\n\n getElementById: function( id ){\n var index = this._private.id2index[ id ];\n if( index !== undefined ){\n return this._private.elements[ index ];\n }\n\n // worst case, return an empty collection\n return Collection( this );\n },\n\n selectionType: function(){\n return this._private.selectionType;\n },\n\n hasCompoundNodes: function(){\n return this._private.hasCompoundNodes;\n },\n\n styleEnabled: function(){\n return this._private.styleEnabled;\n },\n\n addToPool: function( eles ){\n var elements = this._private.elements;\n var id2index = this._private.id2index;\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n\n var id = ele._private.data.id;\n var index = id2index[ id ];\n var alreadyInPool = index !== undefined;\n\n if( !alreadyInPool ){\n index = elements.length;\n elements.push( ele );\n id2index[ id ] = index;\n ele._private.index = index;\n }\n }\n\n return this; // chaining\n },\n\n removeFromPool: function( eles ){\n var elements = this._private.elements;\n var id2index = this._private.id2index;\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n\n var id = ele._private.data.id;\n var index = id2index[ id ];\n var inPool = index !== undefined;\n\n if( inPool ){\n this._private.id2index[ id ] = undefined;\n elements.splice(index, 1);\n\n // adjust the index of all elements past this index\n for( var j = index; j < elements.length; j++ ){\n var jid = elements[j]._private.data.id;\n id2index[ jid ]--;\n elements[j]._private.index--;\n }\n }\n }\n },\n\n container: function(){\n return this._private.container;\n },\n\n options: function(){\n return util.copy( this._private.options );\n },\n\n json: function( obj ){\n var cy = this;\n var _p = cy._private;\n\n if( is.plainObject(obj) ){ // set\n\n cy.startBatch();\n\n if( obj.elements ){\n var idInJson = {};\n\n var updateEles = function( jsons, gr ){\n for( var i = 0; i < jsons.length; i++ ){\n var json = jsons[i];\n var id = json.data.id;\n var ele = cy.getElementById( id );\n\n idInJson[ id ] = true;\n\n if( ele.length !== 0 ){ // existing element should be updated\n ele.json( json );\n } else { // otherwise should be added\n if( gr ){\n cy.add( util.extend({ group: gr }, json) );\n } else {\n cy.add( json );\n }\n }\n }\n };\n\n if( is.array(obj.elements) ){ // elements: []\n updateEles( obj.elements );\n\n } else { // elements: { nodes: [], edges: [] }\n var grs = ['nodes', 'edges'];\n for( var i = 0; i < grs.length; i++ ){\n var gr = grs[i];\n var elements = obj.elements[ gr ];\n\n if( is.array(elements) ){\n updateEles( elements, gr );\n }\n }\n }\n\n // elements not specified in json should be removed\n cy.elements().stdFilter(function( ele ){\n return !idInJson[ ele.id() ];\n }).remove();\n }\n\n if( obj.style ){\n cy.style( obj.style );\n }\n\n if( obj.zoom != null && obj.zoom !== _p.zoom ){\n cy.zoom( obj.zoom );\n }\n\n if( obj.pan ){\n if( obj.pan.x !== _p.pan.x || obj.pan.y !== _p.pan.y ){\n cy.pan( obj.pan );\n }\n }\n\n var fields = [\n 'minZoom', 'maxZoom', 'zoomingEnabled', 'userZoomingEnabled',\n 'panningEnabled', 'userPanningEnabled',\n 'boxSelectionEnabled',\n 'autolock', 'autoungrabify', 'autounselectify'\n ];\n\n for( var i = 0; i < fields.length; i++ ){\n var f = fields[i];\n\n if( obj[f] != null ){\n cy[f]( obj[f] );\n }\n }\n\n cy.endBatch();\n\n return this; // chaining\n } else if( obj === undefined ){ // get\n var json = {};\n\n json.elements = {};\n cy.elements().each(function(i, ele){\n var group = ele.group();\n\n if( !json.elements[group] ){\n json.elements[group] = [];\n }\n\n json.elements[group].push( ele.json() );\n });\n\n if( this._private.styleEnabled ){\n json.style = cy.style().json();\n }\n\n json.zoomingEnabled = cy._private.zoomingEnabled;\n json.userZoomingEnabled = cy._private.userZoomingEnabled;\n json.zoom = cy._private.zoom;\n json.minZoom = cy._private.minZoom;\n json.maxZoom = cy._private.maxZoom;\n json.panningEnabled = cy._private.panningEnabled;\n json.userPanningEnabled = cy._private.userPanningEnabled;\n json.pan = util.copy( cy._private.pan );\n json.boxSelectionEnabled = cy._private.boxSelectionEnabled;\n json.renderer = util.copy( cy._private.options.renderer );\n json.hideEdgesOnViewport = cy._private.options.hideEdgesOnViewport;\n json.hideLabelsOnViewport = cy._private.options.hideLabelsOnViewport;\n json.textureOnViewport = cy._private.options.textureOnViewport;\n json.wheelSensitivity = cy._private.options.wheelSensitivity;\n json.motionBlur = cy._private.options.motionBlur;\n\n return json;\n }\n },\n\n scratch: define.data({\n field: 'scratch',\n bindingEvent: 'scratch',\n allowBinding: true,\n allowSetting: true,\n settingEvent: 'scratch',\n settingTriggersEvent: true,\n triggerFnName: 'trigger',\n allowGetting: true\n }),\n\n removeScratch: define.removeData({\n field: 'scratch',\n event: 'scratch',\n triggerFnName: 'trigger',\n triggerEvent: true\n })\n\n});\n\n[\n require('./add-remove'),\n require('./animation'),\n require('./events'),\n require('./export'),\n require('./layout'),\n require('./notification'),\n require('./renderer'),\n require('./search'),\n require('./style'),\n require('./viewport')\n].forEach(function( props ){\n util.extend( corefn, props );\n});\n\nmodule.exports = Core;\n","'use strict';\n\nvar util = require('../util');\nvar is = require('../is');\n\nvar corefn = ({\n\n layout: function( params ){\n var layout = this._private.prevLayout = ( params == null ? this._private.prevLayout : this.makeLayout( params ) );\n\n layout.run();\n\n return this; // chaining\n },\n\n makeLayout: function( options ){\n var cy = this;\n\n if( options == null ){\n util.error('Layout options must be specified to make a layout');\n return;\n }\n\n if( options.name == null ){\n util.error('A `name` must be specified to make a layout');\n return;\n }\n\n var name = options.name;\n var Layout = cy.extension('layout', name);\n\n if( Layout == null ){\n util.error('Can not apply layout: No such layout `' + name + '` found; did you include its JS file?');\n return;\n }\n\n var eles;\n if( is.string( options.eles ) ){\n eles = cy.$( options.eles );\n } else {\n eles = options.eles != null ? options.eles : cy.$();\n }\n\n var layout = new Layout( util.extend({}, options, {\n cy: cy,\n eles: eles\n }) );\n\n return layout;\n }\n\n});\n\ncorefn.createLayout = corefn.makeLayout;\n\nmodule.exports = corefn;\n","'use strict';\n\nvar corefn = ({\n notify: function( params ){\n var _p = this._private;\n\n if( _p.batchingNotify ){\n var bEles = _p.batchNotifyEles;\n var bTypes = _p.batchNotifyTypes;\n\n if( params.collection ){\n bEles.merge( params.collection );\n }\n\n if( !bTypes.ids[ params.type ] ){\n bTypes.push( params.type );\n }\n\n return; // notifications are disabled during batching\n }\n\n if( !_p.notificationsEnabled ){ return; } // exit on disabled\n\n var renderer = this.renderer();\n\n renderer.notify(params);\n },\n\n notifications: function( bool ){\n var p = this._private;\n\n if( bool === undefined ){\n return p.notificationsEnabled;\n } else {\n p.notificationsEnabled = bool ? true : false;\n }\n },\n\n noNotifications: function( callback ){\n this.notifications(false);\n callback();\n this.notifications(true);\n },\n\n startBatch: function(){\n var _p = this._private;\n\n if( _p.batchCount == null ){\n _p.batchCount = 0;\n }\n\n if( _p.batchCount === 0 ){\n _p.batchingStyle = _p.batchingNotify = true;\n _p.batchStyleEles = this.collection();\n _p.batchNotifyEles = this.collection();\n _p.batchNotifyTypes = [];\n\n _p.batchNotifyTypes.ids = {};\n }\n\n _p.batchCount++;\n\n return this;\n },\n\n endBatch: function(){\n var _p = this._private;\n\n _p.batchCount--;\n\n if( _p.batchCount === 0 ){\n // update style for dirty eles\n _p.batchingStyle = false;\n _p.batchStyleEles.updateStyle();\n\n // notify the renderer of queued eles and event types\n _p.batchingNotify = false;\n this.notify({\n type: _p.batchNotifyTypes,\n collection: _p.batchNotifyEles\n });\n }\n\n return this;\n },\n\n batch: function( callback ){\n this.startBatch();\n callback();\n this.endBatch();\n\n return this;\n },\n\n // for backwards compatibility\n batchData: function( map ){\n var cy = this;\n\n return this.batch(function(){\n for( var id in map ){\n var data = map[id];\n var ele = cy.getElementById( id );\n\n ele.data( data );\n }\n });\n }\n});\n\nmodule.exports = corefn;\n","'use strict';\n\nvar util = require('../util');\n\nvar corefn = ({\n\n renderTo: function( context, zoom, pan, pxRatio ){\n var r = this._private.renderer;\n\n r.renderTo( context, zoom, pan, pxRatio );\n return this;\n },\n\n renderer: function(){\n return this._private.renderer;\n },\n\n forceRender: function(){\n this.notify({\n type: 'draw'\n });\n\n return this;\n },\n\n resize: function(){\n this.notify({\n type: 'resize'\n });\n\n this.trigger('resize');\n\n return this;\n },\n\n initRenderer: function( options ){\n var cy = this;\n\n var RendererProto = cy.extension('renderer', options.name);\n if( RendererProto == null ){\n util.error('Can not initialise: No such renderer `%s` found; did you include its JS file?', options.name);\n return;\n }\n\n var rOpts = util.extend({}, options, {\n cy: cy\n });\n var renderer = cy._private.renderer = new RendererProto( rOpts );\n\n renderer.init( rOpts );\n\n },\n\n triggerOnRender: function(){\n var cbs = this._private.onRenders;\n\n for( var i = 0; i < cbs.length; i++ ){\n var cb = cbs[i];\n\n cb();\n }\n\n return this;\n },\n\n onRender: function( cb ){\n this._private.onRenders.push( cb );\n\n return this;\n },\n\n offRender: function( fn ){\n var cbs = this._private.onRenders;\n\n if( fn == null ){ // unbind all\n this._private.onRenders = [];\n return this;\n }\n\n for( var i = 0; i < cbs.length; i++ ){ // unbind specified\n var cb = cbs[i];\n\n if( fn === cb ){\n cbs.splice( i, 1 );\n break;\n }\n }\n\n return this;\n }\n\n});\n\ncorefn.invalidateDimensions = corefn.resize;\n\nmodule.exports = corefn;\n","'use strict';\n\nvar is = require('../is');\nvar Collection = require('../collection');\n\nvar corefn = ({\n\n // get a collection\n // - empty collection on no args\n // - collection of elements in the graph on selector arg\n // - guarantee a returned collection when elements or collection specified\n collection: function( eles, opts ){\n\n if( is.string( eles ) ){\n return this.$( eles );\n\n } else if( is.elementOrCollection( eles ) ){\n return eles.collection();\n\n } else if( is.array( eles ) ){\n return Collection( this, eles, opts );\n }\n\n return Collection( this );\n },\n\n nodes: function( selector ){\n var nodes = this.$(function(){\n return this.isNode();\n });\n\n if( selector ){\n return nodes.filter( selector );\n }\n\n return nodes;\n },\n\n edges: function( selector ){\n var edges = this.$(function(){\n return this.isEdge();\n });\n\n if( selector ){\n return edges.filter( selector );\n }\n\n return edges;\n },\n\n // search the graph like jQuery\n $: function( selector ){\n var eles = new Collection( this, this._private.elements );\n\n if( selector ){\n return eles.filter( selector );\n }\n\n return eles;\n }\n\n});\n\n// aliases\ncorefn.elements = corefn.filter = corefn.$;\n\nmodule.exports = corefn;\n","'use strict';\n\nvar is = require('../is');\nvar Style = require('../style');\n\nvar corefn = ({\n\n style: function( newStyle ){\n if( newStyle ){\n var s = this.setStyle( newStyle );\n\n s.update();\n }\n\n return this._private.style;\n },\n\n setStyle: function( style ){\n var _p = this._private;\n\n if( is.stylesheet(style) ){\n _p.style = style.generateStyle(this);\n\n } else if( is.array(style) ) {\n _p.style = Style.fromJson(this, style);\n\n } else if( is.string(style) ){\n _p.style = Style.fromString(this, style);\n\n } else {\n _p.style = Style( this );\n }\n\n return _p.style;\n }\n});\n\nmodule.exports = corefn;\n","'use strict';\n\nvar is = require('../is');\n\nvar corefn = ({\n\n autolock: function(bool){\n if( bool !== undefined ){\n this._private.autolock = bool ? true : false;\n } else {\n return this._private.autolock;\n }\n\n return this; // chaining\n },\n\n autoungrabify: function(bool){\n if( bool !== undefined ){\n this._private.autoungrabify = bool ? true : false;\n } else {\n return this._private.autoungrabify;\n }\n\n return this; // chaining\n },\n\n autounselectify: function(bool){\n if( bool !== undefined ){\n this._private.autounselectify = bool ? true : false;\n } else {\n return this._private.autounselectify;\n }\n\n return this; // chaining\n },\n\n panningEnabled: function( bool ){\n if( bool !== undefined ){\n this._private.panningEnabled = bool ? true : false;\n } else {\n return this._private.panningEnabled;\n }\n\n return this; // chaining\n },\n\n userPanningEnabled: function( bool ){\n if( bool !== undefined ){\n this._private.userPanningEnabled = bool ? true : false;\n } else {\n return this._private.userPanningEnabled;\n }\n\n return this; // chaining\n },\n\n zoomingEnabled: function( bool ){\n if( bool !== undefined ){\n this._private.zoomingEnabled = bool ? true : false;\n } else {\n return this._private.zoomingEnabled;\n }\n\n return this; // chaining\n },\n\n userZoomingEnabled: function( bool ){\n if( bool !== undefined ){\n this._private.userZoomingEnabled = bool ? true : false;\n } else {\n return this._private.userZoomingEnabled;\n }\n\n return this; // chaining\n },\n\n boxSelectionEnabled: function( bool ){\n if( bool !== undefined ){\n this._private.boxSelectionEnabled = bool ? true : false;\n } else {\n return this._private.boxSelectionEnabled;\n }\n\n return this; // chaining\n },\n\n pan: function(){\n var args = arguments;\n var pan = this._private.pan;\n var dim, val, dims, x, y;\n\n switch( args.length ){\n case 0: // .pan()\n return pan;\n\n case 1:\n\n if( is.string( args[0] ) ){ // .pan('x')\n dim = args[0];\n return pan[ dim ];\n\n } else if( is.plainObject( args[0] ) ) { // .pan({ x: 0, y: 100 })\n if( !this._private.panningEnabled ){\n return this;\n }\n\n dims = args[0];\n x = dims.x;\n y = dims.y;\n\n if( is.number(x) ){\n pan.x = x;\n }\n\n if( is.number(y) ){\n pan.y = y;\n }\n\n this.trigger('pan viewport');\n }\n break;\n\n case 2: // .pan('x', 100)\n if( !this._private.panningEnabled ){\n return this;\n }\n\n dim = args[0];\n val = args[1];\n\n if( (dim === 'x' || dim === 'y') && is.number(val) ){\n pan[dim] = val;\n }\n\n this.trigger('pan viewport');\n break;\n\n default:\n break; // invalid\n }\n\n this.notify({ // notify the renderer that the viewport changed\n type: 'viewport'\n });\n\n return this; // chaining\n },\n\n panBy: function(params){\n var args = arguments;\n var pan = this._private.pan;\n var dim, val, dims, x, y;\n\n if( !this._private.panningEnabled ){\n return this;\n }\n\n switch( args.length ){\n case 1:\n\n if( is.plainObject( args[0] ) ) { // .panBy({ x: 0, y: 100 })\n dims = args[0];\n x = dims.x;\n y = dims.y;\n\n if( is.number(x) ){\n pan.x += x;\n }\n\n if( is.number(y) ){\n pan.y += y;\n }\n\n this.trigger('pan viewport');\n }\n break;\n\n case 2: // .panBy('x', 100)\n dim = args[0];\n val = args[1];\n\n if( (dim === 'x' || dim === 'y') && is.number(val) ){\n pan[dim] += val;\n }\n\n this.trigger('pan viewport');\n break;\n\n default:\n break; // invalid\n }\n\n this.notify({ // notify the renderer that the viewport changed\n type: 'viewport'\n });\n\n return this; // chaining\n },\n\n fit: function( elements, padding ){\n var viewportState = this.getFitViewport( elements, padding );\n\n if( viewportState ){\n var _p = this._private;\n _p.zoom = viewportState.zoom;\n _p.pan = viewportState.pan;\n\n this.trigger('pan zoom viewport');\n\n this.notify({ // notify the renderer that the viewport changed\n type: 'viewport'\n });\n }\n\n return this; // chaining\n },\n\n getFitViewport: function( elements, padding ){\n if( is.number(elements) && padding === undefined ){ // elements is optional\n padding = elements;\n elements = undefined;\n }\n\n if( !this._private.panningEnabled || !this._private.zoomingEnabled ){\n return;\n }\n\n var bb;\n\n if( is.string(elements) ){\n var sel = elements;\n elements = this.$( sel );\n\n } else if( is.boundingBox(elements) ){ // assume bb\n var bbe = elements;\n bb = {\n x1: bbe.x1,\n y1: bbe.y1,\n x2: bbe.x2,\n y2: bbe.y2\n };\n\n bb.w = bb.x2 - bb.x1;\n bb.h = bb.y2 - bb.y1;\n\n } else if( !is.elementOrCollection(elements) ){\n elements = this.elements();\n }\n\n bb = bb || elements.boundingBox();\n\n var w = this.width();\n var h = this.height();\n var zoom;\n padding = is.number(padding) ? padding : 0;\n\n if( !isNaN(w) && !isNaN(h) && w > 0 && h > 0 && !isNaN(bb.w) && !isNaN(bb.h) && bb.w > 0 && bb.h > 0 ){\n zoom = Math.min( (w - 2*padding)/bb.w, (h - 2*padding)/bb.h );\n\n // crop zoom\n zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom;\n zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom;\n\n var pan = { // now pan to middle\n x: (w - zoom*( bb.x1 + bb.x2 ))/2,\n y: (h - zoom*( bb.y1 + bb.y2 ))/2\n };\n\n return {\n zoom: zoom,\n pan: pan\n };\n }\n\n return;\n },\n\n minZoom: function( zoom ){\n if( zoom === undefined ){\n return this._private.minZoom;\n } else if( is.number(zoom) ){\n this._private.minZoom = zoom;\n }\n\n return this;\n },\n\n maxZoom: function( zoom ){\n if( zoom === undefined ){\n return this._private.maxZoom;\n } else if( is.number(zoom) ){\n this._private.maxZoom = zoom;\n }\n\n return this;\n },\n\n zoom: function( params ){\n var pos; // in rendered px\n var zoom;\n\n if( params === undefined ){ // then get the zoom\n return this._private.zoom;\n\n } else if( is.number(params) ){ // then set the zoom\n zoom = params;\n\n } else if( is.plainObject(params) ){ // then zoom about a point\n zoom = params.level;\n\n if( params.position ){\n var p = params.position;\n var pan = this._private.pan;\n var z = this._private.zoom;\n\n pos = { // convert to rendered px\n x: p.x * z + pan.x,\n y: p.y * z + pan.y\n };\n } else if( params.renderedPosition ){\n pos = params.renderedPosition;\n }\n\n if( pos && !this._private.panningEnabled ){\n return this; // panning disabled\n }\n }\n\n if( !this._private.zoomingEnabled ){\n return this; // zooming disabled\n }\n\n if( !is.number(zoom) || ( pos && (!is.number(pos.x) || !is.number(pos.y)) ) ){\n return this; // can't zoom with invalid params\n }\n\n // crop zoom\n zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom;\n zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom;\n\n if( pos ){ // set zoom about position\n var pan1 = this._private.pan;\n var zoom1 = this._private.zoom;\n var zoom2 = zoom;\n\n var pan2 = {\n x: -zoom2/zoom1 * (pos.x - pan1.x) + pos.x,\n y: -zoom2/zoom1 * (pos.y - pan1.y) + pos.y\n };\n\n this._private.zoom = zoom;\n this._private.pan = pan2;\n\n var posChanged = pan1.x !== pan2.x || pan1.y !== pan2.y;\n this.trigger(' zoom ' + (posChanged ? ' pan ' : '') + ' viewport ' );\n\n } else { // just set the zoom\n this._private.zoom = zoom;\n this.trigger('zoom viewport');\n }\n\n this.notify({ // notify the renderer that the viewport changed\n type: 'viewport'\n });\n\n return this; // chaining\n },\n\n viewport: function( opts ){\n var _p = this._private;\n var zoomDefd = true;\n var panDefd = true;\n var events = []; // to trigger\n var zoomFailed = false;\n var panFailed = false;\n\n if( !opts ){ return this; }\n if( !is.number(opts.zoom) ){ zoomDefd = false; }\n if( !is.plainObject(opts.pan) ){ panDefd = false; }\n if( !zoomDefd && !panDefd ){ return this; }\n\n if( zoomDefd ){\n var z = opts.zoom;\n\n if( z < _p.minZoom || z > _p.maxZoom || !_p.zoomingEnabled ){\n zoomFailed = true;\n\n } else {\n _p.zoom = z;\n\n events.push('zoom');\n }\n }\n\n if( panDefd && (!zoomFailed || !opts.cancelOnFailedZoom) && _p.panningEnabled ){\n var p = opts.pan;\n\n if( is.number(p.x) ){\n _p.pan.x = p.x;\n panFailed = false;\n }\n\n if( is.number(p.y) ){\n _p.pan.y = p.y;\n panFailed = false;\n }\n\n if( !panFailed ){\n events.push('pan');\n }\n }\n\n if( events.length > 0 ){\n events.push('viewport');\n this.trigger( events.join(' ') );\n\n this.notify({\n type: 'viewport'\n });\n }\n\n return this; // chaining\n },\n\n center: function( elements ){\n var pan = this.getCenterPan( elements );\n\n if( pan ){\n this._private.pan = pan;\n\n this.trigger('pan viewport');\n\n this.notify({ // notify the renderer that the viewport changed\n type: 'viewport'\n });\n }\n\n return this; // chaining\n },\n\n getCenterPan: function( elements, zoom ){\n if( !this._private.panningEnabled ){\n return;\n }\n\n if( is.string(elements) ){\n var selector = elements;\n elements = this.elements( selector );\n } else if( !is.elementOrCollection(elements) ){\n elements = this.elements();\n }\n\n var bb = elements.boundingBox();\n var w = this.width();\n var h = this.height();\n zoom = zoom === undefined ? this._private.zoom : zoom;\n\n var pan = { // middle\n x: (w - zoom*( bb.x1 + bb.x2 ))/2,\n y: (h - zoom*( bb.y1 + bb.y2 ))/2\n };\n\n return pan;\n },\n\n reset: function(){\n if( !this._private.panningEnabled || !this._private.zoomingEnabled ){\n return this;\n }\n\n this.viewport({\n pan: { x: 0, y: 0 },\n zoom: 1\n });\n\n return this; // chaining\n },\n\n width: function(){\n var container = this._private.container;\n\n if( container ){\n return container.clientWidth;\n }\n\n return 1; // fallback if no container (not 0 b/c can be used for dividing etc)\n },\n\n height: function(){\n var container = this._private.container;\n\n if( container ){\n return container.clientHeight;\n }\n\n return 1; // fallback if no container (not 0 b/c can be used for dividing etc)\n },\n\n extent: function(){\n var pan = this._private.pan;\n var zoom = this._private.zoom;\n var rb = this.renderedExtent();\n\n var b = {\n x1: ( rb.x1 - pan.x )/zoom,\n x2: ( rb.x2 - pan.x )/zoom,\n y1: ( rb.y1 - pan.y )/zoom,\n y2: ( rb.y2 - pan.y )/zoom\n };\n\n b.w = b.x2 - b.x1;\n b.h = b.y2 - b.y1;\n\n return b;\n },\n\n renderedExtent: function(){\n var width = this.width();\n var height = this.height();\n\n return {\n x1: 0,\n y1: 0,\n x2: width,\n y2: height,\n w: width,\n h: height\n };\n }\n});\n\n// aliases\ncorefn.centre = corefn.center;\n\n// backwards compatibility\ncorefn.autolockNodes = corefn.autolock;\ncorefn.autoungrabifyNodes = corefn.autoungrabify;\n\nmodule.exports = corefn;\n","'use strict';\n\n// use this module to cherry pick functions into your prototype\n// (useful for functions shared between the core and collections, for example)\n\n// e.g.\n// var foo = define.foo({ /* params... */ })\n\nvar util = require('./util');\nvar is = require('./is');\nvar Selector = require('./selector');\nvar Promise = require('./promise');\nvar Event = require('./event');\nvar Animation = require('./animation');\n\nvar define = {\n\n // access data field\n data: function( params ){\n var defaults = {\n field: 'data',\n bindingEvent: 'data',\n allowBinding: false,\n allowSetting: false,\n allowGetting: false,\n settingEvent: 'data',\n settingTriggersEvent: false,\n triggerFnName: 'trigger',\n immutableKeys: {}, // key => true if immutable\n updateStyle: false,\n onSet: function( self ){},\n canSet: function( self ){ return true; }\n };\n params = util.extend({}, defaults, params);\n\n return function dataImpl( name, value ){\n var p = params;\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var single = selfIsArrayLike ? self[0] : self;\n\n // .data('foo', ...)\n if( is.string(name) ){ // set or get property\n\n // .data('foo')\n if( p.allowGetting && value === undefined ){ // get\n\n var ret;\n if( single ){\n ret = single._private[ p.field ][ name ];\n }\n return ret;\n\n // .data('foo', 'bar')\n } else if( p.allowSetting && value !== undefined ) { // set\n var valid = !p.immutableKeys[name];\n if( valid ){\n for( var i = 0, l = all.length; i < l; i++ ){\n if( p.canSet( all[i] ) ){\n all[i]._private[ p.field ][ name ] = value;\n }\n }\n\n // update mappers if asked\n if( p.updateStyle ){ self.updateStyle(); }\n\n // call onSet callback\n p.onSet( self );\n\n if( p.settingTriggersEvent ){\n self[ p.triggerFnName ]( p.settingEvent );\n }\n }\n }\n\n // .data({ 'foo': 'bar' })\n } else if( p.allowSetting && is.plainObject(name) ){ // extend\n var obj = name;\n var k, v;\n\n for( k in obj ){\n v = obj[ k ];\n\n var valid = !p.immutableKeys[k];\n if( valid ){\n for( var i = 0, l = all.length; i < l; i++ ){\n if( p.canSet( all[i] ) ){\n all[i]._private[ p.field ][ k ] = v;\n }\n }\n }\n }\n\n // update mappers if asked\n if( p.updateStyle ){ self.updateStyle(); }\n\n // call onSet callback\n p.onSet( self );\n\n if( p.settingTriggersEvent ){\n self[ p.triggerFnName ]( p.settingEvent );\n }\n\n // .data(function(){ ... })\n } else if( p.allowBinding && is.fn(name) ){ // bind to event\n var fn = name;\n self.bind( p.bindingEvent, fn );\n\n // .data()\n } else if( p.allowGetting && name === undefined ){ // get whole object\n var ret;\n if( single ){\n ret = single._private[ p.field ];\n }\n return ret;\n }\n\n return self; // maintain chainability\n }; // function\n }, // data\n\n // remove data field\n removeData: function( params ){\n var defaults = {\n field: 'data',\n event: 'data',\n triggerFnName: 'trigger',\n triggerEvent: false,\n immutableKeys: {} // key => true if immutable\n };\n params = util.extend({}, defaults, params);\n\n return function removeDataImpl( names ){\n var p = params;\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n\n // .removeData('foo bar')\n if( is.string(names) ){ // then get the list of keys, and delete them\n var keys = names.split(/\\s+/);\n var l = keys.length;\n\n for( var i = 0; i < l; i++ ){ // delete each non-empty key\n var key = keys[i];\n if( is.emptyString(key) ){ continue; }\n\n var valid = !p.immutableKeys[ key ]; // not valid if immutable\n if( valid ){\n for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){\n all[ i_a ]._private[ p.field ][ key ] = undefined;\n }\n }\n }\n\n if( p.triggerEvent ){\n self[ p.triggerFnName ]( p.event );\n }\n\n // .removeData()\n } else if( names === undefined ){ // then delete all keys\n\n for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){\n var _privateFields = all[ i_a ]._private[ p.field ];\n\n for( var key in _privateFields ){\n var validKeyToDelete = !p.immutableKeys[ key ];\n\n if( validKeyToDelete ){\n _privateFields[ key ] = undefined;\n }\n }\n }\n\n if( p.triggerEvent ){\n self[ p.triggerFnName ]( p.event );\n }\n }\n\n return self; // maintain chaining\n }; // function\n }, // removeData\n\n // event function reusable stuff\n event: {\n regex: /(\\w+)(\\.\\w+)?/, // regex for matching event strings (e.g. \"click.namespace\")\n optionalTypeRegex: /(\\w+)?(\\.\\w+)?/,\n falseCallback: function(){ return false; }\n },\n\n // event binding\n on: function( params ){\n var defaults = {\n unbindSelfOnTrigger: false,\n unbindAllBindersOnTrigger: false\n };\n params = util.extend({}, defaults, params);\n\n return function onImpl(events, selector, data, callback){\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var eventsIsString = is.string(events);\n var p = params;\n\n if( is.plainObject(selector) ){ // selector is actually data\n callback = data;\n data = selector;\n selector = undefined;\n } else if( is.fn(selector) || selector === false ){ // selector is actually callback\n callback = selector;\n data = undefined;\n selector = undefined;\n }\n\n if( is.fn(data) || data === false ){ // data is actually callback\n callback = data;\n data = undefined;\n }\n\n // if there isn't a callback, we can't really do anything\n // (can't speak for mapped events arg version)\n if( !(is.fn(callback) || callback === false) && eventsIsString ){\n return self; // maintain chaining\n }\n\n if( eventsIsString ){ // then convert to map\n var map = {};\n map[ events ] = callback;\n events = map;\n }\n\n for( var evts in events ){\n callback = events[evts];\n if( callback === false ){\n callback = define.event.falseCallback;\n }\n\n if( !is.fn(callback) ){ continue; }\n\n evts = evts.split(/\\s+/);\n for( var i = 0; i < evts.length; i++ ){\n var evt = evts[i];\n if( is.emptyString(evt) ){ continue; }\n\n var match = evt.match( define.event.regex ); // type[.namespace]\n\n if( match ){\n var type = match[1];\n var namespace = match[2] ? match[2] : undefined;\n\n var listener = {\n callback: callback, // callback to run\n data: data, // extra data in eventObj.data\n delegated: selector ? true : false, // whether the evt is delegated\n selector: selector, // the selector to match for delegated events\n selObj: new Selector(selector), // cached selector object to save rebuilding\n type: type, // the event type (e.g. 'click')\n namespace: namespace, // the event namespace (e.g. \".foo\")\n unbindSelfOnTrigger: p.unbindSelfOnTrigger,\n unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger,\n binders: all // who bound together\n };\n\n for( var j = 0; j < all.length; j++ ){\n var _p = all[j]._private;\n\n _p.listeners = _p.listeners || [];\n _p.listeners.push( listener );\n }\n }\n } // for events array\n } // for events map\n\n return self; // maintain chaining\n }; // function\n }, // on\n\n eventAliasesOn: function( proto ){\n var p = proto;\n\n p.addListener = p.listen = p.bind = p.on;\n p.removeListener = p.unlisten = p.unbind = p.off;\n p.emit = p.trigger;\n\n // this is just a wrapper alias of .on()\n p.pon = p.promiseOn = function( events, selector ){\n var self = this;\n var args = Array.prototype.slice.call( arguments, 0 );\n\n return new Promise(function( resolve, reject ){\n var callback = function( e ){\n self.off.apply( self, offArgs );\n\n resolve( e );\n };\n\n var onArgs = args.concat([ callback ]);\n var offArgs = onArgs.concat([]);\n\n self.on.apply( self, onArgs );\n });\n };\n },\n\n off: function offImpl( params ){\n var defaults = {\n };\n params = util.extend({}, defaults, params);\n\n return function(events, selector, callback){\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var eventsIsString = is.string(events);\n\n if( arguments.length === 0 ){ // then unbind all\n\n for( var i = 0; i < all.length; i++ ){\n all[i]._private.listeners = [];\n }\n\n return self; // maintain chaining\n }\n\n if( is.fn(selector) || selector === false ){ // selector is actually callback\n callback = selector;\n selector = undefined;\n }\n\n if( eventsIsString ){ // then convert to map\n var map = {};\n map[ events ] = callback;\n events = map;\n }\n\n for( var evts in events ){\n callback = events[evts];\n\n if( callback === false ){\n callback = define.event.falseCallback;\n }\n\n evts = evts.split(/\\s+/);\n for( var h = 0; h < evts.length; h++ ){\n var evt = evts[h];\n if( is.emptyString(evt) ){ continue; }\n\n var match = evt.match( define.event.optionalTypeRegex ); // [type][.namespace]\n if( match ){\n var type = match[1] ? match[1] : undefined;\n var namespace = match[2] ? match[2] : undefined;\n\n for( var i = 0; i < all.length; i++ ){ //\n var listeners = all[i]._private.listeners = all[i]._private.listeners || [];\n\n for( var j = 0; j < listeners.length; j++ ){\n var listener = listeners[j];\n var nsMatches = !namespace || namespace === listener.namespace;\n var typeMatches = !type || listener.type === type;\n var cbMatches = !callback || callback === listener.callback;\n var listenerMatches = nsMatches && typeMatches && cbMatches;\n\n // delete listener if it matches\n if( listenerMatches ){\n listeners.splice(j, 1);\n j--;\n }\n } // for listeners\n } // for all\n } // if match\n } // for events array\n\n } // for events map\n\n return self; // maintain chaining\n }; // function\n }, // off\n\n trigger: function( params ){\n var defaults = {};\n params = util.extend({}, defaults, params);\n\n return function triggerImpl(events, extraParams, fnToTrigger){\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var eventsIsString = is.string(events);\n var eventsIsObject = is.plainObject(events);\n var eventsIsEvent = is.event(events);\n var cy = this._private.cy || ( is.core(this) ? this : null );\n var hasCompounds = cy ? cy.hasCompoundNodes() : false;\n\n if( eventsIsString ){ // then make a plain event object for each event name\n var evts = events.split(/\\s+/);\n events = [];\n\n for( var i = 0; i < evts.length; i++ ){\n var evt = evts[i];\n if( is.emptyString(evt) ){ continue; }\n\n var match = evt.match( define.event.regex ); // type[.namespace]\n var type = match[1];\n var namespace = match[2] ? match[2] : undefined;\n\n events.push( {\n type: type,\n namespace: namespace\n } );\n }\n } else if( eventsIsObject ){ // put in length 1 array\n var eventArgObj = events;\n\n events = [ eventArgObj ];\n }\n\n if( extraParams ){\n if( !is.array(extraParams) ){ // make sure extra params are in an array if specified\n extraParams = [ extraParams ];\n }\n } else { // otherwise, we've got nothing\n extraParams = [];\n }\n\n for( var i = 0; i < events.length; i++ ){ // trigger each event in order\n var evtObj = events[i];\n\n for( var j = 0; j < all.length; j++ ){ // for each\n var triggerer = all[j];\n var listeners = triggerer._private.listeners = triggerer._private.listeners || [];\n var triggererIsElement = is.element(triggerer);\n var bubbleUp = triggererIsElement || params.layout;\n\n // create the event for this element from the event object\n var evt;\n\n if( eventsIsEvent ){ // then just get the object\n evt = evtObj;\n\n evt.cyTarget = evt.cyTarget || triggerer;\n evt.cy = evt.cy || cy;\n\n } else { // then we have to make one\n evt = new Event( evtObj, {\n cyTarget: triggerer,\n cy: cy,\n namespace: evtObj.namespace\n } );\n }\n\n // if a layout was specified, then put it in the typed event\n if( evtObj.layout ){\n evt.layout = evtObj.layout;\n }\n\n // if triggered by layout, put in event\n if( params.layout ){\n evt.layout = triggerer;\n }\n\n // create a rendered position based on the passed position\n if( evt.cyPosition ){\n var pos = evt.cyPosition;\n var zoom = cy.zoom();\n var pan = cy.pan();\n\n evt.cyRenderedPosition = {\n x: pos.x * zoom + pan.x,\n y: pos.y * zoom + pan.y\n };\n }\n\n if( fnToTrigger ){ // then override the listeners list with just the one we specified\n listeners = [{\n namespace: evt.namespace,\n type: evt.type,\n callback: fnToTrigger\n }];\n }\n\n for( var k = 0; k < listeners.length; k++ ){ // check each listener\n var lis = listeners[k];\n var nsMatches = !lis.namespace || lis.namespace === evt.namespace;\n var typeMatches = lis.type === evt.type;\n var targetMatches = lis.delegated ? ( triggerer !== evt.cyTarget && is.element(evt.cyTarget) && lis.selObj.matches(evt.cyTarget) ) : (true); // we're not going to validate the hierarchy; that's too expensive\n var listenerMatches = nsMatches && typeMatches && targetMatches;\n\n if( listenerMatches ){ // then trigger it\n var args = [ evt ];\n args = args.concat( extraParams ); // add extra params to args list\n\n if( lis.data ){ // add on data plugged into binding\n evt.data = lis.data;\n } else { // or clear it in case the event obj is reused\n evt.data = undefined;\n }\n\n if( lis.unbindSelfOnTrigger || lis.unbindAllBindersOnTrigger ){ // then remove listener\n listeners.splice(k, 1);\n k--;\n }\n\n if( lis.unbindAllBindersOnTrigger ){ // then delete the listener for all binders\n var binders = lis.binders;\n for( var l = 0; l < binders.length; l++ ){\n var binder = binders[l];\n if( !binder || binder === triggerer ){ continue; } // already handled triggerer or we can't handle it\n\n var binderListeners = binder._private.listeners;\n for( var m = 0; m < binderListeners.length; m++ ){\n var binderListener = binderListeners[m];\n\n if( binderListener === lis ){ // delete listener from list\n binderListeners.splice(m, 1);\n m--;\n }\n }\n }\n }\n\n // run the callback\n var context = lis.delegated ? evt.cyTarget : triggerer;\n var ret = lis.callback.apply( context, args );\n\n if( ret === false || evt.isPropagationStopped() ){\n // then don't bubble\n bubbleUp = false;\n\n if( ret === false ){\n // returning false is a shorthand for stopping propagation and preventing the def. action\n evt.stopPropagation();\n evt.preventDefault();\n }\n }\n } // if listener matches\n } // for each listener\n\n // bubble up event for elements\n if( bubbleUp ){\n var parent = hasCompounds ? triggerer._private.parent : null;\n var hasParent = parent != null && parent.length !== 0;\n\n if( hasParent ){ // then bubble up to parent\n parent = parent[0];\n parent.trigger(evt);\n } else { // otherwise, bubble up to the core\n cy.trigger(evt);\n }\n }\n\n } // for each of all\n } // for each event\n\n return self; // maintain chaining\n }; // function\n }, // trigger\n\n animated: function( fnParams ){\n var defaults = {};\n fnParams = util.extend({}, defaults, fnParams);\n\n return function animatedImpl(){\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var cy = this._private.cy || this;\n\n if( !cy.styleEnabled() ){ return false; }\n\n var ele = all[0];\n\n if( ele ){\n return ele._private.animation.current.length > 0;\n }\n };\n }, // animated\n\n clearQueue: function( fnParams ){\n var defaults = {};\n fnParams = util.extend({}, defaults, fnParams);\n\n return function clearQueueImpl(){\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var cy = this._private.cy || this;\n\n if( !cy.styleEnabled() ){ return this; }\n\n for( var i = 0; i < all.length; i++ ){\n var ele = all[i];\n ele._private.animation.queue = [];\n }\n\n return this;\n };\n }, // clearQueue\n\n delay: function( fnParams ){\n var defaults = {};\n fnParams = util.extend({}, defaults, fnParams);\n\n return function delayImpl( time, complete ){\n var cy = this._private.cy || this;\n\n if( !cy.styleEnabled() ){ return this; }\n\n return this.animate({\n delay: time,\n duration: time,\n complete: complete\n });\n };\n }, // delay\n\n delayAnimation: function( fnParams ){\n var defaults = {};\n fnParams = util.extend({}, defaults, fnParams);\n\n return function delayAnimationImpl( time, complete ){\n var cy = this._private.cy || this;\n\n if( !cy.styleEnabled() ){ return this; }\n\n return this.animation({\n delay: time,\n duration: time,\n complete: complete\n });\n };\n }, // delay\n\n animation: function( fnParams ){\n var defaults = {};\n fnParams = util.extend({}, defaults, fnParams);\n\n return function animationImpl( properties, params ){\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var cy = this._private.cy || this;\n var isCore = !selfIsArrayLike;\n var isEles = !isCore;\n\n if( !cy.styleEnabled() ){ return this; }\n\n var style = cy.style();\n\n properties = util.extend( {}, properties, params );\n\n if( properties.duration === undefined ){\n properties.duration = 400;\n }\n\n switch( properties.duration ){\n case 'slow':\n properties.duration = 600;\n break;\n case 'fast':\n properties.duration = 200;\n break;\n }\n\n var propertiesEmpty = true;\n if( properties ){ for( var i in properties ){ // jshint ignore:line\n propertiesEmpty = false;\n break;\n } }\n\n if( propertiesEmpty ){\n return new Animation( all[0], properties ); // nothing to animate\n }\n\n if( isEles ){\n properties.style = style.getPropsList( properties.style || properties.css );\n\n properties.css = undefined;\n }\n\n if( properties.renderedPosition && isEles ){\n var rpos = properties.renderedPosition;\n var pan = cy.pan();\n var zoom = cy.zoom();\n\n properties.position = {\n x: ( rpos.x - pan.x ) /zoom,\n y: ( rpos.y - pan.y ) /zoom\n };\n }\n\n // override pan w/ panBy if set\n if( properties.panBy && isCore ){\n var panBy = properties.panBy;\n var cyPan = cy.pan();\n\n properties.pan = {\n x: cyPan.x + panBy.x,\n y: cyPan.y + panBy.y\n };\n }\n\n // override pan w/ center if set\n var center = properties.center || properties.centre;\n if( center && isCore ){\n var centerPan = cy.getCenterPan( center.eles, properties.zoom );\n\n if( centerPan ){\n properties.pan = centerPan;\n }\n }\n\n // override pan & zoom w/ fit if set\n if( properties.fit && isCore ){\n var fit = properties.fit;\n var fitVp = cy.getFitViewport( fit.eles || fit.boundingBox, fit.padding );\n\n if( fitVp ){\n properties.pan = fitVp.pan;\n properties.zoom = fitVp.zoom;\n }\n }\n\n return new Animation( all[0], properties );\n };\n }, // animate\n\n animate: function( fnParams ){\n var defaults = {};\n fnParams = util.extend({}, defaults, fnParams);\n\n return function animateImpl( properties, params ){\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var cy = this._private.cy || this;\n\n if( !cy.styleEnabled() ){ return this; }\n\n if( params ){\n properties = util.extend( {}, properties, params );\n }\n\n // manually hook and run the animation\n for( var i = 0; i < all.length; i++ ){\n var ele = all[i];\n var queue = ele.animated() && (properties.queue === undefined || properties.queue);\n\n var ani = ele.animation( properties, (queue ? { queue: true } : undefined) );\n\n ani.play();\n }\n\n return this; // chaining\n };\n }, // animate\n\n stop: function( fnParams ){\n var defaults = {};\n fnParams = util.extend({}, defaults, fnParams);\n\n return function stopImpl( clearQueue, jumpToEnd ){\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var cy = this._private.cy || this;\n\n if( !cy.styleEnabled() ){ return this; }\n\n for( var i = 0; i < all.length; i++ ){\n var ele = all[i];\n var _p = ele._private;\n var anis = _p.animation.current;\n\n for( var j = 0; j < anis.length; j++ ){\n var ani = anis[j];\n var ani_p = ani._private;\n\n if( jumpToEnd ){\n // next iteration of the animation loop, the animation\n // will go straight to the end and be removed\n ani_p.duration = 0;\n }\n }\n\n // clear the queue of future animations\n if( clearQueue ){\n _p.animation.queue = [];\n }\n\n if( !jumpToEnd ){\n _p.animation.current = [];\n }\n }\n\n // we have to notify (the animation loop doesn't do it for us on `stop`)\n cy.notify({\n collection: this,\n type: 'draw'\n });\n\n return this;\n };\n } // stop\n\n}; // define\n\nmodule.exports = define;\n","'use strict';\n\n// ref\n// https://github.com/jquery/jquery/blob/master/src/event.js\n\nvar Event = function( src, props ) {\n // Allow instantiation without the 'new' keyword\n if ( !(this instanceof Event) ) {\n return new Event( src, props );\n }\n\n // Event object\n if ( src && src.type ) {\n this.originalEvent = src;\n this.type = src.type;\n\n // Events bubbling up the document may have been marked as prevented\n // by a handler lower down the tree; reflect the correct value.\n this.isDefaultPrevented = ( src.defaultPrevented ) ? returnTrue : returnFalse;\n\n // Event type\n } else {\n this.type = src;\n }\n\n // Put explicitly provided properties onto the event object\n if ( props ) {\n // util.extend( this, props );\n\n // more efficient to manually copy fields we use\n this.type = props.type !== undefined ? props.type : this.type;\n this.cy = props.cy;\n this.cyTarget = props.cyTarget;\n this.cyPosition = props.cyPosition;\n this.cyRenderedPosition = props.cyRenderedPosition;\n this.namespace = props.namespace;\n this.layout = props.layout;\n this.data = props.data;\n this.message = props.message;\n }\n\n // Create a timestamp if incoming event doesn't have one\n this.timeStamp = src && src.timeStamp || Date.now();\n};\n\nfunction returnFalse() {\n return false;\n}\n\nfunction returnTrue() {\n return true;\n}\n\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\nEvent.prototype = {\n instanceString: function(){\n return 'event';\n },\n\n preventDefault: function() {\n this.isDefaultPrevented = returnTrue;\n\n var e = this.originalEvent;\n if ( !e ) {\n return;\n }\n\n // if preventDefault exists run it on the original event\n if ( e.preventDefault ) {\n e.preventDefault();\n }\n },\n\n stopPropagation: function() {\n this.isPropagationStopped = returnTrue;\n\n var e = this.originalEvent;\n if ( !e ) {\n return;\n }\n\n // if stopPropagation exists run it on the original event\n if ( e.stopPropagation ) {\n e.stopPropagation();\n }\n },\n\n stopImmediatePropagation: function() {\n this.isImmediatePropagationStopped = returnTrue;\n this.stopPropagation();\n },\n\n isDefaultPrevented: returnFalse,\n isPropagationStopped: returnFalse,\n isImmediatePropagationStopped: returnFalse\n};\n\nmodule.exports = Event;\n","'use strict';\n\nvar util = require('./util');\nvar define = require('./define');\nvar Collection = require('./collection');\nvar Core = require('./core');\nvar incExts = require('./extensions');\nvar is = require('./is');\n\n// registered extensions to cytoscape, indexed by name\nvar extensions = {};\n\n// registered modules for extensions, indexed by name\nvar modules = {};\n\nfunction setExtension( type, name, registrant ){\n\n var ext = registrant;\n\n if( type === 'core' ){\n Core.prototype[ name ] = registrant;\n\n } else if( type === 'collection' ){\n Collection.prototype[ name ] = registrant;\n\n } else if( type === 'layout' ){\n // fill in missing layout functions in the prototype\n\n var Layout = function( options ){\n this.options = options;\n\n registrant.call( this, options );\n\n // make sure layout has _private for use w/ std apis like .on()\n if( !is.plainObject(this._private) ){\n this._private = {};\n }\n\n this._private.cy = options.cy;\n this._private.listeners = [];\n };\n\n var layoutProto = Layout.prototype = Object.create( registrant.prototype );\n\n var optLayoutFns = [];\n\n for( var i = 0; i < optLayoutFns.length; i++ ){\n var fnName = optLayoutFns[i];\n\n layoutProto[fnName] = layoutProto[fnName] || function(){ return this; };\n }\n\n // either .start() or .run() is defined, so autogen the other\n if( layoutProto.start && !layoutProto.run ){\n layoutProto.run = function(){ this.start(); return this; };\n } else if( !layoutProto.start && layoutProto.run ){\n layoutProto.start = function(){ this.run(); return this; };\n }\n\n if( !layoutProto.stop ){\n layoutProto.stop = function(){\n var opts = this.options;\n\n if( opts && opts.animate ){\n var anis = this.animations;\n for( var i = 0; i < anis.length; i++ ){\n anis[i].stop();\n }\n }\n\n this.trigger('layoutstop');\n\n return this;\n };\n }\n\n if( !layoutProto.destroy ){\n layoutProto.destroy = function(){\n return this;\n };\n }\n\n layoutProto.on = define.on({ layout: true });\n layoutProto.one = define.on({ layout: true, unbindSelfOnTrigger: true });\n layoutProto.once = define.on({ layout: true, unbindAllBindersOnTrigger: true });\n layoutProto.off = define.off({ layout: true });\n layoutProto.trigger = define.trigger({ layout: true });\n\n define.eventAliasesOn( layoutProto );\n\n ext = Layout; // replace with our wrapped layout\n\n } else if( type === 'renderer' && name !== 'null' && name !== 'base' ){\n // user registered renderers inherit from base\n\n var bProto = getExtension( 'renderer', 'base' ).prototype;\n var rProto = registrant.prototype;\n\n for( var pName in bProto ){\n var pVal = bProto[ pName ];\n var existsInR = rProto[ pName ] != null;\n\n if( existsInR ){\n util.error('Can not register renderer `' + name + '` since it overrides `' + pName + '` in its prototype');\n return;\n }\n\n rProto[ pName ] = pVal; // take impl from base\n }\n\n bProto.clientFunctions.forEach(function( name ){\n rProto[ name ] = rProto[ name ] || function(){\n util.error('Renderer does not implement `renderer.' + name + '()` on its prototype');\n };\n });\n\n }\n\n return util.setMap({\n map: extensions,\n keys: [ type, name ],\n value: ext\n });\n}\n\nfunction getExtension(type, name){\n return util.getMap({\n map: extensions,\n keys: [ type, name ]\n });\n}\n\nfunction setModule(type, name, moduleType, moduleName, registrant){\n return util.setMap({\n map: modules,\n keys: [ type, name, moduleType, moduleName ],\n value: registrant\n });\n}\n\nfunction getModule(type, name, moduleType, moduleName){\n return util.getMap({\n map: modules,\n keys: [ type, name, moduleType, moduleName ]\n });\n}\n\nvar extension = function(){\n // e.g. extension('renderer', 'svg')\n if( arguments.length === 2 ){\n return getExtension.apply(null, arguments);\n }\n\n // e.g. extension('renderer', 'svg', { ... })\n else if( arguments.length === 3 ){\n return setExtension.apply(null, arguments);\n }\n\n // e.g. extension('renderer', 'svg', 'nodeShape', 'ellipse')\n else if( arguments.length === 4 ){\n return getModule.apply(null, arguments);\n }\n\n // e.g. extension('renderer', 'svg', 'nodeShape', 'ellipse', { ... })\n else if( arguments.length === 5 ){\n return setModule.apply(null, arguments);\n }\n\n else {\n util.error('Invalid extension access syntax');\n }\n\n};\n\n// allows a core instance to access extensions internally\nCore.prototype.extension = extension;\n\n// included extensions\nincExts.forEach(function( group ){\n group.extensions.forEach(function( ext ){\n setExtension( group.type, ext.name, ext.impl );\n });\n});\n\nmodule.exports = extension;\n","'use strict';\n\nmodule.exports = [\n {\n type: 'layout',\n extensions: require('./layout')\n },\n\n {\n type: 'renderer',\n extensions: require('./renderer')\n }\n];\n","'use strict';\n\nvar util = require('../../util');\nvar math = require('../../math');\nvar is = require('../../is');\n\nvar defaults = {\n fit: true, // whether to fit the viewport to the graph\n directed: false, // whether the tree is directed downwards (or edges can point in any direction if false)\n padding: 30, // padding on fit\n circle: false, // put depths in concentric circles if true, put depths top down if false\n spacingFactor: 1.75, // positive spacing factor, larger => more space between nodes (N.B. n/a if causes overlap)\n boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n avoidOverlap: true, // prevents node overlap, may overflow boundingBox if not enough space\n roots: undefined, // the roots of the trees\n maximalAdjustments: 0, // how many times to try to position the nodes in a maximal way (i.e. no backtracking)\n animate: false, // whether to transition the node positions\n animationDuration: 500, // duration of animation in ms if enabled\n animationEasing: undefined, // easing of animation if enabled\n ready: undefined, // callback on layoutready\n stop: undefined // callback on layoutstop\n};\n\nfunction BreadthFirstLayout( options ){\n this.options = util.extend({}, defaults, options);\n}\n\nBreadthFirstLayout.prototype.run = function(){\n var params = this.options;\n var options = params;\n\n var cy = params.cy;\n var eles = options.eles;\n var nodes = eles.nodes().not(':parent');\n var graph = eles;\n\n var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : {\n x1: 0, y1: 0, w: cy.width(), h: cy.height()\n } );\n\n var roots;\n if( is.elementOrCollection(options.roots) ){\n roots = options.roots;\n } else if( is.array(options.roots) ){\n var rootsArray = [];\n\n for( var i = 0; i < options.roots.length; i++ ){\n var id = options.roots[i];\n var ele = cy.getElementById( id );\n rootsArray.push( ele );\n }\n\n roots = cy.collection( rootsArray );\n } else if( is.string(options.roots) ){\n roots = cy.$( options.roots );\n\n } else {\n if( options.directed ){\n roots = nodes.roots();\n } else {\n var components = [];\n var unhandledNodes = nodes;\n\n while( unhandledNodes.length > 0 ){\n var currComp = cy.collection();\n\n eles.bfs({\n roots: unhandledNodes[0],\n visit: function(i, depth, node, edge, pNode){\n currComp = currComp.add( node );\n },\n directed: false\n });\n\n unhandledNodes = unhandledNodes.not( currComp );\n components.push( currComp );\n }\n\n roots = cy.collection();\n for( var i = 0; i < components.length; i++ ){\n var comp = components[i];\n var maxDegree = comp.maxDegree( false );\n var compRoots = comp.filter(function(){\n return this.degree(false) === maxDegree;\n });\n\n roots = roots.add( compRoots );\n }\n\n }\n }\n\n\n var depths = [];\n var foundByBfs = {};\n var id2depth = {};\n var prevNode = {};\n var prevEdge = {};\n var successors = {};\n\n // find the depths of the nodes\n graph.bfs({\n roots: roots,\n directed: options.directed,\n visit: function(i, depth, node, edge, pNode){\n var ele = this[0];\n var id = ele.id();\n\n if( !depths[depth] ){\n depths[depth] = [];\n }\n\n depths[depth].push( ele );\n foundByBfs[ id ] = true;\n id2depth[ id ] = depth;\n prevNode[ id ] = pNode;\n prevEdge[ id ] = edge;\n\n if( pNode ){\n var prevId = pNode.id();\n var succ = successors[ prevId ] = successors[ prevId ] || [];\n\n succ.push( node );\n }\n }\n });\n\n // check for nodes not found by bfs\n var orphanNodes = [];\n for( var i = 0; i < nodes.length; i++ ){\n var ele = nodes[i];\n\n if( foundByBfs[ ele.id() ] ){\n continue;\n } else {\n orphanNodes.push( ele );\n }\n }\n\n // assign orphan nodes a depth from their neighborhood\n var maxChecks = orphanNodes.length * 3;\n var checks = 0;\n while( orphanNodes.length !== 0 && checks < maxChecks ){\n var node = orphanNodes.shift();\n var neighbors = node.neighborhood().nodes();\n var assignedDepth = false;\n\n for( var i = 0; i < neighbors.length; i++ ){\n var depth = id2depth[ neighbors[i].id() ];\n\n if( depth !== undefined ){\n depths[depth].push( node );\n assignedDepth = true;\n break;\n }\n }\n\n if( !assignedDepth ){\n orphanNodes.push( node );\n }\n\n checks++;\n }\n\n // assign orphan nodes that are still left to the depth of their subgraph\n while( orphanNodes.length !== 0 ){\n var node = orphanNodes.shift();\n //var subgraph = graph.bfs( node ).path;\n var assignedDepth = false;\n\n // for( var i = 0; i < subgraph.length; i++ ){\n // var depth = id2depth[ subgraph[i].id() ];\n\n // if( depth !== undefined ){\n // depths[depth].push( node );\n // assignedDepth = true;\n // break;\n // }\n // }\n\n if( !assignedDepth ){ // worst case if the graph really isn't tree friendly, then just dump it in 0\n if( depths.length === 0 ){\n depths.push([]);\n }\n\n depths[0].push( node );\n }\n }\n\n // assign the nodes a depth and index\n var assignDepthsToEles = function(){\n for( var i = 0; i < depths.length; i++ ){\n var eles = depths[i];\n\n for( var j = 0; j < eles.length; j++ ){\n var ele = eles[j];\n\n ele._private.scratch.breadthfirst = {\n depth: i,\n index: j\n };\n }\n }\n };\n assignDepthsToEles();\n\n\n var intersectsDepth = function( node ){ // returns true if has edges pointing in from a higher depth\n var edges = node.connectedEdges(function(){\n return this.data('target') === node.id();\n });\n var thisInfo = node._private.scratch.breadthfirst;\n var highestDepthOfOther = 0;\n var highestOther;\n for( var i = 0; i < edges.length; i++ ){\n var edge = edges[i];\n var otherNode = edge.source()[0];\n var otherInfo = otherNode._private.scratch.breadthfirst;\n\n if( thisInfo.depth <= otherInfo.depth && highestDepthOfOther < otherInfo.depth ){\n highestDepthOfOther = otherInfo.depth;\n highestOther = otherNode;\n }\n }\n\n return highestOther;\n };\n\n // make maximal if so set by adjusting depths\n for( var adj = 0; adj < options.maximalAdjustments; adj++ ){\n\n var nDepths = depths.length;\n var elesToMove = [];\n for( var i = 0; i < nDepths; i++ ){\n var depth = depths[i];\n\n var nDepth = depth.length;\n for( var j = 0; j < nDepth; j++ ){\n var ele = depth[j];\n var info = ele._private.scratch.breadthfirst;\n var intEle = intersectsDepth(ele);\n\n if( intEle ){\n info.intEle = intEle;\n elesToMove.push( ele );\n }\n }\n }\n\n for( var i = 0; i < elesToMove.length; i++ ){\n var ele = elesToMove[i];\n var info = ele._private.scratch.breadthfirst;\n var intEle = info.intEle;\n var intInfo = intEle._private.scratch.breadthfirst;\n\n depths[ info.depth ].splice( info.index, 1 ); // remove from old depth & index\n\n // add to end of new depth\n var newDepth = intInfo.depth + 1;\n while( newDepth > depths.length - 1 ){\n depths.push([]);\n }\n depths[ newDepth ].push( ele );\n\n info.depth = newDepth;\n info.index = depths[newDepth].length - 1;\n }\n\n assignDepthsToEles();\n }\n\n // find min distance we need to leave between nodes\n var minDistance = 0;\n if( options.avoidOverlap ){\n for( var i = 0; i < nodes.length; i++ ){\n var n = nodes[i];\n var nbb = n.boundingBox();\n var w = nbb.w;\n var h = nbb.h;\n\n minDistance = Math.max(minDistance, w, h);\n }\n minDistance *= options.spacingFactor; // just to have some nice spacing\n }\n\n // get the weighted percent for an element based on its connectivity to other levels\n var cachedWeightedPercent = {};\n var getWeightedPercent = function( ele ){\n if( cachedWeightedPercent[ ele.id() ] ){\n return cachedWeightedPercent[ ele.id() ];\n }\n\n var eleDepth = ele._private.scratch.breadthfirst.depth;\n var neighbors = ele.neighborhood().nodes().not(':parent');\n var percent = 0;\n var samples = 0;\n\n for( var i = 0; i < neighbors.length; i++ ){\n var neighbor = neighbors[i];\n var bf = neighbor._private.scratch.breadthfirst;\n var index = bf.index;\n var depth = bf.depth;\n var nDepth = depths[depth].length;\n\n if( eleDepth > depth || eleDepth === 0 ){ // only get influenced by elements above\n percent += index / nDepth;\n samples++;\n }\n }\n\n samples = Math.max(1, samples);\n percent = percent / samples;\n\n if( samples === 0 ){ // so lone nodes have a \"don't care\" state in sorting\n percent = undefined;\n }\n\n cachedWeightedPercent[ ele.id() ] = percent;\n return percent;\n };\n\n\n // rearrange the indices in each depth level based on connectivity\n\n var sortFn = function(a, b){\n var apct = getWeightedPercent( a );\n var bpct = getWeightedPercent( b );\n\n return apct - bpct;\n };\n\n for( var times = 0; times < 3; times++ ){ // do it a few times b/c the depths are dynamic and we want a more stable result\n\n for( var i = 0; i < depths.length; i++ ){\n depths[i] = depths[i].sort( sortFn );\n }\n assignDepthsToEles(); // and update\n\n }\n\n var biggestDepthSize = 0;\n for( var i = 0; i < depths.length; i++ ){\n biggestDepthSize = Math.max( depths[i].length, biggestDepthSize );\n }\n\n var center = {\n x: bb.x1 + bb.w/2,\n y: bb.x1 + bb.h/2\n };\n\n var getPosition = function( ele, isBottomDepth ){\n var info = ele._private.scratch.breadthfirst;\n var depth = info.depth;\n var index = info.index;\n var depthSize = depths[depth].length;\n\n var distanceX = Math.max( bb.w / (depthSize + 1), minDistance );\n var distanceY = Math.max( bb.h / (depths.length + 1), minDistance );\n var radiusStepSize = Math.min( bb.w / 2 / depths.length, bb.h / 2 / depths.length );\n radiusStepSize = Math.max( radiusStepSize, minDistance );\n\n if( !options.circle ){\n\n var epos = {\n x: center.x + (index + 1 - (depthSize + 1)/2) * distanceX,\n y: (depth + 1) * distanceY\n };\n\n if( isBottomDepth ){\n return epos;\n }\n\n // var succs = successors[ ele.id() ];\n // if( succs ){\n // epos.x = 0;\n //\n // for( var i = 0 ; i < succs.length; i++ ){\n // var spos = pos[ succs[i].id() ];\n //\n // epos.x += spos.x;\n // }\n //\n // epos.x /= succs.length;\n // } else {\n // //debugger;\n // }\n\n return epos;\n\n } else {\n if( options.circle ){\n var radius = radiusStepSize * depth + radiusStepSize - (depths.length > 0 && depths[0].length <= 3 ? radiusStepSize/2 : 0);\n var theta = 2 * Math.PI / depths[depth].length * index;\n\n if( depth === 0 && depths[0].length === 1 ){\n radius = 1;\n }\n\n return {\n x: center.x + radius * Math.cos(theta),\n y: center.y + radius * Math.sin(theta)\n };\n\n } else {\n return {\n x: center.x + (index + 1 - (depthSize + 1)/2) * distanceX,\n y: (depth + 1) * distanceY\n };\n }\n }\n\n };\n\n // get positions in reverse depth order\n var pos = {};\n for( var i = depths.length - 1; i >=0; i-- ){\n var depth = depths[i];\n\n for( var j = 0; j < depth.length; j++ ){\n var node = depth[j];\n\n pos[ node.id() ] = getPosition( node, i === depths.length - 1 );\n }\n }\n\n nodes.layoutPositions(this, options, function(){\n return pos[ this.id() ];\n });\n\n return this; // chaining\n};\n\nmodule.exports = BreadthFirstLayout;\n","'use strict';\n\nvar util = require('../../util');\nvar math = require('../../math');\nvar is = require('../../is');\n\nvar defaults = {\n fit: true, // whether to fit the viewport to the graph\n padding: 30, // the padding on fit\n boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n avoidOverlap: true, // prevents node overlap, may overflow boundingBox and radius if not enough space\n radius: undefined, // the radius of the circle\n startAngle: 3/2 * Math.PI, // where nodes start in radians\n sweep: undefined, // how many radians should be between the first and last node (defaults to full circle)\n clockwise: true, // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false)\n sort: undefined, // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') }\n animate: false, // whether to transition the node positions\n animationDuration: 500, // duration of animation in ms if enabled\n animationEasing: undefined, // easing of animation if enabled\n ready: undefined, // callback on layoutready\n stop: undefined // callback on layoutstop\n};\n\nfunction CircleLayout( options ){\n this.options = util.extend({}, defaults, options);\n}\n\nCircleLayout.prototype.run = function(){\n var params = this.options;\n var options = params;\n\n var cy = params.cy;\n var eles = options.eles;\n\n var clockwise = options.counterclockwise !== undefined ? !options.counterclockwise : options.clockwise;\n\n var nodes = eles.nodes().not(':parent');\n\n if( options.sort ){\n nodes = nodes.sort( options.sort );\n }\n\n var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : {\n x1: 0, y1: 0, w: cy.width(), h: cy.height()\n } );\n\n var center = {\n x: bb.x1 + bb.w/2,\n y: bb.y1 + bb.h/2\n };\n\n var sweep = options.sweep === undefined ? 2*Math.PI - 2*Math.PI/nodes.length : options.sweep;\n\n var dTheta = sweep / ( Math.max(1, nodes.length - 1) );\n var r;\n\n var minDistance = 0;\n for( var i = 0; i < nodes.length; i++ ){\n var n = nodes[i];\n var nbb = n.boundingBox();\n var w = nbb.w;\n var h = nbb.h;\n\n minDistance = Math.max(minDistance, w, h);\n }\n\n if( is.number(options.radius) ){\n r = options.radius;\n } else if( nodes.length <= 1 ){\n r = 0;\n } else {\n r = Math.min( bb.h, bb.w )/2 - minDistance;\n }\n\n // calculate the radius\n if( nodes.length > 1 && options.avoidOverlap ){ // but only if more than one node (can't overlap)\n minDistance *= 1.75; // just to have some nice spacing\n\n var dcos = Math.cos(dTheta) - Math.cos(0);\n var dsin = Math.sin(dTheta) - Math.sin(0);\n var rMin = Math.sqrt( minDistance * minDistance / ( dcos*dcos + dsin*dsin ) ); // s.t. no nodes overlapping\n r = Math.max( rMin, r );\n }\n\n var getPos = function( i, ele ){\n var theta = options.startAngle + i * dTheta * ( clockwise ? 1 : -1 );\n\n var rx = r * Math.cos( theta );\n var ry = r * Math.sin( theta );\n var pos = {\n x: center.x + rx,\n y: center.y + ry\n };\n\n return pos;\n };\n\n nodes.layoutPositions( this, options, getPos );\n\n return this; // chaining\n};\n\nmodule.exports = CircleLayout;\n","'use strict';\n\nvar util = require('../../util');\nvar math = require('../../math');\n\nvar defaults = {\n fit: true, // whether to fit the viewport to the graph\n padding: 30, // the padding on fit\n startAngle: 3/2 * Math.PI, // where nodes start in radians\n sweep: undefined, // how many radians should be between the first and last node (defaults to full circle)\n clockwise: true, // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false)\n equidistant: false, // whether levels have an equal radial distance betwen them, may cause bounding box overflow\n minNodeSpacing: 10, // min spacing between outside of nodes (used for radius adjustment)\n boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n avoidOverlap: true, // prevents node overlap, may overflow boundingBox if not enough space\n height: undefined, // height of layout area (overrides container height)\n width: undefined, // width of layout area (overrides container width)\n concentric: function(node){ // returns numeric value for each node, placing higher nodes in levels towards the centre\n return node.degree();\n },\n levelWidth: function(nodes){ // the variation of concentric values in each level\n return nodes.maxDegree() / 4;\n },\n animate: false, // whether to transition the node positions\n animationDuration: 500, // duration of animation in ms if enabled\n animationEasing: undefined, // easing of animation if enabled\n ready: undefined, // callback on layoutready\n stop: undefined // callback on layoutstop\n};\n\nfunction ConcentricLayout( options ){\n this.options = util.extend({}, defaults, options);\n}\n\nConcentricLayout.prototype.run = function(){\n var params = this.options;\n var options = params;\n\n var clockwise = options.counterclockwise !== undefined ? !options.counterclockwise : options.clockwise;\n\n var cy = params.cy;\n\n var eles = options.eles;\n var nodes = eles.nodes().not(':parent');\n\n var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : {\n x1: 0, y1: 0, w: cy.width(), h: cy.height()\n } );\n\n var center = {\n x: bb.x1 + bb.w/2,\n y: bb.y1 + bb.h/2\n };\n\n var nodeValues = []; // { node, value }\n var theta = options.startAngle;\n var maxNodeSize = 0;\n\n for( var i = 0; i < nodes.length; i++ ){\n var node = nodes[i];\n var value;\n\n // calculate the node value\n value = options.concentric.apply(node, [ node ]);\n nodeValues.push({\n value: value,\n node: node\n });\n\n // for style mapping\n node._private.scratch.concentric = value;\n }\n\n // in case we used the `concentric` in style\n nodes.updateStyle();\n\n // calculate max size now based on potentially updated mappers\n for( var i = 0; i < nodes.length; i++ ){\n var node = nodes[i];\n var nbb = node.boundingBox();\n\n maxNodeSize = Math.max( maxNodeSize, nbb.w, nbb.h );\n }\n\n // sort node values in descreasing order\n nodeValues.sort(function(a, b){\n return b.value - a.value;\n });\n\n var levelWidth = options.levelWidth( nodes );\n\n // put the values into levels\n var levels = [ [] ];\n var currentLevel = levels[0];\n for( var i = 0; i < nodeValues.length; i++ ){\n var val = nodeValues[i];\n\n if( currentLevel.length > 0 ){\n var diff = Math.abs( currentLevel[0].value - val.value );\n\n if( diff >= levelWidth ){\n currentLevel = [];\n levels.push( currentLevel );\n }\n }\n\n currentLevel.push( val );\n }\n\n // create positions from levels\n\n var minDist = maxNodeSize + options.minNodeSpacing; // min dist between nodes\n\n if( !options.avoidOverlap ){ // then strictly constrain to bb\n var firstLvlHasMulti = levels.length > 0 && levels[0].length > 1;\n var maxR = ( Math.min(bb.w, bb.h) / 2 - minDist );\n var rStep = maxR / ( levels.length + firstLvlHasMulti ? 1 : 0 );\n\n minDist = Math.min( minDist, rStep );\n }\n\n // find the metrics for each level\n var r = 0;\n for( var i = 0; i < levels.length; i++ ){\n var level = levels[i];\n var sweep = options.sweep === undefined ? 2*Math.PI - 2*Math.PI/level.length : options.sweep;\n var dTheta = level.dTheta = sweep / ( Math.max(1, level.length - 1) );\n\n // calculate the radius\n if( level.length > 1 && options.avoidOverlap ){ // but only if more than one node (can't overlap)\n var dcos = Math.cos(dTheta) - Math.cos(0);\n var dsin = Math.sin(dTheta) - Math.sin(0);\n var rMin = Math.sqrt( minDist * minDist / ( dcos*dcos + dsin*dsin ) ); // s.t. no nodes overlapping\n\n r = Math.max( rMin, r );\n }\n\n level.r = r;\n\n r += minDist;\n }\n\n if( options.equidistant ){\n var rDeltaMax = 0;\n var r = 0;\n\n for( var i = 0; i < levels.length; i++ ){\n var level = levels[i];\n var rDelta = level.r - r;\n\n rDeltaMax = Math.max( rDeltaMax, rDelta );\n }\n\n r = 0;\n for( var i = 0; i < levels.length; i++ ){\n var level = levels[i];\n\n if( i === 0 ){\n r = level.r;\n }\n\n level.r = r;\n\n r += rDeltaMax;\n }\n }\n\n // calculate the node positions\n var pos = {}; // id => position\n for( var i = 0; i < levels.length; i++ ){\n var level = levels[i];\n var dTheta = level.dTheta;\n var r = level.r;\n\n for( var j = 0; j < level.length; j++ ){\n var val = level[j];\n var theta = options.startAngle + (clockwise ? 1 : -1) * dTheta * j;\n\n var p = {\n x: center.x + r * Math.cos(theta),\n y: center.y + r * Math.sin(theta)\n };\n\n pos[ val.node.id() ] = p;\n }\n }\n\n // position the nodes\n nodes.layoutPositions(this, options, function(){\n var id = this.id();\n\n return pos[id];\n });\n\n return this; // chaining\n};\n\nmodule.exports = ConcentricLayout;\n","'use strict';\n\n/*\nThe CoSE layout was written by Gerardo Huck.\nhttps://www.linkedin.com/in/gerardohuck/\n\nBased on the following article:\nhttp://dl.acm.org/citation.cfm?id=1498047\n\nModifications tracked on Github.\n*/\n\nvar util = require('../../util');\nvar math = require('../../math');\nvar Thread = require('../../thread');\nvar is = require('../../is');\n\nvar DEBUG;\n\n/**\n * @brief : default layout options\n */\nvar defaults = {\n // Called on `layoutready`\n ready : function() {},\n\n // Called on `layoutstop`\n stop : function() {},\n\n // Whether to animate while running the layout\n animate : true,\n\n // The layout animates only after this many milliseconds\n // (prevents flashing on fast runs)\n animationThreshold : 250,\n\n // Number of iterations between consecutive screen positions update\n // (0 -> only updated on the end)\n refresh : 20,\n\n // Whether to fit the network view after when done\n fit : true,\n\n // Padding on fit\n padding : 30,\n\n // Constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n boundingBox : undefined,\n\n // Extra spacing between components in non-compound graphs\n componentSpacing : 100,\n\n // Node repulsion (non overlapping) multiplier\n nodeRepulsion : function( node ){ return 400000; },\n\n // Node repulsion (overlapping) multiplier\n nodeOverlap : 10,\n\n // Ideal edge (non nested) length\n idealEdgeLength : function( edge ){ return 10; },\n\n // Divisor to compute edge forces\n edgeElasticity : function( edge ){ return 100; },\n\n // Nesting factor (multiplier) to compute ideal edge length for nested edges\n nestingFactor : 5,\n\n // Gravity force (constant)\n gravity : 80,\n\n // Maximum number of iterations to perform\n numIter : 1000,\n\n // Initial temperature (maximum node displacement)\n initialTemp : 200,\n\n // Cooling factor (how the temperature is reduced between consecutive iterations\n coolingFactor : 0.95,\n\n // Lower temperature threshold (below this point the layout will end)\n minTemp : 1.0,\n\n // Whether to use threading to speed up the layout\n useMultitasking : true\n};\n\n\n/**\n * @brief : constructor\n * @arg options : object containing layout options\n */\nfunction CoseLayout(options) {\n this.options = util.extend({}, defaults, options);\n\n this.options.layout = this;\n}\n\n\n/**\n * @brief : runs the layout\n */\nCoseLayout.prototype.run = function() {\n var options = this.options;\n var cy = options.cy;\n var layout = this;\n var thread = this.thread;\n\n if( !thread || thread.stopped() ){\n thread = this.thread = Thread({ disabled: !options.useMultitasking });\n }\n\n layout.stopped = false;\n\n layout.trigger({ type: 'layoutstart', layout: layout });\n\n // Set DEBUG - Global variable\n if (true === options.debug) {\n DEBUG = true;\n } else {\n DEBUG = false;\n }\n\n // Initialize layout info\n var layoutInfo = createLayoutInfo(cy, layout, options);\n\n // Show LayoutInfo contents if debugging\n if (DEBUG) {\n printLayoutInfo(layoutInfo);\n }\n\n // If required, randomize node positions\n // if (true === options.randomize) {\n randomizePositions(layoutInfo, cy);\n // }\n\n var startTime = Date.now();\n var refreshRequested = false;\n var refresh = function( rOpts ){\n rOpts = rOpts || {};\n\n if( refreshRequested ){\n return;\n }\n\n if( !rOpts.force && Date.now() - startTime < options.animationThreshold ){\n return;\n }\n\n refreshRequested = true;\n\n util.requestAnimationFrame(function(){\n refreshPositions(layoutInfo, cy, options);\n\n // Fit the graph if necessary\n if (true === options.fit) {\n cy.fit( options.padding );\n }\n\n refreshRequested = false;\n });\n };\n\n thread.on('message', function( e ){\n var layoutNodes = e.message;\n\n layoutInfo.layoutNodes = layoutNodes;\n refresh();\n });\n\n thread.pass({\n layoutInfo: layoutInfo,\n options: {\n animate: options.animate,\n refresh: options.refresh,\n componentSpacing: options.componentSpacing,\n nodeOverlap: options.nodeOverlap,\n nestingFactor: options.nestingFactor,\n gravity: options.gravity,\n numIter: options.numIter,\n initialTemp: options.initialTemp,\n coolingFactor: options.coolingFactor,\n minTemp: options.minTemp\n }\n }).run(function( pass ){\n var layoutInfo = pass.layoutInfo;\n var options = pass.options;\n var stopped = false;\n\n /**\n * @brief : Performs one iteration of the physical simulation\n * @arg layoutInfo : LayoutInfo object already initialized\n * @arg cy : Cytoscape object\n * @arg options : Layout options\n */\n var step = function(layoutInfo, options, step) {\n // var s = \"\\n\\n###############################\";\n // s += \"\\nSTEP: \" + step;\n // s += \"\\n###############################\\n\";\n // logDebug(s);\n\n // Calculate node repulsions\n calculateNodeForces(layoutInfo, options);\n // Calculate edge forces\n calculateEdgeForces(layoutInfo, options);\n // Calculate gravity forces\n calculateGravityForces(layoutInfo, options);\n // Propagate forces from parent to child\n propagateForces(layoutInfo, options);\n // Update positions based on calculated forces\n updatePositions(layoutInfo, options);\n };\n\n /**\n * @brief : Computes the node repulsion forces\n */\n var calculateNodeForces = function(layoutInfo, options) {\n // Go through each of the graphs in graphSet\n // Nodes only repel each other if they belong to the same graph\n // var s = 'calculateNodeForces';\n // logDebug(s);\n for (var i = 0; i < layoutInfo.graphSet.length; i ++) {\n var graph = layoutInfo.graphSet[i];\n var numNodes = graph.length;\n\n // s = \"Set: \" + graph.toString();\n // logDebug(s);\n\n // Now get all the pairs of nodes\n // Only get each pair once, (A, B) = (B, A)\n for (var j = 0; j < numNodes; j++) {\n var node1 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]];\n\n for (var k = j + 1; k < numNodes; k++) {\n var node2 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[k]]];\n\n nodeRepulsion(node1, node2, layoutInfo, options);\n }\n }\n }\n };\n\n /**\n * @brief : Compute the node repulsion forces between a pair of nodes\n */\n var nodeRepulsion = function(node1, node2, layoutInfo, options) {\n // var s = \"Node repulsion. Node1: \" + node1.id + \" Node2: \" + node2.id;\n\n var cmptId1 = node1.cmptId;\n var cmptId2 = node2.cmptId;\n\n if( cmptId1 !== cmptId2 && !layoutInfo.isCompound ){ return; }\n\n // Get direction of line connecting both node centers\n var directionX = node2.positionX - node1.positionX;\n var directionY = node2.positionY - node1.positionY;\n // s += \"\\ndirectionX: \" + directionX + \", directionY: \" + directionY;\n\n // If both centers are the same, apply a random force\n if (0 === directionX && 0 === directionY) {\n // s += \"\\nNodes have the same position.\";\n return; // TODO could be improved with random force\n }\n\n var overlap = nodesOverlap(node1, node2, directionX, directionY);\n\n if (overlap > 0) {\n // s += \"\\nNodes DO overlap.\";\n // s += \"\\nOverlap: \" + overlap;\n // If nodes overlap, repulsion force is proportional\n // to the overlap\n var force = options.nodeOverlap * overlap;\n\n // Compute the module and components of the force vector\n var distance = Math.sqrt(directionX * directionX + directionY * directionY);\n // s += \"\\nDistance: \" + distance;\n var forceX = force * directionX / distance;\n var forceY = force * directionY / distance;\n\n } else {\n // s += \"\\nNodes do NOT overlap.\";\n // If there's no overlap, force is inversely proportional\n // to squared distance\n\n // Get clipping points for both nodes\n var point1 = findClippingPoint(node1, directionX, directionY);\n var point2 = findClippingPoint(node2, -1 * directionX, -1 * directionY);\n\n // Use clipping points to compute distance\n var distanceX = point2.x - point1.x;\n var distanceY = point2.y - point1.y;\n var distanceSqr = distanceX * distanceX + distanceY * distanceY;\n var distance = Math.sqrt(distanceSqr);\n // s += \"\\nDistance: \" + distance;\n\n // Compute the module and components of the force vector\n var force = ( node1.nodeRepulsion + node2.nodeRepulsion ) / distanceSqr;\n var forceX = force * distanceX / distance;\n var forceY = force * distanceY / distance;\n }\n\n // Apply force\n if( !node1.isLocked ){\n node1.offsetX -= forceX;\n node1.offsetY -= forceY;\n }\n\n if( !node2.isLocked ){\n node2.offsetX += forceX;\n node2.offsetY += forceY;\n }\n\n // s += \"\\nForceX: \" + forceX + \" ForceY: \" + forceY;\n // logDebug(s);\n\n return;\n };\n\n /**\n * @brief : Determines whether two nodes overlap or not\n * @return : Amount of overlapping (0 => no overlap)\n */\n var nodesOverlap = function(node1, node2, dX, dY) {\n\n if (dX > 0) {\n var overlapX = node1.maxX - node2.minX;\n } else {\n var overlapX = node2.maxX - node1.minX;\n }\n\n if (dY > 0) {\n var overlapY = node1.maxY - node2.minY;\n } else {\n var overlapY = node2.maxY - node1.minY;\n }\n\n if (overlapX >= 0 && overlapY >= 0) {\n return Math.sqrt(overlapX * overlapX + overlapY * overlapY);\n } else {\n return 0;\n }\n };\n\n /**\n * @brief : Finds the point in which an edge (direction dX, dY) intersects\n * the rectangular bounding box of it's source/target node\n */\n var findClippingPoint = function(node, dX, dY) {\n\n // Shorcuts\n var X = node.positionX;\n var Y = node.positionY;\n var H = node.height || 1;\n var W = node.width || 1;\n var dirSlope = dY / dX;\n var nodeSlope = H / W;\n\n // var s = 'Computing clipping point of node ' + node.id +\n // \" . Height: \" + H + \", Width: \" + W +\n // \"\\nDirection \" + dX + \", \" + dY;\n //\n // Compute intersection\n var res = {};\n do {\n // Case: Vertical direction (up)\n if (0 === dX && 0 < dY) {\n res.x = X;\n // s += \"\\nUp direction\";\n res.y = Y + H / 2;\n break;\n }\n\n // Case: Vertical direction (down)\n if (0 === dX && 0 > dY) {\n res.x = X;\n res.y = Y + H / 2;\n // s += \"\\nDown direction\";\n break;\n }\n\n // Case: Intersects the right border\n if (0 < dX &&\n -1 * nodeSlope <= dirSlope &&\n dirSlope <= nodeSlope) {\n res.x = X + W / 2;\n res.y = Y + (W * dY / 2 / dX);\n // s += \"\\nRightborder\";\n break;\n }\n\n // Case: Intersects the left border\n if (0 > dX &&\n -1 * nodeSlope <= dirSlope &&\n dirSlope <= nodeSlope) {\n res.x = X - W / 2;\n res.y = Y - (W * dY / 2 / dX);\n // s += \"\\nLeftborder\";\n break;\n }\n\n // Case: Intersects the top border\n if (0 < dY &&\n ( dirSlope <= -1 * nodeSlope ||\n dirSlope >= nodeSlope )) {\n res.x = X + (H * dX / 2 / dY);\n res.y = Y + H / 2;\n // s += \"\\nTop border\";\n break;\n }\n\n // Case: Intersects the bottom border\n if (0 > dY &&\n ( dirSlope <= -1 * nodeSlope ||\n dirSlope >= nodeSlope )) {\n res.x = X - (H * dX / 2 / dY);\n res.y = Y - H / 2;\n // s += \"\\nBottom border\";\n break;\n }\n\n } while (false);\n\n // s += \"\\nClipping point found at \" + res.x + \", \" + res.y;\n // logDebug(s);\n return res;\n };\n\n /**\n * @brief : Calculates all edge forces\n */\n var calculateEdgeForces = function(layoutInfo, options) {\n // Iterate over all edges\n for (var i = 0; i < layoutInfo.edgeSize; i++) {\n // Get edge, source & target nodes\n var edge = layoutInfo.layoutEdges[i];\n var sourceIx = layoutInfo.idToIndex[edge.sourceId];\n var source = layoutInfo.layoutNodes[sourceIx];\n var targetIx = layoutInfo.idToIndex[edge.targetId];\n var target = layoutInfo.layoutNodes[targetIx];\n\n // Get direction of line connecting both node centers\n var directionX = target.positionX - source.positionX;\n var directionY = target.positionY - source.positionY;\n\n // If both centers are the same, do nothing.\n // A random force has already been applied as node repulsion\n if (0 === directionX && 0 === directionY) {\n return;\n }\n\n // Get clipping points for both nodes\n var point1 = findClippingPoint(source, directionX, directionY);\n var point2 = findClippingPoint(target, -1 * directionX, -1 * directionY);\n\n\n var lx = point2.x - point1.x;\n var ly = point2.y - point1.y;\n var l = Math.sqrt(lx * lx + ly * ly);\n\n var force = Math.pow(edge.idealLength - l, 2) / edge.elasticity;\n\n if (0 !== l) {\n var forceX = force * lx / l;\n var forceY = force * ly / l;\n } else {\n var forceX = 0;\n var forceY = 0;\n }\n\n // Add this force to target and source nodes\n if( !source.isLocked ){\n source.offsetX += forceX;\n source.offsetY += forceY;\n }\n\n if( !target.isLocked ){\n target.offsetX -= forceX;\n target.offsetY -= forceY;\n }\n\n // var s = 'Edge force between nodes ' + source.id + ' and ' + target.id;\n // s += \"\\nDistance: \" + l + \" Force: (\" + forceX + \", \" + forceY + \")\";\n // logDebug(s);\n }\n };\n\n /**\n * @brief : Computes gravity forces for all nodes\n */\n var calculateGravityForces = function(layoutInfo, options) {\n var distThreshold = 1;\n\n // var s = 'calculateGravityForces';\n // logDebug(s);\n for (var i = 0; i < layoutInfo.graphSet.length; i ++) {\n var graph = layoutInfo.graphSet[i];\n var numNodes = graph.length;\n\n // s = \"Set: \" + graph.toString();\n // logDebug(s);\n\n // Compute graph center\n if (0 === i) {\n var centerX = layoutInfo.clientHeight / 2;\n var centerY = layoutInfo.clientWidth / 2;\n } else {\n // Get Parent node for this graph, and use its position as center\n var temp = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[0]]];\n var parent = layoutInfo.layoutNodes[layoutInfo.idToIndex[temp.parentId]];\n var centerX = parent.positionX;\n var centerY = parent.positionY;\n }\n // s = \"Center found at: \" + centerX + \", \" + centerY;\n // logDebug(s);\n\n // Apply force to all nodes in graph\n for (var j = 0; j < numNodes; j++) {\n var node = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]];\n // s = \"Node: \" + node.id;\n\n if( node.isLocked ){ continue; }\n\n var dx = centerX - node.positionX;\n var dy = centerY - node.positionY;\n var d = Math.sqrt(dx * dx + dy * dy);\n if (d > distThreshold) {\n var fx = options.gravity * dx / d;\n var fy = options.gravity * dy / d;\n node.offsetX += fx;\n node.offsetY += fy;\n // s += \": Applied force: \" + fx + \", \" + fy;\n } else {\n // s += \": skypped since it's too close to center\";\n }\n // logDebug(s);\n }\n }\n };\n\n /**\n * @brief : This function propagates the existing offsets from\n * parent nodes to its descendents.\n * @arg layoutInfo : layoutInfo Object\n * @arg cy : cytoscape Object\n * @arg options : Layout options\n */\n var propagateForces = function(layoutInfo, options) {\n // Inline implementation of a queue, used for traversing the graph in BFS order\n var queue = [];\n var start = 0; // Points to the start the queue\n var end = -1; // Points to the end of the queue\n\n // logDebug('propagateForces');\n\n // Start by visiting the nodes in the root graph\n queue.push.apply(queue, layoutInfo.graphSet[0]);\n end += layoutInfo.graphSet[0].length;\n\n // Traverse the graph, level by level,\n while (start <= end) {\n // Get the node to visit and remove it from queue\n var nodeId = queue[start++];\n var nodeIndex = layoutInfo.idToIndex[nodeId];\n var node = layoutInfo.layoutNodes[nodeIndex];\n var children = node.children;\n\n // We only need to process the node if it's compound\n if (0 < children.length && !node.isLocked) {\n var offX = node.offsetX;\n var offY = node.offsetY;\n\n // var s = \"Propagating offset from parent node : \" + node.id +\n // \". OffsetX: \" + offX + \". OffsetY: \" + offY;\n // s += \"\\n Children: \" + children.toString();\n // logDebug(s);\n\n for (var i = 0; i < children.length; i++) {\n var childNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[children[i]]];\n // Propagate offset\n childNode.offsetX += offX;\n childNode.offsetY += offY;\n // Add children to queue to be visited\n queue[++end] = children[i];\n }\n\n // Reset parent offsets\n node.offsetX = 0;\n node.offsetY = 0;\n }\n\n }\n };\n\n /**\n * @brief : Updates the layout model positions, based on\n * the accumulated forces\n */\n var updatePositions = function(layoutInfo, options) {\n // var s = 'Updating positions';\n // logDebug(s);\n\n // Reset boundaries for compound nodes\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n if (0 < n.children.length) {\n // logDebug(\"Resetting boundaries of compound node: \" + n.id);\n n.maxX = undefined;\n n.minX = undefined;\n n.maxY = undefined;\n n.minY = undefined;\n }\n }\n\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n if (0 < n.children.length || n.isLocked) {\n // No need to set compound or locked node position\n // logDebug(\"Skipping position update of node: \" + n.id);\n continue;\n }\n // s = \"Node: \" + n.id + \" Previous position: (\" +\n // n.positionX + \", \" + n.positionY + \").\";\n\n // Limit displacement in order to improve stability\n var tempForce = limitForce(n.offsetX, n.offsetY, layoutInfo.temperature);\n n.positionX += tempForce.x;\n n.positionY += tempForce.y;\n n.offsetX = 0;\n n.offsetY = 0;\n n.minX = n.positionX - n.width;\n n.maxX = n.positionX + n.width;\n n.minY = n.positionY - n.height;\n n.maxY = n.positionY + n.height;\n // s += \" New Position: (\" + n.positionX + \", \" + n.positionY + \").\";\n // logDebug(s);\n\n // Update ancestry boudaries\n updateAncestryBoundaries(n, layoutInfo);\n }\n\n // Update size, position of compund nodes\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n if ( 0 < n.children.length && !n.isLocked ) {\n n.positionX = (n.maxX + n.minX) / 2;\n n.positionY = (n.maxY + n.minY) / 2;\n n.width = n.maxX - n.minX;\n n.height = n.maxY - n.minY;\n // s = \"Updating position, size of compound node \" + n.id;\n // s += \"\\nPositionX: \" + n.positionX + \", PositionY: \" + n.positionY;\n // s += \"\\nWidth: \" + n.width + \", Height: \" + n.height;\n // logDebug(s);\n }\n }\n };\n\n /**\n * @brief : Limits a force (forceX, forceY) to be not\n * greater (in modulo) than max.\n 8 Preserves force direction.\n */\n var limitForce = function(forceX, forceY, max) {\n // var s = \"Limiting force: (\" + forceX + \", \" + forceY + \"). Max: \" + max;\n var force = Math.sqrt(forceX * forceX + forceY * forceY);\n\n if (force > max) {\n var res = {\n x : max * forceX / force,\n y : max * forceY / force\n };\n\n } else {\n var res = {\n x : forceX,\n y : forceY\n };\n }\n\n // s += \".\\nResult: (\" + res.x + \", \" + res.y + \")\";\n // logDebug(s);\n\n return res;\n };\n\n /**\n * @brief : Function used for keeping track of compound node\n * sizes, since they should bound all their subnodes.\n */\n var updateAncestryBoundaries = function(node, layoutInfo) {\n // var s = \"Propagating new position/size of node \" + node.id;\n var parentId = node.parentId;\n if (null == parentId) {\n // If there's no parent, we are done\n // s += \". No parent node.\";\n // logDebug(s);\n return;\n }\n\n // Get Parent Node\n var p = layoutInfo.layoutNodes[layoutInfo.idToIndex[parentId]];\n var flag = false;\n\n // MaxX\n if (null == p.maxX || node.maxX + p.padRight > p.maxX) {\n p.maxX = node.maxX + p.padRight;\n flag = true;\n // s += \"\\nNew maxX for parent node \" + p.id + \": \" + p.maxX;\n }\n\n // MinX\n if (null == p.minX || node.minX - p.padLeft < p.minX) {\n p.minX = node.minX - p.padLeft;\n flag = true;\n // s += \"\\nNew minX for parent node \" + p.id + \": \" + p.minX;\n }\n\n // MaxY\n if (null == p.maxY || node.maxY + p.padBottom > p.maxY) {\n p.maxY = node.maxY + p.padBottom;\n flag = true;\n // s += \"\\nNew maxY for parent node \" + p.id + \": \" + p.maxY;\n }\n\n // MinY\n if (null == p.minY || node.minY - p.padTop < p.minY) {\n p.minY = node.minY - p.padTop;\n flag = true;\n // s += \"\\nNew minY for parent node \" + p.id + \": \" + p.minY;\n }\n\n // If updated boundaries, propagate changes upward\n if (flag) {\n // logDebug(s);\n return updateAncestryBoundaries(p, layoutInfo);\n }\n\n // s += \". No changes in boundaries/position of parent node \" + p.id;\n // logDebug(s);\n return;\n };\n\n var separateComponents = function(layutInfo, options){\n var nodes = layoutInfo.layoutNodes;\n var components = [];\n\n for( var i = 0; i < nodes.length; i++ ){\n var node = nodes[i];\n var cid = node.cmptId;\n var component = components[ cid ] = components[ cid ] || [];\n\n component.push( node );\n }\n\n var totalA = 0;\n\n for( var i = 0; i < components.length; i++ ){\n var c = components[i];\n c.x1 = Infinity;\n c.x2 = -Infinity;\n c.y1 = Infinity;\n c.y2 = -Infinity;\n\n for( var j = 0; j < c.length; j++ ){\n var n = c[j];\n\n c.x1 = Math.min( c.x1, n.positionX - n.width/2 );\n c.x2 = Math.max( c.x2, n.positionX + n.width/2 );\n c.y1 = Math.min( c.y1, n.positionY - n.height/2 );\n c.y2 = Math.max( c.y2, n.positionY + n.height/2 );\n }\n\n c.w = c.x2 - c.x1;\n c.h = c.y2 - c.y1;\n\n totalA += c.w * c.h;\n }\n\n components.sort(function( c1, c2 ){\n return c2.w*c2.h - c1.w*c1.h;\n });\n\n var x = 0;\n var y = 0;\n var usedW = 0;\n var rowH = 0;\n var maxRowW = Math.sqrt( totalA ) * layoutInfo.clientWidth / layoutInfo.clientHeight;\n\n for( var i = 0; i < components.length; i++ ){\n var c = components[i];\n\n for( var j = 0; j < c.length; j++ ){\n var n = c[j];\n\n if( !n.isLocked ){\n n.positionX += x;\n n.positionY += y;\n }\n }\n\n x += c.w + options.componentSpacing;\n usedW += c.w + options.componentSpacing;\n rowH = Math.max( rowH, c.h );\n\n if( usedW > maxRowW ){\n y += rowH + options.componentSpacing;\n x = 0;\n usedW = 0;\n rowH = 0;\n }\n }\n };\n\n var mainLoop = function(i){\n if( stopped ){\n // logDebug(\"Layout manually stopped. Stopping computation in step \" + i);\n return false;\n }\n\n // Do one step in the phisical simulation\n step(layoutInfo, options, i);\n\n // Update temperature\n layoutInfo.temperature = layoutInfo.temperature * options.coolingFactor;\n // logDebug(\"New temperature: \" + layoutInfo.temperature);\n\n if (layoutInfo.temperature < options.minTemp) {\n // logDebug(\"Temperature drop below minimum threshold. Stopping computation in step \" + i);\n return false;\n }\n\n return true;\n };\n\n var i = 0;\n var loopRet;\n\n do {\n var f = 0;\n\n while( f < options.refresh && i < options.numIter ){\n var loopRet = mainLoop(i);\n if( !loopRet ){ break; }\n\n f++;\n i++;\n }\n\n if( options.animate ){\n broadcast( layoutInfo.layoutNodes ); // jshint ignore:line\n }\n\n } while ( loopRet && i + 1 < options.numIter );\n\n separateComponents( layoutInfo, options );\n\n return layoutInfo;\n }).then(function( layoutInfoUpdated ){\n layoutInfo.layoutNodes = layoutInfoUpdated.layoutNodes; // get the positions\n\n thread.stop();\n done();\n });\n\n var done = function(){\n refresh({ force: true });\n\n // Layout has finished\n layout.one('layoutstop', options.stop);\n layout.trigger({ type: 'layoutstop', layout: layout });\n };\n\n return this; // chaining\n};\n\n\n/**\n * @brief : called on continuous layouts to stop them before they finish\n */\nCoseLayout.prototype.stop = function(){\n this.stopped = true;\n\n if( this.thread ){\n this.thread.stop();\n }\n\n this.trigger('layoutstop');\n\n return this; // chaining\n};\n\nCoseLayout.prototype.destroy = function(){\n if( this.thread ){\n this.thread.stop();\n }\n\n return this; // chaining\n};\n\n\n/**\n * @brief : Creates an object which is contains all the data\n * used in the layout process\n * @arg cy : cytoscape.js object\n * @return : layoutInfo object initialized\n */\nvar createLayoutInfo = function(cy, layout, options) {\n // Shortcut\n var edges = options.eles.edges();\n var nodes = options.eles.nodes();\n\n var layoutInfo = {\n isCompound : cy.hasCompoundNodes(),\n layoutNodes : [],\n idToIndex : {},\n nodeSize : nodes.size(),\n graphSet : [],\n indexToGraph : [],\n layoutEdges : [],\n edgeSize : edges.size(),\n temperature : options.initialTemp,\n clientWidth : cy.width(),\n clientHeight : cy.width(),\n boundingBox : math.makeBoundingBox( options.boundingBox ? options.boundingBox : {\n x1: 0, y1: 0, w: cy.width(), h: cy.height()\n } )\n };\n\n var components = options.eles.components();\n var id2cmptId = {};\n\n for( var i = 0; i < components.length; i++ ){\n var component = components[i];\n\n for( var j = 0; j < component.length; j++ ){\n var node = component[j];\n\n id2cmptId[ node.id() ] = i;\n }\n }\n\n // Iterate over all nodes, creating layout nodes\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = nodes[i];\n var nbb = n.boundingBox();\n\n var tempNode = {};\n tempNode.isLocked = n.locked();\n tempNode.id = n.data('id');\n tempNode.parentId = n.data('parent');\n tempNode.cmptId = id2cmptId[ n.id() ];\n tempNode.children = [];\n tempNode.positionX = n.position('x');\n tempNode.positionY = n.position('y');\n tempNode.offsetX = 0;\n tempNode.offsetY = 0;\n tempNode.height = nbb.w;\n tempNode.width = nbb.h;\n tempNode.maxX = tempNode.positionX + tempNode.width / 2;\n tempNode.minX = tempNode.positionX - tempNode.width / 2;\n tempNode.maxY = tempNode.positionY + tempNode.height / 2;\n tempNode.minY = tempNode.positionY - tempNode.height / 2;\n tempNode.padLeft = parseFloat( n.style('padding-left') );\n tempNode.padRight = parseFloat( n.style('padding-right') );\n tempNode.padTop = parseFloat( n.style('padding-top') );\n tempNode.padBottom = parseFloat( n.style('padding-bottom') );\n\n // forces\n tempNode.nodeRepulsion = is.fn( options.nodeRepulsion ) ? options.nodeRepulsion.call( n, n ) : options.nodeRepulsion;\n\n // Add new node\n layoutInfo.layoutNodes.push(tempNode);\n // Add entry to id-index map\n layoutInfo.idToIndex[tempNode.id] = i;\n }\n\n // Inline implementation of a queue, used for traversing the graph in BFS order\n var queue = [];\n var start = 0; // Points to the start the queue\n var end = -1; // Points to the end of the queue\n\n var tempGraph = [];\n\n // Second pass to add child information and\n // initialize queue for hierarchical traversal\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n var p_id = n.parentId;\n // Check if node n has a parent node\n if (null != p_id) {\n // Add node Id to parent's list of children\n layoutInfo.layoutNodes[layoutInfo.idToIndex[p_id]].children.push(n.id);\n } else {\n // If a node doesn't have a parent, then it's in the root graph\n queue[++end] = n.id;\n tempGraph.push(n.id);\n }\n }\n\n // Add root graph to graphSet\n layoutInfo.graphSet.push(tempGraph);\n\n // Traverse the graph, level by level,\n while (start <= end) {\n // Get the node to visit and remove it from queue\n var node_id = queue[start++];\n var node_ix = layoutInfo.idToIndex[node_id];\n var node = layoutInfo.layoutNodes[node_ix];\n var children = node.children;\n if (children.length > 0) {\n // Add children nodes as a new graph to graph set\n layoutInfo.graphSet.push(children);\n // Add children to que queue to be visited\n for (var i = 0; i < children.length; i++) {\n queue[++end] = children[i];\n }\n }\n }\n\n // Create indexToGraph map\n for (var i = 0; i < layoutInfo.graphSet.length; i++) {\n var graph = layoutInfo.graphSet[i];\n for (var j = 0; j < graph.length; j++) {\n var index = layoutInfo.idToIndex[graph[j]];\n layoutInfo.indexToGraph[index] = i;\n }\n }\n\n // Iterate over all edges, creating Layout Edges\n for (var i = 0; i < layoutInfo.edgeSize; i++) {\n var e = edges[i];\n var tempEdge = {};\n tempEdge.id = e.data('id');\n tempEdge.sourceId = e.data('source');\n tempEdge.targetId = e.data('target');\n\n // Compute ideal length\n var idealLength = is.fn( options.idealEdgeLength ) ? options.idealEdgeLength.call( e, e ) : options.idealEdgeLength;\n var elasticity = is.fn( options.edgeElasticity ) ? options.edgeElasticity.call( e, e ) : options.edgeElasticity;\n\n // Check if it's an inter graph edge\n var sourceIx = layoutInfo.idToIndex[tempEdge.sourceId];\n var targetIx = layoutInfo.idToIndex[tempEdge.targetId];\n var sourceGraph = layoutInfo.indexToGraph[sourceIx];\n var targetGraph = layoutInfo.indexToGraph[targetIx];\n\n if (sourceGraph != targetGraph) {\n // Find lowest common graph ancestor\n var lca = findLCA(tempEdge.sourceId, tempEdge.targetId, layoutInfo);\n\n // Compute sum of node depths, relative to lca graph\n var lcaGraph = layoutInfo.graphSet[lca];\n var depth = 0;\n\n // Source depth\n var tempNode = layoutInfo.layoutNodes[sourceIx];\n while ( -1 === lcaGraph.indexOf(tempNode.id) ) {\n tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]];\n depth++;\n }\n\n // Target depth\n tempNode = layoutInfo.layoutNodes[targetIx];\n while ( -1 === lcaGraph.indexOf(tempNode.id) ) {\n tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]];\n depth++;\n }\n\n // logDebug('LCA of nodes ' + tempEdge.sourceId + ' and ' + tempEdge.targetId +\n // \". Index: \" + lca + \" Contents: \" + lcaGraph.toString() +\n // \". Depth: \" + depth);\n\n // Update idealLength\n idealLength *= depth * options.nestingFactor;\n }\n\n tempEdge.idealLength = idealLength;\n tempEdge.elasticity = elasticity;\n\n layoutInfo.layoutEdges.push(tempEdge);\n }\n\n // Finally, return layoutInfo object\n return layoutInfo;\n};\n\n\n/**\n * @brief : This function finds the index of the lowest common\n * graph ancestor between 2 nodes in the subtree\n * (from the graph hierarchy induced tree) whose\n * root is graphIx\n *\n * @arg node1: node1's ID\n * @arg node2: node2's ID\n * @arg layoutInfo: layoutInfo object\n *\n */\nvar findLCA = function(node1, node2, layoutInfo) {\n // Find their common ancester, starting from the root graph\n var res = findLCA_aux(node1, node2, 0, layoutInfo);\n if (2 > res.count) {\n // If aux function couldn't find the common ancester,\n // then it is the root graph\n return 0;\n } else {\n return res.graph;\n }\n};\n\n\n/**\n * @brief : Auxiliary function used for LCA computation\n *\n * @arg node1 : node1's ID\n * @arg node2 : node2's ID\n * @arg graphIx : subgraph index\n * @arg layoutInfo : layoutInfo object\n *\n * @return : object of the form {count: X, graph: Y}, where:\n * X is the number of ancesters (max: 2) found in\n * graphIx (and it's subgraphs),\n * Y is the graph index of the lowest graph containing\n * all X nodes\n */\nvar findLCA_aux = function(node1, node2, graphIx, layoutInfo) {\n var graph = layoutInfo.graphSet[graphIx];\n // If both nodes belongs to graphIx\n if (-1 < graph.indexOf(node1) && -1 < graph.indexOf(node2)) {\n return {count:2, graph:graphIx};\n }\n\n // Make recursive calls for all subgraphs\n var c = 0;\n for (var i = 0; i < graph.length; i++) {\n var nodeId = graph[i];\n var nodeIx = layoutInfo.idToIndex[nodeId];\n var children = layoutInfo.layoutNodes[nodeIx].children;\n\n // If the node has no child, skip it\n if (0 === children.length) {\n continue;\n }\n\n var childGraphIx = layoutInfo.indexToGraph[layoutInfo.idToIndex[children[0]]];\n var result = findLCA_aux(node1, node2, childGraphIx, layoutInfo);\n if (0 === result.count) {\n // Neither node1 nor node2 are present in this subgraph\n continue;\n } else if (1 === result.count) {\n // One of (node1, node2) is present in this subgraph\n c++;\n if (2 === c) {\n // We've already found both nodes, no need to keep searching\n break;\n }\n } else {\n // Both nodes are present in this subgraph\n return result;\n }\n }\n\n return {count:c, graph:graphIx};\n};\n\n\n/**\n * @brief: printsLayoutInfo into js console\n * Only used for debbuging\n */\nvar printLayoutInfo = function(layoutInfo) {\n /* jshint ignore:start */\n\n if (!DEBUG) {\n return;\n }\n console.debug(\"layoutNodes:\");\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n var s =\n \"\\nindex: \" + i +\n \"\\nId: \" + n.id +\n \"\\nChildren: \" + n.children.toString() +\n \"\\nparentId: \" + n.parentId +\n \"\\npositionX: \" + n.positionX +\n \"\\npositionY: \" + n.positionY +\n \"\\nOffsetX: \" + n.offsetX +\n \"\\nOffsetY: \" + n.offsetY +\n \"\\npadLeft: \" + n.padLeft +\n \"\\npadRight: \" + n.padRight +\n \"\\npadTop: \" + n.padTop +\n \"\\npadBottom: \" + n.padBottom;\n\n console.debug(s);\n }\n\n console.debug('idToIndex');\n for (var i in layoutInfo.idToIndex) {\n console.debug(\"Id: \" + i + \"\\nIndex: \" + layoutInfo.idToIndex[i]);\n }\n\n console.debug('Graph Set');\n var set = layoutInfo.graphSet;\n for (var i = 0; i < set.length; i ++) {\n console.debug(\"Set : \" + i + \": \" + set[i].toString());\n }\n\n var s = 'IndexToGraph';\n for (var i = 0; i < layoutInfo.indexToGraph.length; i ++) {\n s += \"\\nIndex : \" + i + \" Graph: \"+ layoutInfo.indexToGraph[i];\n }\n console.debug(s);\n\n s = 'Layout Edges';\n for (var i = 0; i < layoutInfo.layoutEdges.length; i++) {\n var e = layoutInfo.layoutEdges[i];\n s += \"\\nEdge Index: \" + i + \" ID: \" + e.id +\n \" SouceID: \" + e.sourceId + \" TargetId: \" + e.targetId +\n \" Ideal Length: \" + e.idealLength;\n }\n console.debug(s);\n\n s = \"nodeSize: \" + layoutInfo.nodeSize;\n s += \"\\nedgeSize: \" + layoutInfo.edgeSize;\n s += \"\\ntemperature: \" + layoutInfo.temperature;\n console.debug(s);\n\n return;\n /* jshint ignore:end */\n};\n\n\n/**\n * @brief : Randomizes the position of all nodes\n */\nvar randomizePositions = function(layoutInfo, cy) {\n var width = layoutInfo.clientWidth;\n var height = layoutInfo.clientHeight;\n\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n\n // No need to randomize compound nodes or locked nodes\n if ( 0 === n.children.length && !n.isLocked ) {\n n.positionX = Math.random() * width;\n n.positionY = Math.random() * height;\n }\n }\n};\n\n\n/**\n * @brief : Updates the positions of nodes in the network\n * @arg layoutInfo : LayoutInfo object\n * @arg cy : Cytoscape object\n * @arg options : Layout options\n */\nvar refreshPositions = function(layoutInfo, cy, options) {\n // var s = 'Refreshing positions';\n // logDebug(s);\n\n var layout = options.layout;\n var nodes = options.eles.nodes();\n var bb = layoutInfo.boundingBox;\n var coseBB = { x1: Infinity, x2: -Infinity, y1: Infinity, y2: -Infinity };\n\n if( options.boundingBox ){\n nodes.forEach(function( node ){\n var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[node.data('id')]];\n\n coseBB.x1 = Math.min( coseBB.x1, lnode.positionX );\n coseBB.x2 = Math.max( coseBB.x2, lnode.positionX );\n\n coseBB.y1 = Math.min( coseBB.y1, lnode.positionY );\n coseBB.y2 = Math.max( coseBB.y2, lnode.positionY );\n });\n\n coseBB.w = coseBB.x2 - coseBB.x1;\n coseBB.h = coseBB.y2 - coseBB.y1;\n }\n\n nodes.positions(function(i, ele) {\n var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[ele.data('id')]];\n // s = \"Node: \" + lnode.id + \". Refreshed position: (\" +\n // lnode.positionX + \", \" + lnode.positionY + \").\";\n // logDebug(s);\n\n if( options.boundingBox ){ // then add extra bounding box constraint\n var pctX = (lnode.positionX - coseBB.x1) / coseBB.w;\n var pctY = (lnode.positionY - coseBB.y1) / coseBB.h;\n\n return {\n x: bb.x1 + pctX * bb.w,\n y: bb.y1 + pctY * bb.h\n };\n } else {\n return {\n x: lnode.positionX,\n y: lnode.positionY\n };\n }\n });\n\n // Trigger layoutReady only on first call\n if (true !== layoutInfo.ready) {\n // s = 'Triggering layoutready';\n // logDebug(s);\n layoutInfo.ready = true;\n layout.one('layoutready', options.ready);\n layout.trigger({ type: 'layoutready', layout: this });\n }\n};\n\n/**\n * @brief : Logs a debug message in JS console, if DEBUG is ON\n */\n// var logDebug = function(text) {\n// if (DEBUG) {\n// console.debug(text);\n// }\n// };\n\nmodule.exports = CoseLayout;\n","'use strict';\n\nvar util = require('../../util');\nvar math = require('../../math');\n\nvar defaults = {\n fit: true, // whether to fit the viewport to the graph\n padding: 30, // padding used on fit\n boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n avoidOverlap: true, // prevents node overlap, may overflow boundingBox if not enough space\n avoidOverlapPadding: 10, // extra spacing around nodes when avoidOverlap: true\n condense: false, // uses all available space on false, uses minimal space on true\n rows: undefined, // force num of rows in the grid\n cols: undefined, // force num of columns in the grid\n position: function( node ){}, // returns { row, col } for element\n sort: undefined, // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') }\n animate: false, // whether to transition the node positions\n animationDuration: 500, // duration of animation in ms if enabled\n animationEasing: undefined, // easing of animation if enabled\n ready: undefined, // callback on layoutready\n stop: undefined // callback on layoutstop\n};\n\nfunction GridLayout( options ){\n this.options = util.extend({}, defaults, options);\n}\n\nGridLayout.prototype.run = function(){\n var params = this.options;\n var options = params;\n\n var cy = params.cy;\n var eles = options.eles;\n var nodes = eles.nodes().not(':parent');\n\n if( options.sort ){\n nodes = nodes.sort( options.sort );\n }\n\n var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : {\n x1: 0, y1: 0, w: cy.width(), h: cy.height()\n } );\n\n if( bb.h === 0 || bb.w === 0){\n nodes.layoutPositions(this, options, function(){\n return { x: bb.x1, y: bb.y1 };\n });\n\n } else {\n\n // width/height * splits^2 = cells where splits is number of times to split width\n var cells = nodes.size();\n var splits = Math.sqrt( cells * bb.h/bb.w );\n var rows = Math.round( splits );\n var cols = Math.round( bb.w/bb.h * splits );\n\n var small = function(val){\n if( val == null ){\n return Math.min(rows, cols);\n } else {\n var min = Math.min(rows, cols);\n if( min == rows ){\n rows = val;\n } else {\n cols = val;\n }\n }\n };\n\n var large = function(val){\n if( val == null ){\n return Math.max(rows, cols);\n } else {\n var max = Math.max(rows, cols);\n if( max == rows ){\n rows = val;\n } else {\n cols = val;\n }\n }\n };\n\n var oRows = options.rows;\n var oCols = options.cols != null ? options.cols : options.columns;\n\n // if rows or columns were set in options, use those values\n if( oRows != null && oCols != null ){\n rows = oRows;\n cols = oCols;\n } else if( oRows != null && oCols == null ){\n rows = oRows;\n cols = Math.ceil( cells / rows );\n } else if( oRows == null && oCols != null ){\n cols = oCols;\n rows = Math.ceil( cells / cols );\n }\n\n // otherwise use the automatic values and adjust accordingly\n\n // if rounding was up, see if we can reduce rows or columns\n else if( cols * rows > cells ){\n var sm = small();\n var lg = large();\n\n // reducing the small side takes away the most cells, so try it first\n if( (sm - 1) * lg >= cells ){\n small(sm - 1);\n } else if( (lg - 1) * sm >= cells ){\n large(lg - 1);\n }\n } else {\n\n // if rounding was too low, add rows or columns\n while( cols * rows < cells ){\n var sm = small();\n var lg = large();\n\n // try to add to larger side first (adds less in multiplication)\n if( (lg + 1) * sm >= cells ){\n large(lg + 1);\n } else {\n small(sm + 1);\n }\n }\n }\n\n var cellWidth = bb.w / cols;\n var cellHeight = bb.h / rows;\n\n if( options.condense ){\n cellWidth = 0;\n cellHeight = 0;\n }\n\n if( options.avoidOverlap ){\n for( var i = 0; i < nodes.length; i++ ){\n var node = nodes[i];\n var pos = node._private.position;\n\n if( pos.x == null || pos.y == null ){ // for bb\n pos.x = 0;\n pos.y = 0;\n }\n\n var nbb = node.boundingBox();\n var p = options.avoidOverlapPadding;\n\n var w = nbb.w + p;\n var h = nbb.h + p;\n\n cellWidth = Math.max( cellWidth, w );\n cellHeight = Math.max( cellHeight, h );\n }\n }\n\n var cellUsed = {}; // e.g. 'c-0-2' => true\n\n var used = function(row, col){\n return cellUsed['c-' + row + '-' + col] ? true : false;\n };\n\n var use = function(row, col){\n cellUsed['c-' + row + '-' + col] = true;\n };\n\n // to keep track of current cell position\n var row = 0;\n var col = 0;\n var moveToNextCell = function(){\n col++;\n if( col >= cols ){\n col = 0;\n row++;\n }\n };\n\n // get a cache of all the manual positions\n var id2manPos = {};\n for( var i = 0; i < nodes.length; i++ ){\n var node = nodes[i];\n var rcPos = options.position( node );\n\n if( rcPos && (rcPos.row !== undefined || rcPos.col !== undefined) ){ // must have at least row or col def'd\n var pos = {\n row: rcPos.row,\n col: rcPos.col\n };\n\n if( pos.col === undefined ){ // find unused col\n pos.col = 0;\n\n while( used(pos.row, pos.col) ){\n pos.col++;\n }\n } else if( pos.row === undefined ){ // find unused row\n pos.row = 0;\n\n while( used(pos.row, pos.col) ){\n pos.row++;\n }\n }\n\n id2manPos[ node.id() ] = pos;\n use( pos.row, pos.col );\n }\n }\n\n var getPos = function(i, element){\n var x, y;\n\n if( element.locked() || element.isFullAutoParent() ){\n return false;\n }\n\n // see if we have a manual position set\n var rcPos = id2manPos[ element.id() ];\n if( rcPos ){\n x = rcPos.col * cellWidth + cellWidth/2 + bb.x1;\n y = rcPos.row * cellHeight + cellHeight/2 + bb.y1;\n\n } else { // otherwise set automatically\n\n while( used(row, col) ){\n moveToNextCell();\n }\n\n x = col * cellWidth + cellWidth/2 + bb.x1;\n y = row * cellHeight + cellHeight/2 + bb.y1;\n use( row, col );\n\n moveToNextCell();\n }\n\n return { x: x, y: y };\n\n };\n\n nodes.layoutPositions( this, options, getPos );\n }\n\n return this; // chaining\n\n};\n\nmodule.exports = GridLayout;\n","'use strict';\n\nmodule.exports = [\n { name: 'breadthfirst', impl: require('./breadthfirst') },\n { name: 'circle', impl: require('./circle') },\n { name: 'concentric',impl: require('./concentric') },\n { name: 'cose', impl: require('./cose') },\n { name: 'grid', impl: require('./grid') },\n { name: 'null', impl: require('./null') },\n { name: 'preset', impl: require('./preset') },\n { name: 'random', impl: require('./random') }\n];\n","'use strict';\n\nvar util = require('../../util');\n\n// default layout options\nvar defaults = {\n ready: function(){}, // on layoutready\n stop: function(){} // on layoutstop\n};\n\n// constructor\n// options : object containing layout options\nfunction NullLayout( options ){\n this.options = util.extend({}, defaults, options);\n}\n\n// runs the layout\nNullLayout.prototype.run = function(){\n var options = this.options;\n var eles = options.eles; // elements to consider in the layout\n var layout = this;\n\n // cy is automatically populated for us in the constructor\n var cy = options.cy; // jshint ignore:line\n\n layout.trigger('layoutstart');\n\n // puts all nodes at (0, 0)\n eles.nodes().positions(function(){\n return {\n x: 0,\n y: 0\n };\n });\n\n // trigger layoutready when each node has had its position set at least once\n layout.one('layoutready', options.ready);\n layout.trigger('layoutready');\n\n // trigger layoutstop when the layout stops (e.g. finishes)\n layout.one('layoutstop', options.stop);\n layout.trigger('layoutstop');\n\n return this; // chaining\n};\n\n// called on continuous layouts to stop them before they finish\nNullLayout.prototype.stop = function(){\n return this; // chaining\n};\n\nmodule.exports = NullLayout;\n","'use strict';\n\nvar util = require('../../util');\nvar is = require('../../is');\n\nvar defaults = {\n positions: undefined, // map of (node id) => (position obj); or function(node){ return somPos; }\n zoom: undefined, // the zoom level to set (prob want fit = false if set)\n pan: undefined, // the pan level to set (prob want fit = false if set)\n fit: true, // whether to fit to viewport\n padding: 30, // padding on fit\n animate: false, // whether to transition the node positions\n animationDuration: 500, // duration of animation in ms if enabled\n animationEasing: undefined, // easing of animation if enabled\n ready: undefined, // callback on layoutready\n stop: undefined // callback on layoutstop\n};\n\nfunction PresetLayout( options ){\n this.options = util.extend({}, defaults, options);\n}\n\nPresetLayout.prototype.run = function(){\n var options = this.options;\n var eles = options.eles;\n\n var nodes = eles.nodes();\n var posIsFn = is.fn( options.positions );\n\n function getPosition(node){\n if( options.positions == null ){\n return null;\n }\n\n if( posIsFn ){\n return options.positions.apply( node, [ node ] );\n }\n\n var pos = options.positions[node._private.data.id];\n\n if( pos == null ){\n return null;\n }\n\n return pos;\n }\n\n nodes.layoutPositions(this, options, function(i, node){\n var position = getPosition(node);\n\n if( node.locked() || position == null ){\n return false;\n }\n\n return position;\n });\n\n return this; // chaining\n};\n\nmodule.exports = PresetLayout;\n","'use strict';\n\nvar util = require('../../util');\nvar math = require('../../math');\n\nvar defaults = {\n fit: true, // whether to fit to viewport\n padding: 30, // fit padding\n boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n animate: false, // whether to transition the node positions\n animationDuration: 500, // duration of animation in ms if enabled\n animationEasing: undefined, // easing of animation if enabled\n ready: undefined, // callback on layoutready\n stop: undefined // callback on layoutstop\n};\n\nfunction RandomLayout( options ){\n this.options = util.extend({}, defaults, options);\n}\n\nRandomLayout.prototype.run = function(){\n var options = this.options;\n var cy = options.cy;\n var eles = options.eles;\n var nodes = eles.nodes().not(':parent');\n\n var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : {\n x1: 0, y1: 0, w: cy.width(), h: cy.height()\n } );\n\n var getPos = function( i, node ){\n return {\n x: bb.x1 + Math.round( Math.random() * bb.w ),\n y: bb.y1 + Math.round( Math.random() * bb.h )\n };\n };\n\n nodes.layoutPositions( this, options, getPos );\n\n return this; // chaining\n};\n\nmodule.exports = RandomLayout;\n","'use strict';\n\nvar math = require('../../../math');\nvar is = require('../../../is');\nvar util = require('../../../util');\n\nvar BRp = {};\n\nBRp.arrowShapeHeight = 0.3;\n\nBRp.registerArrowShapes = function(){\n var arrowShapes = this.arrowShapes = {};\n var renderer = this;\n\n // Contract for arrow shapes:\n // 0, 0 is arrow tip\n // (0, 1) is direction towards node\n // (1, 0) is right\n //\n // functional api:\n // collide: check x, y in shape\n // roughCollide: called before collide, no false negatives\n // draw: draw\n // spacing: dist(arrowTip, nodeBoundary)\n // gap: dist(edgeTip, nodeBoundary), edgeTip may != arrowTip\n\n var bbCollide = function( x, y, size, angle, translation, padding ){\n var x1 = translation.x - size/2 - padding;\n var x2 = translation.x + size/2 + padding;\n var y1 = translation.y - size/2 - padding;\n var y2 = translation.y + size/2 + padding;\n\n var inside = (x1 <= x && x <= x2) && (y1 <= y && y <= y2);\n\n return inside;\n };\n\n var transform = function( x, y, size, angle, translation ){\n var xRotated = x * Math.cos(angle) - y * Math.sin(angle);\n var yRotated = x * Math.sin(angle) + y * Math.cos(angle);\n\n var xScaled = xRotated * size;\n var yScaled = yRotated * size;\n\n var xTranslated = xScaled + translation.x;\n var yTranslated = yScaled + translation.y;\n\n return {\n x: xTranslated,\n y: yTranslated\n };\n };\n\n var transformPoints = function( pts, size, angle, translation ){\n var retPts = [];\n\n for( var i = 0; i < pts.length; i += 2 ){\n var x = pts[i];\n var y = pts[i + 1];\n\n retPts.push( transform(x, y, size, angle, translation) );\n }\n\n return retPts;\n };\n\n var pointsToArr = function( pts ){\n var ret = [];\n\n for( var i = 0; i < pts.length; i++ ){\n var p = pts[i];\n\n ret.push( p.x, p.y );\n }\n\n return ret;\n };\n\n var defineArrowShape = function( name, defn ){\n if( is.string(defn) ){\n defn = arrowShapes[ defn ];\n }\n\n arrowShapes[ name ] = util.extend( {\n name: name,\n\n points: [\n -0.15, -0.3,\n 0.15, -0.3,\n 0.15, 0.3,\n -0.15, 0.3\n ],\n\n collide: function( x, y, size, angle, translation, padding ){\n var points = pointsToArr( transformPoints( this.points, size + 2*padding, angle, translation ) );\n var inside = math.pointInsidePolygonPoints( x, y, points );\n\n return inside;\n },\n\n roughCollide: bbCollide,\n\n draw: function( context, size, angle, translation ){\n var points = transformPoints( this.points, size, angle, translation );\n\n renderer.arrowShapeImpl('polygon')( context, points );\n },\n\n spacing: function( edge ){\n return 0;\n },\n\n gap: function( edge ){\n return edge._private.style['width'].pfValue * 2;\n }\n }, defn );\n };\n\n defineArrowShape( 'none', {\n collide: util.falsify,\n\n roughCollide: util.falsify,\n\n draw: util.noop,\n\n spacing: util.zeroify,\n\n gap: util.zeroify\n } );\n\n defineArrowShape( 'triangle', {\n points: [\n -0.15, -0.3,\n 0, 0,\n 0.15, -0.3\n ]\n } );\n\n defineArrowShape( 'arrow', 'triangle' );\n\n defineArrowShape( 'triangle-backcurve', {\n points: arrowShapes['triangle'].points,\n\n controlPoint: [ 0, -0.15 ],\n\n roughCollide: bbCollide,\n\n draw: function( context, size, angle, translation ){\n var ptsTrans = transformPoints( this.points, size, angle, translation );\n var ctrlPt = this.controlPoint;\n var ctrlPtTrans = transform( ctrlPt[0], ctrlPt[1], size, angle, translation );\n\n renderer.arrowShapeImpl( this.name )( context, ptsTrans, ctrlPtTrans );\n },\n\n gap: function( edge ){\n return edge._private.style['width'].pfValue;\n }\n } );\n\n\n defineArrowShape( 'triangle-tee', {\n points: [\n -0.15, -0.3,\n 0, 0,\n 0.15, -0.3,\n -0.15, -0.3\n ],\n\n pointsTee: [\n -0.15, -0.4,\n -0.15, -0.5,\n 0.15, -0.5,\n 0.15, -0.4\n ],\n\n collide: function( x, y, size, angle, translation, padding ){\n var triPts = pointsToArr( transformPoints( this.points, size + 2*padding, angle, translation ) );\n var teePts = pointsToArr( transformPoints( this.pointsTee, size + 2*padding, angle, translation ) );\n\n var inside = math.pointInsidePolygonPoints( x, y, triPts ) || math.pointInsidePolygonPoints( x, y, teePts );\n\n return inside;\n },\n\n draw: function( context, size, angle, translation ){\n var triPts = transformPoints( this.points, size, angle, translation );\n var teePts = transformPoints( this.pointsTee, size, angle, translation );\n\n renderer.arrowShapeImpl( this.name )( context, triPts, teePts );\n }\n } );\n\n defineArrowShape( 'vee', {\n points: [\n -0.15, -0.3,\n 0, 0,\n 0.15, -0.3,\n 0, -0.15\n ],\n\n gap: function( edge ){\n return edge._private.style['width'].pfValue;\n }\n } );\n\n defineArrowShape( 'half-triangle-overshot', {\n points: [\n 0, -0.25,\n -0.5, -0.25,\n 0.5, 0.25\n ],\n\n leavePathOpen: true,\n\n matchEdgeWidth: true\n } );\n\n defineArrowShape( 'circle', {\n radius: 0.15,\n\n collide: function( x, y, size, angle, translation, padding ){\n var t = translation;\n var inside = ( Math.pow(t.x - x, 2) + Math.pow(t.y - y, 2) <= Math.pow((size + 2*padding) * this.radius, 2) );\n\n return inside;\n },\n\n draw: function( context, size, angle, translation ){\n renderer.arrowShapeImpl( this.name )( context, translation.x, translation.y, this.radius * size );\n },\n\n spacing: function( edge ){\n return renderer.getArrowWidth(edge._private.style['width'].pfValue)\n * this.radius;\n }\n } );\n\n defineArrowShape( 'inhibitor', {\n points: [\n -0.25, 0,\n -0.25, -0.1,\n 0.25, -0.1,\n 0.25, 0\n ],\n\n spacing: function( edge ){\n return 1;\n },\n\n gap: function( edge ){\n return 1;\n }\n } );\n\n defineArrowShape( 'tee', 'inhibitor' );\n\n defineArrowShape( 'square', {\n points: [\n -0.15, 0.00,\n 0.15, 0.00,\n 0.15, -0.3,\n -0.15, -0.3\n ]\n } );\n\n defineArrowShape( 'diamond', {\n points: [\n -0.15, -0.15,\n 0, -0.3,\n 0.15, -0.15,\n 0, 0\n ],\n\n gap: function( edge ){\n return edge._private.style['width'].pfValue;\n }\n } );\n\n};\n\nmodule.exports = BRp;\n","'use strict';\n\nvar BRp = {};\n\nvar delEleCache = function( r ){\n r.eleEache = null;\n};\n\nvar getEleCache = function( r ){\n if( !r.eleEache ){\n r.eleEache = {\n nodes: r.cy.nodes(),\n edges: r.cy.edges()\n };\n }\n\n return r.eleEache;\n};\n\nBRp.getCachedElements = function(){\n return getEleCache( this );\n};\n\nBRp.getCachedNodes = function(){\n return getEleCache( this ).nodes;\n};\n\nBRp.getCachedEdges = function(){\n return getEleCache( this ).edges;\n};\n\nBRp.updateElementsCache = function(){\n var r = this;\n\n delEleCache( r );\n\n return getEleCache( r );\n};\n\nmodule.exports = BRp;\n","'use strict';\n\nvar math = require('../../../math');\nvar is = require('../../../is');\nvar zIndexSort = require('../../../collection/zsort');\n\nvar BRp = {};\n\n// Project mouse\nBRp.projectIntoViewport = function(clientX, clientY) {\n var offsets = this.findContainerClientCoords();\n var offsetLeft = offsets[0];\n var offsetTop = offsets[1];\n\n var x = clientX - offsetLeft;\n var y = clientY - offsetTop;\n\n x -= this.cy.pan().x; y -= this.cy.pan().y; x /= this.cy.zoom(); y /= this.cy.zoom();\n return [x, y];\n};\n\nBRp.findContainerClientCoords = function() {\n var container = this.container;\n\n var bb = this.containerBB = this.containerBB || container.getBoundingClientRect();\n\n return [bb.left, bb.top, bb.right - bb.left, bb.bottom - bb.top];\n};\n\nBRp.invalidateContainerClientCoordsCache = function(){\n this.containerBB = null;\n};\n\n// Find nearest element\nBRp.findNearestElement = function(x, y, visibleElementsOnly, isTouch){\n var self = this;\n var r = this;\n var eles = r.getCachedZSortedEles();\n var near = [];\n var zoom = r.cy.zoom();\n var hasCompounds = r.cy.hasCompoundNodes();\n var edgeThreshold = (isTouch ? 24 : 8) / zoom;\n var nodeThreshold = (isTouch ? 8 : 2) / zoom;\n var labelThreshold = (isTouch ? 8 : 2) / zoom;\n\n function checkNode(node){\n var _p = node._private;\n\n if( _p.style['events'].strValue === 'no' ){ return; }\n\n var width = node.outerWidth() + 2*nodeThreshold;\n var height = node.outerHeight() + 2*nodeThreshold;\n var hw = width/2;\n var hh = height/2;\n var pos = _p.position;\n\n if(\n pos.x - hw <= x && x <= pos.x + hw // bb check x\n &&\n pos.y - hh <= y && y <= pos.y + hh // bb check y\n ){\n var visible = !visibleElementsOnly || ( node.visible() && !node.transparent() );\n\n // exit early if invisible edge and must be visible\n if( visibleElementsOnly && !visible ){\n return;\n }\n\n var shape = r.nodeShapes[ self.getNodeShape(node) ];\n\n if(\n shape.checkPoint(x, y, 0, width, height, pos.x, pos.y)\n ){\n near.push( node );\n }\n\n }\n }\n\n function checkEdge(edge){\n var _p = edge._private;\n\n if( _p.style['events'].strValue === 'no' ){ return; }\n\n var rs = _p.rscratch;\n var style = _p.style;\n var width = style['width'].pfValue/2 + edgeThreshold; // more like a distance radius from centre\n var widthSq = width * width;\n var width2 = width * 2;\n var src = _p.source;\n var tgt = _p.target;\n var inEdgeBB = false;\n var sqDist;\n\n // exit early if invisible edge and must be visible\n var passedVisibilityCheck;\n var passesVisibilityCheck = function(){\n if( passedVisibilityCheck !== undefined ){\n return passedVisibilityCheck;\n }\n\n if( !visibleElementsOnly ){\n passedVisibilityCheck = true;\n return true;\n }\n\n var visible = edge.visible() && !edge.transparent();\n if( visible ){\n passedVisibilityCheck = true;\n return true;\n }\n\n passedVisibilityCheck = false;\n return false;\n };\n\n if( rs.edgeType === 'segments' || rs.edgeType === 'straight' || rs.edgeType === 'haystack' ){\n var pts = rs.allpts;\n\n for( var i = 0; i + 3 < pts.length; i += 2 ){\n if(\n (inEdgeBB = math.inLineVicinity(x, y, pts[i], pts[i+1], pts[i+2], pts[i+3], width2))\n && passesVisibilityCheck() &&\n widthSq > ( sqDist = math.sqDistanceToFiniteLine(x, y, pts[i], pts[i+1], pts[i+2], pts[i+3]) )\n ){\n near.push( edge );\n }\n }\n\n } else if( rs.edgeType === 'bezier' || rs.edgeType === 'multibezier' || rs.edgeType === 'self' || rs.edgeType === 'compound' ){\n var pts = rs.allpts;\n for( var i = 0; i + 5 < rs.allpts.length; i += 4 ){\n if(\n (inEdgeBB = math.inBezierVicinity(x, y, pts[i], pts[i+1], pts[i+2], pts[i+3], pts[i+4], pts[i+5], width2))\n && passesVisibilityCheck() &&\n (widthSq > (sqDist = math.sqDistanceToQuadraticBezier(x, y, pts[i], pts[i+1], pts[i+2], pts[i+3], pts[i+4], pts[i+5])) )\n ){\n near.push( edge );\n }\n }\n }\n\n // if we're close to the edge but didn't hit it, maybe we hit its arrows\n if( inEdgeBB && passesVisibilityCheck() && near.length === 0 || near[near.length - 1] !== edge ){\n var src = src || _p.source;\n var tgt = tgt || _p.target;\n\n var eWidth = style['width'].pfValue;\n var arSize = self.getArrowWidth( eWidth );\n\n var arrows = [\n { name: 'source', x: rs.arrowStartX, y: rs.arrowStartY, angle: rs.srcArrowAngle },\n { name: 'target', x: rs.arrowEndX, y: rs.arrowEndY, angle: rs.tgtArrowAngle },\n { name: 'mid-source', x: rs.midX, y: rs.midY, angle: rs.midsrcArrowAngle },\n { name: 'mid-target', x: rs.midX, y: rs.midY, angle: rs.midtgtArrowAngle }\n ];\n\n for( var i = 0; i < arrows.length; i++ ){\n var ar = arrows[i];\n var shape = r.arrowShapes[ style[ar.name+'-arrow-shape'].value ];\n\n if(\n shape.roughCollide(x, y, arSize, ar.angle, { x: ar.x, y: ar.y }, edgeThreshold)\n &&\n shape.collide(x, y, arSize, ar.angle, { x: ar.x, y: ar.y }, edgeThreshold)\n ){\n near.push( edge );\n break;\n }\n }\n }\n\n // for compound graphs, hitting edge may actually want a connected node instead (b/c edge may have greater z-index precedence)\n if( hasCompounds && near.length > 0 && near[ near.length - 1 ] === edge ){\n checkNode( src );\n checkNode( tgt );\n }\n }\n\n function checkLabel(ele){\n var _p = ele._private;\n var th = labelThreshold;\n\n if( _p.style['text-events'].strValue === 'no' ){ return; }\n\n // adjust bb w/ angle\n if( _p.group === 'edges' && _p.style['edge-text-rotation'].strValue === 'autorotate' ){\n\n var rstyle = _p.rstyle;\n var lw = rstyle.labelWidth + 2*th;\n var lh = rstyle.labelHeight + 2*th;\n var lx = rstyle.labelX;\n var ly = rstyle.labelY;\n\n var theta = _p.rscratch.labelAngle;\n var cos = Math.cos( theta );\n var sin = Math.sin( theta );\n\n var rotate = function( x, y ){\n x = x - lx;\n y = y - ly;\n\n return {\n x: x*cos - y*sin + lx,\n y: x*sin + y*cos + ly\n };\n };\n\n var lx1 = lx - lw/2;\n var lx2 = lx + lw/2;\n var ly1 = ly - lh/2;\n var ly2 = ly + lh/2;\n\n var px1y1 = rotate( lx1, ly1 );\n var px1y2 = rotate( lx1, ly2 );\n var px2y1 = rotate( lx2, ly1 );\n var px2y2 = rotate( lx2, ly2 );\n\n var points = [\n px1y1.x, px1y1.y,\n px2y1.x, px2y1.y,\n px2y2.x, px2y2.y,\n px1y2.x, px1y2.y\n ];\n\n if( math.pointInsidePolygonPoints( x, y, points ) ){\n near.push( ele );\n }\n\n } else {\n var bb = ele.boundingBox({\n includeLabels: true,\n includeNodes: false,\n includeEdges: false\n });\n\n // adjust bb w/ threshold\n bb.x1 -= th;\n bb.y1 -= th;\n bb.x2 += th;\n bb.y2 += th;\n bb.w = bb.x2 - bb.x1;\n bb.h = bb.y2 - bb.y1;\n\n if( math.inBoundingBox( bb, x, y ) ){\n near.push( ele );\n }\n }\n\n }\n\n for( var i = eles.length - 1; i >= 0; i-- ){ // reverse order for precedence\n var ele = eles[i];\n var _p = ele._private;\n\n if( near.length > 0 ){ break; } // since we check in z-order, first found is top and best result => exit early\n\n if( _p.group === 'nodes' ){\n checkNode( ele );\n\n } else { // then edge\n checkEdge( ele );\n }\n\n checkLabel( ele );\n\n }\n\n\n if( near.length > 0 ){\n return near[ near.length - 1 ];\n } else {\n return null;\n }\n};\n\n// 'Give me everything from this box'\nBRp.getAllInBox = function(x1, y1, x2, y2) {\n var nodes = this.getCachedNodes();\n var edges = this.getCachedEdges();\n var box = [];\n\n var x1c = Math.min(x1, x2);\n var x2c = Math.max(x1, x2);\n var y1c = Math.min(y1, y2);\n var y2c = Math.max(y1, y2);\n\n x1 = x1c;\n x2 = x2c;\n y1 = y1c;\n y2 = y2c;\n\n var boxBb = math.makeBoundingBox({\n x1: x1, y1: y1,\n x2: x2, y2: y2\n });\n\n for ( var i = 0; i < nodes.length; i++ ){\n var node = nodes[i];\n var nodeBb = node.boundingBox({\n includeNodes: true,\n includeEdges: false,\n includeLabels: false\n });\n\n if( math.boundingBoxesIntersect(boxBb, nodeBb) ){\n box.push(nodes[i]);\n }\n }\n\n for( var e = 0; e < edges.length; e++ ){\n var edge = edges[e];\n var _p = edge._private;\n var rs = _p.rscratch;\n\n if( rs.startX != null && rs.startY != null && !math.inBoundingBox( boxBb, rs.startX, rs.startY ) ){ continue; }\n if( rs.endX != null && rs.endY != null && !math.inBoundingBox( boxBb, rs.endX, rs.endY ) ){ continue; }\n\n if( rs.edgeType === 'bezier' || rs.edgeType === 'multibezier' || rs.edgeType === 'self' || rs.edgeType === 'compound' || rs.edgeType === 'segments' || rs.edgeType === 'haystack' ){\n\n var pts = _p.rstyle.bezierPts || _p.rstyle.linePts || _p.rstyle.haystackPts;\n var allInside = true;\n\n for( var i = 0; i < pts.length; i++ ){\n if( !math.pointInBoundingBox( boxBb, pts[i] ) ){\n allInside = false;\n break;\n }\n }\n\n if( allInside ){\n box.push( edge );\n }\n\n } else if( rs.edgeType === 'haystack' || rs.edgeType === 'straight' ){\n box.push( edge );\n }\n\n }\n\n return box;\n};\n\n\n/**\n * Returns the shape of the given node. If the height or width of the given node\n * is set to auto, the node is considered to be a compound.\n *\n * @param node a node\n * @return {String} shape of the node\n */\nBRp.getNodeShape = function( node ){\n var r = this;\n var style = node._private.style;\n var shape = style['shape'].value;\n\n if( node.isParent() ){\n if( shape === 'rectangle' || shape === 'roundrectangle' ){\n return shape;\n } else {\n return 'rectangle';\n }\n }\n\n if( shape === 'polygon' ){\n var points = style['shape-polygon-points'].value;\n\n return r.nodeShapes.makePolygon( points ).name;\n }\n\n return shape;\n};\n\nBRp.updateCachedZSortedEles = function(){\n this.getCachedZSortedEles( true );\n};\n\nBRp.getCachedZSortedEles = function( forceRecalc ){\n var lastNodes = this.lastZOrderCachedNodes;\n var lastEdges = this.lastZOrderCachedEdges;\n var nodes = this.getCachedNodes();\n var edges = this.getCachedEdges();\n var eles = [];\n\n if( forceRecalc || !lastNodes || !lastEdges || lastNodes !== nodes || lastEdges !== edges ){\n //console.time('cachezorder')\n\n for( var i = 0; i < nodes.length; i++ ){\n var n = nodes[i];\n\n if( n.animated() || (n.visible() && !n.transparent()) ){\n eles.push( n );\n }\n }\n\n for( var i = 0; i < edges.length; i++ ){\n var e = edges[i];\n\n if( e.animated() || (e.visible() && !e.transparent()) ){\n eles.push( e );\n }\n }\n\n eles.sort( zIndexSort );\n this.cachedZSortedEles = eles;\n //console.log('make cache')\n\n //console.timeEnd('cachezorder')\n } else {\n eles = this.cachedZSortedEles;\n //console.log('read cache')\n }\n\n this.lastZOrderCachedNodes = nodes;\n this.lastZOrderCachedEdges = edges;\n\n return eles;\n};\n\nfunction pushBezierPts(edge, pts){\n var qbezierAt = function( p1, p2, p3, t ){ return math.qbezierAt(p1, p2, p3, t); };\n var _p = edge._private;\n var bpts = _p.rstyle.bezierPts;\n\n bpts.push({\n x: qbezierAt( pts[0], pts[2], pts[4], 0.05 ),\n y: qbezierAt( pts[1], pts[3], pts[5], 0.05 )\n });\n\n bpts.push({\n x: qbezierAt( pts[0], pts[2], pts[4], 0.25 ),\n y: qbezierAt( pts[1], pts[3], pts[5], 0.25 )\n });\n\n bpts.push({\n x: qbezierAt( pts[0], pts[2], pts[4], 0.4 ),\n y: qbezierAt( pts[1], pts[3], pts[5], 0.4 )\n });\n\n bpts.push({\n x: qbezierAt( pts[0], pts[2], pts[4], 0.5 ),\n y: qbezierAt( pts[1], pts[3], pts[5], 0.5 )\n });\n\n bpts.push({\n x: qbezierAt( pts[0], pts[2], pts[4], 0.6 ),\n y: qbezierAt( pts[1], pts[3], pts[5], 0.6 )\n });\n\n bpts.push({\n x: qbezierAt( pts[0], pts[2], pts[4], 0.75 ),\n y: qbezierAt( pts[1], pts[3], pts[5], 0.75 )\n });\n\n bpts.push({\n x: qbezierAt( pts[0], pts[2], pts[4], 0.95 ),\n y: qbezierAt( pts[1], pts[3], pts[5], 0.95 )\n });\n}\n\nBRp.projectLines = function( edge ){\n var _p = edge._private;\n var rs = _p.rscratch;\n var et = rs.edgeType;\n\n if( et === 'multibezier' || et === 'bezier' || et === 'self' || et === 'compound' ){\n var bpts = _p.rstyle.bezierPts = []; // jshint ignore:line\n\n for( var i = 0; i + 5 < rs.allpts.length; i += 4 ){\n pushBezierPts( edge, rs.allpts.slice(i, i+6) );\n }\n } else if( et === 'segments' ){\n var lpts = _p.rstyle.linePts = [];\n\n for( var i = 0; i + 1 < rs.allpts.length; i += 2 ){\n lpts.push({\n x: rs.allpts[i],\n y: rs.allpts[i+1]\n });\n }\n } else if( et === 'haystack' ){\n var hpts = rs.haystackPts;\n\n _p.rstyle.haystackPts = [\n { x: hpts[0], y: hpts[1] },\n { x: hpts[2], y: hpts[3] }\n ];\n }\n};\n\nBRp.projectBezier = BRp.projectLines;\n\nBRp.recalculateNodeLabelProjection = function( node ){\n var content = node._private.style['label'].strValue;\n if( !content || content.match(/^\\s+$/) ){ return; }\n\n var textX, textY;\n var nodeWidth = node.outerWidth();\n var nodeHeight = node.outerHeight();\n var nodePos = node._private.position;\n var textHalign = node._private.style['text-halign'].strValue;\n var textValign = node._private.style['text-valign'].strValue;\n var rs = node._private.rscratch;\n var rstyle = node._private.rstyle;\n\n switch( textHalign ){\n case 'left':\n textX = nodePos.x - nodeWidth / 2;\n break;\n\n case 'right':\n textX = nodePos.x + nodeWidth / 2;\n break;\n\n default: // e.g. center\n textX = nodePos.x;\n }\n\n switch( textValign ){\n case 'top':\n textY = nodePos.y - nodeHeight / 2;\n break;\n\n case 'bottom':\n textY = nodePos.y + nodeHeight / 2;\n break;\n\n default: // e.g. middle\n textY = nodePos.y;\n }\n\n rs.labelX = textX;\n rs.labelY = textY;\n rstyle.labelX = textX;\n rstyle.labelY = textY;\n\n this.applyLabelDimensions( node );\n};\n\nBRp.recalculateEdgeLabelProjection = function( edge ){\n var content = edge._private.style['label'].strValue;\n if( !content || content.match(/^\\s+$/) ){ return; }\n\n var textX, textY;\n var _p = edge._private;\n var rs = _p.rscratch;\n //var style = _p.style;\n var rstyle = _p.rstyle;\n\n textX = rs.midX;\n textY = rs.midY;\n\n // add center point to style so bounding box calculations can use it\n rs.labelX = textX;\n rs.labelY = textY;\n rstyle.labelX = textX;\n rstyle.labelY = textY;\n\n this.applyLabelDimensions( edge );\n};\n\nBRp.applyLabelDimensions = function( ele ){\n var rs = ele._private.rscratch;\n var rstyle = ele._private.rstyle;\n\n var text = this.getLabelText( ele );\n var labelDims = this.calculateLabelDimensions( ele, text );\n\n rstyle.labelWidth = labelDims.width;\n rs.labelWidth = labelDims.width;\n\n rstyle.labelHeight = labelDims.height;\n rs.labelHeight = labelDims.height;\n};\n\nBRp.getLabelText = function( ele ){\n var style = ele._private.style;\n var text = ele._private.style['label'].strValue;\n var textTransform = style['text-transform'].value;\n var rscratch = ele._private.rscratch;\n\n if (textTransform == 'none') {\n } else if (textTransform == 'uppercase') {\n text = text.toUpperCase();\n } else if (textTransform == 'lowercase') {\n text = text.toLowerCase();\n }\n\n if( style['text-wrap'].value === 'wrap' ){\n //console.log('wrap');\n\n // save recalc if the label is the same as before\n if( rscratch.labelWrapKey === rscratch.labelKey ){\n // console.log('wrap cache hit');\n return rscratch.labelWrapCachedText;\n }\n // console.log('wrap cache miss');\n\n var lines = text.split('\\n');\n var maxW = style['text-max-width'].pfValue;\n var wrappedLines = [];\n\n for( var l = 0; l < lines.length; l++ ){\n var line = lines[l];\n var lineDims = this.calculateLabelDimensions( ele, line, 'line=' + line );\n var lineW = lineDims.width;\n\n if( lineW > maxW ){ // line is too long\n var words = line.split(/\\s+/); // NB: assume collapsed whitespace into single space\n var subline = '';\n\n for( var w = 0; w < words.length; w++ ){\n var word = words[w];\n var testLine = subline.length === 0 ? word : subline + ' ' + word;\n var testDims = this.calculateLabelDimensions( ele, testLine, 'testLine=' + testLine );\n var testW = testDims.width;\n\n if( testW <= maxW ){ // word fits on current line\n subline += word + ' ';\n } else { // word starts new line\n wrappedLines.push( subline );\n subline = word + ' ';\n }\n }\n\n // if there's remaining text, put it in a wrapped line\n if( !subline.match(/^\\s+$/) ){\n wrappedLines.push( subline );\n }\n } else { // line is already short enough\n wrappedLines.push( line );\n }\n } // for\n\n rscratch.labelWrapCachedLines = wrappedLines;\n rscratch.labelWrapCachedText = text = wrappedLines.join('\\n');\n rscratch.labelWrapKey = rscratch.labelKey;\n\n // console.log(text)\n } // if wrap\n\n return text;\n};\n\nBRp.calculateLabelDimensions = function( ele, text, extraKey ){\n var r = this;\n var style = ele._private.style;\n var fStyle = style['font-style'].strValue;\n var size = style['font-size'].pfValue + 'px';\n var family = style['font-family'].strValue;\n // var variant = style['font-variant'].strValue;\n var weight = style['font-weight'].strValue;\n\n var cacheKey = ele._private.labelKey;\n\n if( extraKey ){\n cacheKey += '$@$' + extraKey;\n }\n\n var cache = r.labelDimCache || (r.labelDimCache = {});\n\n if( cache[cacheKey] ){\n return cache[cacheKey];\n }\n\n var div = this.labelCalcDiv;\n\n if( !div ){\n div = this.labelCalcDiv = document.createElement('div');\n document.body.appendChild( div );\n }\n\n var ds = div.style;\n\n // from ele style\n ds.fontFamily = family;\n ds.fontStyle = fStyle;\n ds.fontSize = size;\n // ds.fontVariant = variant;\n ds.fontWeight = weight;\n\n // forced style\n ds.position = 'absolute';\n ds.left = '-9999px';\n ds.top = '-9999px';\n ds.zIndex = '-1';\n ds.visibility = 'hidden';\n ds.pointerEvents = 'none';\n ds.padding = '0';\n ds.lineHeight = '1';\n\n if( style['text-wrap'].value === 'wrap' ){\n ds.whiteSpace = 'pre'; // so newlines are taken into account\n } else {\n ds.whiteSpace = 'normal';\n }\n\n // put label content in div\n div.textContent = text;\n\n cache[cacheKey] = {\n width: div.clientWidth,\n height: div.clientHeight\n };\n\n return cache[cacheKey];\n};\n\nBRp.recalculateRenderedStyle = function( eles ){\n var edges = [];\n var nodes = [];\n var handledEdge = {};\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var _p = ele._private;\n var style = _p.style;\n var rs = _p.rscratch;\n var rstyle = _p.rstyle;\n var id = _p.data.id;\n var bbStyleSame = rs.boundingBoxKey != null && _p.boundingBoxKey === rs.boundingBoxKey;\n var labelStyleSame = rs.labelKey != null && _p.labelKey === rs.labelKey;\n var styleSame = bbStyleSame && labelStyleSame;\n\n if( _p.group === 'nodes' ){\n var pos = _p.position;\n var posSame = rstyle.nodeX != null && rstyle.nodeY != null && pos.x === rstyle.nodeX && pos.y === rstyle.nodeY;\n var wSame = rstyle.nodeW != null && rstyle.nodeW === style['width'].pfValue;\n var hSame = rstyle.nodeH != null && rstyle.nodeH === style['height'].pfValue;\n\n if( !posSame || !styleSame || !wSame || !hSame ){\n nodes.push( ele );\n }\n\n rstyle.nodeX = pos.x;\n rstyle.nodeY = pos.y;\n rstyle.nodeW = style['width'].pfValue;\n rstyle.nodeH = style['height'].pfValue;\n } else { // edges\n\n var srcPos = _p.source._private.position;\n var tgtPos = _p.target._private.position;\n var srcSame = rstyle.srcX != null && rstyle.srcY != null && srcPos.x === rstyle.srcX && srcPos.y === rstyle.srcY;\n var tgtSame = rstyle.tgtX != null && rstyle.tgtY != null && tgtPos.x === rstyle.tgtX && tgtPos.y === rstyle.tgtY;\n var positionsSame = srcSame && tgtSame;\n\n if( !positionsSame || !styleSame ){\n if( rs.edgeType === 'bezier' || rs.edgeType === 'straight' || rs.edgeType === 'self' || rs.edgeType === 'compound' ){\n if( !handledEdge[ id ] ){\n edges.push( ele );\n handledEdge[ id ] = true;\n\n var parallelEdges = ele.parallelEdges();\n for( var i = 0; i < parallelEdges.length; i++ ){\n var pEdge = parallelEdges[i];\n var pId = pEdge._private.data.id;\n\n if( !handledEdge[ pId ] ){\n edges.push( pEdge );\n handledEdge[ pId ] = true;\n }\n\n }\n }\n } else {\n edges.push( ele );\n }\n } // if positions diff\n\n // update rstyle positions\n rstyle.srcX = srcPos.x;\n rstyle.srcY = srcPos.y;\n rstyle.tgtX = tgtPos.x;\n rstyle.tgtY = tgtPos.y;\n\n } // if edges\n\n rs.boundingBoxKey = _p.boundingBoxKey;\n rs.labelKey = _p.labelKey;\n }\n\n this.recalculateEdgeProjections( edges );\n this.recalculateLabelProjections( nodes, edges );\n};\n\nBRp.recalculateLabelProjections = function( nodes, edges ){\n for( var i = 0; i < nodes.length; i++ ){\n this.recalculateNodeLabelProjection( nodes[i] );\n }\n\n for( var i = 0; i < edges.length; i++ ){\n this.recalculateEdgeLabelProjection( edges[i] );\n }\n};\n\nBRp.recalculateEdgeProjections = function( edges ){\n this.findEdgeControlPoints( edges );\n};\n\n\n// Find edge control points\nBRp.findEdgeControlPoints = function(edges) {\n if( !edges || edges.length === 0 ){ return; }\n\n var r = this;\n var cy = r.cy;\n var hasCompounds = cy.hasCompoundNodes();\n var hashTable = {};\n var pairIds = [];\n var haystackEdges = [];\n var autorotateEdges = [];\n\n // create a table of edge (src, tgt) => list of edges between them\n var pairId;\n for (var i = 0; i < edges.length; i++){\n var edge = edges[i];\n var _p = edge._private;\n var data = _p.data;\n var style = _p.style;\n var curveStyle = style['curve-style'].value;\n var edgeIsUnbundled = curveStyle === 'unbundled-bezier' || curveStyle === 'segments';\n\n // ignore edges who are not to be displayed\n // they shouldn't take up space\n if( style.display.value === 'none' ){\n continue;\n }\n\n if( style['edge-text-rotation'].strValue === 'autorotate' ){\n autorotateEdges.push( edge );\n }\n\n if( curveStyle === 'haystack' ){\n haystackEdges.push( edge );\n continue;\n }\n\n var srcId = data.source;\n var tgtId = data.target;\n\n pairId = srcId > tgtId ?\n tgtId + '$-$' + srcId :\n srcId + '$-$' + tgtId ;\n\n if( edgeIsUnbundled ){\n pairId = 'unbundled' + '$-$' + data.id;\n }\n\n if( hashTable[pairId] == null ){\n hashTable[pairId] = [];\n pairIds.push( pairId );\n }\n\n hashTable[pairId].push( edge );\n\n if( edgeIsUnbundled ){\n hashTable[pairId].hasUnbundled = true;\n }\n }\n\n var src, tgt, src_p, tgt_p, srcPos, tgtPos, srcW, srcH, tgtW, tgtH, srcShape, tgtShape;\n var vectorNormInverse;\n var badBezier;\n\n // for each pair (src, tgt), create the ctrl pts\n // Nested for loop is OK; total number of iterations for both loops = edgeCount\n for (var p = 0; p < pairIds.length; p++) {\n pairId = pairIds[p];\n var pairEdges = hashTable[pairId];\n\n // for each pair id, the edges should be sorted by index\n pairEdges.sort(function(edge1, edge2){\n return edge1._private.index - edge2._private.index;\n });\n\n src = pairEdges[0]._private.source;\n tgt = pairEdges[0]._private.target;\n\n src_p = src._private;\n tgt_p = tgt._private;\n\n // make sure src/tgt distinction is consistent\n // (src/tgt in this case are just for ctrlpts and don't actually have to be true src/tgt)\n if( src_p.data.id > tgt_p.data.id ){\n var temp = src;\n src = tgt;\n tgt = temp;\n }\n\n srcPos = src_p.position;\n tgtPos = tgt_p.position;\n\n srcW = src.outerWidth();\n srcH = src.outerHeight();\n\n tgtW = tgt.outerWidth();\n tgtH = tgt.outerHeight();\n\n srcShape = r.nodeShapes[ this.getNodeShape(src) ];\n tgtShape = r.nodeShapes[ this.getNodeShape(tgt) ];\n\n badBezier = false;\n\n\n if( (pairEdges.length > 1 && src !== tgt) || pairEdges.hasUnbundled ){\n\n // pt outside src shape to calc distance/displacement from src to tgt\n var srcOutside = srcShape.intersectLine(\n srcPos.x,\n srcPos.y,\n srcW,\n srcH,\n tgtPos.x,\n tgtPos.y,\n 0\n );\n\n // pt outside tgt shape to calc distance/displacement from src to tgt\n var tgtOutside = tgtShape.intersectLine(\n tgtPos.x,\n tgtPos.y,\n tgtW,\n tgtH,\n srcPos.x,\n srcPos.y,\n 0\n );\n\n var midptSrcPts = {\n x1: srcOutside[0],\n x2: tgtOutside[0],\n y1: srcOutside[1],\n y2: tgtOutside[1]\n };\n\n var dy = ( tgtOutside[1] - srcOutside[1] );\n var dx = ( tgtOutside[0] - srcOutside[0] );\n var l = Math.sqrt( dx*dx + dy*dy );\n\n var vector = {\n x: dx,\n y: dy\n };\n\n var vectorNorm = {\n x: vector.x/l,\n y: vector.y/l\n };\n vectorNormInverse = {\n x: -vectorNorm.y,\n y: vectorNorm.x\n };\n\n\n // if src intersection is inside tgt or tgt intersection is inside src, then no ctrl pts to draw\n if(\n tgtShape.checkPoint( srcOutside[0], srcOutside[1], 0, tgtW, tgtH, tgtPos.x, tgtPos.y ) ||\n srcShape.checkPoint( tgtOutside[0], tgtOutside[1], 0, srcW, srcH, srcPos.x, srcPos.y )\n ){\n vectorNormInverse = {};\n badBezier = true;\n }\n\n }\n\n var edge;\n var edge_p;\n var rs;\n\n for (var i = 0; i < pairEdges.length; i++) {\n edge = pairEdges[i];\n edge_p = edge._private;\n rs = edge_p.rscratch;\n\n var edgeIndex1 = rs.lastEdgeIndex;\n var edgeIndex2 = i;\n\n var numEdges1 = rs.lastNumEdges;\n var numEdges2 = pairEdges.length;\n\n var eStyle = edge_p.style;\n var style = eStyle;\n var curveStyle = eStyle['curve-style'].value;\n var ctrlptDists = eStyle['control-point-distances'];\n var ctrlptWs = eStyle['control-point-weights'];\n var bezierN = ctrlptDists && ctrlptWs ? Math.min( ctrlptDists.value.length, ctrlptWs.value.length ) : 1;\n var stepSize = eStyle['control-point-step-size'].pfValue;\n var ctrlptDist = ctrlptDists !== undefined ? ctrlptDists.pfValue[0] : undefined;\n var ctrlptWeight = ctrlptWs.value[0];\n var edgeIsUnbundled = curveStyle === 'unbundled-bezier' || curveStyle === 'segments';\n\n var swappedDirection = edge_p.source !== src;\n\n if( swappedDirection && edgeIsUnbundled ){\n ctrlptDist *= -1;\n }\n\n var srcX1 = rs.lastSrcCtlPtX;\n var srcX2 = srcPos.x;\n var srcY1 = rs.lastSrcCtlPtY;\n var srcY2 = srcPos.y;\n var srcW1 = rs.lastSrcCtlPtW;\n var srcW2 = src.outerWidth();\n var srcH1 = rs.lastSrcCtlPtH;\n var srcH2 = src.outerHeight();\n\n var tgtX1 = rs.lastTgtCtlPtX;\n var tgtX2 = tgtPos.x;\n var tgtY1 = rs.lastTgtCtlPtY;\n var tgtY2 = tgtPos.y;\n var tgtW1 = rs.lastTgtCtlPtW;\n var tgtW2 = tgt.outerWidth();\n var tgtH1 = rs.lastTgtCtlPtH;\n var tgtH2 = tgt.outerHeight();\n\n var width1 = rs.lastW;\n var width2 = eStyle['control-point-step-size'].pfValue;\n\n if( badBezier ){\n rs.badBezier = true;\n } else {\n rs.badBezier = false;\n }\n\n if( srcX1 === srcX2 && srcY1 === srcY2 && srcW1 === srcW2 && srcH1 === srcH2\n && tgtX1 === tgtX2 && tgtY1 === tgtY2 && tgtW1 === tgtW2 && tgtH1 === tgtH2\n && width1 === width2\n && ((edgeIndex1 === edgeIndex2 && numEdges1 === numEdges2) || edgeIsUnbundled) ){\n // console.log('edge ctrl pt cache HIT')\n continue; // then the control points haven't changed and we can skip calculating them\n } else {\n rs.lastSrcCtlPtX = srcX2;\n rs.lastSrcCtlPtY = srcY2;\n rs.lastSrcCtlPtW = srcW2;\n rs.lastSrcCtlPtH = srcH2;\n rs.lastTgtCtlPtX = tgtX2;\n rs.lastTgtCtlPtY = tgtY2;\n rs.lastTgtCtlPtW = tgtW2;\n rs.lastTgtCtlPtH = tgtH2;\n rs.lastEdgeIndex = edgeIndex2;\n rs.lastNumEdges = numEdges2;\n rs.lastWidth = width2;\n // console.log('edge ctrl pt cache MISS')\n }\n\n if( src === tgt ){\n // Self-edge\n\n rs.edgeType = 'self';\n\n var j = i;\n var loopDist = stepSize;\n\n if( edgeIsUnbundled ){\n j = 0;\n loopDist = ctrlptDist;\n }\n\n rs.ctrlpts = [\n srcPos.x,\n srcPos.y - (1 + Math.pow(srcH, 1.12) / 100) * loopDist * (j / 3 + 1),\n\n srcPos.x - (1 + Math.pow(srcW, 1.12) / 100) * loopDist * (j / 3 + 1),\n srcPos.y\n ];\n\n } else if(\n hasCompounds &&\n ( src.isParent() || src.isChild() || tgt.isParent() || tgt.isChild() ) &&\n ( src.parents().anySame(tgt) || tgt.parents().anySame(src) )\n ){\n // Compound edge\n\n rs.edgeType = 'compound';\n\n // because the line approximation doesn't apply for compound beziers\n // (loop/self edges are already elided b/c of cheap src==tgt check)\n rs.badBezier = false;\n\n var j = i;\n var loopDist = stepSize;\n\n if( edgeIsUnbundled ){\n j = 0;\n loopDist = ctrlptDist;\n }\n\n var loopW = 50;\n\n var loopaPos = {\n x: srcPos.x - srcW/2,\n y: srcPos.y - srcH/2\n };\n\n var loopbPos = {\n x: tgtPos.x - tgtW/2,\n y: tgtPos.y - tgtH/2\n };\n\n var loopPos = {\n x: Math.min( loopaPos.x, loopbPos.x ),\n y: Math.min( loopaPos.y, loopbPos.y )\n };\n\n // avoids cases with impossible beziers\n var minCompoundStretch = 0.5;\n var compoundStretchA = Math.max( minCompoundStretch, Math.log(srcW * 0.01) );\n var compoundStretchB = Math.max( minCompoundStretch, Math.log(tgtW * 0.01) );\n\n rs.ctrlpts = [\n loopPos.x,\n loopPos.y - (1 + Math.pow(loopW, 1.12) / 100) * loopDist * (j / 3 + 1) * compoundStretchA,\n\n loopPos.x - (1 + Math.pow(loopW, 1.12) / 100) * loopDist * (j / 3 + 1) * compoundStretchB,\n loopPos.y\n ];\n\n } else if( curveStyle === 'segments' ){\n // Segments (multiple straight lines)\n\n rs.edgeType = 'segments';\n rs.segpts = [];\n\n var segmentWs = eStyle['segment-weights'].pfValue;\n var segmentDs = eStyle['segment-distances'].pfValue;\n var segmentsN = Math.min( segmentWs.length, segmentDs.length );\n\n for( var s = 0; s < segmentsN; s++ ){\n var w = segmentWs[s];\n var d = segmentDs[s];\n\n // d = swappedDirection ? -d : d;\n //\n // d = Math.abs(d);\n\n // var w1 = !swappedDirection ? (1 - w) : w;\n // var w2 = !swappedDirection ? w : (1 - w);\n\n var w1 = (1 - w);\n var w2 = w;\n\n var adjustedMidpt = {\n x: midptSrcPts.x1 * w1 + midptSrcPts.x2 * w2,\n y: midptSrcPts.y1 * w1 + midptSrcPts.y2 * w2\n };\n\n rs.segpts.push(\n adjustedMidpt.x + vectorNormInverse.x * d,\n adjustedMidpt.y + vectorNormInverse.y * d\n );\n }\n\n // Straight edge\n } else if (\n pairEdges.length % 2 === 1\n && i === Math.floor(pairEdges.length / 2)\n && !edgeIsUnbundled\n ){\n\n rs.edgeType = 'straight';\n\n } else {\n // (Multi)bezier\n\n var multi = edgeIsUnbundled;\n\n rs.edgeType = multi ? 'multibezier' : 'bezier';\n rs.ctrlpts = [];\n\n for( var b = 0; b < bezierN; b++ ){\n var normctrlptDist = (0.5 - pairEdges.length / 2 + i) * stepSize;\n var manctrlptDist;\n var sign = math.signum( normctrlptDist );\n\n if( multi ){\n ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[b] : stepSize; // fall back on step size\n ctrlptWeight = ctrlptWs.value[b];\n }\n\n if( edgeIsUnbundled ){ // multi or single unbundled\n manctrlptDist = ctrlptDist;\n } else {\n manctrlptDist = ctrlptDist !== undefined ? sign * ctrlptDist : undefined;\n }\n\n var distanceFromMidpoint = manctrlptDist !== undefined ? manctrlptDist : normctrlptDist;\n\n var w1 = !swappedDirection || edgeIsUnbundled ? (1 - ctrlptWeight) : ctrlptWeight;\n var w2 = !swappedDirection || edgeIsUnbundled ? ctrlptWeight : (1 - ctrlptWeight);\n\n var adjustedMidpt = {\n x: midptSrcPts.x1 * w1 + midptSrcPts.x2 * w2,\n y: midptSrcPts.y1 * w1 + midptSrcPts.y2 * w2\n };\n\n rs.ctrlpts.push(\n adjustedMidpt.x + vectorNormInverse.x * distanceFromMidpoint,\n adjustedMidpt.y + vectorNormInverse.y * distanceFromMidpoint\n );\n }\n\n }\n\n // find endpts for edge\n this.findEndpoints( edge );\n\n var badStart = !is.number( rs.startX ) || !is.number( rs.startY );\n var badAStart = !is.number( rs.arrowStartX ) || !is.number( rs.arrowStartY );\n var badEnd = !is.number( rs.endX ) || !is.number( rs.endY );\n var badAEnd = !is.number( rs.arrowEndX ) || !is.number( rs.arrowEndY );\n\n var minCpADistFactor = 3;\n var arrowW = this.getArrowWidth( eStyle['width'].pfValue ) * this.arrowShapeHeight;\n var minCpADist = minCpADistFactor * arrowW;\n\n if( rs.edgeType === 'bezier' ){\n var startACpDist = math.distance( { x: rs.ctrlpts[0], y: rs.ctrlpts[1] }, { x: rs.startX, y: rs.startY } );\n var closeStartACp = startACpDist < minCpADist;\n var endACpDist = math.distance( { x: rs.ctrlpts[0], y: rs.ctrlpts[1] }, { x: rs.endX, y: rs.endY } );\n var closeEndACp = endACpDist < minCpADist;\n\n var overlapping = false;\n\n if( badStart || badAStart || closeStartACp ){\n overlapping = true;\n\n // project control point along line from src centre to outside the src shape\n // (otherwise intersection will yield nothing)\n var cpD = { // delta\n x: rs.ctrlpts[0] - srcPos.x,\n y: rs.ctrlpts[1] - srcPos.y\n };\n var cpL = Math.sqrt( cpD.x*cpD.x + cpD.y*cpD.y ); // length of line\n var cpM = { // normalised delta\n x: cpD.x / cpL,\n y: cpD.y / cpL\n };\n var radius = Math.max(srcW, srcH);\n var cpProj = { // *2 radius guarantees outside shape\n x: rs.ctrlpts[0] + cpM.x * 2 * radius,\n y: rs.ctrlpts[1] + cpM.y * 2 * radius\n };\n\n var srcCtrlPtIntn = srcShape.intersectLine(\n srcPos.x,\n srcPos.y,\n srcW,\n srcH,\n cpProj.x,\n cpProj.y,\n 0\n );\n\n if( closeStartACp ){\n rs.ctrlpts[0] = rs.ctrlpts[0] + cpM.x * (minCpADist - startACpDist);\n rs.ctrlpts[1] = rs.ctrlpts[1] + cpM.y * (minCpADist - startACpDist);\n } else {\n rs.ctrlpts[0] = srcCtrlPtIntn[0] + cpM.x * minCpADist;\n rs.ctrlpts[1] = srcCtrlPtIntn[1] + cpM.y * minCpADist;\n }\n }\n\n if( badEnd || badAEnd || closeEndACp ){\n overlapping = true;\n\n // project control point along line from tgt centre to outside the tgt shape\n // (otherwise intersection will yield nothing)\n var cpD = { // delta\n x: rs.ctrlpts[0] - tgtPos.x,\n y: rs.ctrlpts[1] - tgtPos.y\n };\n var cpL = Math.sqrt( cpD.x*cpD.x + cpD.y*cpD.y ); // length of line\n var cpM = { // normalised delta\n x: cpD.x / cpL,\n y: cpD.y / cpL\n };\n var radius = Math.max(srcW, srcH);\n var cpProj = { // *2 radius guarantees outside shape\n x: rs.ctrlpts[0] + cpM.x * 2 * radius,\n y: rs.ctrlpts[1] + cpM.y * 2 * radius\n };\n\n var tgtCtrlPtIntn = tgtShape.intersectLine(\n tgtPos.x,\n tgtPos.y,\n tgtW,\n tgtH,\n cpProj.x,\n cpProj.y,\n 0\n );\n\n if( closeEndACp ){\n rs.ctrlpts[0] = rs.ctrlpts[0] + cpM.x * (minCpADist - endACpDist);\n rs.ctrlpts[1] = rs.ctrlpts[1] + cpM.y * (minCpADist - endACpDist);\n } else {\n rs.ctrlpts[0] = tgtCtrlPtIntn[0] + cpM.x * minCpADist;\n rs.ctrlpts[1] = tgtCtrlPtIntn[1] + cpM.y * minCpADist;\n }\n\n }\n\n if( overlapping ){\n // recalc endpts\n this.findEndpoints( edge );\n }\n\n }\n\n if( rs.edgeType === 'multibezier' || rs.edgeType === 'bezier' || rs.edgeType === 'self' || rs.edgeType === 'compound' ){\n rs.allpts = [];\n\n rs.allpts.push( rs.startX, rs.startY );\n\n for( var b = 0; b+1 < rs.ctrlpts.length; b += 2 ){\n // ctrl pt itself\n rs.allpts.push( rs.ctrlpts[b], rs.ctrlpts[b+1] );\n\n // the midpt between ctrlpts as intermediate destination pts\n if( b + 3 < rs.ctrlpts.length ){\n rs.allpts.push( (rs.ctrlpts[b] + rs.ctrlpts[b+2])/2, (rs.ctrlpts[b+1] + rs.ctrlpts[b+3])/2 );\n }\n }\n\n rs.allpts.push( rs.endX, rs.endY );\n\n var m, mt;\n if( rs.edgeType === 'bezier' ){\n rs.midX = math.qbezierAt( rs.arrowStartX, rs.ctrlpts[0], rs.arrowEndX, 0.5 );\n rs.midY = math.qbezierAt( rs.arrowStartY, rs.ctrlpts[1], rs.arrowEndY, 0.5 );\n } else if( rs.ctrlpts.length/2 % 2 === 0 ){\n m = rs.allpts.length/2 - 1;\n\n rs.midX = rs.allpts[m];\n rs.midY = rs.allpts[m+1];\n } else {\n m = rs.allpts.length/2 - 3;\n mt = 0.5;\n\n rs.midX = math.qbezierAt( rs.allpts[m], rs.allpts[m+2], rs.allpts[m+4], mt );\n rs.midY = math.qbezierAt( rs.allpts[m+1], rs.allpts[m+3], rs.allpts[m+5], mt );\n }\n\n } else if( rs.edgeType === 'straight' ){\n // need to calc these after endpts\n rs.allpts = [ rs.startX, rs.startY, rs.endX, rs.endY ];\n\n // default midpt for labels etc\n rs.midX = ( rs.arrowStartX + rs.arrowEndX )/2;\n rs.midY = ( rs.arrowStartY + rs.arrowEndY )/2;\n\n } else if( rs.edgeType === 'segments' ){\n rs.allpts = [];\n rs.allpts.push( rs.startX, rs.startY );\n rs.allpts.push.apply( rs.allpts, rs.segpts );\n rs.allpts.push( rs.endX, rs.endY );\n\n if( rs.segpts.length % 4 === 0 ){\n var i2 = rs.segpts.length / 2;\n var i1 = i2 - 2;\n\n rs.midX = ( rs.segpts[i1] + rs.segpts[i2] ) / 2;\n rs.midY = ( rs.segpts[i1+1] + rs.segpts[i2+1] ) / 2;\n } else {\n var i1 = rs.segpts.length / 2 - 1;\n\n rs.midX = rs.segpts[i1];\n rs.midY = rs.segpts[i1+1];\n }\n\n\n }\n\n this.projectLines( edge );\n this.calculateArrowAngles( edge );\n this.recalculateEdgeLabelProjection( edge );\n\n }\n }\n\n for( var i = 0; i < haystackEdges.length; i++ ){\n var edge = haystackEdges[i];\n var _p = edge._private;\n var style = _p.style;\n var rscratch = _p.rscratch;\n var rs = rscratch;\n\n if( !rscratch.haystack ){\n var angle = Math.random() * 2 * Math.PI;\n\n rscratch.source = {\n x: Math.cos(angle),\n y: Math.sin(angle)\n };\n\n var angle = Math.random() * 2 * Math.PI;\n\n rscratch.target = {\n x: Math.cos(angle),\n y: Math.sin(angle)\n };\n\n }\n\n var src = _p.source;\n var tgt = _p.target;\n var srcPos = src._private.position;\n var tgtPos = tgt._private.position;\n var srcW = src.width();\n var tgtW = tgt.width();\n var srcH = src.height();\n var tgtH = tgt.height();\n var radius = style['haystack-radius'].value;\n var halfRadius = radius/2; // b/c have to half width/height\n\n rs.haystackPts = rs.allpts = [\n rs.source.x * srcW * halfRadius + srcPos.x,\n rs.source.y * srcH * halfRadius + srcPos.y,\n rs.target.x * tgtW * halfRadius + tgtPos.x,\n rs.target.y * tgtH * halfRadius + tgtPos.y\n ];\n\n rs.midX = (rs.allpts[0] + rs.allpts[2])/2;\n rs.midY = (rs.allpts[1] + rs.allpts[3])/2;\n\n // always override as haystack in case set to different type previously\n rscratch.edgeType = 'haystack';\n rscratch.haystack = true;\n\n this.projectLines( edge );\n this.calculateArrowAngles( edge );\n this.recalculateEdgeLabelProjection( edge );\n }\n\n for( var i = 0 ; i < autorotateEdges.length; i++ ){\n var edge = autorotateEdges[i];\n var rs = edge._private.rscratch;\n\n rs.labelAngle = Math.atan( rs.midDispY / rs.midDispX );\n }\n\n return hashTable;\n};\n\nvar getAngleFromDisp = function( dispX, dispY ){\n return Math.atan2( dispY, dispX ) - Math.PI/2;\n};\n\nBRp.calculateArrowAngles = function( edge ){\n var rs = edge._private.rscratch;\n var isHaystack = rs.edgeType === 'haystack';\n var isMultibezier = rs.edgeType === 'multibezier';\n var isSegments = rs.edgeType === 'segments';\n var isCompound = rs.edgeType === 'compound';\n var isSelf = rs.edgeType === 'self';\n\n // Displacement gives direction for arrowhead orientation\n var dispX, dispY;\n var startX, startY, endX, endY;\n\n var srcPos = edge.source().position();\n var tgtPos = edge.target().position();\n\n if( isHaystack ){\n startX = rs.haystackPts[0];\n startY = rs.haystackPts[1];\n endX = rs.haystackPts[2];\n endY = rs.haystackPts[3];\n } else {\n startX = rs.arrowStartX;\n startY = rs.arrowStartY;\n endX = rs.arrowEndX;\n endY = rs.arrowEndY;\n }\n\n // source\n //\n\n dispX = srcPos.x - startX;\n dispY = srcPos.y - startY;\n\n rs.srcArrowAngle = getAngleFromDisp( dispX, dispY );\n\n // mid target\n //\n\n var midX = rs.midX;\n var midY = rs.midY;\n\n if( isHaystack ){\n midX = ( startX + endX )/2;\n midY = ( startY + endY )/2;\n }\n\n dispX = endX - startX;\n dispY = endY - startY;\n\n if( isSelf ){\n dispX = -1;\n dispY = 1;\n } else if( isSegments ){\n var pts = rs.allpts;\n\n if( pts.length / 2 % 2 === 0 ){\n var i2 = pts.length / 2;\n var i1 = i2 - 2;\n\n dispX = ( pts[i2] - pts[i1] );\n dispY = ( pts[i2+1] - pts[i1+1] );\n } else {\n var i2 = pts.length / 2 - 1;\n var i1 = i2 - 2;\n var i3 = i2 + 2;\n\n dispX = ( pts[i2] - pts[i1] );\n dispY = ( pts[i2+1] - pts[i1+1] );\n }\n } else if( isMultibezier || isCompound ){\n var pts = rs.allpts;\n var cpts = rs.ctrlpts;\n var bp0x, bp0y;\n var bp1x, bp1y;\n\n if( cpts.length / 2 % 2 === 0 ){\n var p0 = pts.length / 2 - 1; // startpt\n var ic = p0 + 2;\n var p1 = ic + 2;\n\n bp0x = math.qbezierAt( pts[p0], pts[ic], pts[p1], 0.0 );\n bp0y = math.qbezierAt( pts[p0+1], pts[ic+1], pts[p1+1], 0.0 );\n\n bp1x = math.qbezierAt( pts[p0], pts[ic], pts[p1], 0.0001 );\n bp1y = math.qbezierAt( pts[p0+1], pts[ic+1], pts[p1+1], 0.0001 );\n } else {\n var ic = pts.length / 2 - 1; // ctrpt\n var p0 = ic - 2; // startpt\n var p1 = ic + 2; // endpt\n\n bp0x = math.qbezierAt( pts[p0], pts[ic], pts[p1], 0.4999 );\n bp0y = math.qbezierAt( pts[p0+1], pts[ic+1], pts[p1+1], 0.4999 );\n\n bp1x = math.qbezierAt( pts[p0], pts[ic], pts[p1], 0.5 );\n bp1y = math.qbezierAt( pts[p0+1], pts[ic+1], pts[p1+1], 0.5 );\n }\n\n dispX = ( bp1x - bp0x );\n dispY = ( bp1y - bp0y );\n }\n\n rs.midtgtArrowAngle = getAngleFromDisp( dispX, dispY );\n\n rs.midDispX = dispX;\n rs.midDispY = dispY;\n\n // mid source\n //\n\n dispX *= -1;\n dispY *= -1;\n\n if( isSegments ){\n var pts = rs.allpts;\n\n if( pts.length / 2 % 2 === 0 ){\n // already ok\n } else {\n var i2 = pts.length / 2 - 1;\n var i3 = i2 + 2;\n\n dispX = -( pts[i3] - pts[i2] );\n dispY = -( pts[i3+1] - pts[i2+1] );\n }\n }\n\n rs.midsrcArrowAngle = getAngleFromDisp( dispX, dispY );\n\n // target\n //\n\n dispX = tgtPos.x - endX;\n dispY = tgtPos.y - endY;\n\n rs.tgtArrowAngle = getAngleFromDisp( dispX, dispY );\n};\n\n\nBRp.findEndpoints = function( edge ){\n var r = this;\n var intersect;\n\n var source = edge.source()[0];\n var target = edge.target()[0];\n\n var src_p = source._private;\n var tgt_p = target._private;\n\n var srcPos = src_p.position;\n var tgtPos = tgt_p.position;\n\n var tgtArShape = edge._private.style['target-arrow-shape'].value;\n var srcArShape = edge._private.style['source-arrow-shape'].value;\n\n var rs = edge._private.rscratch;\n\n var et = rs.edgeType;\n var bezier = et === 'bezier' || et === 'multibezier' || et === 'self' || et === 'compound';\n var multi = et !== 'bezier';\n var lines = et === 'straight' || et === 'segments';\n var segments = et === 'segments';\n\n var p1, p2;\n\n if( bezier ){\n var cpStart = [ rs.ctrlpts[0], rs.ctrlpts[1] ];\n var cpEnd = multi ? [ rs.ctrlpts[rs.ctrlpts.length - 2], rs.ctrlpts[rs.ctrlpts.length - 1] ] : cpStart;\n\n p1 = cpEnd;\n p2 = cpStart;\n } else if( lines ){\n var srcArrowFromPt = !segments ? [ tgtPos.x, tgtPos.y ] : rs.segpts.slice( 0, 2 );\n var tgtArrowFromPt = !segments ? [ srcPos.x, srcPos.y ] : rs.segpts.slice( rs.segpts.length - 2 );\n\n p1 = tgtArrowFromPt;\n p2 = srcArrowFromPt;\n }\n\n intersect = r.nodeShapes[this.getNodeShape(target)].intersectLine(\n tgtPos.x,\n tgtPos.y,\n target.outerWidth(),\n target.outerHeight(),\n p1[0],\n p1[1],\n 0\n );\n\n var arrowEnd = math.shortenIntersection(intersect, p1,\n r.arrowShapes[tgtArShape].spacing(edge));\n var edgeEnd = math.shortenIntersection(intersect, p1,\n r.arrowShapes[tgtArShape].gap(edge));\n\n rs.endX = edgeEnd[0];\n rs.endY = edgeEnd[1];\n\n rs.arrowEndX = arrowEnd[0];\n rs.arrowEndY = arrowEnd[1];\n\n intersect = r.nodeShapes[this.getNodeShape(source)].intersectLine(\n srcPos.x,\n srcPos.y,\n source.outerWidth(),\n source.outerHeight(),\n p2[0],\n p2[1],\n 0\n );\n\n var arrowStart = math.shortenIntersection(\n intersect, p2,\n r.arrowShapes[srcArShape].spacing(edge)\n );\n var edgeStart = math.shortenIntersection(\n intersect, p2,\n r.arrowShapes[srcArShape].gap(edge)\n );\n\n rs.startX = edgeStart[0];\n rs.startY = edgeStart[1];\n\n rs.arrowStartX = arrowStart[0];\n rs.arrowStartY = arrowStart[1];\n\n if( lines ){\n if( !is.number(rs.startX) || !is.number(rs.startY) || !is.number(rs.endX) || !is.number(rs.endY) ){\n rs.badLine = true;\n } else {\n rs.badLine = false;\n }\n }\n};\n\nBRp.getArrowWidth = BRp.getArrowHeight = function(edgeWidth) {\n var cache = this.arrowWidthCache = this.arrowWidthCache || {};\n\n var cachedVal = cache[edgeWidth];\n if( cachedVal ){\n return cachedVal;\n }\n\n cachedVal = Math.max(Math.pow(edgeWidth * 13.37, 0.9), 29);\n cache[edgeWidth] = cachedVal;\n\n return cachedVal;\n};\n\nmodule.exports = BRp;\n","'use strict';\n\nvar BRp = {};\n\nBRp.getCachedImage = function(url, onLoad) {\n var r = this;\n var imageCache = r.imageCache = r.imageCache || {};\n\n if( imageCache[url] && imageCache[url].image ){\n return imageCache[url].image;\n }\n\n var cache = imageCache[url] = imageCache[url] || {};\n\n var image = cache.image = new Image();\n image.addEventListener('load', onLoad);\n image.src = url;\n\n return image;\n};\n\nmodule.exports = BRp;\n","'use strict';\n\nvar is = require('../../../is');\nvar util = require('../../../util');\n\nvar BaseRenderer = function(){};\nvar BR = BaseRenderer;\nvar BRp = BR.prototype;\n\nBRp.clientFunctions = [ 'redrawHint', 'render', 'renderTo', 'matchCanvasSize', 'nodeShapeImpl', 'arrowShapeImpl' ];\n\nBRp.init = function( options ){\n var r = this;\n\n r.options = options;\n\n r.cy = options.cy;\n\n r.container = options.cy.container();\n\n r.selection = [undefined, undefined, undefined, undefined, 0]; // Coordinates for selection box, plus enabled flag\n\n //--Pointer-related data\n r.hoverData = {down: null, last: null,\n downTime: null, triggerMode: null,\n dragging: false,\n initialPan: [null, null], capture: false};\n\n r.dragData = {possibleDragElements: []};\n\n r.touchData = {\n start: null, capture: false,\n\n // These 3 fields related to tap, taphold events\n startPosition: [null, null, null, null, null, null],\n singleTouchStartTime: null,\n singleTouchMoved: true,\n\n now: [null, null, null, null, null, null],\n earlier: [null, null, null, null, null, null]\n };\n\n r.redraws = 0;\n r.showFps = options.showFps;\n\n r.hideEdgesOnViewport = options.hideEdgesOnViewport;\n r.hideLabelsOnViewport = options.hideLabelsOnViewport;\n r.textureOnViewport = options.textureOnViewport;\n r.wheelSensitivity = options.wheelSensitivity;\n r.motionBlurEnabled = options.motionBlur; // on by default\n r.forcedPixelRatio = options.pixelRatio;\n r.motionBlur = true; // for initial kick off\n r.motionBlurOpacity = options.motionBlurOpacity;\n r.motionBlurTransparency = 1 - r.motionBlurOpacity;\n r.motionBlurPxRatio = 1;\n r.mbPxRBlurry = 1; //0.8;\n r.minMbLowQualFrames = 4;\n r.fullQualityMb = false;\n r.clearedForMotionBlur = [];\n r.desktopTapThreshold = options.desktopTapThreshold;\n r.desktopTapThreshold2 = options.desktopTapThreshold * options.desktopTapThreshold;\n r.touchTapThreshold = options.touchTapThreshold;\n r.touchTapThreshold2 = options.touchTapThreshold * options.touchTapThreshold;\n r.tapholdDuration = 500;\n\n r.bindings = [];\n\n r.registerNodeShapes();\n r.registerArrowShapes();\n r.load();\n};\n\nBRp.notify = function(params) {\n var types;\n var r = this;\n\n if( is.array( params.type ) ){\n types = params.type;\n\n } else {\n types = [ params.type ];\n }\n\n for( var i = 0; i < types.length; i++ ){\n var type = types[i];\n\n switch( type ){\n case 'destroy':\n r.destroy();\n return;\n\n case 'add':\n case 'remove':\n case 'load':\n r.updateElementsCache();\n break;\n\n case 'viewport':\n r.redrawHint('select', true);\n break;\n\n case 'style':\n r.updateCachedZSortedEles();\n break;\n }\n\n if( type === 'load' || type === 'resize' ){\n r.invalidateContainerClientCoordsCache();\n r.matchCanvasSize(r.container);\n }\n } // for\n\n r.redrawHint('eles', true);\n r.redrawHint('drag', true);\n\n this.startRenderLoop();\n\n this.redraw();\n};\n\nBRp.destroy = function(){\n this.destroyed = true;\n\n this.cy.stopAnimationLoop();\n\n for( var i = 0; i < this.bindings.length; i++ ){\n var binding = this.bindings[i];\n var b = binding;\n\n b.target.removeEventListener(b.event, b.handler, b.useCapture);\n }\n\n if( this.removeObserver ){\n this.removeObserver.disconnect();\n }\n\n if( this.labelCalcDiv ){\n try{\n document.body.removeChild(this.labelCalcDiv);\n } catch(e){\n // ie10 issue #1014\n }\n }\n};\n\n[\n require('./arrow-shapes'),\n require('./cached-eles'),\n require('./coord-ele-math'),\n require('./images'),\n require('./load-listeners'),\n require('./node-shapes'),\n require('./redraw')\n].forEach(function( props ){\n util.extend( BRp, props );\n});\n\nmodule.exports = BR;\n","'use strict';\n\nvar is = require('../../../is');\nvar util = require('../../../util');\nvar Event = require('../../../event');\nvar Collection = require('../../../collection');\n\nvar BRp = {};\n\nBRp.registerBinding = function(target, event, handler, useCapture){\n this.bindings.push({\n target: target,\n event: event,\n handler: handler,\n useCapture: useCapture\n });\n\n target.addEventListener(event, handler, useCapture);\n};\n\nBRp.nodeIsDraggable = function(node) {\n if (node._private.style['opacity'].value !== 0\n && node._private.style['visibility'].value == 'visible'\n && node._private.style['display'].value == 'element'\n && !node.locked()\n && node.grabbable() ) {\n\n return true;\n }\n\n return false;\n};\n\nBRp.load = function() {\n var r = this;\n\n var triggerEvents = function( target, names, e, props ){\n if( target == null ){\n target = r.cy;\n }\n\n for( var i = 0; i < names.length; i++ ){\n var name = names[i];\n\n var event = Event( e, util.extend({ type: name }, props) );\n target.trigger( event );\n }\n };\n\n var isMultSelKeyDown = function( e ){\n return e.shiftKey || e.metaKey || e.ctrlKey; // maybe e.altKey\n };\n\n var getDragListIds = function(opts){\n var listHasId;\n\n if( opts.addToList && r.cy.hasCompoundNodes() ){ // only needed for compound graphs\n if( !opts.addToList.hasId ){ // build ids lookup if doesn't already exist\n opts.addToList.hasId = {};\n\n for( var i = 0; i < opts.addToList.length; i++ ){\n var ele = opts.addToList[i];\n\n opts.addToList.hasId[ ele.id() ] = true;\n }\n }\n\n listHasId = opts.addToList.hasId;\n }\n\n return listHasId || {};\n };\n\n // helper function to determine which child nodes and inner edges\n // of a compound node to be dragged as well as the grabbed and selected nodes\n var addDescendantsToDrag = function(node, opts){\n if( !node._private.cy.hasCompoundNodes() ){\n return;\n }\n\n if( opts.inDragLayer == null && opts.addToList == null ){ return; } // nothing to do\n\n var listHasId = getDragListIds( opts );\n\n var innerNodes = node.descendants();\n\n for( var i = 0; i < innerNodes.size(); i++ ){\n var iNode = innerNodes[i];\n var _p = iNode._private;\n\n if( opts.inDragLayer ){\n _p.rscratch.inDragLayer = true;\n }\n\n if( opts.addToList && !listHasId[ iNode.id() ] ){\n opts.addToList.push( iNode );\n listHasId[ iNode.id() ] = true;\n\n _p.grabbed = true;\n }\n\n var edges = _p.edges;\n for( var j = 0; opts.inDragLayer && j < edges.length; j++ ){\n edges[j]._private.rscratch.inDragLayer = true;\n }\n }\n };\n\n // adds the given nodes, and its edges to the drag layer\n var addNodeToDrag = function(node, opts){\n\n var _p = node._private;\n var listHasId = getDragListIds( opts );\n\n if( opts.inDragLayer ){\n _p.rscratch.inDragLayer = true;\n }\n\n if( opts.addToList && !listHasId[ node.id() ] ){\n opts.addToList.push( node );\n listHasId[ node.id() ] = true;\n\n _p.grabbed = true;\n }\n\n var edges = _p.edges;\n for( var i = 0; opts.inDragLayer && i < edges.length; i++ ){\n edges[i]._private.rscratch.inDragLayer = true;\n }\n\n addDescendantsToDrag( node, opts ); // always add to drag\n\n // also add nodes and edges related to the topmost ancestor\n updateAncestorsInDragLayer( node, {\n inDragLayer: opts.inDragLayer\n } );\n };\n\n var freeDraggedElements = function( draggedElements ){\n if( !draggedElements ){ return; }\n\n for (var i=0; i < draggedElements.length; i++) {\n\n var dEi_p = draggedElements[i]._private;\n\n if(dEi_p.group === 'nodes') {\n dEi_p.rscratch.inDragLayer = false;\n dEi_p.grabbed = false;\n\n var sEdges = dEi_p.edges;\n for( var j = 0; j < sEdges.length; j++ ){ sEdges[j]._private.rscratch.inDragLayer = false; }\n\n // for compound nodes, also remove related nodes and edges from the drag layer\n updateAncestorsInDragLayer(draggedElements[i], { inDragLayer: false });\n\n } else if( dEi_p.group === 'edges' ){\n dEi_p.rscratch.inDragLayer = false;\n }\n\n }\n };\n\n // helper function to determine which ancestor nodes and edges should go\n // to the drag layer (or should be removed from drag layer).\n var updateAncestorsInDragLayer = function(node, opts) {\n\n if( opts.inDragLayer == null && opts.addToList == null ){ return; } // nothing to do\n\n // find top-level parent\n var parent = node;\n\n if( !node._private.cy.hasCompoundNodes() ){\n return;\n }\n\n while( parent.parent().nonempty() ){\n parent = parent.parent()[0];\n }\n\n // no parent node: no nodes to add to the drag layer\n if( parent == node ){\n return;\n }\n\n var nodes = parent.descendants()\n .merge( parent )\n .unmerge( node )\n .unmerge( node.descendants() )\n ;\n\n var edges = nodes.connectedEdges();\n\n var listHasId = getDragListIds( opts );\n\n for( var i = 0; i < nodes.size(); i++ ){\n if( opts.inDragLayer !== undefined ){\n nodes[i]._private.rscratch.inDragLayer = opts.inDragLayer;\n }\n\n if( opts.addToList && !listHasId[ nodes[i].id() ] ){\n opts.addToList.push( nodes[i] );\n listHasId[ nodes[i].id() ] = true;\n\n nodes[i]._private.grabbed = true;\n }\n }\n\n for( var j = 0; opts.inDragLayer !== undefined && j < edges.length; j++ ) {\n edges[j]._private.rscratch.inDragLayer = opts.inDragLayer;\n }\n };\n\n if( typeof MutationObserver !== 'undefined' ){\n r.removeObserver = new MutationObserver(function( mutns ){\n for( var i = 0; i < mutns.length; i++ ){\n var mutn = mutns[i];\n var rNodes = mutn.removedNodes;\n\n if( rNodes ){ for( var j = 0; j < rNodes.length; j++ ){\n var rNode = rNodes[j];\n\n if( rNode === r.container ){\n r.destroy();\n break;\n }\n } }\n }\n });\n\n if( r.container.parentNode ){\n r.removeObserver.observe( r.container.parentNode, { childList: true } );\n }\n } else {\n r.registerBinding(r.container, 'DOMNodeRemoved', function(e){\n r.destroy();\n });\n }\n\n\n\n // auto resize\n r.registerBinding(window, 'resize', util.debounce( function(e) {\n r.invalidateContainerClientCoordsCache();\n\n r.matchCanvasSize(r.container);\n r.redrawHint('eles', true);\n r.redraw();\n }, 100 ) );\n\n var invalCtnrBBOnScroll = function(domEle){\n r.registerBinding(domEle, 'scroll', function(e){\n r.invalidateContainerClientCoordsCache();\n } );\n };\n\n var bbCtnr = r.cy.container();\n\n for( ;; ){\n\n invalCtnrBBOnScroll( bbCtnr );\n\n if( bbCtnr.parentNode ){\n bbCtnr = bbCtnr.parentNode;\n } else {\n break;\n }\n\n }\n\n // stop right click menu from appearing on cy\n r.registerBinding(r.container, 'contextmenu', function(e){\n e.preventDefault();\n });\n\n var inBoxSelection = function(){\n return r.selection[4] !== 0;\n };\n\n // Primary key\n r.registerBinding(r.container, 'mousedown', function(e) {\n e.preventDefault();\n r.hoverData.capture = true;\n r.hoverData.which = e.which;\n\n var cy = r.cy;\n var pos = r.projectIntoViewport(e.clientX, e.clientY);\n var select = r.selection;\n var near = r.findNearestElement(pos[0], pos[1], true, false);\n var draggedElements = r.dragData.possibleDragElements;\n\n r.hoverData.mdownPos = pos;\n\n var checkForTaphold = function(){\n r.hoverData.tapholdCancelled = false;\n\n clearTimeout( r.hoverData.tapholdTimeout );\n\n r.hoverData.tapholdTimeout = setTimeout(function(){\n\n if( r.hoverData.tapholdCancelled ){\n return;\n } else {\n var ele = r.hoverData.down;\n\n if( ele ){\n ele.trigger( Event(e, {\n type: 'taphold',\n cyPosition: { x: pos[0], y: pos[1] }\n }) );\n } else {\n cy.trigger( Event(e, {\n type: 'taphold',\n cyPosition: { x: pos[0], y: pos[1] }\n }) );\n }\n }\n\n }, r.tapholdDuration);\n };\n\n // Right click button\n if( e.which == 3 ){\n\n r.hoverData.cxtStarted = true;\n\n var cxtEvt = Event(e, {\n type: 'cxttapstart',\n cyPosition: { x: pos[0], y: pos[1] }\n });\n\n if( near ){\n near.activate();\n near.trigger( cxtEvt );\n\n r.hoverData.down = near;\n } else {\n cy.trigger( cxtEvt );\n }\n\n r.hoverData.downTime = (new Date()).getTime();\n r.hoverData.cxtDragged = false;\n\n // Primary button\n } else if (e.which == 1) {\n\n if( near ){\n near.activate();\n }\n\n // Element dragging\n {\n // If something is under the cursor and it is draggable, prepare to grab it\n if (near != null) {\n\n if( r.nodeIsDraggable(near) ){\n\n var grabEvent = Event(e, {\n type: 'grab',\n cyPosition: { x: pos[0], y: pos[1] }\n });\n\n if ( near.isNode() && !near.selected() ){\n\n draggedElements = r.dragData.possibleDragElements = [];\n addNodeToDrag( near, { addToList: draggedElements } );\n\n near.trigger(grabEvent);\n\n } else if ( near.isNode() && near.selected() ){\n draggedElements = r.dragData.possibleDragElements = [ ];\n\n var selectedNodes = cy.$(function(){ return this.isNode() && this.selected(); });\n\n for( var i = 0; i < selectedNodes.length; i++ ){\n\n // Only add this selected node to drag if it is draggable, eg. has nonzero opacity\n if( r.nodeIsDraggable( selectedNodes[i] ) ){\n addNodeToDrag( selectedNodes[i], { addToList: draggedElements } );\n }\n }\n\n near.trigger( grabEvent );\n }\n\n r.redrawHint('eles', true);\n r.redrawHint('drag', true);\n\n }\n\n }\n\n r.hoverData.down = near;\n r.hoverData.downTime = (new Date()).getTime();\n }\n\n triggerEvents( near, ['mousedown', 'tapstart', 'vmousedown'], e, {\n cyPosition: { x: pos[0], y: pos[1] }\n } );\n\n if ( near == null ) {\n select[4] = 1;\n\n r.data.bgActivePosistion = {\n x: pos[0],\n y: pos[1]\n };\n\n r.redrawHint('select', true);\n\n r.redraw();\n } else if( near.isEdge() ){\n select[4] = 1; // for future pan\n }\n\n checkForTaphold();\n\n }\n\n // Initialize selection box coordinates\n select[0] = select[2] = pos[0];\n select[1] = select[3] = pos[1];\n\n }, false);\n\n r.registerBinding(window, 'mousemove', function(e) {\n var preventDefault = false;\n var capture = r.hoverData.capture;\n\n // save cycles if mouse events aren't to be captured\n if ( !capture ){\n var containerPageCoords = r.findContainerClientCoords();\n\n if (e.clientX > containerPageCoords[0] && e.clientX < containerPageCoords[0] + r.canvasWidth\n && e.clientY > containerPageCoords[1] && e.clientY < containerPageCoords[1] + r.canvasHeight\n ) {\n // inside container bounds so OK\n } else {\n return;\n }\n\n var cyContainer = r.container;\n var target = e.target;\n var tParent = target.parentNode;\n var containerIsTarget = false;\n\n while( tParent ){\n if( tParent === cyContainer ){\n containerIsTarget = true;\n break;\n }\n\n tParent = tParent.parentNode;\n }\n\n if( !containerIsTarget ){ return; } // if target is outisde cy container, then this event is not for us\n }\n\n var cy = r.cy;\n var zoom = cy.zoom();\n var pos = r.projectIntoViewport(e.clientX, e.clientY);\n var select = r.selection;\n\n var near = null;\n if( !r.hoverData.draggingEles ){\n near = r.findNearestElement(pos[0], pos[1], true, false);\n }\n var last = r.hoverData.last;\n var down = r.hoverData.down;\n\n var disp = [pos[0] - select[2], pos[1] - select[3]];\n\n var draggedElements = r.dragData.possibleDragElements;\n\n var dx = select[2] - select[0];\n var dx2 = dx * dx;\n var dy = select[3] - select[1];\n var dy2 = dy * dy;\n var dist2 = dx2 + dy2;\n var rdist2 = dist2 * zoom * zoom;\n\n var multSelKeyDown = isMultSelKeyDown( e );\n\n r.hoverData.tapholdCancelled = true;\n\n var updateDragDelta = function(){\n var dragDelta = r.hoverData.dragDelta = r.hoverData.dragDelta || [];\n\n if( dragDelta.length === 0 ){\n dragDelta.push( disp[0] );\n dragDelta.push( disp[1] );\n } else {\n dragDelta[0] += disp[0];\n dragDelta[1] += disp[1];\n }\n };\n\n\n preventDefault = true;\n\n triggerEvents( near, ['mousemove', 'vmousemove', 'tapdrag'], e, {\n cyPosition: { x: pos[0], y: pos[1] }\n } );\n\n // trigger context drag if rmouse down\n if( r.hoverData.which === 3 ){\n var cxtEvt = Event(e, {\n type: 'cxtdrag',\n cyPosition: { x: pos[0], y: pos[1] }\n });\n\n if( down ){\n down.trigger( cxtEvt );\n } else {\n cy.trigger( cxtEvt );\n }\n\n r.hoverData.cxtDragged = true;\n\n if( !r.hoverData.cxtOver || near !== r.hoverData.cxtOver ){\n\n if( r.hoverData.cxtOver ){\n r.hoverData.cxtOver.trigger( Event(e, {\n type: 'cxtdragout',\n cyPosition: { x: pos[0], y: pos[1] }\n }) );\n }\n\n r.hoverData.cxtOver = near;\n\n if( near ){\n near.trigger( Event(e, {\n type: 'cxtdragover',\n cyPosition: { x: pos[0], y: pos[1] }\n }) );\n }\n\n }\n\n // Check if we are drag panning the entire graph\n } else if (r.hoverData.dragging) {\n preventDefault = true;\n\n if( cy.panningEnabled() && cy.userPanningEnabled() ){\n var deltaP;\n\n if( r.hoverData.justStartedPan ){\n var mdPos = r.hoverData.mdownPos;\n\n deltaP = {\n x: ( pos[0] - mdPos[0] ) * zoom,\n y: ( pos[1] - mdPos[1] ) * zoom\n };\n\n r.hoverData.justStartedPan = false;\n\n } else {\n deltaP = {\n x: disp[0] * zoom,\n y: disp[1] * zoom\n };\n\n }\n\n cy.panBy( deltaP );\n\n r.hoverData.dragged = true;\n }\n\n // Needs reproject due to pan changing viewport\n pos = r.projectIntoViewport(e.clientX, e.clientY);\n\n // Checks primary button down & out of time & mouse not moved much\n } else if(\n select[4] == 1 && (down == null || down.isEdge())\n ){\n\n if( !r.hoverData.dragging && cy.boxSelectionEnabled() && ( multSelKeyDown || !cy.panningEnabled() || !cy.userPanningEnabled() ) ){\n r.data.bgActivePosistion = undefined;\n r.hoverData.selecting = true;\n\n r.redrawHint('select', true);\n r.redraw();\n\n } else if( !r.hoverData.selecting && cy.panningEnabled() && cy.userPanningEnabled() ){\n r.hoverData.dragging = true;\n r.hoverData.justStartedPan = true;\n select[4] = 0;\n\n r.data.bgActivePosistion = {\n x: pos[0],\n y: pos[1]\n };\n\n r.redrawHint('select', true);\n r.redraw();\n }\n\n if( down && down.isEdge() && down.active() ){ down.unactivate(); }\n\n } else {\n if( down && down.isEdge() && down.active() ){ down.unactivate(); }\n\n if (near != last) {\n\n if (last) {\n triggerEvents( last, ['mouseout', 'tapdragout'], e, {\n cyPosition: { x: pos[0], y: pos[1] }\n } );\n }\n\n if (near) {\n triggerEvents( near, ['mouseover', 'tapdragover'], e, {\n cyPosition: { x: pos[0], y: pos[1] }\n } );\n }\n\n r.hoverData.last = near;\n }\n\n if( down && down.isNode() && r.nodeIsDraggable(down) ){\n\n if( rdist2 >= r.desktopTapThreshold2 ){ // then drag\n\n var justStartedDrag = !r.dragData.didDrag;\n\n if( justStartedDrag ) {\n r.redrawHint('eles', true);\n }\n\n r.dragData.didDrag = true; // indicate that we actually did drag the node\n\n var toTrigger = [];\n\n for( var i = 0; i < draggedElements.length; i++ ){\n var dEle = draggedElements[i];\n\n // now, add the elements to the drag layer if not done already\n if( !r.hoverData.draggingEles ){\n addNodeToDrag( dEle, { inDragLayer: true } );\n }\n\n // Locked nodes not draggable, as well as non-visible nodes\n if( dEle.isNode() && r.nodeIsDraggable(dEle) && dEle.grabbed() ){\n var dPos = dEle._private.position;\n\n toTrigger.push( dEle );\n\n if( is.number(disp[0]) && is.number(disp[1]) ){\n var updatePos = !dEle.isParent();\n\n if( updatePos ){\n dPos.x += disp[0];\n dPos.y += disp[1];\n }\n\n if( justStartedDrag ){\n var dragDelta = r.hoverData.dragDelta;\n\n if( updatePos && is.number(dragDelta[0]) && is.number(dragDelta[1]) ){\n dPos.x += dragDelta[0];\n dPos.y += dragDelta[1];\n }\n }\n }\n\n }\n }\n\n r.hoverData.draggingEles = true;\n\n var tcol = (Collection(cy, toTrigger));\n\n tcol.updateCompoundBounds();\n tcol.trigger('position drag');\n\n r.redrawHint('drag', true);\n r.redraw();\n\n } else { // otherwise save drag delta for when we actually start dragging so the relative grab pos is constant\n updateDragDelta();\n }\n }\n\n // prevent the dragging from triggering text selection on the page\n preventDefault = true;\n }\n\n select[2] = pos[0]; select[3] = pos[1];\n\n if( preventDefault ){\n if(e.stopPropagation) e.stopPropagation();\n if(e.preventDefault) e.preventDefault();\n return false;\n }\n }, false);\n\n r.registerBinding(window, 'mouseup', function(e) {\n var capture = r.hoverData.capture;\n if (!capture) { return; }\n r.hoverData.capture = false;\n\n var cy = r.cy; var pos = r.projectIntoViewport(e.clientX, e.clientY); var select = r.selection;\n var near = r.findNearestElement(pos[0], pos[1], true, false);\n var draggedElements = r.dragData.possibleDragElements; var down = r.hoverData.down;\n var multSelKeyDown = isMultSelKeyDown( e );\n\n if( r.data.bgActivePosistion ){\n r.redrawHint('select', true);\n r.redraw();\n }\n\n r.hoverData.tapholdCancelled = true;\n\n r.data.bgActivePosistion = undefined; // not active bg now\n\n if( down ){\n down.unactivate();\n }\n\n if( r.hoverData.which === 3 ){\n var cxtEvt = Event(e, {\n type: 'cxttapend',\n cyPosition: { x: pos[0], y: pos[1] }\n });\n\n if( down ){\n down.trigger( cxtEvt );\n } else {\n cy.trigger( cxtEvt );\n }\n\n if( !r.hoverData.cxtDragged ){\n var cxtTap = Event(e, {\n type: 'cxttap',\n cyPosition: { x: pos[0], y: pos[1] }\n });\n\n if( down ){\n down.trigger( cxtTap );\n } else {\n cy.trigger( cxtTap );\n }\n }\n\n r.hoverData.cxtDragged = false;\n r.hoverData.which = null;\n\n } else if( r.hoverData.which === 1 ) {\n\n // Deselect all elements if nothing is currently under the mouse cursor and we aren't dragging something\n if ( (down == null) // not mousedown on node\n && !r.dragData.didDrag // didn't move the node around\n && !r.hoverData.selecting // not box selection\n && !r.hoverData.dragged // didn't pan\n && !isMultSelKeyDown( e )\n ) {\n\n cy.$(function(){\n return this.selected();\n }).unselect();\n\n if (draggedElements.length > 0) {\n r.redrawHint('eles', true);\n }\n\n r.dragData.possibleDragElements = draggedElements = [];\n }\n\n triggerEvents( near, ['mouseup', 'tapend', 'vmouseup'], e, {\n cyPosition: { x: pos[0], y: pos[1] }\n } );\n\n if(\n !r.dragData.didDrag // didn't move a node around\n && !r.hoverData.dragged // didn't pan\n ){\n triggerEvents( near, ['click', 'tap', 'vclick'], e, {\n cyPosition: { x: pos[0], y: pos[1] }\n } );\n }\n\n // Single selection\n if( near == down && !r.dragData.didDrag && !r.hoverData.selecting ){\n if( near != null && near._private.selectable ){\n\n if( r.hoverData.dragging ){\n // if panning, don't change selection state\n } else if( cy.selectionType() === 'additive' || multSelKeyDown ){\n if( near.selected() ){\n near.unselect();\n } else {\n near.select();\n }\n } else {\n if( !multSelKeyDown ){\n cy.$(':selected').unmerge( near ).unselect();\n near.select();\n }\n }\n\n r.redrawHint('eles', true);\n }\n }\n\n if ( r.hoverData.selecting ) {\n var newlySelected = [];\n var box = r.getAllInBox( select[0], select[1], select[2], select[3] );\n\n r.redrawHint('select', true);\n\n if( box.length > 0 ) {\n r.redrawHint('eles', true);\n }\n\n for( var i = 0; i < box.length; i++ ){\n if( box[i]._private.selectable ){\n newlySelected.push( box[i] );\n }\n }\n\n var newlySelCol = Collection( cy, newlySelected );\n\n if( cy.selectionType() === 'additive' ){\n newlySelCol.select();\n } else {\n if( !multSelKeyDown ){\n cy.$(':selected').unmerge( newlySelCol ).unselect();\n }\n\n newlySelCol.select();\n }\n\n // always need redraw in case eles unselectable\n r.redraw();\n\n }\n\n // Cancel drag pan\n if( r.hoverData.dragging ){\n r.hoverData.dragging = false;\n\n r.redrawHint('select', true);\n r.redrawHint('eles', true);\n\n r.redraw();\n }\n\n if (!select[4]) {\n\n\n r.redrawHint('drag', true);\n r.redrawHint('eles', true);\n\n freeDraggedElements( draggedElements );\n\n if( down ){ down.trigger('free'); }\n }\n\n } // else not right mouse\n\n select[4] = 0; r.hoverData.down = null;\n\n r.hoverData.cxtStarted = false;\n r.hoverData.draggingEles = false;\n r.hoverData.selecting = false;\n r.dragData.didDrag = false;\n r.hoverData.dragged = false;\n r.hoverData.dragDelta = [];\n\n }, false);\n\n var wheelHandler = function(e) {\n\n\n if( r.scrollingPage ){ return; } // while scrolling, ignore wheel-to-zoom\n\n var cy = r.cy;\n var pos = r.projectIntoViewport(e.clientX, e.clientY);\n var rpos = [pos[0] * cy.zoom() + cy.pan().x,\n pos[1] * cy.zoom() + cy.pan().y];\n\n if( r.hoverData.draggingEles || r.hoverData.dragging || r.hoverData.cxtStarted || inBoxSelection() ){ // if pan dragging or cxt dragging, wheel movements make no zoom\n e.preventDefault();\n return;\n }\n\n if( cy.panningEnabled() && cy.userPanningEnabled() && cy.zoomingEnabled() && cy.userZoomingEnabled() ){\n e.preventDefault();\n\n r.data.wheelZooming = true;\n clearTimeout( r.data.wheelTimeout );\n r.data.wheelTimeout = setTimeout(function(){\n r.data.wheelZooming = false;\n\n r.redrawHint('eles', true);\n r.redraw();\n }, 150);\n\n var diff = e.deltaY / -250 || e.wheelDeltaY / 1000 || e.wheelDelta / 1000;\n diff = diff * r.wheelSensitivity;\n\n var needsWheelFix = e.deltaMode === 1;\n if( needsWheelFix ){ // fixes slow wheel events on ff/linux and ff/windows\n diff *= 33;\n }\n\n cy.zoom({\n level: cy.zoom() * Math.pow(10, diff),\n renderedPosition: { x: rpos[0], y: rpos[1] }\n });\n }\n\n };\n\n // Functions to help with whether mouse wheel should trigger zooming\n // --\n r.registerBinding(r.container, 'wheel', wheelHandler, true);\n\n // disable nonstandard wheel events\n // r.registerBinding(r.container, 'mousewheel', wheelHandler, true);\n // r.registerBinding(r.container, 'DOMMouseScroll', wheelHandler, true);\n // r.registerBinding(r.container, 'MozMousePixelScroll', wheelHandler, true); // older firefox\n\n r.registerBinding(window, 'scroll', function(e){\n r.scrollingPage = true;\n\n clearTimeout( r.scrollingPageTimeout );\n r.scrollingPageTimeout = setTimeout(function(){\n r.scrollingPage = false;\n }, 250);\n }, true);\n\n // Functions to help with handling mouseout/mouseover on the Cytoscape container\n // Handle mouseout on Cytoscape container\n r.registerBinding(r.container, 'mouseout', function(e) {\n var pos = r.projectIntoViewport(e.clientX, e.clientY);\n\n r.cy.trigger(Event(e, {\n type: 'mouseout',\n cyPosition: { x: pos[0], y: pos[1] }\n }));\n }, false);\n\n r.registerBinding(r.container, 'mouseover', function(e) {\n var pos = r.projectIntoViewport(e.clientX, e.clientY);\n\n r.cy.trigger(Event(e, {\n type: 'mouseover',\n cyPosition: { x: pos[0], y: pos[1] }\n }));\n }, false);\n\n var f1x1, f1y1, f2x1, f2y1; // starting points for pinch-to-zoom\n var distance1, distance1Sq; // initial distance between finger 1 and finger 2 for pinch-to-zoom\n var center1, modelCenter1; // center point on start pinch to zoom\n var offsetLeft, offsetTop;\n var containerWidth, containerHeight;\n var twoFingersStartInside;\n\n var distance = function(x1, y1, x2, y2){\n return Math.sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) );\n };\n\n var distanceSq = function(x1, y1, x2, y2){\n return (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);\n };\n\n var touchstartHandler;\n r.registerBinding(r.container, 'touchstart', touchstartHandler = function(e) {\n r.touchData.capture = true;\n r.data.bgActivePosistion = undefined;\n\n var cy = r.cy;\n var nodes = r.getCachedNodes();\n var edges = r.getCachedEdges();\n var now = r.touchData.now;\n var earlier = r.touchData.earlier;\n\n if (e.touches[0]) { var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY); now[0] = pos[0]; now[1] = pos[1]; }\n if (e.touches[1]) { var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY); now[2] = pos[0]; now[3] = pos[1]; }\n if (e.touches[2]) { var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY); now[4] = pos[0]; now[5] = pos[1]; }\n\n\n // record starting points for pinch-to-zoom\n if( e.touches[1] ){\n\n // anything in the set of dragged eles should be released\n var release = function( eles ){\n for( var i = 0; i < eles.length; i++ ){\n eles[i]._private.grabbed = false;\n eles[i]._private.rscratch.inDragLayer = false;\n if( eles[i].active() ){ eles[i].unactivate(); }\n }\n };\n release(nodes);\n release(edges);\n\n var offsets = r.findContainerClientCoords();\n offsetLeft = offsets[0];\n offsetTop = offsets[1];\n containerWidth = offsets[2];\n containerHeight = offsets[3];\n\n f1x1 = e.touches[0].clientX - offsetLeft;\n f1y1 = e.touches[0].clientY - offsetTop;\n\n f2x1 = e.touches[1].clientX - offsetLeft;\n f2y1 = e.touches[1].clientY - offsetTop;\n\n twoFingersStartInside =\n 0 <= f1x1 && f1x1 <= containerWidth\n && 0 <= f2x1 && f2x1 <= containerWidth\n && 0 <= f1y1 && f1y1 <= containerHeight\n && 0 <= f2y1 && f2y1 <= containerHeight\n ;\n\n var pan = cy.pan();\n var zoom = cy.zoom();\n\n distance1 = distance( f1x1, f1y1, f2x1, f2y1 );\n distance1Sq = distanceSq( f1x1, f1y1, f2x1, f2y1 );\n center1 = [ (f1x1 + f2x1)/2, (f1y1 + f2y1)/2 ];\n modelCenter1 = [\n (center1[0] - pan.x) / zoom,\n (center1[1] - pan.y) / zoom\n ];\n\n // consider context tap\n var cxtDistThreshold = 200;\n var cxtDistThresholdSq = cxtDistThreshold * cxtDistThreshold;\n if( distance1Sq < cxtDistThresholdSq && !e.touches[2] ){\n\n var near1 = r.findNearestElement(now[0], now[1], true, true);\n var near2 = r.findNearestElement(now[2], now[3], true, true);\n\n if( near1 && near1.isNode() ){\n near1.activate().trigger( Event(e, {\n type: 'cxttapstart',\n cyPosition: { x: now[0], y: now[1] }\n }) );\n r.touchData.start = near1;\n\n } else if( near2 && near2.isNode() ){\n near2.activate().trigger( Event(e, {\n type: 'cxttapstart',\n cyPosition: { x: now[0], y: now[1] }\n }) );\n r.touchData.start = near2;\n\n } else {\n cy.trigger( Event(e, {\n type: 'cxttapstart',\n cyPosition: { x: now[0], y: now[1] }\n }) );\n r.touchData.start = null;\n }\n\n if( r.touchData.start ){ r.touchData.start._private.grabbed = false; }\n r.touchData.cxt = true;\n r.touchData.cxtDragged = false;\n r.data.bgActivePosistion = undefined;\n\n r.redraw();\n return;\n\n }\n\n }\n\n if (e.touches[2]) {\n\n } else if (e.touches[1]) {\n\n } else if (e.touches[0]) {\n var near = r.findNearestElement(now[0], now[1], true, true);\n\n if (near != null) {\n near.activate();\n\n r.touchData.start = near;\n\n if( near.isNode() && r.nodeIsDraggable(near) ){\n\n var draggedEles = r.dragData.touchDragEles = [];\n\n r.redrawHint('eles', true);\n r.redrawHint('drag', true);\n\n if( near.selected() ){\n // reset drag elements, since near will be added again\n\n var selectedNodes = cy.$(function(){\n return this.isNode() && this.selected();\n });\n\n for( var k = 0; k < selectedNodes.length; k++ ){\n var selectedNode = selectedNodes[k];\n\n if( r.nodeIsDraggable(selectedNode) ){\n addNodeToDrag( selectedNode, { addToList: draggedEles } );\n }\n }\n } else {\n addNodeToDrag( near, { addToList: draggedEles } );\n }\n\n near.trigger( Event(e, {\n type: 'grab',\n cyPosition: { x: now[0], y: now[1] }\n }) );\n }\n }\n\n triggerEvents( near, ['touchstart', 'tapstart', 'vmousedown'], e, {\n cyPosition: { x: now[0], y: now[1] }\n } );\n\n if (near == null) {\n r.data.bgActivePosistion = {\n x: pos[0],\n y: pos[1]\n };\n\n r.redrawHint('select', true);\n r.redraw();\n }\n\n\n // Tap, taphold\n // -----\n\n for (var i=0; i= factorThresholdSq || distance2Sq >= distThresholdSq ){\n r.touchData.cxt = false;\n if( r.touchData.start ){ r.touchData.start.unactivate(); r.touchData.start = null; }\n r.data.bgActivePosistion = undefined;\n r.redrawHint('select', true);\n\n var cxtEvt = Event(e, {\n type: 'cxttapend',\n cyPosition: { x: now[0], y: now[1] }\n });\n if( r.touchData.start ){\n r.touchData.start.trigger( cxtEvt );\n } else {\n cy.trigger( cxtEvt );\n }\n }\n\n }\n\n // context swipe\n if( capture && r.touchData.cxt ){\n var cxtEvt = Event(e, {\n type: 'cxtdrag',\n cyPosition: { x: now[0], y: now[1] }\n });\n r.data.bgActivePosistion = undefined;\n r.redrawHint('select', true);\n\n if( r.touchData.start ){\n r.touchData.start.trigger( cxtEvt );\n } else {\n cy.trigger( cxtEvt );\n }\n\n if( r.touchData.start ){ r.touchData.start._private.grabbed = false; }\n r.touchData.cxtDragged = true;\n\n var near = r.findNearestElement(now[0], now[1], true, true);\n\n if( !r.touchData.cxtOver || near !== r.touchData.cxtOver ){\n\n if( r.touchData.cxtOver ){\n r.touchData.cxtOver.trigger( Event(e, {\n type: 'cxtdragout',\n cyPosition: { x: now[0], y: now[1] }\n }) );\n }\n\n r.touchData.cxtOver = near;\n\n if( near ){\n near.trigger( Event(e, {\n type: 'cxtdragover',\n cyPosition: { x: now[0], y: now[1] }\n }) );\n\n }\n\n }\n\n // box selection\n } else if( capture && e.touches[2] && cy.boxSelectionEnabled() ){\n e.preventDefault();\n\n r.data.bgActivePosistion = undefined;\n\n this.lastThreeTouch = +new Date();\n r.touchData.selecting = true;\n\n r.redrawHint('select', true);\n\n if( !select || select.length === 0 || select[0] === undefined ){\n select[0] = (now[0] + now[2] + now[4])/3;\n select[1] = (now[1] + now[3] + now[5])/3;\n select[2] = (now[0] + now[2] + now[4])/3 + 1;\n select[3] = (now[1] + now[3] + now[5])/3 + 1;\n } else {\n select[2] = (now[0] + now[2] + now[4])/3;\n select[3] = (now[1] + now[3] + now[5])/3;\n }\n\n select[4] = 1;\n r.touchData.selecting = true;\n\n r.redraw();\n\n // pinch to zoom\n } else if ( capture && e.touches[1] && cy.zoomingEnabled() && cy.panningEnabled() && cy.userZoomingEnabled() && cy.userPanningEnabled() ) { // two fingers => pinch to zoom\n e.preventDefault();\n\n r.data.bgActivePosistion = undefined;\n r.redrawHint('select', true);\n\n var draggedEles = r.dragData.touchDragEles;\n if( draggedEles ){\n r.redrawHint('drag', true);\n\n for( var i = 0; i < draggedEles.length; i++ ){\n draggedEles[i]._private.grabbed = false;\n draggedEles[i]._private.rscratch.inDragLayer = false;\n }\n }\n\n // (x2, y2) for fingers 1 and 2\n var f1x2 = e.touches[0].clientX - offsetLeft, f1y2 = e.touches[0].clientY - offsetTop;\n var f2x2 = e.touches[1].clientX - offsetLeft, f2y2 = e.touches[1].clientY - offsetTop;\n\n\n var distance2 = distance( f1x2, f1y2, f2x2, f2y2 );\n // var distance2Sq = distanceSq( f1x2, f1y2, f2x2, f2y2 );\n // var factor = Math.sqrt( distance2Sq ) / Math.sqrt( distance1Sq );\n var factor = distance2 / distance1;\n\n if( factor != 1 && twoFingersStartInside){\n // delta finger1\n var df1x = f1x2 - f1x1;\n var df1y = f1y2 - f1y1;\n\n // delta finger 2\n var df2x = f2x2 - f2x1;\n var df2y = f2y2 - f2y1;\n\n // translation is the normalised vector of the two fingers movement\n // i.e. so pinching cancels out and moving together pans\n var tx = (df1x + df2x)/2;\n var ty = (df1y + df2y)/2;\n\n // adjust factor by the speed multiplier\n // var speed = 1.5;\n // if( factor > 1 ){\n // factor = (factor - 1) * speed + 1;\n // } else {\n // factor = 1 - (1 - factor) * speed;\n // }\n\n // now calculate the zoom\n var zoom1 = cy.zoom();\n var zoom2 = zoom1 * factor;\n var pan1 = cy.pan();\n\n // the model center point converted to the current rendered pos\n var ctrx = modelCenter1[0] * zoom1 + pan1.x;\n var ctry = modelCenter1[1] * zoom1 + pan1.y;\n\n var pan2 = {\n x: -zoom2/zoom1 * (ctrx - pan1.x - tx) + ctrx,\n y: -zoom2/zoom1 * (ctry - pan1.y - ty) + ctry\n };\n\n // remove dragged eles\n if( r.touchData.start ){\n var draggedEles = r.dragData.touchDragEles;\n\n if( draggedEles ){ for( var i = 0; i < draggedEles.length; i++ ){\n var dEi_p = draggedEles[i]._private;\n\n dEi_p.grabbed = false;\n dEi_p.rscratch.inDragLayer = false;\n } }\n\n var start_p = r.touchData.start._private;\n start_p.active = false;\n start_p.grabbed = false;\n start_p.rscratch.inDragLayer = false;\n\n r.redrawHint('drag', true);\n\n r.touchData.start\n .trigger('free')\n .trigger('unactivate')\n ;\n }\n\n cy.viewport({\n zoom: zoom2,\n pan: pan2,\n cancelOnFailedZoom: true\n });\n\n distance1 = distance2;\n f1x1 = f1x2;\n f1y1 = f1y2;\n f2x1 = f2x2;\n f2y1 = f2y2;\n\n r.pinching = true;\n }\n\n // Re-project\n if (e.touches[0]) { var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY); now[0] = pos[0]; now[1] = pos[1]; }\n if (e.touches[1]) { var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY); now[2] = pos[0]; now[3] = pos[1]; }\n if (e.touches[2]) { var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY); now[4] = pos[0]; now[5] = pos[1]; }\n\n } else if (e.touches[0]) {\n var start = r.touchData.start;\n var last = r.touchData.last;\n var near = near || r.findNearestElement(now[0], now[1], true, true);\n\n if( start != null ){\n e.preventDefault();\n }\n\n // dragging nodes\n if( start != null && start._private.group == 'nodes' && r.nodeIsDraggable(start) ){\n\n if( rdist2 >= r.touchTapThreshold2 ){ // then dragging can happen\n var draggedEles = r.dragData.touchDragEles;\n var justStartedDrag = !r.dragData.didDrag;\n\n for( var k = 0; k < draggedEles.length; k++ ){\n var draggedEle = draggedEles[k];\n\n if( justStartedDrag ){\n addNodeToDrag( draggedEle, { inDragLayer: true } );\n }\n\n if( r.nodeIsDraggable(draggedEle) && draggedEle.isNode() && draggedEle.grabbed() ){\n r.dragData.didDrag = true;\n var dPos = draggedEle._private.position;\n var updatePos = !draggedEle.isParent();\n\n if( updatePos && is.number(disp[0]) && is.number(disp[1]) ){\n dPos.x += disp[0];\n dPos.y += disp[1];\n }\n\n if( justStartedDrag ){\n r.redrawHint('eles', true);\n\n var dragDelta = r.touchData.dragDelta;\n\n if( updatePos && is.number(dragDelta[0]) && is.number(dragDelta[1]) ){\n dPos.x += dragDelta[0];\n dPos.y += dragDelta[1];\n }\n\n }\n }\n }\n\n var tcol = Collection(cy, draggedEles);\n\n tcol.updateCompoundBounds();\n tcol.trigger('position drag');\n\n r.hoverData.draggingEles = true;\n\n r.redrawHint('drag', true);\n\n if(\n r.touchData.startPosition[0] == earlier[0]\n && r.touchData.startPosition[1] == earlier[1]\n ){\n\n r.redrawHint('eles', true);\n }\n\n r.redraw();\n } else { // otherise keep track of drag delta for later\n var dragDelta = r.touchData.dragDelta = r.touchData.dragDelta || [];\n\n if( dragDelta.length === 0 ){\n dragDelta.push( disp[0] );\n dragDelta.push( disp[1] );\n } else {\n dragDelta[0] += disp[0];\n dragDelta[1] += disp[1];\n }\n }\n }\n\n // touchmove\n {\n triggerEvents( (start || near), ['touchmove', 'tapdrag', 'vmousemove'], e, {\n cyPosition: { x: now[0], y: now[1] }\n } );\n\n if (near != last) {\n if (last) { last.trigger(Event(e, { type: 'tapdragout', cyPosition: { x: now[0], y: now[1] } })); }\n if (near) { near.trigger(Event(e, { type: 'tapdragover', cyPosition: { x: now[0], y: now[1] } })); }\n }\n\n r.touchData.last = near;\n }\n\n // check to cancel taphold\n for (var i=0;i r.touchTapThreshold2 ){\n\n r.touchData.singleTouchMoved = true;\n }\n }\n\n // panning\n if(\n capture\n && ( start == null || start.isEdge() )\n && cy.panningEnabled() && cy.userPanningEnabled()\n ){\n\n e.preventDefault();\n\n if( r.swipePanning ){\n cy.panBy({\n x: disp[0] * zoom,\n y: disp[1] * zoom\n });\n\n } else if( rdist2 >= r.touchTapThreshold2 ){\n r.swipePanning = true;\n\n cy.panBy({\n x: dx * zoom,\n y: dy * zoom\n });\n\n if( start ){\n start.unactivate();\n\n if( !r.data.bgActivePosistion ){\n r.data.bgActivePosistion = {\n x: now[0],\n y: now[1]\n };\n }\n\n r.redrawHint('select', true);\n\n r.touchData.start = null;\n }\n }\n\n // Re-project\n var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);\n now[0] = pos[0]; now[1] = pos[1];\n }\n }\n\n for (var j=0; j 0 ) {\n r.redrawHint('eles', true);\n } else {\n r.redraw();\n }\n }\n\n var updateStartStyle = false;\n\n if( start != null ){\n start._private.active = false;\n updateStartStyle = true;\n start.unactivate();\n }\n\n if (e.touches[2]) {\n r.data.bgActivePosistion = undefined;\n r.redrawHint('select', true);\n } else if (e.touches[1]) {\n\n } else if (e.touches[0]) {\n\n // Last touch released\n } else if (!e.touches[0]) {\n\n r.data.bgActivePosistion = undefined;\n r.redrawHint('select', true);\n\n var draggedEles = r.dragData.touchDragEles;\n\n if (start != null ) {\n\n var startWasGrabbed = start._private.grabbed;\n\n freeDraggedElements( draggedEles );\n\n r.redrawHint('drag', true);\n r.redrawHint('eles', true);\n\n if( startWasGrabbed ){\n start.trigger('free');\n }\n\n triggerEvents( start, ['touchend', 'tapend', 'vmouseup'], e, {\n cyPosition: { x: now[0], y: now[1] }\n } );\n\n start.unactivate();\n\n r.touchData.start = null;\n\n } else {\n var near = r.findNearestElement(now[0], now[1], true, true);\n\n triggerEvents( near, ['touchend', 'tapend', 'vmouseup'], e, {\n cyPosition: { x: now[0], y: now[1] }\n } );\n\n }\n\n var dx = r.touchData.startPosition[0] - now[0];\n var dx2 = dx * dx;\n var dy = r.touchData.startPosition[1] - now[1];\n var dy2 = dy * dy;\n var dist2 = dx2 + dy2;\n var rdist2 = dist2 * zoom * zoom;\n\n // Prepare to select the currently touched node, only if it hasn't been dragged past a certain distance\n if (start != null\n && !r.dragData.didDrag // didn't drag nodes around\n && start._private.selectable\n && rdist2 < r.touchTapThreshold2\n && !r.pinching // pinch to zoom should not affect selection\n ) {\n\n if( cy.selectionType() === 'single' ){\n cy.$(':selected').unmerge( start ).unselect();\n start.select();\n } else {\n if( start.selected() ){\n start.unselect();\n } else {\n start.select();\n }\n }\n\n updateStartStyle = true;\n\n\n r.redrawHint('eles', true);\n }\n\n // Tap event, roughly same as mouse click event for touch\n if( !r.touchData.singleTouchMoved ){\n triggerEvents( start, ['tap', 'vclick'], e, {\n cyPosition: { x: now[0], y: now[1] }\n } );\n }\n\n r.touchData.singleTouchMoved = true;\n }\n\n for( var j = 0; j < now.length; j++ ){ earlier[j] = now[j]; }\n\n r.dragData.didDrag = false; // reset for next mousedown\n\n if( e.touches.length === 0 ){\n r.touchData.dragDelta = [];\n }\n\n if( updateStartStyle && start ){\n start.updateStyle(false);\n }\n\n if( e.touches.length < 2 ){\n r.pinching = false;\n r.redrawHint('eles', true);\n r.redraw();\n }\n\n //r.redraw();\n\n }, false);\n\n // fallback compatibility layer for ms pointer events\n if( typeof TouchEvent === 'undefined' ){\n\n var pointers = [];\n\n var makeTouch = function( e ){\n return {\n clientX: e.clientX,\n clientY: e.clientY,\n force: 1,\n identifier: e.pointerId,\n pageX: e.pageX,\n pageY: e.pageY,\n radiusX: e.width/2,\n radiusY: e.height/2,\n screenX: e.screenX,\n screenY: e.screenY,\n target: e.target\n };\n };\n\n var makePointer = function( e ){\n return {\n event: e,\n touch: makeTouch(e)\n };\n };\n\n var addPointer = function( e ){\n pointers.push( makePointer(e) );\n };\n\n var removePointer = function( e ){\n for( var i = 0; i < pointers.length; i++ ){\n var p = pointers[i];\n\n if( p.event.pointerId === e.pointerId ){\n pointers.splice( i, 1 );\n return;\n }\n }\n };\n\n var updatePointer = function( e ){\n var p = pointers.filter(function( p ){\n return p.event.pointerId === e.pointerId;\n })[0];\n\n p.event = e;\n p.touch = makeTouch(e);\n };\n\n var addTouchesToEvent = function( e ){\n e.touches = pointers.map(function( p ){\n return p.touch;\n });\n };\n\n var pointerIsMouse = function( e ){\n return e.pointerType === 'mouse' || e.pointerType === 4;\n };\n\n r.registerBinding(r.container, 'pointerdown', function(e){\n if( pointerIsMouse(e) ){ return; } // mouse already handled\n\n e.preventDefault();\n\n addPointer( e );\n\n addTouchesToEvent( e );\n touchstartHandler( e );\n });\n\n r.registerBinding(r.container, 'pointerup', function(e){\n if( pointerIsMouse(e) ){ return; } // mouse already handled\n\n removePointer( e );\n\n addTouchesToEvent( e );\n touchendHandler( e );\n });\n\n r.registerBinding(r.container, 'pointercancel', function(e){\n if( pointerIsMouse(e) ){ return; } // mouse already handled\n\n removePointer( e );\n\n addTouchesToEvent( e );\n touchcancelHandler( e );\n });\n\n r.registerBinding(r.container, 'pointermove', function(e){\n if( pointerIsMouse(e) ){ return; } // mouse already handled\n\n e.preventDefault();\n\n updatePointer( e );\n\n addTouchesToEvent( e );\n touchmoveHandler( e );\n });\n\n }\n};\n\nmodule.exports = BRp;\n","'use strict';\n\nvar math = require('../../../math');\n\nvar BRp = {};\n\nBRp.registerNodeShapes = function(){\n var nodeShapes = this.nodeShapes = {};\n var renderer = this;\n\n nodeShapes['ellipse'] = {\n name: 'ellipse',\n\n draw: function( context, centerX, centerY, width, height ){\n renderer.nodeShapeImpl( this.name )( context, centerX, centerY, width, height );\n },\n\n intersectLine: function( nodeX, nodeY, width, height, x, y, padding ){\n return math.intersectLineEllipse(\n x, y,\n nodeX,\n nodeY,\n width / 2 + padding,\n height / 2 + padding)\n ;\n },\n\n checkPoint: function( x, y, padding, width, height, centerX, centerY ){\n x -= centerX;\n y -= centerY;\n\n x /= (width / 2 + padding);\n y /= (height / 2 + padding);\n\n return x*x + y*y <= 1;\n }\n };\n\n function generatePolygon( name, points ){\n return ( nodeShapes[name] = {\n name: name,\n\n points: points,\n\n draw: function( context, centerX, centerY, width, height ){\n renderer.nodeShapeImpl('polygon')( context, centerX, centerY, width, height, this.points );\n },\n\n intersectLine: function( nodeX, nodeY, width, height, x, y, padding ){\n return math.polygonIntersectLine(\n x, y,\n this.points,\n nodeX,\n nodeY,\n width / 2, height / 2,\n padding)\n ;\n },\n\n checkPoint: function( x, y, padding, width, height, centerX, centerY ){\n return math.pointInsidePolygon(x, y, nodeShapes[name].points,\n centerX, centerY, width, height, [0, -1], padding)\n ;\n }\n } );\n }\n\n generatePolygon( 'triangle', math.generateUnitNgonPointsFitToSquare(3, 0) );\n\n generatePolygon( 'square', math.generateUnitNgonPointsFitToSquare(4, 0) );\n nodeShapes['rectangle'] = nodeShapes['square'];\n\n nodeShapes['roundrectangle'] = {\n name: 'roundrectangle',\n\n points: math.generateUnitNgonPointsFitToSquare(4, 0),\n\n draw: function( context, centerX, centerY, width, height ){\n renderer.nodeShapeImpl( this.name )( context, centerX, centerY, width, height );\n },\n\n intersectLine: function( nodeX, nodeY, width, height, x, y, padding ){\n return math.roundRectangleIntersectLine(\n x, y,\n nodeX,\n nodeY,\n width, height,\n padding)\n ;\n },\n\n // Looks like the width passed into this function is actually the total width / 2\n checkPoint: function(\n x, y, padding, width, height, centerX, centerY ){\n\n var cornerRadius = math.getRoundRectangleRadius(width, height);\n\n // Check hBox\n if (math.pointInsidePolygon(x, y, this.points,\n centerX, centerY, width, height - 2 * cornerRadius, [0, -1], padding) ){\n return true;\n }\n\n // Check vBox\n if (math.pointInsidePolygon(x, y, this.points,\n centerX, centerY, width - 2 * cornerRadius, height, [0, -1], padding) ){\n return true;\n }\n\n var checkInEllipse = function( x, y, centerX, centerY, width, height, padding ){\n x -= centerX;\n y -= centerY;\n\n x /= (width / 2 + padding);\n y /= (height / 2 + padding);\n\n return (x*x + y*y <= 1);\n };\n\n\n // Check top left quarter circle\n if (checkInEllipse(x, y,\n centerX - width / 2 + cornerRadius,\n centerY - height / 2 + cornerRadius,\n cornerRadius * 2, cornerRadius * 2, padding) ){\n\n return true;\n }\n\n // Check top right quarter circle\n if (checkInEllipse(x, y,\n centerX + width / 2 - cornerRadius,\n centerY - height / 2 + cornerRadius,\n cornerRadius * 2, cornerRadius * 2, padding) ){\n\n return true;\n }\n\n // Check bottom right quarter circle\n if (checkInEllipse(x, y,\n centerX + width / 2 - cornerRadius,\n centerY + height / 2 - cornerRadius,\n cornerRadius * 2, cornerRadius * 2, padding) ){\n\n return true;\n }\n\n // Check bottom left quarter circle\n if (checkInEllipse(x, y,\n centerX - width / 2 + cornerRadius,\n centerY + height / 2 - cornerRadius,\n cornerRadius * 2, cornerRadius * 2, padding) ){\n\n return true;\n }\n\n return false;\n }\n };\n\n generatePolygon( 'diamond', [\n 0, 1,\n 1, 0,\n 0, -1,\n -1, 0\n ] );\n\n generatePolygon( 'pentagon', math.generateUnitNgonPointsFitToSquare(5, 0) );\n\n generatePolygon( 'hexagon', math.generateUnitNgonPointsFitToSquare(6, 0) );\n\n generatePolygon( 'heptagon', math.generateUnitNgonPointsFitToSquare(7, 0) );\n\n generatePolygon( 'octagon', math.generateUnitNgonPointsFitToSquare(8, 0) );\n\n var star5Points = new Array(20);\n {\n var outerPoints = math.generateUnitNgonPoints(5, 0);\n var innerPoints = math.generateUnitNgonPoints(5, Math.PI / 5);\n\n // Outer radius is 1; inner radius of star is smaller\n var innerRadius = 0.5 * (3 - Math.sqrt(5));\n innerRadius *= 1.57;\n\n for (var i=0;i redrawLimit ? minRedrawLimit : redrawLimit;\n redrawLimit = redrawLimit < maxRedrawLimit ? redrawLimit : maxRedrawLimit;\n\n if( r.lastDrawTime === undefined ){ r.lastDrawTime = 0; }\n\n var nowTime = Date.now();\n var timeElapsed = nowTime - r.lastDrawTime;\n var callAfterLimit = timeElapsed >= redrawLimit;\n\n if( !forcedContext ){\n if( !callAfterLimit || r.currentlyDrawing ){\n r.skipFrame = true;\n return;\n }\n }\n\n r.requestedFrame = true;\n r.currentlyDrawing = true;\n r.renderOptions = options;\n};\n\nBRp.startRenderLoop = function(){\n var r = this;\n\n var renderFn = function(){\n if( r.destroyed ){ return; }\n\n if( r.requestedFrame && !r.skipFrame ){\n var startTime = util.performanceNow();\n\n r.render( r.renderOptions );\n\n var endTime = r.lastRedrawTime = util.performanceNow();\n\n if( r.averageRedrawTime === undefined ){\n r.averageRedrawTime = endTime - startTime;\n }\n\n if( r.redrawCount === undefined ){\n r.redrawCount = 0;\n }\n\n r.redrawCount++;\n\n if( r.redrawTotalTime === undefined ){\n r.redrawTotalTime = 0;\n }\n\n var duration = endTime - startTime;\n\n r.redrawTotalTime += duration;\n r.lastRedrawTime = duration;\n\n // use a weighted average with a bias from the previous average so we don't spike so easily\n r.averageRedrawTime = r.averageRedrawTime/2 + duration/2;\n\n r.requestedFrame = false;\n }\n\n r.skipFrame = false;\n\n util.requestAnimationFrame( renderFn );\n };\n\n util.requestAnimationFrame( renderFn );\n\n};\n\nmodule.exports = BRp;\n","'use strict';\n\nvar CRp = {};\n\nvar impl;\n\nCRp.arrowShapeImpl = function( name ){\n return ( impl || (impl = {\n 'polygon': function( context, points ){\n for( var i = 0; i < points.length; i++ ){\n var pt = points[i];\n\n context.lineTo( pt.x, pt.y );\n }\n },\n\n 'triangle-backcurve': function( context, points, controlPoint ){\n var firstPt;\n\n for( var i = 0; i < points.length; i++ ){\n var pt = points[i];\n\n if( i === 0 ){\n firstPt = pt;\n }\n\n context.lineTo( pt.x, pt.y );\n }\n\n context.quadraticCurveTo( controlPoint.x, controlPoint.y, firstPt.x, firstPt.y );\n },\n\n 'triangle-tee': function( context, trianglePoints, teePoints ){\n var triPts = trianglePoints;\n for( var i = 0; i < triPts.length; i++ ){\n var pt = triPts[i];\n\n context.lineTo( pt.x, pt.y );\n }\n\n var teePts = teePoints;\n var firstTeePt = teePoints[0];\n context.moveTo( firstTeePt.x, firstTeePt.y );\n\n for( var i = 0; i < teePts.length; i++ ){\n var pt = teePts[i];\n\n context.lineTo( pt.x, pt.y );\n }\n },\n\n 'circle': function( context, rx, ry, r ){\n context.arc(rx, ry, r, 0, Math.PI * 2, false);\n }\n }) )[ name ];\n};\n\nmodule.exports = CRp;\n","'use strict';\n\nvar CRp = {};\n\nCRp.drawEdge = function(context, edge, drawOverlayInstead) {\n var rs = edge._private.rscratch;\n var usePaths = this.usePaths();\n\n // if bezier ctrl pts can not be calculated, then die\n if( rs.badBezier || rs.badLine || isNaN( rs.allpts[0] ) ){ // iNaN in case edge is impossible and browser bugs (e.g. safari)\n return;\n }\n\n var style = edge._private.style;\n\n // Edge line width\n if (style['width'].pfValue <= 0) {\n return;\n }\n\n var overlayPadding = style['overlay-padding'].pfValue;\n var overlayOpacity = style['overlay-opacity'].value;\n var overlayColor = style['overlay-color'].value;\n\n // Edge color & opacity\n if( drawOverlayInstead ){\n\n if( overlayOpacity === 0 ){ // exit early if no overlay\n return;\n }\n\n this.strokeStyle(context, overlayColor[0], overlayColor[1], overlayColor[2], overlayOpacity);\n context.lineCap = 'round';\n\n if( rs.edgeType == 'self' && !usePaths ){\n context.lineCap = 'butt';\n }\n\n } else {\n var lineColor = style['line-color'].value;\n\n this.strokeStyle(context, lineColor[0], lineColor[1], lineColor[2], style.opacity.value);\n\n context.lineCap = 'butt';\n }\n\n var edgeWidth = style['width'].pfValue + (drawOverlayInstead ? 2 * overlayPadding : 0);\n var lineStyle = drawOverlayInstead ? 'solid' : style['line-style'].value;\n context.lineWidth = edgeWidth;\n\n var shadowBlur = style['shadow-blur'].pfValue;\n var shadowOpacity = style['shadow-opacity'].value;\n var shadowColor = style['shadow-color'].value;\n var shadowOffsetX = style['shadow-offset-x'].pfValue;\n var shadowOffsetY = style['shadow-offset-y'].pfValue;\n\n this.shadowStyle(context, shadowColor, drawOverlayInstead ? 0 : shadowOpacity, shadowBlur, shadowOffsetX, shadowOffsetY);\n\n this.drawEdgePath(\n edge,\n context,\n rs.allpts,\n lineStyle,\n edgeWidth\n );\n\n this.drawArrowheads(context, edge, drawOverlayInstead);\n\n this.shadowStyle(context, 'transparent', 0); // reset for next guy\n\n};\n\n\nCRp.drawEdgePath = function(edge, context, pts, type, width) {\n var rs = edge._private.rscratch;\n var canvasCxt = context;\n var path;\n var pathCacheHit = false;\n var usePaths = this.usePaths();\n\n if( usePaths ){\n var pathCacheKey = pts.join('$');\n var keyMatches = rs.pathCacheKey && rs.pathCacheKey === pathCacheKey;\n\n if( keyMatches ){\n path = context = rs.pathCache;\n pathCacheHit = true;\n } else {\n path = context = new Path2D();\n rs.pathCacheKey = pathCacheKey;\n rs.pathCache = path;\n }\n }\n\n if( canvasCxt.setLineDash ){ // for very outofdate browsers\n switch( type ){\n case 'dotted':\n canvasCxt.setLineDash([ 1, 1 ]);\n break;\n\n case 'dashed':\n canvasCxt.setLineDash([ 6, 3 ]);\n break;\n\n case 'solid':\n canvasCxt.setLineDash([ ]);\n break;\n }\n }\n\n if( !pathCacheHit ){\n if( context.beginPath ){ context.beginPath(); }\n context.moveTo( pts[0], pts[1] );\n\n switch( rs.edgeType ){\n case 'bezier':\n case 'self':\n case 'compound':\n case 'multibezier':\n if( !rs.badBezier ){\n for( var i = 2; i + 3 < pts.length; i += 4 ){\n context.quadraticCurveTo( pts[i], pts[i+1], pts[i+2], pts[i+3] );\n }\n }\n break;\n\n case 'straight':\n case 'segments':\n case 'haystack':\n if( !rs.badLine ){\n for( var i = 2; i + 1 < pts.length; i += 2 ){\n context.lineTo( pts[i], pts[i+1] );\n }\n }\n break;\n }\n }\n\n context = canvasCxt;\n if( usePaths ){\n context.stroke( path );\n } else {\n context.stroke();\n }\n\n // reset any line dashes\n if( context.setLineDash ){ // for very outofdate browsers\n context.setLineDash([ ]);\n }\n\n};\n\nCRp.drawArrowheads = function(context, edge, drawOverlayInstead) {\n if( drawOverlayInstead ){ return; } // don't do anything for overlays\n\n var rs = edge._private.rscratch;\n var isHaystack = rs.edgeType === 'haystack';\n\n if( !isHaystack ){\n this.drawArrowhead( context, edge, 'source', rs.arrowStartX, rs.arrowStartY, rs.srcArrowAngle );\n }\n\n this.drawArrowhead( context, edge, 'mid-target', rs.midX, rs.midY, rs.midtgtArrowAngle );\n\n this.drawArrowhead( context, edge, 'mid-source', rs.midX, rs.midY, rs.midsrcArrowAngle );\n\n if( !isHaystack ){\n this.drawArrowhead( context, edge, 'target', rs.arrowEndX, rs.arrowEndY, rs.tgtArrowAngle );\n }\n};\n\nCRp.drawArrowhead = function( context, edge, prefix, x, y, angle ){\n if( isNaN(x) || x == null || isNaN(y) || y == null || isNaN(angle) || angle == null ){ return; }\n\n var self = this;\n var style = edge._private.style;\n var arrowShape = style[prefix + '-arrow-shape'].value;\n\n if( arrowShape === 'none' ){\n return;\n }\n\n var gco = context.globalCompositeOperation;\n\n var arrowClearFill = style[prefix + '-arrow-fill'].value === 'hollow' ? 'both' : 'filled';\n var arrowFill = style[prefix + '-arrow-fill'].value;\n\n if( arrowShape === 'half-triangle-overshot' ){\n arrowFill = 'hollow';\n arrowClearFill = 'hollow';\n }\n\n if( style.opacity.value !== 1 || arrowFill === 'hollow' ){ // then extra clear is needed\n context.globalCompositeOperation = 'destination-out';\n\n self.fillStyle(context, 255, 255, 255, 1);\n self.strokeStyle(context, 255, 255, 255, 1);\n\n self.drawArrowShape( edge, prefix, context,\n arrowClearFill, style['width'].pfValue, style[prefix + '-arrow-shape'].value,\n x, y, angle\n );\n\n context.globalCompositeOperation = gco;\n } // otherwise, the opaque arrow clears it for free :)\n\n var color = style[prefix + '-arrow-color'].value;\n self.fillStyle(context, color[0], color[1], color[2], style.opacity.value);\n self.strokeStyle(context, color[0], color[1], color[2], style.opacity.value);\n\n self.drawArrowShape( edge, prefix, context,\n arrowFill, style['width'].pfValue, style[prefix + '-arrow-shape'].value,\n x, y, angle\n );\n};\n\nCRp.drawArrowShape = function(edge, arrowType, context, fill, edgeWidth, shape, x, y, angle) {\n var r = this;\n var usePaths = this.usePaths();\n var rs = edge._private.rscratch;\n var pathCacheHit = false;\n var path;\n var canvasContext = context;\n var translation = { x: x, y: y };\n var size = this.getArrowWidth( edgeWidth );\n var shapeImpl = r.arrowShapes[shape];\n\n if( usePaths ){\n var pathCacheKey = size + '$' + shape + '$' + angle + '$' + x + '$' + y;\n rs.arrowPathCacheKey = rs.arrowPathCacheKey || {};\n rs.arrowPathCache = rs.arrowPathCache || {};\n\n var alreadyCached = rs.arrowPathCacheKey[arrowType] === pathCacheKey;\n if( alreadyCached ){\n path = context = rs.arrowPathCache[arrowType];\n pathCacheHit = true;\n } else {\n path = context = new Path2D();\n rs.arrowPathCacheKey[arrowType] = pathCacheKey;\n rs.arrowPathCache[arrowType] = path;\n }\n }\n\n if( context.beginPath ){ context.beginPath(); }\n\n if( !pathCacheHit ){\n shapeImpl.draw(context, size, angle, translation);\n }\n\n if( !shapeImpl.leavePathOpen && context.closePath ){\n context.closePath();\n }\n\n context = canvasContext;\n\n if( fill === 'filled' || fill === 'both' ){\n if( usePaths ){\n context.fill( path );\n } else {\n context.fill();\n }\n }\n\n if( fill === 'hollow' || fill === 'both' ){\n context.lineWidth = ( shapeImpl.matchEdgeWidth ? edgeWidth : 1 );\n context.lineJoin = 'miter';\n\n if( usePaths ){\n context.stroke( path );\n } else {\n context.stroke();\n }\n\n }\n};\n\nmodule.exports = CRp;\n","'use strict';\n\nvar CRp = {};\n\nCRp.safeDrawImage = function( context, img, ix, iy, iw, ih, x, y, w, h ){\n var r = this;\n\n try {\n context.drawImage( img, ix, iy, iw, ih, x, y, w, h );\n } catch(e){\n r.data.canvasNeedsRedraw[r.NODE] = true;\n r.data.canvasNeedsRedraw[r.DRAG] = true;\n\n r.drawingImage = true;\n\n r.redraw();\n }\n};\n\nCRp.drawInscribedImage = function(context, img, node) {\n var r = this;\n var nodeX = node._private.position.x;\n var nodeY = node._private.position.y;\n var style = node._private.style;\n var fit = style['background-fit'].value;\n var xPos = style['background-position-x'];\n var yPos = style['background-position-y'];\n var repeat = style['background-repeat'].value;\n var nodeW = node.width();\n var nodeH = node.height();\n var rs = node._private.rscratch;\n var clip = style['background-clip'].value;\n var shouldClip = clip === 'node';\n var imgOpacity = style['background-image-opacity'].value;\n\n var imgW = img.width || img.cachedW;\n var imgH = img.height || img.cachedH;\n\n // workaround for broken browsers like ie\n if( null == imgW || null == imgH ){\n document.body.appendChild( img );\n\n imgW = img.cachedW = img.width || img.offsetWidth;\n imgH = img.cachedH = img.height || img.offsetHeight;\n\n document.body.removeChild( img );\n }\n\n var w = imgW;\n var h = imgH;\n\n var bgW = style['background-width'];\n if( bgW.value !== 'auto' ){\n if( bgW.units === '%' ){\n w = bgW.value/100 * nodeW;\n } else {\n w = bgW.pfValue;\n }\n }\n\n var bgH = style['background-height'];\n if( bgH.value !== 'auto' ){\n if( bgH.units === '%' ){\n h = bgH.value/100 * nodeH;\n } else {\n h = bgH.pfValue;\n }\n }\n\n if( w === 0 || h === 0 ){\n return; // no point in drawing empty image (and chrome is broken in this case)\n }\n\n if( fit === 'contain' ){\n var scale = Math.min( nodeW/w, nodeH/h );\n\n w *= scale;\n h *= scale;\n\n } else if( fit === 'cover' ){\n var scale = Math.max( nodeW/w, nodeH/h );\n\n w *= scale;\n h *= scale;\n }\n\n var x = (nodeX - nodeW/2); // left\n if( xPos.units === '%' ){\n x += (nodeW - w) * xPos.value/100;\n } else {\n x += xPos.pfValue;\n }\n\n var y = (nodeY - nodeH/2); // top\n if( yPos.units === '%' ){\n y += (nodeH - h) * yPos.value/100;\n } else {\n y += yPos.pfValue;\n }\n\n if( rs.pathCache ){\n x -= nodeX;\n y -= nodeY;\n\n nodeX = 0;\n nodeY = 0;\n }\n\n var gAlpha = context.globalAlpha;\n\n context.globalAlpha = imgOpacity;\n\n if( repeat === 'no-repeat' ){\n\n if( shouldClip ){\n context.save();\n\n if( rs.pathCache ){\n context.clip( rs.pathCache );\n } else {\n r.nodeShapes[r.getNodeShape(node)].draw(\n context,\n nodeX, nodeY,\n nodeW, nodeH);\n\n context.clip();\n }\n }\n\n r.safeDrawImage( context, img, 0, 0, imgW, imgH, x, y, w, h );\n\n if( shouldClip ){\n context.restore();\n }\n } else {\n var pattern = context.createPattern( img, repeat );\n context.fillStyle = pattern;\n\n r.nodeShapes[r.getNodeShape(node)].draw(\n context,\n nodeX, nodeY,\n nodeW, nodeH);\n\n context.translate(x, y);\n context.fill();\n context.translate(-x, -y);\n }\n\n context.globalAlpha = gAlpha;\n\n};\n\nmodule.exports = CRp;\n","'use strict';\n\nvar is = require('../../../is');\n\nvar CRp = {};\n\n// Draw edge text\nCRp.drawEdgeText = function(context, edge) {\n var text = edge._private.style['label'].strValue;\n\n if( !text || text.match(/^\\s+$/) ){\n return;\n }\n\n if( this.hideEdgesOnViewport && (this.dragData.didDrag || this.pinching || this.hoverData.dragging || this.data.wheel || this.swipePanning) ){ return; } // save cycles on pinching\n\n var computedSize = edge._private.style['font-size'].pfValue * edge.cy().zoom();\n var minSize = edge._private.style['min-zoomed-font-size'].pfValue;\n\n if( computedSize < minSize ){\n return;\n }\n\n // Calculate text draw position\n\n context.textAlign = 'center';\n context.textBaseline = 'middle';\n\n var rs = edge._private.rscratch;\n if( !is.number( rs.labelX ) || !is.number( rs.labelY ) ){ return; } // no pos => label can't be rendered\n\n var style = edge._private.style;\n var autorotate = style['edge-text-rotation'].strValue === 'autorotate';\n var theta;\n\n if( autorotate ){\n theta = rs.labelAngle;\n\n context.translate(rs.labelX, rs.labelY);\n context.rotate(theta);\n\n this.drawText(context, edge, 0, 0);\n\n context.rotate(-theta);\n context.translate(-rs.labelX, -rs.labelY);\n } else {\n this.drawText(context, edge, rs.labelX, rs.labelY);\n }\n\n};\n\n// Draw node text\nCRp.drawNodeText = function(context, node) {\n var text = node._private.style['label'].strValue;\n\n if ( !text || text.match(/^\\s+$/) ) {\n return;\n }\n\n var computedSize = node._private.style['font-size'].pfValue * node.cy().zoom();\n var minSize = node._private.style['min-zoomed-font-size'].pfValue;\n\n if( computedSize < minSize ){\n return;\n }\n\n // this.recalculateNodeLabelProjection( node );\n\n var textHalign = node._private.style['text-halign'].strValue;\n var textValign = node._private.style['text-valign'].strValue;\n var rs = node._private.rscratch;\n if( !is.number( rs.labelX ) || !is.number( rs.labelY ) ){ return; } // no pos => label can't be rendered\n\n switch( textHalign ){\n case 'left':\n context.textAlign = 'right';\n break;\n\n case 'right':\n context.textAlign = 'left';\n break;\n\n default: // e.g. center\n context.textAlign = 'center';\n }\n\n switch( textValign ){\n case 'top':\n context.textBaseline = 'bottom';\n break;\n\n case 'bottom':\n context.textBaseline = 'top';\n break;\n\n default: // e.g. center\n context.textBaseline = 'middle';\n }\n\n this.drawText(context, node, rs.labelX, rs.labelY);\n};\n\nCRp.getFontCache = function(context){\n var cache;\n\n this.fontCaches = this.fontCaches || [];\n\n for( var i = 0; i < this.fontCaches.length; i++ ){\n cache = this.fontCaches[i];\n\n if( cache.context === context ){\n return cache;\n }\n }\n\n cache = {\n context: context\n };\n this.fontCaches.push(cache);\n\n return cache;\n};\n\n// set up canvas context with font\n// returns transformed text string\nCRp.setupTextStyle = function( context, element ){\n // Font style\n var parentOpacity = element.effectiveOpacity();\n var style = element._private.style;\n var labelStyle = style['font-style'].strValue;\n var labelSize = style['font-size'].pfValue + 'px';\n var labelFamily = style['font-family'].strValue;\n var labelWeight = style['font-weight'].strValue;\n var opacity = style['text-opacity'].value * style['opacity'].value * parentOpacity;\n var outlineOpacity = style['text-outline-opacity'].value * opacity;\n var color = style['color'].value;\n var outlineColor = style['text-outline-color'].value;\n var shadowBlur = style['text-shadow-blur'].pfValue;\n var shadowOpacity = style['text-shadow-opacity'].value;\n var shadowColor = style['text-shadow-color'].value;\n var shadowOffsetX = style['text-shadow-offset-x'].pfValue;\n var shadowOffsetY = style['text-shadow-offset-y'].pfValue;\n\n var fontCacheKey = element._private.fontKey;\n var cache = this.getFontCache(context);\n\n if( cache.key !== fontCacheKey ){\n context.font = labelStyle + ' ' + labelWeight + ' ' + labelSize + ' ' + labelFamily;\n\n cache.key = fontCacheKey;\n }\n\n var text = this.getLabelText( element );\n\n // Calculate text draw position based on text alignment\n\n // so text outlines aren't jagged\n context.lineJoin = 'round';\n\n this.fillStyle(context, color[0], color[1], color[2], opacity);\n\n this.strokeStyle(context, outlineColor[0], outlineColor[1], outlineColor[2], outlineOpacity);\n\n this.shadowStyle(context, shadowColor, shadowOpacity, shadowBlur, shadowOffsetX, shadowOffsetY);\n\n return text;\n};\n\nfunction roundRect(ctx, x, y, width, height, radius) {\n var radius = radius || 5;\n ctx.beginPath();\n ctx.moveTo(x + radius, y);\n ctx.lineTo(x + width - radius, y);\n ctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n ctx.lineTo(x + width, y + height - radius);\n ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n ctx.lineTo(x + radius, y + height);\n ctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n ctx.lineTo(x, y + radius);\n ctx.quadraticCurveTo(x, y, x + radius, y);\n ctx.closePath();\n ctx.fill();\n}\n\n// Draw text\nCRp.drawText = function(context, element, textX, textY) {\n var _p = element._private;\n var style = _p.style;\n var rstyle = _p.rstyle;\n var rscratch = _p.rscratch;\n var parentOpacity = element.effectiveOpacity();\n if( parentOpacity === 0 || style['text-opacity'].value === 0){ return; }\n\n var text = this.setupTextStyle( context, element );\n var halign = style['text-halign'].value;\n var valign = style['text-valign'].value;\n\n if( element.isEdge() ){\n halign = 'center';\n valign = 'center';\n }\n\n if( element.isNode() ){\n var pLeft = style['padding-left'].pfValue;\n var pRight = style['padding-right'].pfValue;\n var pTop = style['padding-top'].pfValue;\n var pBottom = style['padding-bottom'].pfValue;\n\n textX += pLeft/2;\n textX -= pRight/2;\n\n textY += pTop/2;\n textY -= pBottom/2;\n }\n\n if ( text != null && !isNaN(textX) && !isNaN(textY)) {\n var backgroundOpacity = style['text-background-opacity'].value;\n var borderOpacity = style['text-border-opacity'].value;\n var textBorderWidth = style['text-border-width'].pfValue;\n\n if( backgroundOpacity > 0 || (textBorderWidth > 0 && borderOpacity > 0) ){\n var margin = 4 + textBorderWidth/2;\n\n if (element.isNode()) {\n //Move textX, textY to include the background margins\n if (valign === 'top') {\n textY -= margin;\n } else if (valign === 'bottom') {\n textY += margin;\n }\n if (halign === 'left') {\n textX -= margin;\n } else if (halign === 'right') {\n textX += margin;\n }\n }\n\n var bgWidth = rstyle.labelWidth;\n var bgHeight = rstyle.labelHeight;\n var bgX = textX;\n\n if (halign) {\n if (halign == 'center') {\n bgX = bgX - bgWidth / 2;\n } else if (halign == 'left') {\n bgX = bgX- bgWidth;\n }\n }\n\n var bgY = textY;\n\n if (element.isNode()) {\n if (valign == 'top') {\n bgY = bgY - bgHeight;\n } else if (valign == 'center') {\n bgY = bgY- bgHeight / 2;\n }\n } else {\n bgY = bgY - bgHeight / 2;\n }\n\n if (style['edge-text-rotation'].strValue === 'autorotate') {\n textY = 0;\n bgWidth += 4;\n bgX = textX - bgWidth / 2;\n bgY = textY - bgHeight / 2;\n } else {\n // Adjust with border width & margin\n bgX -= margin;\n bgY -= margin;\n bgHeight += margin*2;\n bgWidth += margin*2;\n }\n\n if( backgroundOpacity > 0 ){\n var textFill = context.fillStyle;\n var textBackgroundColor = style['text-background-color'].value;\n\n context.fillStyle = 'rgba(' + textBackgroundColor[0] + ',' + textBackgroundColor[1] + ',' + textBackgroundColor[2] + ',' + backgroundOpacity * parentOpacity + ')';\n var styleShape = style['text-background-shape'].strValue;\n if (styleShape == 'roundrectangle') {\n roundRect(context, bgX, bgY, bgWidth, bgHeight, 2);\n } else {\n context.fillRect(bgX,bgY,bgWidth,bgHeight);\n }\n context.fillStyle = textFill;\n }\n\n if( textBorderWidth > 0 && borderOpacity > 0 ){\n var textStroke = context.strokeStyle;\n var textLineWidth = context.lineWidth;\n var textBorderColor = style['text-border-color'].value;\n var textBorderStyle = style['text-border-style'].value;\n\n context.strokeStyle = 'rgba(' + textBorderColor[0] + ',' + textBorderColor[1] + ',' + textBorderColor[2] + ',' + borderOpacity * parentOpacity + ')';\n context.lineWidth = textBorderWidth;\n\n if( context.setLineDash ){ // for very outofdate browsers\n switch( textBorderStyle ){\n case 'dotted':\n context.setLineDash([ 1, 1 ]);\n break;\n case 'dashed':\n context.setLineDash([ 4, 2 ]);\n break;\n case 'double':\n context.lineWidth = textBorderWidth/4; // 50% reserved for white between the two borders\n context.setLineDash([ ]);\n break;\n case 'solid':\n context.setLineDash([ ]);\n break;\n }\n }\n\n context.strokeRect(bgX,bgY,bgWidth,bgHeight);\n\n if( textBorderStyle === 'double' ){\n var whiteWidth = textBorderWidth/2;\n\n context.strokeRect(bgX+whiteWidth,bgY+whiteWidth,bgWidth-whiteWidth*2,bgHeight-whiteWidth*2);\n }\n\n if( context.setLineDash ){ // for very outofdate browsers\n context.setLineDash([ ]);\n }\n context.lineWidth = textLineWidth;\n context.strokeStyle = textStroke;\n }\n\n }\n\n var lineWidth = 2 * style['text-outline-width'].pfValue; // *2 b/c the stroke is drawn centred on the middle\n\n if( lineWidth > 0 ){\n context.lineWidth = lineWidth;\n }\n\n if( style['text-wrap'].value === 'wrap' ){\n var lines = rscratch.labelWrapCachedLines;\n var lineHeight = rstyle.labelHeight / lines.length;\n\n switch( valign ){\n case 'top':\n textY -= (lines.length - 1) * lineHeight;\n break;\n\n case 'bottom':\n // nothing required\n break;\n\n default:\n case 'center':\n textY -= (lines.length - 1) * lineHeight / 2;\n }\n\n for( var l = 0; l < lines.length; l++ ){\n if( lineWidth > 0 ){\n context.strokeText( lines[l], textX, textY );\n }\n\n context.fillText( lines[l], textX, textY );\n\n textY += lineHeight;\n }\n\n } else {\n if( lineWidth > 0 ){\n context.strokeText( text, textX, textY );\n }\n\n context.fillText( text, textX, textY );\n }\n\n\n this.shadowStyle(context, 'transparent', 0); // reset for next guy\n }\n};\n\n\nmodule.exports = CRp;\n","'use strict';\n\nvar is = require('../../../is');\n\nvar CRp = {};\n\n// Draw node\nCRp.drawNode = function(context, node, drawOverlayInstead) {\n\n var r = this;\n var nodeWidth, nodeHeight;\n var style = node._private.style;\n var rs = node._private.rscratch;\n var _p = node._private;\n var pos = _p.position;\n\n if( !is.number(pos.x) || !is.number(pos.y) ){\n return; // can't draw node with undefined position\n }\n\n var usePaths = this.usePaths();\n var canvasContext = context;\n var path;\n var pathCacheHit = false;\n\n var overlayPadding = style['overlay-padding'].pfValue;\n var overlayOpacity = style['overlay-opacity'].value;\n var overlayColor = style['overlay-color'].value;\n\n if( drawOverlayInstead && overlayOpacity === 0 ){ // exit early if drawing overlay but none to draw\n return;\n }\n\n var parentOpacity = node.effectiveOpacity();\n if( parentOpacity === 0 ){ return; }\n\n nodeWidth = node.width() + style['padding-left'].pfValue + style['padding-right'].pfValue;\n nodeHeight = node.height() + style['padding-top'].pfValue + style['padding-bottom'].pfValue;\n\n context.lineWidth = style['border-width'].pfValue;\n\n if( drawOverlayInstead === undefined || !drawOverlayInstead ){\n\n var url = style['background-image'].value[2] ||\n style['background-image'].value[1];\n var image;\n\n if (url !== undefined) {\n\n // get image, and if not loaded then ask to redraw when later loaded\n image = this.getCachedImage(url, function(){\n r.data.canvasNeedsRedraw[r.NODE] = true;\n r.data.canvasNeedsRedraw[r.DRAG] = true;\n\n r.drawingImage = true;\n\n r.redraw();\n });\n\n var prevBging = _p.backgrounding;\n _p.backgrounding = !image.complete;\n\n if( prevBging !== _p.backgrounding ){ // update style b/c :backgrounding state changed\n node.updateStyle( false );\n }\n }\n\n // Node color & opacity\n\n var bgColor = style['background-color'].value;\n var borderColor = style['border-color'].value;\n var borderStyle = style['border-style'].value;\n\n this.fillStyle(context, bgColor[0], bgColor[1], bgColor[2], style['background-opacity'].value * parentOpacity);\n\n this.strokeStyle(context, borderColor[0], borderColor[1], borderColor[2], style['border-opacity'].value * parentOpacity);\n\n var shadowBlur = style['shadow-blur'].pfValue;\n var shadowOpacity = style['shadow-opacity'].value;\n var shadowColor = style['shadow-color'].value;\n var shadowOffsetX = style['shadow-offset-x'].pfValue;\n var shadowOffsetY = style['shadow-offset-y'].pfValue;\n\n this.shadowStyle(context, shadowColor, shadowOpacity, shadowBlur, shadowOffsetX, shadowOffsetY);\n\n context.lineJoin = 'miter'; // so borders are square with the node shape\n\n if( context.setLineDash ){ // for very outofdate browsers\n switch( borderStyle ){\n case 'dotted':\n context.setLineDash([ 1, 1 ]);\n break;\n\n case 'dashed':\n context.setLineDash([ 4, 2 ]);\n break;\n\n case 'solid':\n case 'double':\n context.setLineDash([ ]);\n break;\n }\n }\n\n\n var styleShape = style['shape'].strValue;\n\n if( usePaths ){\n var pathCacheKey = styleShape + '$' + nodeWidth +'$' + nodeHeight;\n\n context.translate( pos.x, pos.y );\n\n if( rs.pathCacheKey === pathCacheKey ){\n path = context = rs.pathCache;\n pathCacheHit = true;\n } else {\n path = context = new Path2D();\n rs.pathCacheKey = pathCacheKey;\n rs.pathCache = path;\n }\n }\n\n if( !pathCacheHit ){\n\n var npos = pos;\n\n if( usePaths ){\n npos = {\n x: 0,\n y: 0\n };\n }\n\n r.nodeShapes[this.getNodeShape(node)].draw(\n context,\n npos.x,\n npos.y,\n nodeWidth,\n nodeHeight);\n }\n\n context = canvasContext;\n\n if( usePaths ){\n context.fill( path );\n } else {\n context.fill();\n }\n\n this.shadowStyle(context, 'transparent', 0); // reset for next guy\n\n if (url !== undefined) {\n if( image.complete ){\n this.drawInscribedImage(context, image, node);\n }\n }\n\n var darkness = style['background-blacken'].value;\n var borderWidth = style['border-width'].pfValue;\n\n if( this.hasPie(node) ){\n this.drawPie( context, node, parentOpacity );\n\n // redraw path for blacken and border\n if( darkness !== 0 || borderWidth !== 0 ){\n\n if( !usePaths ){\n r.nodeShapes[this.getNodeShape(node)].draw(\n context,\n pos.x,\n pos.y,\n nodeWidth,\n nodeHeight);\n }\n }\n }\n\n if( darkness > 0 ){\n this.fillStyle(context, 0, 0, 0, darkness);\n\n if( usePaths ){\n context.fill( path );\n } else {\n context.fill();\n }\n\n } else if( darkness < 0 ){\n this.fillStyle(context, 255, 255, 255, -darkness);\n\n if( usePaths ){\n context.fill( path );\n } else {\n context.fill();\n }\n }\n\n // Border width, draw border\n if (borderWidth > 0) {\n\n if( usePaths ){\n context.stroke( path );\n } else {\n context.stroke();\n }\n\n if( borderStyle === 'double' ){\n context.lineWidth = style['border-width'].pfValue/3;\n\n var gco = context.globalCompositeOperation;\n context.globalCompositeOperation = 'destination-out';\n\n if( usePaths ){\n context.stroke( path );\n } else {\n context.stroke();\n }\n\n context.globalCompositeOperation = gco;\n }\n\n }\n\n if( usePaths ){\n context.translate( -pos.x, -pos.y );\n }\n\n // reset in case we changed the border style\n if( context.setLineDash ){ // for very outofdate browsers\n context.setLineDash([ ]);\n }\n\n // draw the overlay\n } else {\n\n if( overlayOpacity > 0 ){\n this.fillStyle(context, overlayColor[0], overlayColor[1], overlayColor[2], overlayOpacity);\n\n r.nodeShapes['roundrectangle'].draw(\n context,\n node._private.position.x,\n node._private.position.y,\n nodeWidth + overlayPadding * 2,\n nodeHeight + overlayPadding * 2\n );\n\n context.fill();\n }\n }\n\n};\n\n// does the node have at least one pie piece?\nCRp.hasPie = function(node){\n node = node[0]; // ensure ele ref\n\n return node._private.hasPie;\n};\n\nCRp.drawPie = function( context, node, nodeOpacity ){\n node = node[0]; // ensure ele ref\n\n var _p = node._private;\n var cyStyle = node.cy().style();\n var style = _p.style;\n var pieSize = style['pie-size'];\n var nodeW = node.width();\n var nodeH = node.height();\n var x = _p.position.x;\n var y = _p.position.y;\n var radius = Math.min( nodeW, nodeH ) / 2; // must fit in node\n var lastPercent = 0; // what % to continue drawing pie slices from on [0, 1]\n var usePaths = this.usePaths();\n\n if( usePaths ){\n x = 0;\n y = 0;\n }\n\n if( pieSize.units === '%' ){\n radius = radius * pieSize.value / 100;\n } else if( pieSize.pfValue !== undefined ){\n radius = pieSize.pfValue / 2;\n }\n\n for( var i = 1; i <= cyStyle.pieBackgroundN; i++ ){ // 1..N\n var size = style['pie-' + i + '-background-size'].value;\n var color = style['pie-' + i + '-background-color'].value;\n var opacity = style['pie-' + i + '-background-opacity'].value * nodeOpacity;\n var percent = size / 100; // map integer range [0, 100] to [0, 1]\n\n // percent can't push beyond 1\n if( percent + lastPercent > 1 ){\n percent = 1 - lastPercent;\n }\n\n var angleStart = 1.5 * Math.PI + 2 * Math.PI * lastPercent; // start at 12 o'clock and go clockwise\n var angleDelta = 2 * Math.PI * percent;\n var angleEnd = angleStart + angleDelta;\n\n // ignore if\n // - zero size\n // - we're already beyond the full circle\n // - adding the current slice would go beyond the full circle\n if( size === 0 || lastPercent >= 1 || lastPercent + percent > 1 ){\n continue;\n }\n\n context.beginPath();\n context.moveTo(x, y);\n context.arc( x, y, radius, angleStart, angleEnd );\n context.closePath();\n\n this.fillStyle(context, color[0], color[1], color[2], opacity);\n\n context.fill();\n\n lastPercent += percent;\n }\n\n};\n\n\nmodule.exports = CRp;\n","'use strict';\n\nvar CRp = {};\n\nvar util = require('../../../util');\nvar math = require('../../../math');\n\nvar motionBlurDelay = 100;\n\n// var isFirefox = typeof InstallTrigger !== 'undefined';\n\nCRp.getPixelRatio = function(){\n var context = this.data.contexts[0];\n\n if( this.forcedPixelRatio != null ){\n return this.forcedPixelRatio;\n }\n\n var backingStore = context.backingStorePixelRatio ||\n context.webkitBackingStorePixelRatio ||\n context.mozBackingStorePixelRatio ||\n context.msBackingStorePixelRatio ||\n context.oBackingStorePixelRatio ||\n context.backingStorePixelRatio || 1;\n\n return (window.devicePixelRatio || 1) / backingStore;\n};\n\nCRp.paintCache = function(context){\n var caches = this.paintCaches = this.paintCaches || [];\n var needToCreateCache = true;\n var cache;\n\n for(var i = 0; i < caches.length; i++ ){\n cache = caches[i];\n\n if( cache.context === context ){\n needToCreateCache = false;\n break;\n }\n }\n\n if( needToCreateCache ){\n cache = {\n context: context\n };\n caches.push( cache );\n }\n\n return cache;\n};\n\nCRp.fillStyle = function(context, r, g, b, a){\n context.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n\n // turn off for now, seems context does its own caching\n\n // var cache = this.paintCache(context);\n\n // var fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n\n // if( cache.fillStyle !== fillStyle ){\n // context.fillStyle = cache.fillStyle = fillStyle;\n // }\n};\n\nCRp.strokeStyle = function(context, r, g, b, a){\n context.strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n\n // turn off for now, seems context does its own caching\n\n // var cache = this.paintCache(context);\n\n // var strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n\n // if( cache.strokeStyle !== strokeStyle ){\n // context.strokeStyle = cache.strokeStyle = strokeStyle;\n // }\n};\n\nCRp.shadowStyle = function(context, color, opacity, blur, offsetX, offsetY){\n var zoom = this.cy.zoom();\n\n var cache = this.paintCache(context);\n\n // don't make expensive changes to the shadow style if it's not used\n if( cache.shadowOpacity === 0 && opacity === 0 ){\n return;\n }\n\n cache.shadowOpacity = opacity;\n\n if (opacity > 0) {\n context.shadowBlur = blur * zoom;\n context.shadowColor = \"rgba(\" + color[0] + \",\" + color[1] + \",\" + color[2] + \",\" + opacity + \")\";\n context.shadowOffsetX = offsetX * zoom;\n context.shadowOffsetY = offsetY * zoom;\n } else {\n context.shadowBlur = 0;\n context.shadowColor = \"transparent\";\n }\n};\n\n// Resize canvas\nCRp.matchCanvasSize = function(container) {\n var r = this;\n var data = r.data;\n var width = container.clientWidth;\n var height = container.clientHeight;\n var pixelRatio = r.getPixelRatio();\n var mbPxRatio = r.motionBlurPxRatio;\n\n if(\n container === r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_NODE] ||\n container === r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_DRAG]\n ){\n pixelRatio = mbPxRatio;\n }\n\n var canvasWidth = width * pixelRatio;\n var canvasHeight = height * pixelRatio;\n var canvas;\n\n if( canvasWidth === r.canvasWidth && canvasHeight === r.canvasHeight ){\n return; // save cycles if same\n }\n\n r.fontCaches = null; // resizing resets the style\n\n var canvasContainer = data.canvasContainer;\n canvasContainer.style.width = width + 'px';\n canvasContainer.style.height = height + 'px';\n\n for (var i = 0; i < r.CANVAS_LAYERS; i++) {\n\n canvas = data.canvases[i];\n\n if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) {\n\n canvas.width = canvasWidth;\n canvas.height = canvasHeight;\n\n canvas.style.width = width + 'px';\n canvas.style.height = height + 'px';\n }\n }\n\n for (var i = 0; i < r.BUFFER_COUNT; i++) {\n\n canvas = data.bufferCanvases[i];\n\n if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) {\n\n canvas.width = canvasWidth;\n canvas.height = canvasHeight;\n\n canvas.style.width = width + 'px';\n canvas.style.height = height + 'px';\n }\n }\n\n r.textureMult = 1;\n if( pixelRatio <= 1 ){\n canvas = data.bufferCanvases[ r.TEXTURE_BUFFER ];\n\n r.textureMult = 2;\n canvas.width = canvasWidth * r.textureMult;\n canvas.height = canvasHeight * r.textureMult;\n }\n\n r.canvasWidth = canvasWidth;\n r.canvasHeight = canvasHeight;\n\n};\n\nCRp.renderTo = function( cxt, zoom, pan, pxRatio ){\n this.render({\n forcedContext: cxt,\n forcedZoom: zoom,\n forcedPan: pan,\n drawAllLayers: true,\n forcedPxRatio: pxRatio\n });\n};\n\nCRp.render = function( options ) {\n options = options || util.staticEmptyObject();\n\n var forcedContext = options.forcedContext;\n var drawAllLayers = options.drawAllLayers;\n var drawOnlyNodeLayer = options.drawOnlyNodeLayer;\n var forcedZoom = options.forcedZoom;\n var forcedPan = options.forcedPan;\n var r = this;\n var pixelRatio = options.forcedPxRatio === undefined ? this.getPixelRatio() : options.forcedPxRatio;\n var cy = r.cy; var data = r.data;\n var needDraw = data.canvasNeedsRedraw;\n var textureDraw = r.textureOnViewport && !forcedContext && (r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming);\n var motionBlur = options.motionBlur !== undefined ? options.motionBlur : r.motionBlur;\n var mbPxRatio = r.motionBlurPxRatio;\n var hasCompoundNodes = cy.hasCompoundNodes();\n var inNodeDragGesture = r.hoverData.draggingEles;\n var inBoxSelection = r.hoverData.selecting || r.touchData.selecting ? true : false;\n motionBlur = motionBlur && !forcedContext && r.motionBlurEnabled && !inBoxSelection;\n var motionBlurFadeEffect = motionBlur;\n\n if( !forcedContext && r.motionBlurTimeout ){\n clearTimeout( r.motionBlurTimeout );\n }\n\n if( motionBlur ){\n if( r.mbFrames == null ){\n r.mbFrames = 0;\n }\n\n if( !r.drawingImage ){ // image loading frames don't count towards motion blur blurry frames\n r.mbFrames++;\n }\n\n if( r.mbFrames < 3 ){ // need several frames before even high quality motionblur\n motionBlurFadeEffect = false;\n }\n\n // go to lower quality blurry frames when several m/b frames have been rendered (avoids flashing)\n if( r.mbFrames > r.minMbLowQualFrames ){\n //r.fullQualityMb = false;\n r.motionBlurPxRatio = r.mbPxRBlurry;\n }\n }\n\n if( r.clearingMotionBlur ){\n r.motionBlurPxRatio = 1;\n }\n\n // b/c drawToContext() may be async w.r.t. redraw(), keep track of last texture frame\n // because a rogue async texture frame would clear needDraw\n if( r.textureDrawLastFrame && !textureDraw ){\n needDraw[r.NODE] = true;\n needDraw[r.SELECT_BOX] = true;\n }\n\n var edges = r.getCachedEdges();\n var coreStyle = cy.style()._private.coreStyle;\n\n var zoom = cy.zoom();\n var effectiveZoom = forcedZoom !== undefined ? forcedZoom : zoom;\n var pan = cy.pan();\n var effectivePan = {\n x: pan.x,\n y: pan.y\n };\n\n var vp = {\n zoom: zoom,\n pan: {\n x: pan.x,\n y: pan.y\n }\n };\n var prevVp = r.prevViewport;\n var viewportIsDiff = prevVp === undefined || vp.zoom !== prevVp.zoom || vp.pan.x !== prevVp.pan.x || vp.pan.y !== prevVp.pan.y;\n\n // we want the low quality motionblur only when the viewport is being manipulated etc (where it's not noticed)\n if( !viewportIsDiff && !(inNodeDragGesture && !hasCompoundNodes) ){\n r.motionBlurPxRatio = 1;\n }\n\n if( forcedPan ){\n effectivePan = forcedPan;\n }\n\n // apply pixel ratio\n\n effectiveZoom *= pixelRatio;\n effectivePan.x *= pixelRatio;\n effectivePan.y *= pixelRatio;\n\n var eles = {\n drag: {\n nodes: [],\n edges: [],\n eles: []\n },\n nondrag: {\n nodes: [],\n edges: [],\n eles: []\n }\n };\n\n function mbclear( context, x, y, w, h ){\n var gco = context.globalCompositeOperation;\n\n context.globalCompositeOperation = 'destination-out';\n r.fillStyle( context, 255, 255, 255, r.motionBlurTransparency );\n context.fillRect(x, y, w, h);\n\n context.globalCompositeOperation = gco;\n }\n\n function setContextTransform(context, clear){\n var ePan, eZoom, w, h;\n\n if( !r.clearingMotionBlur && (context === data.bufferContexts[r.MOTIONBLUR_BUFFER_NODE] || context === data.bufferContexts[r.MOTIONBLUR_BUFFER_DRAG]) ){\n ePan = {\n x: pan.x * mbPxRatio,\n y: pan.y * mbPxRatio\n };\n\n eZoom = zoom * mbPxRatio;\n\n w = r.canvasWidth * mbPxRatio;\n h = r.canvasHeight * mbPxRatio;\n } else {\n ePan = effectivePan;\n eZoom = effectiveZoom;\n\n w = r.canvasWidth;\n h = r.canvasHeight;\n }\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n\n if( clear === 'motionBlur' ){\n mbclear(context, 0, 0, w, h);\n } else if( !forcedContext && (clear === undefined || clear) ){\n context.clearRect(0, 0, w, h);\n }\n\n if( !drawAllLayers ){\n context.translate( ePan.x, ePan.y );\n context.scale( eZoom, eZoom );\n }\n if( forcedPan ){\n context.translate( forcedPan.x, forcedPan.y );\n }\n if( forcedZoom ){\n context.scale( forcedZoom, forcedZoom );\n }\n }\n\n if( !textureDraw ){\n r.textureDrawLastFrame = false;\n }\n\n if( textureDraw ){\n r.textureDrawLastFrame = true;\n\n var bb;\n\n if( !r.textureCache ){\n r.textureCache = {};\n\n bb = r.textureCache.bb = cy.elements().boundingBox();\n\n r.textureCache.texture = r.data.bufferCanvases[ r.TEXTURE_BUFFER ];\n\n var cxt = r.data.bufferContexts[ r.TEXTURE_BUFFER ];\n\n cxt.setTransform(1, 0, 0, 1, 0, 0);\n cxt.clearRect(0, 0, r.canvasWidth * r.textureMult, r.canvasHeight * r.textureMult);\n\n r.render({\n forcedContext: cxt,\n drawOnlyNodeLayer: true,\n forcedPxRatio: pixelRatio * r.textureMult\n });\n\n var vp = r.textureCache.viewport = {\n zoom: cy.zoom(),\n pan: cy.pan(),\n width: r.canvasWidth,\n height: r.canvasHeight\n };\n\n vp.mpan = {\n x: (0 - vp.pan.x)/vp.zoom,\n y: (0 - vp.pan.y)/vp.zoom\n };\n }\n\n needDraw[r.DRAG] = false;\n needDraw[r.NODE] = false;\n\n var context = data.contexts[r.NODE];\n\n var texture = r.textureCache.texture;\n var vp = r.textureCache.viewport;\n bb = r.textureCache.bb;\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n\n if( motionBlur ){\n mbclear(context, 0, 0, vp.width, vp.height);\n } else {\n context.clearRect(0, 0, vp.width, vp.height);\n }\n\n var outsideBgColor = coreStyle['outside-texture-bg-color'].value;\n var outsideBgOpacity = coreStyle['outside-texture-bg-opacity'].value;\n r.fillStyle( context, outsideBgColor[0], outsideBgColor[1], outsideBgColor[2], outsideBgOpacity );\n context.fillRect( 0, 0, vp.width, vp.height );\n\n var zoom = cy.zoom();\n\n setContextTransform( context, false );\n\n context.clearRect( vp.mpan.x, vp.mpan.y, vp.width/vp.zoom/pixelRatio, vp.height/vp.zoom/pixelRatio );\n context.drawImage( texture, vp.mpan.x, vp.mpan.y, vp.width/vp.zoom/pixelRatio, vp.height/vp.zoom/pixelRatio );\n\n } else if( r.textureOnViewport && !forcedContext ){ // clear the cache since we don't need it\n r.textureCache = null;\n }\n\n var vpManip = (r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming || r.hoverData.draggingEles);\n var hideEdges = r.hideEdgesOnViewport && vpManip;\n var hideLabels = r.hideLabelsOnViewport && vpManip;\n\n if (needDraw[r.DRAG] || needDraw[r.NODE] || drawAllLayers || drawOnlyNodeLayer) {\n if( hideEdges ){\n } else {\n r.findEdgeControlPoints(edges);\n }\n\n var zEles = r.getCachedZSortedEles();\n var extent = cy.extent();\n\n for (var i = 0; i < zEles.length; i++) {\n var ele = zEles[i];\n var list;\n var bb = forcedContext ? null : ele.boundingBox();\n var insideExtent = forcedContext ? true : math.boundingBoxesIntersect( extent, bb );\n\n if( !insideExtent ){ continue; } // no need to render\n\n if ( ele._private.rscratch.inDragLayer ) {\n list = eles.drag;\n } else {\n list = eles.nondrag;\n }\n\n list.eles.push( ele );\n }\n\n }\n\n\n function drawElements( list, context ){\n var eles = list.eles;\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n\n if( ele.isNode() ){\n r.drawNode(context, ele);\n\n if( !hideLabels ){\n r.drawNodeText(context, ele);\n }\n\n r.drawNode(context, ele, true);\n } else if( !hideEdges ) {\n r.drawEdge(context, ele);\n\n if( !hideLabels ){\n r.drawEdgeText(context, ele);\n }\n\n r.drawEdge(context, ele, true);\n }\n\n\n }\n\n }\n\n var needMbClear = [];\n\n needMbClear[r.NODE] = !needDraw[r.NODE] && motionBlur && !r.clearedForMotionBlur[r.NODE] || r.clearingMotionBlur;\n if( needMbClear[r.NODE] ){ r.clearedForMotionBlur[r.NODE] = true; }\n\n needMbClear[r.DRAG] = !needDraw[r.DRAG] && motionBlur && !r.clearedForMotionBlur[r.DRAG] || r.clearingMotionBlur;\n if( needMbClear[r.DRAG] ){ r.clearedForMotionBlur[r.DRAG] = true; }\n\n if( needDraw[r.NODE] || drawAllLayers || drawOnlyNodeLayer || needMbClear[r.NODE] ){\n var useBuffer = motionBlur && !needMbClear[r.NODE] && mbPxRatio !== 1;\n var context = forcedContext || ( useBuffer ? r.data.bufferContexts[ r.MOTIONBLUR_BUFFER_NODE ] : data.contexts[r.NODE] );\n var clear = motionBlur && !useBuffer ? 'motionBlur' : undefined;\n\n setContextTransform( context, clear );\n drawElements(eles.nondrag, context);\n\n if( !drawAllLayers && !motionBlur ){\n needDraw[r.NODE] = false;\n }\n }\n\n if ( !drawOnlyNodeLayer && (needDraw[r.DRAG] || drawAllLayers || needMbClear[r.DRAG]) ) {\n var useBuffer = motionBlur && !needMbClear[r.DRAG] && mbPxRatio !== 1;\n var context = forcedContext || ( useBuffer ? r.data.bufferContexts[ r.MOTIONBLUR_BUFFER_DRAG ] : data.contexts[r.DRAG] );\n\n setContextTransform( context, motionBlur && !useBuffer ? 'motionBlur' : undefined );\n drawElements(eles.drag, context);\n\n if( !drawAllLayers && !motionBlur ){\n needDraw[r.DRAG] = false;\n }\n }\n\n if( r.showFps || (!drawOnlyNodeLayer && (needDraw[r.SELECT_BOX] && !drawAllLayers)) ) {\n var context = forcedContext || data.contexts[r.SELECT_BOX];\n\n setContextTransform( context );\n\n if( r.selection[4] == 1 && ( r.hoverData.selecting || r.touchData.selecting ) ){\n var zoom = r.cy.zoom();\n var borderWidth = coreStyle['selection-box-border-width'].value / zoom;\n\n context.lineWidth = borderWidth;\n context.fillStyle = \"rgba(\"\n + coreStyle['selection-box-color'].value[0] + \",\"\n + coreStyle['selection-box-color'].value[1] + \",\"\n + coreStyle['selection-box-color'].value[2] + \",\"\n + coreStyle['selection-box-opacity'].value + \")\";\n\n context.fillRect(\n r.selection[0],\n r.selection[1],\n r.selection[2] - r.selection[0],\n r.selection[3] - r.selection[1]);\n\n if (borderWidth > 0) {\n context.strokeStyle = \"rgba(\"\n + coreStyle['selection-box-border-color'].value[0] + \",\"\n + coreStyle['selection-box-border-color'].value[1] + \",\"\n + coreStyle['selection-box-border-color'].value[2] + \",\"\n + coreStyle['selection-box-opacity'].value + \")\";\n\n context.strokeRect(\n r.selection[0],\n r.selection[1],\n r.selection[2] - r.selection[0],\n r.selection[3] - r.selection[1]);\n }\n }\n\n if( data.bgActivePosistion && !r.hoverData.selecting ){\n var zoom = r.cy.zoom();\n var pos = data.bgActivePosistion;\n\n context.fillStyle = \"rgba(\"\n + coreStyle['active-bg-color'].value[0] + \",\"\n + coreStyle['active-bg-color'].value[1] + \",\"\n + coreStyle['active-bg-color'].value[2] + \",\"\n + coreStyle['active-bg-opacity'].value + \")\";\n\n context.beginPath();\n context.arc(pos.x, pos.y, coreStyle['active-bg-size'].pfValue / zoom, 0, 2 * Math.PI);\n context.fill();\n }\n\n var timeToRender = r.lastRedrawTime;\n if( r.showFps && timeToRender ){\n timeToRender = Math.round( timeToRender );\n var fps = Math.round(1000/timeToRender);\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n\n context.fillStyle = 'rgba(255, 0, 0, 0.75)';\n context.strokeStyle = 'rgba(255, 0, 0, 0.75)';\n context.lineWidth = 1;\n context.fillText( '1 frame = ' + timeToRender + ' ms = ' + fps + ' fps', 0, 20);\n\n var maxFps = 60;\n context.strokeRect(0, 30, 250, 20);\n context.fillRect(0, 30, 250 * Math.min(fps/maxFps, 1), 20);\n }\n\n if( !drawAllLayers ){\n needDraw[r.SELECT_BOX] = false;\n }\n }\n\n // motionblur: blit rendered blurry frames\n if( motionBlur && mbPxRatio !== 1 ){\n var cxtNode = data.contexts[r.NODE];\n var txtNode = r.data.bufferCanvases[ r.MOTIONBLUR_BUFFER_NODE ];\n\n var cxtDrag = data.contexts[r.DRAG];\n var txtDrag = r.data.bufferCanvases[ r.MOTIONBLUR_BUFFER_DRAG ];\n\n var drawMotionBlur = function( cxt, txt, needClear ){\n cxt.setTransform(1, 0, 0, 1, 0, 0);\n\n if( needClear || !motionBlurFadeEffect ){\n cxt.clearRect( 0, 0, r.canvasWidth, r.canvasHeight );\n } else {\n mbclear( cxt, 0, 0, r.canvasWidth, r.canvasHeight );\n }\n\n var pxr = mbPxRatio;\n\n cxt.drawImage(\n txt, // img\n 0, 0, // sx, sy\n r.canvasWidth * pxr, r.canvasHeight * pxr, // sw, sh\n 0, 0, // x, y\n r.canvasWidth, r.canvasHeight // w, h\n );\n };\n\n if( needDraw[r.NODE] || needMbClear[r.NODE] ){\n drawMotionBlur( cxtNode, txtNode, needMbClear[r.NODE] );\n needDraw[r.NODE] = false;\n }\n\n if( needDraw[r.DRAG] || needMbClear[r.DRAG] ){\n drawMotionBlur( cxtDrag, txtDrag, needMbClear[r.DRAG] );\n needDraw[r.DRAG] = false;\n }\n }\n\n r.currentlyDrawing = false;\n\n r.prevViewport = vp;\n\n if( r.clearingMotionBlur ){\n r.clearingMotionBlur = false;\n r.motionBlurCleared = true;\n r.motionBlur = true;\n }\n\n if( motionBlur ){\n r.motionBlurTimeout = setTimeout(function(){\n r.motionBlurTimeout = null;\n\n r.clearedForMotionBlur[r.NODE] = false;\n r.clearedForMotionBlur[r.DRAG] = false;\n r.motionBlur = false;\n r.clearingMotionBlur = !textureDraw;\n r.mbFrames = 0;\n\n needDraw[r.NODE] = true;\n needDraw[r.DRAG] = true;\n\n r.redraw();\n }, motionBlurDelay);\n }\n\n r.drawingImage = false;\n\n\n if( !forcedContext && !r.initrender ){\n r.initrender = true;\n cy.trigger('initrender');\n }\n\n if( !forcedContext ){\n cy.triggerOnRender();\n }\n\n};\n\nmodule.exports = CRp;\n","'use strict';\n\n var math = require('../../../math');\n\n var CRp = {};\n\n // @O Polygon drawing\n CRp.drawPolygonPath = function(\n context, x, y, width, height, points) {\n\n var halfW = width / 2;\n var halfH = height / 2;\n\n if( context.beginPath ){ context.beginPath(); }\n\n context.moveTo( x + halfW * points[0], y + halfH * points[1] );\n\n for (var i = 1; i < points.length / 2; i++) {\n context.lineTo( x + halfW * points[i * 2], y + halfH * points[i * 2 + 1] );\n }\n\n context.closePath();\n };\n\n // Round rectangle drawing\n CRp.drawRoundRectanglePath = function(\n context, x, y, width, height, radius) {\n\n var halfWidth = width / 2;\n var halfHeight = height / 2;\n var cornerRadius = math.getRoundRectangleRadius(width, height);\n\n if( context.beginPath ){ context.beginPath(); }\n\n // Start at top middle\n context.moveTo(x, y - halfHeight);\n // Arc from middle top to right side\n context.arcTo(x + halfWidth, y - halfHeight, x + halfWidth, y, cornerRadius);\n // Arc from right side to bottom\n context.arcTo(x + halfWidth, y + halfHeight, x, y + halfHeight, cornerRadius);\n // Arc from bottom to left side\n context.arcTo(x - halfWidth, y + halfHeight, x - halfWidth, y, cornerRadius);\n // Arc from left side to topBorder\n context.arcTo(x - halfWidth, y - halfHeight, x, y - halfHeight, cornerRadius);\n // Join line\n context.lineTo(x, y - halfHeight);\n\n\n context.closePath();\n };\n\n var sin0 = Math.sin(0);\n var cos0 = Math.cos(0);\n\n var sin = {};\n var cos = {};\n\n var ellipseStepSize = Math.PI / 40;\n\n for (var i = 0 * Math.PI; i < 2 * Math.PI; i += ellipseStepSize ) {\n sin[i] = Math.sin(i);\n cos[i] = Math.cos(i);\n }\n\n CRp.drawEllipsePath = function(context, centerX, centerY, width, height){\n if( context.beginPath ){ context.beginPath(); }\n\n if( context.ellipse ){\n context.ellipse( centerX, centerY, width/2, height/2, 0, 0, 2*Math.PI );\n } else {\n var xPos, yPos;\n var rw = width/2;\n var rh = height/2;\n for (var i = 0 * Math.PI; i < 2 * Math.PI; i += ellipseStepSize ) {\n xPos = centerX - (rw * sin[i]) * sin0 + (rw * cos[i]) * cos0;\n yPos = centerY + (rh * cos[i]) * sin0 + (rh * sin[i]) * cos0;\n\n if (i === 0) {\n context.moveTo(xPos, yPos);\n } else {\n context.lineTo(xPos, yPos);\n }\n }\n }\n\n context.closePath();\n };\n\nmodule.exports = CRp;\n","'use strict';\n\nvar is = require('../../../is');\n\nvar CRp = {};\n\nCRp.createBuffer = function(w, h) {\n var buffer = document.createElement('canvas');\n buffer.width = w;\n buffer.height = h;\n\n return [buffer, buffer.getContext('2d')];\n};\n\nCRp.bufferCanvasImage = function( options ){\n var cy = this.cy;\n var bb = cy.elements().boundingBox();\n var width = options.full ? Math.ceil(bb.w) : this.container.clientWidth;\n var height = options.full ? Math.ceil(bb.h) : this.container.clientHeight;\n var scale = 1;\n\n if( options.scale !== undefined ){\n width *= options.scale;\n height *= options.scale;\n\n scale = options.scale;\n } else if( is.number(options.maxWidth) || is.number(options.maxHeight) ){\n var maxScaleW = Infinity;\n var maxScaleH = Infinity;\n\n if( is.number(options.maxWidth) ){\n maxScaleW = scale * options.maxWidth / width;\n }\n\n if( is.number(options.maxHeight) ){\n maxScaleH = scale * options.maxHeight / height;\n }\n\n scale = Math.min( maxScaleW, maxScaleH );\n\n width *= scale;\n height *= scale;\n }\n\n var buffCanvas = document.createElement('canvas');\n\n buffCanvas.width = width;\n buffCanvas.height = height;\n\n buffCanvas.style.width = width + 'px';\n buffCanvas.style.height = height + 'px';\n\n var buffCxt = buffCanvas.getContext('2d');\n\n // Rasterize the layers, but only if container has nonzero size\n if (width > 0 && height > 0) {\n\n buffCxt.clearRect( 0, 0, width, height );\n\n if( options.bg ){\n buffCxt.fillStyle = options.bg;\n buffCxt.rect( 0, 0, width, height );\n buffCxt.fill();\n }\n\n buffCxt.globalCompositeOperation = 'source-over';\n\n if( options.full ){ // draw the full bounds of the graph\n this.render({\n forcedContext: buffCxt,\n drawAllLayers: true,\n forcedZoom: scale,\n forcedPan: { x: -bb.x1*scale, y: -bb.y1*scale },\n forcedPxRatio: 1\n });\n } else { // draw the current view\n var cyPan = cy.pan();\n var pan = {\n x: cyPan.x * scale,\n y: cyPan.y * scale\n };\n var zoom = cy.zoom() * scale;\n\n this.render({\n forcedContext: buffCxt,\n drawAllLayers: true,\n forcedZoom: zoom,\n forcedPan: pan,\n forcedPxRatio: 1\n });\n }\n }\n\n return buffCanvas;\n};\n\nCRp.png = function( options ){\n return this.bufferCanvasImage( options ).toDataURL('image/png');\n};\n\nCRp.jpg = function( options ){\n return this.bufferCanvasImage( options ).toDataURL('image/jpeg');\n};\n\nmodule.exports = CRp;\n","/*\nThe canvas renderer was written by Yue Dong.\n\nModifications tracked on Github.\n*/\n\n'use strict';\n\nvar util = require('../../../util');\nvar is = require('../../../is');\n\nvar CR = CanvasRenderer;\nvar CRp = CanvasRenderer.prototype;\n\nCRp.CANVAS_LAYERS = 3;\n//\nCRp.SELECT_BOX = 0;\nCRp.DRAG = 1;\nCRp.NODE = 2;\n\nCRp.BUFFER_COUNT = 3;\n//\nCRp.TEXTURE_BUFFER = 0;\nCRp.MOTIONBLUR_BUFFER_NODE = 1;\nCRp.MOTIONBLUR_BUFFER_DRAG = 2;\n\nfunction CanvasRenderer(options) {\n var r = this;\n\n r.data = {\n canvases: new Array(CRp.CANVAS_LAYERS),\n contexts: new Array(CRp.CANVAS_LAYERS),\n canvasNeedsRedraw: new Array(CRp.CANVAS_LAYERS),\n\n bufferCanvases: new Array(CRp.BUFFER_COUNT),\n bufferContexts: new Array(CRp.CANVAS_LAYERS)\n };\n\n r.data.canvasContainer = document.createElement('div');\n var containerStyle = r.data.canvasContainer.style;\n r.data.canvasContainer.setAttribute('style', '-webkit-tap-highlight-color: rgba(0,0,0,0);');\n containerStyle.position = 'relative';\n containerStyle.zIndex = '0';\n containerStyle.overflow = 'hidden';\n\n var container = options.cy.container();\n container.appendChild( r.data.canvasContainer );\n container.setAttribute('style', ( container.getAttribute('style') || '' ) + '-webkit-tap-highlight-color: rgba(0,0,0,0);');\n\n for (var i = 0; i < CRp.CANVAS_LAYERS; i++) {\n var canvas = r.data.canvases[i] = document.createElement('canvas');\n r.data.contexts[i] = canvas.getContext('2d');\n canvas.setAttribute( 'style', '-webkit-user-select: none; -moz-user-select: -moz-none; user-select: none; -webkit-tap-highlight-color: rgba(0,0,0,0); outline-style: none;' + ( is.ms() ? ' -ms-touch-action: none; touch-action: none; ' : '' ) );\n canvas.style.position = 'absolute';\n canvas.setAttribute('data-id', 'layer' + i);\n canvas.style.zIndex = String(CRp.CANVAS_LAYERS - i);\n r.data.canvasContainer.appendChild(canvas);\n\n r.data.canvasNeedsRedraw[i] = false;\n }\n r.data.topCanvas = r.data.canvases[0];\n\n r.data.canvases[CRp.NODE].setAttribute('data-id', 'layer' + CRp.NODE + '-node');\n r.data.canvases[CRp.SELECT_BOX].setAttribute('data-id', 'layer' + CRp.SELECT_BOX + '-selectbox');\n r.data.canvases[CRp.DRAG].setAttribute('data-id', 'layer' + CRp.DRAG + '-drag');\n\n for (var i = 0; i < CRp.BUFFER_COUNT; i++) {\n r.data.bufferCanvases[i] = document.createElement('canvas');\n r.data.bufferContexts[i] = r.data.bufferCanvases[i].getContext('2d');\n r.data.bufferCanvases[i].style.position = 'absolute';\n r.data.bufferCanvases[i].setAttribute('data-id', 'buffer' + i);\n r.data.bufferCanvases[i].style.zIndex = String(-i - 1);\n r.data.bufferCanvases[i].style.visibility = 'hidden';\n //r.data.canvasContainer.appendChild(r.data.bufferCanvases[i]);\n }\n\n r.pathsEnabled = true;\n}\n\nCRp.redrawHint = function( group, bool ){\n var r = this;\n\n switch( group ){\n case 'eles':\n r.data.canvasNeedsRedraw[ CRp.NODE ] = bool;\n break;\n case 'drag':\n r.data.canvasNeedsRedraw[ CRp.DRAG ] = bool;\n break;\n case 'select':\n r.data.canvasNeedsRedraw[ CRp.SELECT_BOX ] = bool;\n break;\n }\n};\n\n// whether to use Path2D caching for drawing\nvar pathsImpld = typeof Path2D !== 'undefined';\n\nCRp.path2dEnabled = function( on ){\n if( on === undefined ){\n return this.pathsEnabled;\n }\n\n this.pathsEnabled = on ? true : false;\n};\n\nCRp.usePaths = function(){\n return pathsImpld && this.pathsEnabled;\n};\n\n[\n require('./arrow-shapes'),\n require('./drawing-edges'),\n require('./drawing-images'),\n require('./drawing-label-text'),\n require('./drawing-nodes'),\n require('./drawing-redraw'),\n require('./drawing-shapes'),\n require('./export-image'),\n require('./node-shapes')\n].forEach(function( props ){\n util.extend( CRp, props );\n});\n\nmodule.exports = CR;\n","'use strict';\n\nvar CRp = {};\n\nvar impl;\n\nCRp.nodeShapeImpl = function( name ){\n var self = this;\n\n return ( impl || (impl = {\n 'ellipse': function( context, centerX, centerY, width, height ){\n self.drawEllipsePath( context, centerX, centerY, width, height );\n },\n\n 'polygon': function( context, centerX, centerY, width, height, points ){\n self.drawPolygonPath( context, centerX, centerY, width, height, points );\n },\n\n 'roundrectangle': function( context, centerX, centerY, width, height ){\n self.drawRoundRectanglePath( context, centerX, centerY, width, height, 10 );\n }\n }) )[ name ];\n};\n\nmodule.exports = CRp;\n","'use strict';\n\nmodule.exports = [\n { name: 'null', impl: require('./null') },\n { name: 'base', impl: require('./base') },\n { name: 'canvas', impl: require('./canvas') }\n];\n","'use strict';\n\nfunction NullRenderer(options){\n this.options = options;\n this.notifications = 0; // for testing\n}\n\nvar noop = function(){};\n\nNullRenderer.prototype = {\n recalculateRenderedStyle: noop,\n notify: function(){ this.notifications++; },\n init: noop\n};\n\nmodule.exports = NullRenderer;\n","'use strict';\n\nvar is = require('./is');\nvar util = require('./util');\nvar Thread = require('./thread');\nvar Promise = require('./promise');\nvar define = require('./define');\n\nvar Fabric = function( N ){\n if( !(this instanceof Fabric) ){\n return new Fabric( N );\n }\n\n this._private = {\n pass: []\n };\n\n var defN = 4;\n\n if( is.number(N) ){\n // then use the specified number of threads\n } if( typeof navigator !== 'undefined' && navigator.hardwareConcurrency != null ){\n N = navigator.hardwareConcurrency;\n } else {\n try{\n N = require('os').cpus().length;\n } catch( err ){\n N = defN;\n }\n } // TODO could use an estimation here but would the additional expense be worth it?\n\n for( var i = 0; i < N; i++ ){\n this[i] = new Thread();\n }\n\n this.length = N;\n};\n\nvar fabfn = Fabric.prototype; // short alias\n\nutil.extend(fabfn, {\n\n instanceString: function(){ return 'fabric'; },\n\n // require fn in all threads\n require: function( fn, as ){\n for( var i = 0; i < this.length; i++ ){\n var thread = this[i];\n\n thread.require( fn, as );\n }\n\n return this;\n },\n\n // get a random thread\n random: function(){\n var i = Math.round( (this.length - 1) * Math.random() );\n var thread = this[i];\n\n return thread;\n },\n\n // run on random thread\n run: function( fn ){\n var pass = this._private.pass.shift();\n\n return this.random().pass( pass ).run( fn );\n },\n\n // sends a random thread a message\n message: function( m ){\n return this.random().message( m );\n },\n\n // send all threads a message\n broadcast: function( m ){\n for( var i = 0; i < this.length; i++ ){\n var thread = this[i];\n\n thread.message( m );\n }\n\n return this; // chaining\n },\n\n // stop all threads\n stop: function(){\n for( var i = 0; i < this.length; i++ ){\n var thread = this[i];\n\n thread.stop();\n }\n\n return this; // chaining\n },\n\n // pass data to be used with .spread() etc.\n pass: function( data ){\n var pass = this._private.pass;\n\n if( is.array(data) ){\n pass.push( data );\n } else {\n throw 'Only arrays may be used with fabric.pass()';\n }\n\n return this; // chaining\n },\n\n spreadSize: function(){\n var subsize = Math.ceil( this._private.pass[0].length / this.length );\n\n subsize = Math.max( 1, subsize ); // don't pass less than one ele to each thread\n\n return subsize;\n },\n\n // split the data into slices to spread the data equally among threads\n spread: function( fn ){\n var self = this;\n var _p = self._private;\n var subsize = self.spreadSize(); // number of pass eles to handle in each thread\n var pass = _p.pass.shift().concat([]); // keep a copy\n var runPs = [];\n\n for( var i = 0; i < this.length; i++ ){\n var thread = this[i];\n var slice = pass.splice( 0, subsize );\n\n var runP = thread.pass( slice ).run( fn );\n\n runPs.push( runP );\n\n var doneEarly = pass.length === 0;\n if( doneEarly ){ break; }\n }\n\n return Promise.all( runPs ).then(function( thens ){\n var postpass = [];\n var p = 0;\n\n // fill postpass with the total result joined from all threads\n for( var i = 0; i < thens.length; i++ ){\n var then = thens[i]; // array result from thread i\n\n for( var j = 0; j < then.length; j++ ){\n var t = then[j]; // array element\n\n postpass[ p++ ] = t;\n }\n }\n\n return postpass;\n });\n },\n\n // parallel version of array.map()\n map: function( fn ){\n var self = this;\n\n self.require( fn, '_$_$_fabmap' );\n\n return self.spread(function( split ){\n var mapped = [];\n var origResolve = resolve; // jshint ignore:line\n\n resolve = function( val ){ // jshint ignore:line\n mapped.push( val );\n };\n\n for( var i = 0; i < split.length; i++ ){\n var oldLen = mapped.length;\n var ret = _$_$_fabmap( split[i] ); // jshint ignore:line\n var nothingInsdByResolve = oldLen === mapped.length;\n\n if( nothingInsdByResolve ){\n mapped.push( ret );\n }\n }\n\n resolve = origResolve; // jshint ignore:line\n\n return mapped;\n });\n\n },\n\n // parallel version of array.filter()\n filter: function( fn ){\n var _p = this._private;\n var pass = _p.pass[0];\n\n return this.map( fn ).then(function( include ){\n var ret = [];\n\n for( var i = 0; i < pass.length; i++ ){\n var datum = pass[i];\n var incDatum = include[i];\n\n if( incDatum ){\n ret.push( datum );\n }\n }\n\n return ret;\n });\n },\n\n // sorts the passed array using a divide and conquer strategy\n sort: function( cmp ){\n var self = this;\n var P = this._private.pass[0].length;\n var subsize = this.spreadSize();\n\n cmp = cmp || function( a, b ){ // default comparison function\n if( a < b ){\n return -1;\n } else if( a > b ){\n return 1;\n }\n\n return 0;\n };\n\n self.require( cmp, '_$_$_cmp' );\n\n return self.spread(function( split ){ // sort each split normally\n var sortedSplit = split.sort( _$_$_cmp ); // jshint ignore:line\n resolve( sortedSplit ); // jshint ignore:line\n\n }).then(function( joined ){\n // do all the merging in the main thread to minimise data transfer\n\n // TODO could do merging in separate threads but would incur add'l cost of data transfer\n // for each level of the merge\n\n var merge = function( i, j, max ){\n // don't overflow array\n j = Math.min( j, P );\n max = Math.min( max, P );\n\n // left and right sides of merge\n var l = i;\n var r = j;\n\n var sorted = [];\n\n for( var k = l; k < max; k++ ){\n\n var eleI = joined[i];\n var eleJ = joined[j];\n\n if( i < r && ( j >= max || cmp(eleI, eleJ) <= 0 ) ){\n sorted.push( eleI );\n i++;\n } else {\n sorted.push( eleJ );\n j++;\n }\n\n }\n\n // in the array proper, put the sorted values\n for( var k = 0; k < sorted.length; k++ ){ // kth sorted item\n var index = l + k;\n\n joined[ index ] = sorted[k];\n }\n };\n\n for( var splitL = subsize; splitL < P; splitL *= 2 ){ // merge until array is \"split\" as 1\n\n for( var i = 0; i < P; i += 2*splitL ){\n merge( i, i + splitL, i + 2*splitL );\n }\n\n }\n\n return joined;\n });\n }\n\n\n});\n\nvar defineRandomPasser = function( opts ){\n opts = opts || {};\n\n return function( fn, arg1 ){\n var pass = this._private.pass.shift();\n\n return this.random().pass( pass )[ opts.threadFn ]( fn, arg1 );\n };\n};\n\nutil.extend(fabfn, {\n randomMap: defineRandomPasser({ threadFn: 'map' }),\n\n reduce: defineRandomPasser({ threadFn: 'reduce' }),\n\n reduceRight: defineRandomPasser({ threadFn: 'reduceRight' })\n});\n\n// aliases\nvar fn = fabfn;\nfn.promise = fn.run;\nfn.terminate = fn.halt = fn.stop;\nfn.include = fn.require;\n\n// pull in event apis\nutil.extend(fabfn, {\n on: define.on(),\n one: define.on({ unbindSelfOnTrigger: true }),\n off: define.off(),\n trigger: define.trigger()\n});\n\ndefine.eventAliasesOn( fabfn );\n\nmodule.exports = Fabric;\n","'use strict';\n/* jshint ignore:start */\n\n// Generated by CoffeeScript 1.8.0\n(function() {\n var Heap, defaultCmp, floor, heapify, heappop, heappush, heappushpop, heapreplace, insort, min, nlargest, nsmallest, updateItem, _siftdown, _siftup;\n\n floor = Math.floor, min = Math.min;\n\n\n /*\n Default comparison function to be used\n */\n\n defaultCmp = function(x, y) {\n if (x < y) {\n return -1;\n }\n if (x > y) {\n return 1;\n }\n return 0;\n };\n\n\n /*\n Insert item x in list a, and keep it sorted assuming a is sorted.\n\n If x is already in a, insert it to the right of the rightmost x.\n\n Optional args lo (default 0) and hi (default a.length) bound the slice\n of a to be searched.\n */\n\n insort = function(a, x, lo, hi, cmp) {\n var mid;\n if (lo == null) {\n lo = 0;\n }\n if (cmp == null) {\n cmp = defaultCmp;\n }\n if (lo < 0) {\n throw new Error('lo must be non-negative');\n }\n if (hi == null) {\n hi = a.length;\n }\n while (lo < hi) {\n mid = floor((lo + hi) / 2);\n if (cmp(x, a[mid]) < 0) {\n hi = mid;\n } else {\n lo = mid + 1;\n }\n }\n return ([].splice.apply(a, [lo, lo - lo].concat(x)), x);\n };\n\n\n /*\n Push item onto heap, maintaining the heap invariant.\n */\n\n heappush = function(array, item, cmp) {\n if (cmp == null) {\n cmp = defaultCmp;\n }\n array.push(item);\n return _siftdown(array, 0, array.length - 1, cmp);\n };\n\n\n /*\n Pop the smallest item off the heap, maintaining the heap invariant.\n */\n\n heappop = function(array, cmp) {\n var lastelt, returnitem;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n lastelt = array.pop();\n if (array.length) {\n returnitem = array[0];\n array[0] = lastelt;\n _siftup(array, 0, cmp);\n } else {\n returnitem = lastelt;\n }\n return returnitem;\n };\n\n\n /*\n Pop and return the current smallest value, and add the new item.\n\n This is more efficient than heappop() followed by heappush(), and can be\n more appropriate when using a fixed size heap. Note that the value\n returned may be larger than item! That constrains reasonable use of\n this routine unless written as part of a conditional replacement:\n if item > array[0]\n item = heapreplace(array, item)\n */\n\n heapreplace = function(array, item, cmp) {\n var returnitem;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n returnitem = array[0];\n array[0] = item;\n _siftup(array, 0, cmp);\n return returnitem;\n };\n\n\n /*\n Fast version of a heappush followed by a heappop.\n */\n\n heappushpop = function(array, item, cmp) {\n var _ref;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n if (array.length && cmp(array[0], item) < 0) {\n _ref = [array[0], item], item = _ref[0], array[0] = _ref[1];\n _siftup(array, 0, cmp);\n }\n return item;\n };\n\n\n /*\n Transform list into a heap, in-place, in O(array.length) time.\n */\n\n heapify = function(array, cmp) {\n var i, _i, _j, _len, _ref, _ref1, _results, _results1;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n _ref1 = (function() {\n _results1 = [];\n for (var _j = 0, _ref = floor(array.length / 2); 0 <= _ref ? _j < _ref : _j > _ref; 0 <= _ref ? _j++ : _j--){ _results1.push(_j); }\n return _results1;\n }).apply(this).reverse();\n _results = [];\n for (_i = 0, _len = _ref1.length; _i < _len; _i++) {\n i = _ref1[_i];\n _results.push(_siftup(array, i, cmp));\n }\n return _results;\n };\n\n\n /*\n Update the position of the given item in the heap.\n This function should be called every time the item is being modified.\n */\n\n updateItem = function(array, item, cmp) {\n var pos;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n pos = array.indexOf(item);\n if (pos === -1) {\n return;\n }\n _siftdown(array, 0, pos, cmp);\n return _siftup(array, pos, cmp);\n };\n\n\n /*\n Find the n largest elements in a dataset.\n */\n\n nlargest = function(array, n, cmp) {\n var elem, result, _i, _len, _ref;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n result = array.slice(0, n);\n if (!result.length) {\n return result;\n }\n heapify(result, cmp);\n _ref = array.slice(n);\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n elem = _ref[_i];\n heappushpop(result, elem, cmp);\n }\n return result.sort(cmp).reverse();\n };\n\n\n /*\n Find the n smallest elements in a dataset.\n */\n\n nsmallest = function(array, n, cmp) {\n var elem, i, los, result, _i, _j, _len, _ref, _ref1, _results;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n if (n * 10 <= array.length) {\n result = array.slice(0, n).sort(cmp);\n if (!result.length) {\n return result;\n }\n los = result[result.length - 1];\n _ref = array.slice(n);\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n elem = _ref[_i];\n if (cmp(elem, los) < 0) {\n insort(result, elem, 0, null, cmp);\n result.pop();\n los = result[result.length - 1];\n }\n }\n return result;\n }\n heapify(array, cmp);\n _results = [];\n for (i = _j = 0, _ref1 = min(n, array.length); 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 0 <= _ref1 ? ++_j : --_j) {\n _results.push(heappop(array, cmp));\n }\n return _results;\n };\n\n _siftdown = function(array, startpos, pos, cmp) {\n var newitem, parent, parentpos;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n newitem = array[pos];\n while (pos > startpos) {\n parentpos = (pos - 1) >> 1;\n parent = array[parentpos];\n if (cmp(newitem, parent) < 0) {\n array[pos] = parent;\n pos = parentpos;\n continue;\n }\n break;\n }\n return array[pos] = newitem;\n };\n\n _siftup = function(array, pos, cmp) {\n var childpos, endpos, newitem, rightpos, startpos;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n endpos = array.length;\n startpos = pos;\n newitem = array[pos];\n childpos = 2 * pos + 1;\n while (childpos < endpos) {\n rightpos = childpos + 1;\n if (rightpos < endpos && !(cmp(array[childpos], array[rightpos]) < 0)) {\n childpos = rightpos;\n }\n array[pos] = array[childpos];\n pos = childpos;\n childpos = 2 * pos + 1;\n }\n array[pos] = newitem;\n return _siftdown(array, startpos, pos, cmp);\n };\n\n Heap = (function() {\n Heap.push = heappush;\n\n Heap.pop = heappop;\n\n Heap.replace = heapreplace;\n\n Heap.pushpop = heappushpop;\n\n Heap.heapify = heapify;\n\n Heap.updateItem = updateItem;\n\n Heap.nlargest = nlargest;\n\n Heap.nsmallest = nsmallest;\n\n function Heap(cmp) {\n this.cmp = cmp != null ? cmp : defaultCmp;\n this.nodes = [];\n }\n\n Heap.prototype.push = function(x) {\n return heappush(this.nodes, x, this.cmp);\n };\n\n Heap.prototype.pop = function() {\n return heappop(this.nodes, this.cmp);\n };\n\n Heap.prototype.peek = function() {\n return this.nodes[0];\n };\n\n Heap.prototype.contains = function(x) {\n return this.nodes.indexOf(x) !== -1;\n };\n\n Heap.prototype.replace = function(x) {\n return heapreplace(this.nodes, x, this.cmp);\n };\n\n Heap.prototype.pushpop = function(x) {\n return heappushpop(this.nodes, x, this.cmp);\n };\n\n Heap.prototype.heapify = function() {\n return heapify(this.nodes, this.cmp);\n };\n\n Heap.prototype.updateItem = function(x) {\n return updateItem(this.nodes, x, this.cmp);\n };\n\n Heap.prototype.clear = function() {\n return this.nodes = [];\n };\n\n Heap.prototype.empty = function() {\n return this.nodes.length === 0;\n };\n\n Heap.prototype.size = function() {\n return this.nodes.length;\n };\n\n Heap.prototype.clone = function() {\n var heap;\n heap = new Heap();\n heap.nodes = this.nodes.slice(0);\n return heap;\n };\n\n Heap.prototype.toArray = function() {\n return this.nodes.slice(0);\n };\n\n Heap.prototype.insert = Heap.prototype.push;\n\n Heap.prototype.top = Heap.prototype.peek;\n\n Heap.prototype.front = Heap.prototype.peek;\n\n Heap.prototype.has = Heap.prototype.contains;\n\n Heap.prototype.copy = Heap.prototype.clone;\n\n return Heap;\n\n })();\n\n (function(root, factory) {\n if (typeof define === 'function' && define.amd) {\n return define([], factory);\n } else if (typeof exports === 'object') {\n return module.exports = factory();\n } else {\n return root.Heap = factory();\n }\n })(this, function() {\n return Heap;\n });\n\n}).call(this);\n\n/* jshint ignore:end */\n","'use strict';\n\nvar window = require('./window');\nvar is = require('./is');\nvar Core = require('./core');\nvar extension = require('./extension');\nvar registerJquery = require('./jquery-plugin');\nvar Stylesheet = require('./stylesheet');\nvar Thread = require('./thread');\nvar Fabric = require('./fabric');\n\nvar cytoscape = function( options ){ // jshint ignore:line\n // if no options specified, use default\n if( options === undefined ){\n options = {};\n }\n\n // create instance\n if( is.plainObject( options ) ){\n return new Core( options );\n }\n\n // allow for registration of extensions\n else if( is.string( options ) ) {\n return extension.apply(extension, arguments);\n }\n};\n\n// replaced by build system\ncytoscape.version = '{{VERSION}}';\n\n// try to register w/ jquery\nif( window && window.jQuery ){\n registerJquery( window.jQuery, cytoscape );\n}\n\n// expose register api\ncytoscape.registerJquery = function( jQuery ){\n registerJquery( jQuery, cytoscape );\n};\n\n// expose public apis (mostly for extensions)\ncytoscape.stylesheet = cytoscape.Stylesheet = Stylesheet;\ncytoscape.thread = cytoscape.Thread = Thread;\ncytoscape.fabric = cytoscape.Fabric = Fabric;\n\nmodule.exports = cytoscape;\n","'use strict';\n\nvar window = require('./window');\nvar navigator = window ? window.navigator : null;\n\nvar typeofstr = typeof '';\nvar typeofobj = typeof {};\nvar typeoffn = typeof function(){};\nvar typeofhtmlele = typeof HTMLElement;\n\nvar instanceStr = function( obj ){\n return obj && obj.instanceString && is.fn( obj.instanceString ) ? obj.instanceString() : null;\n};\n\nvar is = {\n defined: function(obj){\n return obj != null; // not undefined or null\n },\n\n string: function(obj){\n return obj != null && typeof obj == typeofstr;\n },\n\n fn: function(obj){\n return obj != null && typeof obj === typeoffn;\n },\n\n array: function(obj){\n return Array.isArray ? Array.isArray(obj) : obj != null && obj instanceof Array;\n },\n\n plainObject: function(obj){\n return obj != null && typeof obj === typeofobj && !is.array(obj) && obj.constructor === Object;\n },\n\n object: function(obj){\n return obj != null && typeof obj === typeofobj;\n },\n\n number: function(obj){\n return obj != null && typeof obj === typeof 1 && !isNaN(obj);\n },\n\n integer: function( obj ){\n return is.number(obj) && Math.floor(obj) === obj;\n },\n\n bool: function(obj){\n return obj != null && typeof obj === typeof true;\n },\n\n htmlElement: function(obj){\n if( 'undefined' === typeofhtmlele ){\n return undefined;\n } else {\n return null != obj && obj instanceof HTMLElement;\n }\n },\n\n elementOrCollection: function(obj){\n return is.element(obj) || is.collection(obj);\n },\n\n element: function(obj){\n return instanceStr(obj) === 'collection' && obj._private.single;\n },\n\n collection: function(obj){\n return instanceStr(obj) === 'collection' && !obj._private.single;\n },\n\n core: function(obj){\n return instanceStr(obj) === 'core';\n },\n\n style: function(obj){\n return instanceStr(obj) === 'style';\n },\n\n stylesheet: function(obj){\n return instanceStr(obj) === 'stylesheet';\n },\n\n event: function(obj){\n return instanceStr(obj) === 'event';\n },\n\n thread: function(obj){\n return instanceStr(obj) === 'thread';\n },\n\n fabric: function(obj){\n return instanceStr(obj) === 'fabric';\n },\n\n emptyString: function(obj){\n if( !obj ){ // null is empty\n return true;\n } else if( is.string(obj) ){\n if( obj === '' || obj.match(/^\\s+$/) ){\n return true; // empty string is empty\n }\n }\n\n return false; // otherwise, we don't know what we've got\n },\n\n nonemptyString: function(obj){\n if( obj && is.string(obj) && obj !== '' && !obj.match(/^\\s+$/) ){\n return true;\n }\n\n return false;\n },\n\n domElement: function(obj){\n if( typeof HTMLElement === 'undefined' ){\n return false; // we're not in a browser so it doesn't matter\n } else {\n return obj instanceof HTMLElement;\n }\n },\n\n boundingBox: function(obj){\n return is.plainObject(obj) &&\n is.number(obj.x1) && is.number(obj.x2) &&\n is.number(obj.y1) && is.number(obj.y2)\n ;\n },\n\n promise: function(obj){\n return is.object(obj) && is.fn(obj.then);\n },\n\n touch: function(){\n return window && ( ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch );\n },\n\n gecko: function(){\n return typeof InstallTrigger !== 'undefined' || ('MozAppearance' in document.documentElement.style);\n },\n\n webkit: function(){\n return typeof webkitURL !== 'undefined' || ('WebkitAppearance' in document.documentElement.style);\n },\n\n chromium: function(){\n return typeof chrome !== 'undefined';\n },\n\n khtml: function(){\n return navigator && navigator.vendor.match(/kde/i); // probably a better way to detect this...\n },\n\n khtmlEtc: function(){\n return is.khtml() || is.webkit() || is.chromium();\n },\n\n ms: function(){\n return navigator && navigator.userAgent.match(/msie|trident|edge/i); // probably a better way to detect this...\n },\n\n windows: function(){\n return navigator && navigator.appVersion.match(/Win/i);\n },\n\n mac: function(){\n return navigator && navigator.appVersion.match(/Mac/i);\n },\n\n linux: function(){\n return navigator && navigator.appVersion.match(/Linux/i);\n },\n\n unix: function(){\n return navigator && navigator.appVersion.match(/X11/i);\n }\n};\n\nmodule.exports = is;\n","'use strict';\n\nvar is = require('./is');\n\nvar cyReg = function( $ele ){\n var d = $ele[0]._cyreg = $ele[0]._cyreg || {};\n\n return d;\n};\n\nvar registerJquery = function( $, cytoscape ){\n if( !$ ){ return; } // no jquery => don't need this\n\n if( $.fn.cytoscape ){ return; } // already registered\n\n // allow calls on a jQuery selector by proxying calls to $.cytoscape\n // e.g. $(\"#foo\").cytoscape(options) => $.cytoscape(options) on #foo\n $.fn.cytoscape = function(opts){\n var $this = $(this);\n\n // get object\n if( opts === 'get' ){\n return cyReg( $this ).cy;\n }\n\n // bind to ready\n else if( is.fn(opts) ){\n\n var ready = opts;\n var cy = cyReg( $this ).cy;\n\n if( cy && cy.isReady() ){ // already ready so just trigger now\n cy.trigger('ready', [], ready);\n\n } else { // not yet ready, so add to readies list\n var data = cyReg( $this );\n var readies = data.readies = data.readies || [];\n\n readies.push( ready );\n }\n\n }\n\n // proxy to create instance\n else if( is.plainObject(opts) ){\n return $this.each(function(){\n var options = $.extend({}, opts, {\n container: $(this)[0]\n });\n\n cytoscape(options);\n });\n }\n };\n\n // allow access to the global cytoscape object under jquery for legacy reasons\n $.cytoscape = cytoscape;\n\n // use short alias (cy) if not already defined\n if( $.fn.cy == null && $.cy == null ){\n $.fn.cy = $.fn.cytoscape;\n $.cy = $.cytoscape;\n }\n};\n\nmodule.exports = registerJquery;\n","'use strict';\n\nvar math = {};\n\nmath.signum = function(x){\n if( x > 0 ){\n return 1;\n } else if( x < 0 ){\n return -1;\n } else {\n return 0;\n }\n};\n\nmath.distance = function( p1, p2 ){\n return Math.sqrt( math.sqDistance(p1, p2) );\n};\n\nmath.sqDistance = function( p1, p2 ){\n var dx = p2.x - p1.x;\n var dy = p2.y - p1.y;\n\n return dx*dx + dy*dy;\n};\n\n// from http://en.wikipedia.org/wiki/Bézier_curve#Quadratic_curves\nmath.qbezierAt = function(p0, p1, p2, t){\n return (1 - t)*(1 - t)*p0 + 2*(1 - t)*t*p1 + t*t*p2;\n};\n\nmath.qbezierPtAt = function(p0, p1, p2, t){\n return {\n x: math.qbezierAt( p0.x, p1.x, p2.x, t ),\n y: math.qbezierAt( p0.y, p1.y, p2.y, t )\n };\n};\n\n// makes a full bb (x1, y1, x2, y2, w, h) from implicit params\nmath.makeBoundingBox = function( bb ){\n if( bb.x1 != null && bb.y1 != null ){\n if( bb.x2 != null && bb.y2 != null && bb.x2 >= bb.x1 && bb.y2 >= bb.y1 ){\n return {\n x1: bb.x1,\n y1: bb.y1,\n x2: bb.x2,\n y2: bb.y2,\n w: bb.x2 - bb.x1,\n h: bb.y2 - bb.y1\n };\n } else if( bb.w != null && bb.h != null && bb.w >= 0 && bb.h >= 0 ){\n return {\n x1: bb.x1,\n y1: bb.y1,\n x2: bb.x1 + bb.w,\n y2: bb.y1 + bb.h,\n w: bb.w,\n h: bb.h\n };\n }\n }\n};\n\nmath.boundingBoxesIntersect = function( bb1, bb2 ){\n // case: one bb to right of other\n if( bb1.x1 > bb2.x2 ){ return false; }\n if( bb2.x1 > bb1.x2 ){ return false; }\n\n // case: one bb to left of other\n if( bb1.x2 < bb2.x1 ){ return false; }\n if( bb2.x2 < bb1.x1 ){ return false; }\n\n // case: one bb above other\n if( bb1.y2 < bb2.y1 ){ return false; }\n if( bb2.y2 < bb1.y1 ){ return false; }\n\n // case: one bb below other\n if( bb1.y1 > bb2.y2 ){ return false; }\n if( bb2.y1 > bb1.y2 ){ return false; }\n\n // otherwise, must have some overlap\n return true;\n};\n\nmath.inBoundingBox = function( bb, x, y ){\n return bb.x1 <= x && x <= bb.x2 && bb.y1 <= y && y <= bb.y2;\n};\n\nmath.pointInBoundingBox = function( bb, pt ){\n return this.inBoundingBox( bb, pt.x, pt.y );\n};\n\nmath.roundRectangleIntersectLine = function(\n x, y, nodeX, nodeY, width, height, padding) {\n\n var cornerRadius = this.getRoundRectangleRadius(width, height);\n\n var halfWidth = width / 2;\n var halfHeight = height / 2;\n\n // Check intersections with straight line segments\n var straightLineIntersections;\n\n // Top segment, left to right\n {\n var topStartX = nodeX - halfWidth + cornerRadius - padding;\n var topStartY = nodeY - halfHeight - padding;\n var topEndX = nodeX + halfWidth - cornerRadius + padding;\n var topEndY = topStartY;\n\n straightLineIntersections = this.finiteLinesIntersect(\n x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false);\n\n if (straightLineIntersections.length > 0) {\n return straightLineIntersections;\n }\n }\n\n // Right segment, top to bottom\n {\n var rightStartX = nodeX + halfWidth + padding;\n var rightStartY = nodeY - halfHeight + cornerRadius - padding;\n var rightEndX = rightStartX;\n var rightEndY = nodeY + halfHeight - cornerRadius + padding;\n\n straightLineIntersections = this.finiteLinesIntersect(\n x, y, nodeX, nodeY, rightStartX, rightStartY, rightEndX, rightEndY, false);\n\n if (straightLineIntersections.length > 0) {\n return straightLineIntersections;\n }\n }\n\n // Bottom segment, left to right\n {\n var bottomStartX = nodeX - halfWidth + cornerRadius - padding;\n var bottomStartY = nodeY + halfHeight + padding;\n var bottomEndX = nodeX + halfWidth - cornerRadius + padding;\n var bottomEndY = bottomStartY;\n\n straightLineIntersections = this.finiteLinesIntersect(\n x, y, nodeX, nodeY, bottomStartX, bottomStartY, bottomEndX, bottomEndY, false);\n\n if (straightLineIntersections.length > 0) {\n return straightLineIntersections;\n }\n }\n\n // Left segment, top to bottom\n {\n var leftStartX = nodeX - halfWidth - padding;\n var leftStartY = nodeY - halfHeight + cornerRadius - padding;\n var leftEndX = leftStartX;\n var leftEndY = nodeY + halfHeight - cornerRadius + padding;\n\n straightLineIntersections = this.finiteLinesIntersect(\n x, y, nodeX, nodeY, leftStartX, leftStartY, leftEndX, leftEndY, false);\n\n if (straightLineIntersections.length > 0) {\n return straightLineIntersections;\n }\n }\n\n // Check intersections with arc segments\n var arcIntersections;\n\n // Top Left\n {\n var topLeftCenterX = nodeX - halfWidth + cornerRadius;\n var topLeftCenterY = nodeY - halfHeight + cornerRadius;\n arcIntersections = this.intersectLineCircle(\n x, y, nodeX, nodeY,\n topLeftCenterX, topLeftCenterY, cornerRadius + padding);\n\n // Ensure the intersection is on the desired quarter of the circle\n if (arcIntersections.length > 0\n && arcIntersections[0] <= topLeftCenterX\n && arcIntersections[1] <= topLeftCenterY) {\n return [arcIntersections[0], arcIntersections[1]];\n }\n }\n\n // Top Right\n {\n var topRightCenterX = nodeX + halfWidth - cornerRadius;\n var topRightCenterY = nodeY - halfHeight + cornerRadius;\n arcIntersections = this.intersectLineCircle(\n x, y, nodeX, nodeY,\n topRightCenterX, topRightCenterY, cornerRadius + padding);\n\n // Ensure the intersection is on the desired quarter of the circle\n if (arcIntersections.length > 0\n && arcIntersections[0] >= topRightCenterX\n && arcIntersections[1] <= topRightCenterY) {\n return [arcIntersections[0], arcIntersections[1]];\n }\n }\n\n // Bottom Right\n {\n var bottomRightCenterX = nodeX + halfWidth - cornerRadius;\n var bottomRightCenterY = nodeY + halfHeight - cornerRadius;\n arcIntersections = this.intersectLineCircle(\n x, y, nodeX, nodeY,\n bottomRightCenterX, bottomRightCenterY, cornerRadius + padding);\n\n // Ensure the intersection is on the desired quarter of the circle\n if (arcIntersections.length > 0\n && arcIntersections[0] >= bottomRightCenterX\n && arcIntersections[1] >= bottomRightCenterY) {\n return [arcIntersections[0], arcIntersections[1]];\n }\n }\n\n // Bottom Left\n {\n var bottomLeftCenterX = nodeX - halfWidth + cornerRadius;\n var bottomLeftCenterY = nodeY + halfHeight - cornerRadius;\n arcIntersections = this.intersectLineCircle(\n x, y, nodeX, nodeY,\n bottomLeftCenterX, bottomLeftCenterY, cornerRadius + padding);\n\n // Ensure the intersection is on the desired quarter of the circle\n if (arcIntersections.length > 0\n && arcIntersections[0] <= bottomLeftCenterX\n && arcIntersections[1] >= bottomLeftCenterY) {\n return [arcIntersections[0], arcIntersections[1]];\n }\n }\n\n return []; // if nothing\n};\n\nmath.inLineVicinity = function(x, y, lx1, ly1, lx2, ly2, tolerance){\n var t = tolerance;\n\n var x1 = Math.min(lx1, lx2);\n var x2 = Math.max(lx1, lx2);\n var y1 = Math.min(ly1, ly2);\n var y2 = Math.max(ly1, ly2);\n\n return x1 - t <= x && x <= x2 + t\n && y1 - t <= y && y <= y2 + t;\n};\n\nmath.inBezierVicinity = function(\n x, y, x1, y1, x2, y2, x3, y3, tolerance) {\n\n var bb = {\n x1: Math.min( x1, x3, x2 ) - tolerance,\n x2: Math.max( x1, x3, x2 ) + tolerance,\n y1: Math.min( y1, y3, y2 ) - tolerance,\n y2: Math.max( y1, y3, y2 ) + tolerance\n };\n\n // if outside the rough bounding box for the bezier, then it can't be a hit\n if( x < bb.x1 || x > bb.x2 || y < bb.y1 || y > bb.y2 ){\n // console.log('bezier out of rough bb')\n return false;\n } else {\n // console.log('do more expensive check');\n return true;\n }\n\n};\n\nmath.solveCubic = function(a, b, c, d, result) {\n\n // Solves a cubic function, returns root in form [r1, i1, r2, i2, r3, i3], where\n // r is the real component, i is the imaginary component\n\n // An implementation of the Cardano method from the year 1545\n // http://en.wikipedia.org/wiki/Cubic_function#The_nature_of_the_roots\n\n b /= a;\n c /= a;\n d /= a;\n\n var discriminant, q, r, dum1, s, t, term1, r13;\n\n q = (3.0 * c - (b * b)) / 9.0;\n r = -(27.0 * d) + b * (9.0 * c - 2.0 * (b * b));\n r /= 54.0;\n\n discriminant = q * q * q + r * r;\n result[1] = 0;\n term1 = (b / 3.0);\n\n if (discriminant > 0) {\n s = r + Math.sqrt(discriminant);\n s = ((s < 0) ? -Math.pow(-s, (1.0 / 3.0)) : Math.pow(s, (1.0 / 3.0)));\n t = r - Math.sqrt(discriminant);\n t = ((t < 0) ? -Math.pow(-t, (1.0 / 3.0)) : Math.pow(t, (1.0 / 3.0)));\n result[0] = -term1 + s + t;\n term1 += (s + t) / 2.0;\n result[4] = result[2] = -term1;\n term1 = Math.sqrt(3.0) * (-t + s) / 2;\n result[3] = term1;\n result[5] = -term1;\n return;\n }\n\n result[5] = result[3] = 0;\n\n if (discriminant === 0) {\n r13 = ((r < 0) ? -Math.pow(-r, (1.0 / 3.0)) : Math.pow(r, (1.0 / 3.0)));\n result[0] = -term1 + 2.0 * r13;\n result[4] = result[2] = -(r13 + term1);\n return;\n }\n\n q = -q;\n dum1 = q * q * q;\n dum1 = Math.acos(r / Math.sqrt(dum1));\n r13 = 2.0 * Math.sqrt(q);\n result[0] = -term1 + r13 * Math.cos(dum1 / 3.0);\n result[2] = -term1 + r13 * Math.cos((dum1 + 2.0 * Math.PI) / 3.0);\n result[4] = -term1 + r13 * Math.cos((dum1 + 4.0 * Math.PI) / 3.0);\n\n return;\n};\n\nmath.sqDistanceToQuadraticBezier = function(\n x, y, x1, y1, x2, y2, x3, y3) {\n\n // Find minimum distance by using the minimum of the distance\n // function between the given point and the curve\n\n // This gives the coefficients of the resulting cubic equation\n // whose roots tell us where a possible minimum is\n // (Coefficients are divided by 4)\n\n var a = 1.0 * x1*x1 - 4*x1*x2 + 2*x1*x3 + 4*x2*x2 - 4*x2*x3 + x3*x3\n + y1*y1 - 4*y1*y2 + 2*y1*y3 + 4*y2*y2 - 4*y2*y3 + y3*y3;\n\n var b = 1.0 * 9*x1*x2 - 3*x1*x1 - 3*x1*x3 - 6*x2*x2 + 3*x2*x3\n + 9*y1*y2 - 3*y1*y1 - 3*y1*y3 - 6*y2*y2 + 3*y2*y3;\n\n var c = 1.0 * 3*x1*x1 - 6*x1*x2 + x1*x3 - x1*x + 2*x2*x2 + 2*x2*x - x3*x\n + 3*y1*y1 - 6*y1*y2 + y1*y3 - y1*y + 2*y2*y2 + 2*y2*y - y3*y;\n\n var d = 1.0 * x1*x2 - x1*x1 + x1*x - x2*x\n + y1*y2 - y1*y1 + y1*y - y2*y;\n\n // debug(\"coefficients: \" + a / a + \", \" + b / a + \", \" + c / a + \", \" + d / a);\n\n var roots = [];\n\n // Use the cubic solving algorithm\n this.solveCubic(a, b, c, d, roots);\n\n var zeroThreshold = 0.0000001;\n\n var params = [];\n\n for (var index = 0; index < 6; index += 2) {\n if (Math.abs(roots[index + 1]) < zeroThreshold\n && roots[index] >= 0\n && roots[index] <= 1.0) {\n params.push(roots[index]);\n }\n }\n\n params.push(1.0);\n params.push(0.0);\n\n var minDistanceSquared = -1;\n var closestParam;\n\n var curX, curY, distSquared;\n for (var i = 0; i < params.length; i++) {\n curX = Math.pow(1.0 - params[i], 2.0) * x1\n + 2.0 * (1 - params[i]) * params[i] * x2\n + params[i] * params[i] * x3;\n\n curY = Math.pow(1 - params[i], 2.0) * y1\n + 2 * (1.0 - params[i]) * params[i] * y2\n + params[i] * params[i] * y3;\n\n distSquared = Math.pow(curX - x, 2) + Math.pow(curY - y, 2);\n // debug('distance for param ' + params[i] + \": \" + Math.sqrt(distSquared));\n if (minDistanceSquared >= 0) {\n if (distSquared < minDistanceSquared) {\n minDistanceSquared = distSquared;\n closestParam = params[i];\n }\n } else {\n minDistanceSquared = distSquared;\n closestParam = params[i];\n }\n }\n\n return minDistanceSquared;\n};\n\nmath.sqDistanceToFiniteLine = function(x, y, x1, y1, x2, y2) {\n var offset = [x - x1, y - y1];\n var line = [x2 - x1, y2 - y1];\n\n var lineSq = line[0] * line[0] + line[1] * line[1];\n var hypSq = offset[0] * offset[0] + offset[1] * offset[1];\n\n var dotProduct = offset[0] * line[0] + offset[1] * line[1];\n var adjSq = dotProduct * dotProduct / lineSq;\n\n if (dotProduct < 0) {\n return hypSq;\n }\n\n if (adjSq > lineSq) {\n return (x - x2) * (x - x2) + (y - y2) * (y - y2);\n }\n\n return hypSq - adjSq;\n};\n\nmath.pointInsidePolygonPoints = function(x, y, points){\n var x1, y1, x2, y2;\n var y3;\n\n // Intersect with vertical line through (x, y)\n var up = 0;\n var down = 0;\n for (var i = 0; i < points.length / 2; i++) {\n\n x1 = points[i * 2];\n y1 = points[i * 2 + 1];\n\n if (i + 1 < points.length / 2) {\n x2 = points[(i + 1) * 2];\n y2 = points[(i + 1) * 2 + 1];\n } else {\n x2 = points[(i + 1 - points.length / 2) * 2];\n y2 = points[(i + 1 - points.length / 2) * 2 + 1];\n }\n\n if (x1 == x && x2 == x) {\n\n } else if ((x1 >= x && x >= x2)\n || (x1 <= x && x <= x2)) {\n\n y3 = (x - x1) / (x2 - x1) * (y2 - y1) + y1;\n\n if (y3 > y) {\n up++;\n }\n\n if (y3 < y) {\n down++;\n }\n\n } else {\n continue;\n }\n\n }\n\n if (up % 2 === 0) {\n return false;\n } else {\n return true;\n }\n};\n\nmath.pointInsidePolygon = function(\n x, y, basePoints, centerX, centerY, width, height, direction, padding) {\n\n //var direction = arguments[6];\n var transformedPoints = new Array(basePoints.length);\n\n // Gives negative angle\n var angle;\n\n if( direction[0] != null ){\n angle = Math.atan(direction[1] / direction[0]);\n\n if (direction[0] < 0) {\n angle = angle + Math.PI / 2;\n } else {\n angle = -angle - Math.PI / 2;\n }\n } else {\n angle = direction;\n }\n\n var cos = Math.cos(-angle);\n var sin = Math.sin(-angle);\n\n // console.log(\"base: \" + basePoints);\n for (var i = 0; i < transformedPoints.length / 2; i++) {\n transformedPoints[i * 2] =\n width / 2 * (basePoints[i * 2] * cos\n - basePoints[i * 2 + 1] * sin);\n\n transformedPoints[i * 2 + 1] =\n height / 2 * (basePoints[i * 2 + 1] * cos\n + basePoints[i * 2] * sin);\n\n transformedPoints[i * 2] += centerX;\n transformedPoints[i * 2 + 1] += centerY;\n }\n\n var points;\n\n if (padding > 0) {\n var expandedLineSet = this.expandPolygon(\n transformedPoints,\n -padding);\n\n points = this.joinLines(expandedLineSet);\n } else {\n points = transformedPoints;\n }\n\n return math.pointInsidePolygonPoints( x, y, points );\n};\n\nmath.joinLines = function(lineSet) {\n\n var vertices = new Array(lineSet.length / 2);\n\n var currentLineStartX, currentLineStartY, currentLineEndX, currentLineEndY;\n var nextLineStartX, nextLineStartY, nextLineEndX, nextLineEndY;\n\n for (var i = 0; i < lineSet.length / 4; i++) {\n currentLineStartX = lineSet[i * 4];\n currentLineStartY = lineSet[i * 4 + 1];\n currentLineEndX = lineSet[i * 4 + 2];\n currentLineEndY = lineSet[i * 4 + 3];\n\n if (i < lineSet.length / 4 - 1) {\n nextLineStartX = lineSet[(i + 1) * 4];\n nextLineStartY = lineSet[(i + 1) * 4 + 1];\n nextLineEndX = lineSet[(i + 1) * 4 + 2];\n nextLineEndY = lineSet[(i + 1) * 4 + 3];\n } else {\n nextLineStartX = lineSet[0];\n nextLineStartY = lineSet[1];\n nextLineEndX = lineSet[2];\n nextLineEndY = lineSet[3];\n }\n\n var intersection = this.finiteLinesIntersect(\n currentLineStartX, currentLineStartY,\n currentLineEndX, currentLineEndY,\n nextLineStartX, nextLineStartY,\n nextLineEndX, nextLineEndY,\n true);\n\n vertices[i * 2] = intersection[0];\n vertices[i * 2 + 1] = intersection[1];\n }\n\n return vertices;\n};\n\nmath.expandPolygon = function(points, pad) {\n\n var expandedLineSet = new Array(points.length * 2);\n\n var currentPointX, currentPointY, nextPointX, nextPointY;\n\n for (var i = 0; i < points.length / 2; i++) {\n currentPointX = points[i * 2];\n currentPointY = points[i * 2 + 1];\n\n if (i < points.length / 2 - 1) {\n nextPointX = points[(i + 1) * 2];\n nextPointY = points[(i + 1) * 2 + 1];\n } else {\n nextPointX = points[0];\n nextPointY = points[1];\n }\n\n // Current line: [currentPointX, currentPointY] to [nextPointX, nextPointY]\n\n // Assume CCW polygon winding\n\n var offsetX = (nextPointY - currentPointY);\n var offsetY = -(nextPointX - currentPointX);\n\n // Normalize\n var offsetLength = Math.sqrt(offsetX * offsetX + offsetY * offsetY);\n var normalizedOffsetX = offsetX / offsetLength;\n var normalizedOffsetY = offsetY / offsetLength;\n\n expandedLineSet[i * 4] = currentPointX + normalizedOffsetX * pad;\n expandedLineSet[i * 4 + 1] = currentPointY + normalizedOffsetY * pad;\n expandedLineSet[i * 4 + 2] = nextPointX + normalizedOffsetX * pad;\n expandedLineSet[i * 4 + 3] = nextPointY + normalizedOffsetY * pad;\n }\n\n return expandedLineSet;\n};\n\nmath.intersectLineEllipse = function(\n x, y, centerX, centerY, ellipseWradius, ellipseHradius) {\n\n var dispX = centerX - x;\n var dispY = centerY - y;\n\n dispX /= ellipseWradius;\n dispY /= ellipseHradius;\n\n var len = Math.sqrt(dispX * dispX + dispY * dispY);\n\n var newLength = len - 1;\n\n if (newLength < 0) {\n return [];\n }\n\n var lenProportion = newLength / len;\n\n return [(centerX - x) * lenProportion + x, (centerY - y) * lenProportion + y];\n};\n\n// Returns intersections of increasing distance from line's start point\nmath.intersectLineCircle = function(\n x1, y1, x2, y2, centerX, centerY, radius) {\n\n // Calculate d, direction vector of line\n var d = [x2 - x1, y2 - y1]; // Direction vector of line\n var c = [centerX, centerY]; // Center of circle\n var f = [x1 - centerX, y1 - centerY];\n\n var a = d[0] * d[0] + d[1] * d[1];\n var b = 2 * (f[0] * d[0] + f[1] * d[1]);\n var c = (f[0] * f[0] + f[1] * f[1]) - radius * radius ;\n\n var discriminant = b*b-4*a*c;\n\n if (discriminant < 0) {\n return [];\n }\n\n var t1 = (-b + Math.sqrt(discriminant)) / (2 * a);\n var t2 = (-b - Math.sqrt(discriminant)) / (2 * a);\n\n var tMin = Math.min(t1, t2);\n var tMax = Math.max(t1, t2);\n var inRangeParams = [];\n\n if (tMin >= 0 && tMin <= 1) {\n inRangeParams.push(tMin);\n }\n\n if (tMax >= 0 && tMax <= 1) {\n inRangeParams.push(tMax);\n }\n\n if (inRangeParams.length === 0) {\n return [];\n }\n\n var nearIntersectionX = inRangeParams[0] * d[0] + x1;\n var nearIntersectionY = inRangeParams[0] * d[1] + y1;\n\n if (inRangeParams.length > 1) {\n\n if (inRangeParams[0] == inRangeParams[1]) {\n return [nearIntersectionX, nearIntersectionY];\n } else {\n\n var farIntersectionX = inRangeParams[1] * d[0] + x1;\n var farIntersectionY = inRangeParams[1] * d[1] + y1;\n\n return [nearIntersectionX, nearIntersectionY, farIntersectionX, farIntersectionY];\n }\n\n } else {\n return [nearIntersectionX, nearIntersectionY];\n }\n\n};\n\nmath.findCircleNearPoint = function(centerX, centerY,\n radius, farX, farY) {\n\n var displacementX = farX - centerX;\n var displacementY = farY - centerY;\n var distance = Math.sqrt(displacementX * displacementX\n + displacementY * displacementY);\n\n var unitDisplacementX = displacementX / distance;\n var unitDisplacementY = displacementY / distance;\n\n return [centerX + unitDisplacementX * radius,\n centerY + unitDisplacementY * radius];\n};\n\nmath.findMaxSqDistanceToOrigin = function(points) {\n var maxSqDistance = 0.000001;\n var sqDistance;\n\n for (var i = 0; i < points.length / 2; i++) {\n\n sqDistance = points[i * 2] * points[i * 2]\n + points[i * 2 + 1] * points[i * 2 + 1];\n\n if (sqDistance > maxSqDistance) {\n maxSqDistance = sqDistance;\n }\n }\n\n return maxSqDistance;\n};\n\nmath.finiteLinesIntersect = function(\n x1, y1, x2, y2, x3, y3, x4, y4, infiniteLines) {\n\n var ua_t = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3);\n var ub_t = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3);\n var u_b = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);\n\n if (u_b !== 0) {\n var ua = ua_t / u_b;\n var ub = ub_t / u_b;\n\n if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {\n return [x1 + ua * (x2 - x1), y1 + ua * (y2 - y1)];\n\n } else {\n if (!infiniteLines) {\n return [];\n } else {\n return [x1 + ua * (x2 - x1), y1 + ua * (y2 - y1)];\n }\n }\n } else {\n if (ua_t === 0 || ub_t === 0) {\n\n // Parallel, coincident lines. Check if overlap\n\n // Check endpoint of second line\n if ([x1, x2, x4].sort()[1] === x4) {\n return [x4, y4];\n }\n\n // Check start point of second line\n if ([x1, x2, x3].sort()[1] === x3) {\n return [x3, y3];\n }\n\n // Endpoint of first line\n if ([x3, x4, x2].sort()[1] === x2) {\n return [x2, y2];\n }\n\n return [];\n } else {\n\n // Parallel, non-coincident\n return [];\n }\n }\n};\n\nmath.polygonIntersectLine = function(\n x, y, basePoints, centerX, centerY, width, height, padding) {\n\n var intersections = [];\n var intersection;\n\n var transformedPoints = new Array(basePoints.length);\n\n for (var i = 0; i < transformedPoints.length / 2; i++) {\n transformedPoints[i * 2] = basePoints[i * 2] * width + centerX;\n transformedPoints[i * 2 + 1] = basePoints[i * 2 + 1] * height + centerY;\n }\n\n var points;\n\n if (padding > 0) {\n var expandedLineSet = math.expandPolygon(\n transformedPoints,\n -padding);\n\n points = math.joinLines(expandedLineSet);\n } else {\n points = transformedPoints;\n }\n // var points = transformedPoints;\n\n var currentX, currentY, nextX, nextY;\n\n for (var i = 0; i < points.length / 2; i++) {\n\n currentX = points[i * 2];\n currentY = points[i * 2 + 1];\n\n if (i < points.length / 2 - 1) {\n nextX = points[(i + 1) * 2];\n nextY = points[(i + 1) * 2 + 1];\n } else {\n nextX = points[0];\n nextY = points[1];\n }\n\n intersection = this.finiteLinesIntersect(\n x, y, centerX, centerY,\n currentX, currentY,\n nextX, nextY);\n\n if (intersection.length !== 0) {\n intersections.push(intersection[0], intersection[1]);\n }\n }\n\n return intersections;\n};\n\nmath.shortenIntersection = function(\n intersection, offset, amount) {\n\n var disp = [intersection[0] - offset[0], intersection[1] - offset[1]];\n\n var length = Math.sqrt(disp[0] * disp[0] + disp[1] * disp[1]);\n\n var lenRatio = (length - amount) / length;\n\n if (lenRatio < 0) {\n lenRatio = 0.00001;\n }\n\n return [offset[0] + lenRatio * disp[0], offset[1] + lenRatio * disp[1]];\n};\n\nmath.generateUnitNgonPointsFitToSquare = function(sides, rotationRadians) {\n var points = math.generateUnitNgonPoints(sides, rotationRadians);\n points = math.fitPolygonToSquare(points);\n\n return points;\n};\n\nmath.fitPolygonToSquare = function(points){\n var x, y;\n var sides = points.length/2;\n var minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n\n for (var i = 0; i < sides; i++) {\n x = points[2 * i];\n y = points[2 * i + 1];\n\n minX = Math.min( minX, x );\n maxX = Math.max( maxX, x );\n minY = Math.min( minY, y );\n maxY = Math.max( maxY, y );\n }\n\n // stretch factors\n var sx = 2 / (maxX - minX);\n var sy = 2 / (maxY - minY);\n\n for (var i = 0; i < sides; i++){\n x = points[2 * i] = points[2 * i] * sx;\n y = points[2 * i + 1] = points[2 * i + 1] * sy;\n\n minX = Math.min( minX, x );\n maxX = Math.max( maxX, x );\n minY = Math.min( minY, y );\n maxY = Math.max( maxY, y );\n }\n\n if( minY < -1 ){\n for (var i = 0; i < sides; i++){\n y = points[2 * i + 1] = points[2 * i + 1] + (-1 -minY);\n }\n }\n\n return points;\n};\n\nmath.generateUnitNgonPoints = function(sides, rotationRadians) {\n\n var increment = 1.0 / sides * 2 * Math.PI;\n var startAngle = sides % 2 === 0 ?\n Math.PI / 2.0 + increment / 2.0 : Math.PI / 2.0;\n // console.log(nodeShapes['square']);\n startAngle += rotationRadians;\n\n var points = new Array(sides * 2);\n\n var currentAngle, x, y;\n for (var i = 0; i < sides; i++) {\n currentAngle = i * increment + startAngle;\n\n x = points[2 * i] = Math.cos(currentAngle);// * (1 + i/2);\n y = points[2 * i + 1] = Math.sin(-currentAngle);// * (1 + i/2);\n }\n\n return points;\n};\n\nmath.getRoundRectangleRadius = function(width, height) {\n\n // Set the default radius, unless half of width or height is smaller than default\n return Math.min(width / 4, height / 4, 8);\n};\n\nmodule.exports = math;\n","// internal, minimal Promise impl s.t. apis can return promises in old envs\n// based on thenable (http://github.com/rse/thenable)\n\n'use strict';\n\n/* promise states [Promises/A+ 2.1] */\nvar STATE_PENDING = 0; /* [Promises/A+ 2.1.1] */\nvar STATE_FULFILLED = 1; /* [Promises/A+ 2.1.2] */\nvar STATE_REJECTED = 2; /* [Promises/A+ 2.1.3] */\n\n/* promise object constructor */\nvar api = function (executor) {\n /* optionally support non-constructor/plain-function call */\n if (!(this instanceof api))\n return new api(executor);\n\n /* initialize object */\n this.id = \"Thenable/1.0.7\";\n this.state = STATE_PENDING; /* initial state */\n this.fulfillValue = undefined; /* initial value */ /* [Promises/A+ 1.3, 2.1.2.2] */\n this.rejectReason = undefined; /* initial reason */ /* [Promises/A+ 1.5, 2.1.3.2] */\n this.onFulfilled = []; /* initial handlers */\n this.onRejected = []; /* initial handlers */\n\n /* provide optional information-hiding proxy */\n this.proxy = {\n then: this.then.bind(this)\n };\n\n /* support optional executor function */\n if (typeof executor === \"function\")\n executor.call(this, this.fulfill.bind(this), this.reject.bind(this));\n};\n\n/* promise API methods */\napi.prototype = {\n /* promise resolving methods */\n fulfill: function (value) { return deliver(this, STATE_FULFILLED, \"fulfillValue\", value); },\n reject: function (value) { return deliver(this, STATE_REJECTED, \"rejectReason\", value); },\n\n /* \"The then Method\" [Promises/A+ 1.1, 1.2, 2.2] */\n then: function (onFulfilled, onRejected) {\n var curr = this;\n var next = new api(); /* [Promises/A+ 2.2.7] */\n curr.onFulfilled.push(\n resolver(onFulfilled, next, \"fulfill\")); /* [Promises/A+ 2.2.2/2.2.6] */\n curr.onRejected.push(\n resolver(onRejected, next, \"reject\" )); /* [Promises/A+ 2.2.3/2.2.6] */\n execute(curr);\n return next.proxy; /* [Promises/A+ 2.2.7, 3.3] */\n }\n};\n\n/* deliver an action */\nvar deliver = function (curr, state, name, value) {\n if (curr.state === STATE_PENDING) {\n curr.state = state; /* [Promises/A+ 2.1.2.1, 2.1.3.1] */\n curr[name] = value; /* [Promises/A+ 2.1.2.2, 2.1.3.2] */\n execute(curr);\n }\n return curr;\n};\n\n/* execute all handlers */\nvar execute = function (curr) {\n if (curr.state === STATE_FULFILLED)\n execute_handlers(curr, \"onFulfilled\", curr.fulfillValue);\n else if (curr.state === STATE_REJECTED)\n execute_handlers(curr, \"onRejected\", curr.rejectReason);\n};\n\n/* execute particular set of handlers */\nvar execute_handlers = function (curr, name, value) {\n /* global setImmediate: true */\n /* global setTimeout: true */\n\n /* short-circuit processing */\n if (curr[name].length === 0)\n return;\n\n /* iterate over all handlers, exactly once */\n var handlers = curr[name];\n curr[name] = []; /* [Promises/A+ 2.2.2.3, 2.2.3.3] */\n var func = function () {\n for (var i = 0; i < handlers.length; i++)\n handlers[i](value); /* [Promises/A+ 2.2.5] */\n };\n\n /* execute procedure asynchronously */ /* [Promises/A+ 2.2.4, 3.1] */\n if (typeof setImmediate === \"function\")\n setImmediate(func);\n else\n setTimeout(func, 0);\n};\n\n/* generate a resolver function */\nvar resolver = function (cb, next, method) {\n return function (value) {\n if (typeof cb !== \"function\") /* [Promises/A+ 2.2.1, 2.2.7.3, 2.2.7.4] */\n next[method].call(next, value); /* [Promises/A+ 2.2.7.3, 2.2.7.4] */\n else {\n var result;\n try { result = cb(value); } /* [Promises/A+ 2.2.2.1, 2.2.3.1, 2.2.5, 3.2] */\n catch (e) {\n next.reject(e); /* [Promises/A+ 2.2.7.2] */\n return;\n }\n resolve(next, result); /* [Promises/A+ 2.2.7.1] */\n }\n };\n};\n\n/* \"Promise Resolution Procedure\" */ /* [Promises/A+ 2.3] */\nvar resolve = function (promise, x) {\n /* sanity check arguments */ /* [Promises/A+ 2.3.1] */\n if (promise === x || promise.proxy === x) {\n promise.reject(new TypeError(\"cannot resolve promise with itself\"));\n return;\n }\n\n /* surgically check for a \"then\" method\n (mainly to just call the \"getter\" of \"then\" only once) */\n var then;\n if ((typeof x === \"object\" && x !== null) || typeof x === \"function\") {\n try { then = x.then; } /* [Promises/A+ 2.3.3.1, 3.5] */\n catch (e) {\n promise.reject(e); /* [Promises/A+ 2.3.3.2] */\n return;\n }\n }\n\n /* handle own Thenables [Promises/A+ 2.3.2]\n and similar \"thenables\" [Promises/A+ 2.3.3] */\n if (typeof then === \"function\") {\n var resolved = false;\n try {\n /* call retrieved \"then\" method */ /* [Promises/A+ 2.3.3.3] */\n then.call(x,\n /* resolvePromise */ /* [Promises/A+ 2.3.3.3.1] */\n function (y) {\n if (resolved) return; resolved = true; /* [Promises/A+ 2.3.3.3.3] */\n if (y === x) /* [Promises/A+ 3.6] */\n promise.reject(new TypeError(\"circular thenable chain\"));\n else\n resolve(promise, y);\n },\n\n /* rejectPromise */ /* [Promises/A+ 2.3.3.3.2] */\n function (r) {\n if (resolved) return; resolved = true; /* [Promises/A+ 2.3.3.3.3] */\n promise.reject(r);\n }\n );\n }\n catch (e) {\n if (!resolved) /* [Promises/A+ 2.3.3.3.3] */\n promise.reject(e); /* [Promises/A+ 2.3.3.3.4] */\n }\n return;\n }\n\n /* handle other values */\n promise.fulfill(x); /* [Promises/A+ 2.3.4, 2.3.3.4] */\n};\n\n// use native promises where possible\nvar Promise = typeof Promise === 'undefined' ? api : Promise;\n\n// so we always have Promise.all()\nPromise.all = Promise.all || function( ps ){\n return new Promise(function( resolveAll, rejectAll ){\n var vals = new Array( ps.length );\n var doneCount = 0;\n\n var fulfill = function( i, val ){\n vals[i] = val;\n doneCount++;\n\n if( doneCount === ps.length ){\n resolveAll( vals );\n }\n };\n\n for( var i = 0; i < ps.length; i++ ){\n (function( i ){\n var p = ps[i];\n var isPromise = p.then != null;\n\n if( isPromise ){\n p.then(function( val ){\n fulfill( i, val );\n }, function( err ){\n rejectAll( err );\n });\n } else {\n var val = p;\n fulfill( i, val );\n }\n })( i );\n }\n\n });\n};\n\nmodule.exports = Promise;\n","'use strict';\n\nvar is = require('./is');\nvar util = require('./util');\n\nvar Selector = function( onlyThisGroup, selector ){\n\n if( !(this instanceof Selector) ){\n return new Selector(onlyThisGroup, selector);\n }\n\n if( selector === undefined && onlyThisGroup !== undefined ){\n selector = onlyThisGroup;\n onlyThisGroup = undefined;\n }\n\n var self = this;\n\n self._private = {\n selectorText: null,\n invalid: true\n };\n\n if( !selector || ( is.string(selector) && selector.match(/^\\s*$/) ) ){\n\n if( onlyThisGroup == null ){\n // ignore\n self.length = 0;\n } else {\n self[0] = newQuery();\n self[0].group = onlyThisGroup;\n self.length = 1;\n }\n\n } else if( is.elementOrCollection( selector ) ){\n var collection = selector.collection();\n\n self[0] = newQuery();\n self[0].collection = collection;\n self.length = 1;\n\n } else if( is.fn( selector ) ) {\n self[0] = newQuery();\n self[0].filter = selector;\n self.length = 1;\n\n } else if( is.string( selector ) ){\n\n // the current subject in the query\n var currentSubject = null;\n\n // storage for parsed queries\n var newQuery = function(){\n return {\n classes: [],\n colonSelectors: [],\n data: [],\n group: null,\n ids: [],\n meta: [],\n\n // fake selectors\n collection: null, // a collection to match against\n filter: null, // filter function\n\n // these are defined in the upward direction rather than down (e.g. child)\n // because we need to go up in Selector.filter()\n parent: null, // parent query obj\n ancestor: null, // ancestor query obj\n subject: null, // defines subject in compound query (subject query obj; points to self if subject)\n\n // use these only when subject has been defined\n child: null,\n descendant: null\n };\n };\n\n // tokens in the query language\n var tokens = {\n metaChar: '[\\\\!\\\\\"\\\\#\\\\$\\\\%\\\\&\\\\\\'\\\\(\\\\)\\\\*\\\\+\\\\,\\\\.\\\\/\\\\:\\\\;\\\\<\\\\=\\\\>\\\\?\\\\@\\\\[\\\\]\\\\^\\\\`\\\\{\\\\|\\\\}\\\\~]', // chars we need to escape in var names, etc\n comparatorOp: '=|\\\\!=|>|>=|<|<=|\\\\$=|\\\\^=|\\\\*=', // binary comparison op (used in data selectors)\n boolOp: '\\\\?|\\\\!|\\\\^', // boolean (unary) operators (used in data selectors)\n string: '\"(?:\\\\\\\\\"|[^\"])+\"' + '|' + \"'(?:\\\\\\\\'|[^'])+'\", // string literals (used in data selectors) -- doublequotes | singlequotes\n number: util.regex.number, // number literal (used in data selectors) --- e.g. 0.1234, 1234, 12e123\n meta: 'degree|indegree|outdegree', // allowed metadata fields (i.e. allowed functions to use from Collection)\n separator: '\\\\s*,\\\\s*', // queries are separated by commas, e.g. edge[foo = 'bar'], node.someClass\n descendant: '\\\\s+',\n child: '\\\\s+>\\\\s+',\n subject: '\\\\$'\n };\n tokens.variable = '(?:[\\\\w-]|(?:\\\\\\\\'+ tokens.metaChar +'))+'; // a variable name\n tokens.value = tokens.string + '|' + tokens.number; // a value literal, either a string or number\n tokens.className = tokens.variable; // a class name (follows variable conventions)\n tokens.id = tokens.variable; // an element id (follows variable conventions)\n\n // when a token like a variable has escaped meta characters, we need to clean the backslashes out\n // so that values get compared properly in Selector.filter()\n var cleanMetaChars = function(str){\n return str.replace(new RegExp('\\\\\\\\(' + tokens.metaChar + ')', 'g'), function(match, $1, offset, original){\n return $1;\n });\n };\n\n // add @ variants to comparatorOp\n var ops = tokens.comparatorOp.split('|');\n for( var i = 0; i < ops.length; i++ ){\n var op = ops[i];\n tokens.comparatorOp += '|@' + op;\n }\n\n // add ! variants to comparatorOp\n var ops = tokens.comparatorOp.split('|');\n for( var i = 0; i < ops.length; i++ ){\n var op = ops[i];\n\n if( op.indexOf('!') >= 0 ){ continue; } // skip ops that explicitly contain !\n if( op === '=' ){ continue; } // skip = b/c != is explicitly defined\n\n tokens.comparatorOp += '|\\\\!' + op;\n }\n\n // NOTE: add new expression syntax here to have it recognised by the parser;\n // - a query contains all adjacent (i.e. no separator in between) expressions;\n // - the current query is stored in self[i] --- you can use the reference to `this` in the populate function;\n // - you need to check the query objects in Selector.filter() for it actually filter properly, but that's pretty straight forward\n // - when you add something here, also add to Selector.toString()\n var exprs = [\n {\n name: 'group',\n query: true,\n regex: '(node|edge|\\\\*)',\n populate: function( group ){\n this.group = group == \"*\" ? group : group + 's';\n }\n },\n\n {\n name: 'state',\n query: true,\n // NB: if one colon selector is a substring of another from its start, place the longer one first\n // e.g. :foobar|:foo\n regex: '(:selected|:unselected|:locked|:unlocked|:visible|:hidden|:transparent|:grabbed|:free|:removed|:inside|:grabbable|:ungrabbable|:animated|:unanimated|:selectable|:unselectable|:orphan|:nonorphan|:parent|:child|:loop|:simple|:active|:inactive|:touch|:backgrounding|:nonbackgrounding)',\n populate: function( state ){\n this.colonSelectors.push( state );\n }\n },\n\n {\n name: 'id',\n query: true,\n regex: '\\\\#('+ tokens.id +')',\n populate: function( id ){\n this.ids.push( cleanMetaChars(id) );\n }\n },\n\n {\n name: 'className',\n query: true,\n regex: '\\\\.('+ tokens.className +')',\n populate: function( className ){\n this.classes.push( cleanMetaChars(className) );\n }\n },\n\n {\n name: 'dataExists',\n query: true,\n regex: '\\\\[\\\\s*('+ tokens.variable +')\\\\s*\\\\]',\n populate: function( variable ){\n this.data.push({\n field: cleanMetaChars(variable)\n });\n }\n },\n\n {\n name: 'dataCompare',\n query: true,\n regex: '\\\\[\\\\s*('+ tokens.variable +')\\\\s*('+ tokens.comparatorOp +')\\\\s*('+ tokens.value +')\\\\s*\\\\]',\n populate: function( variable, comparatorOp, value ){\n var valueIsString = new RegExp('^' + tokens.string + '$').exec(value) != null;\n\n if( valueIsString ){\n value = value.substring(1, value.length - 1);\n } else {\n value = parseFloat(value);\n }\n\n this.data.push({\n field: cleanMetaChars(variable),\n operator: comparatorOp,\n value: value\n });\n }\n },\n\n {\n name: 'dataBool',\n query: true,\n regex: '\\\\[\\\\s*('+ tokens.boolOp +')\\\\s*('+ tokens.variable +')\\\\s*\\\\]',\n populate: function( boolOp, variable ){\n this.data.push({\n field: cleanMetaChars(variable),\n operator: boolOp\n });\n }\n },\n\n {\n name: 'metaCompare',\n query: true,\n regex: '\\\\[\\\\[\\\\s*('+ tokens.meta +')\\\\s*('+ tokens.comparatorOp +')\\\\s*('+ tokens.number +')\\\\s*\\\\]\\\\]',\n populate: function( meta, comparatorOp, number ){\n this.meta.push({\n field: cleanMetaChars(meta),\n operator: comparatorOp,\n value: parseFloat(number)\n });\n }\n },\n\n {\n name: 'nextQuery',\n separator: true,\n regex: tokens.separator,\n populate: function(){\n // go on to next query\n self[++i] = newQuery();\n currentSubject = null;\n }\n },\n\n {\n name: 'child',\n separator: true,\n regex: tokens.child,\n populate: function(){\n // this query is the parent of the following query\n var childQuery = newQuery();\n childQuery.parent = this;\n childQuery.subject = currentSubject;\n\n // we're now populating the child query with expressions that follow\n self[i] = childQuery;\n }\n },\n\n {\n name: 'descendant',\n separator: true,\n regex: tokens.descendant,\n populate: function(){\n // this query is the ancestor of the following query\n var descendantQuery = newQuery();\n descendantQuery.ancestor = this;\n descendantQuery.subject = currentSubject;\n\n // we're now populating the descendant query with expressions that follow\n self[i] = descendantQuery;\n }\n },\n\n {\n name: 'subject',\n modifier: true,\n regex: tokens.subject,\n populate: function(){\n if( currentSubject != null && this.subject != this ){\n util.error('Redefinition of subject in selector `' + selector + '`');\n return false;\n }\n\n currentSubject = this;\n this.subject = this;\n }\n\n }\n ];\n\n self._private.selectorText = selector;\n var remaining = selector;\n var i = 0;\n\n // of all the expressions, find the first match in the remaining text\n var consumeExpr = function( expectation ){\n var expr;\n var match;\n var name;\n\n for( var j = 0; j < exprs.length; j++ ){\n var e = exprs[j];\n var n = e.name;\n\n // ignore this expression if it doesn't meet the expectation function\n if( is.fn( expectation ) && !expectation(n, e) ){ continue; }\n\n var m = remaining.match(new RegExp( '^' + e.regex ));\n\n if( m != null ){\n match = m;\n expr = e;\n name = n;\n\n var consumed = m[0];\n remaining = remaining.substring( consumed.length );\n\n break; // we've consumed one expr, so we can return now\n }\n }\n\n return {\n expr: expr,\n match: match,\n name: name\n };\n };\n\n // consume all leading whitespace\n var consumeWhitespace = function(){\n var match = remaining.match(/^\\s+/);\n\n if( match ){\n var consumed = match[0];\n remaining = remaining.substring( consumed.length );\n }\n };\n\n self[0] = newQuery(); // get started\n\n consumeWhitespace(); // get rid of leading whitespace\n for(;;){\n var check = consumeExpr();\n\n if( check.expr == null ){\n util.error('The selector `'+ selector +'`is invalid');\n return;\n } else {\n var args = [];\n for(var j = 1; j < check.match.length; j++){\n args.push( check.match[j] );\n }\n\n // let the token populate the selector object (i.e. in self[i])\n var ret = check.expr.populate.apply( self[i], args );\n\n if( ret === false ){ return; } // exit if population failed\n }\n\n // we're done when there's nothing left to parse\n if( remaining.match(/^\\s*$/) ){\n break;\n }\n }\n\n self.length = i + 1;\n\n // adjust references for subject\n for(var j = 0; j < self.length; j++){\n var query = self[j];\n\n if( query.subject != null ){\n // go up the tree until we reach the subject\n for(;;){\n if( query.subject == query ){ break; } // done if subject is self\n\n if( query.parent != null ){ // swap parent/child reference\n var parent = query.parent;\n var child = query;\n\n child.parent = null;\n parent.child = child;\n\n query = parent; // go up the tree\n } else if( query.ancestor != null ){ // swap ancestor/descendant\n var ancestor = query.ancestor;\n var descendant = query;\n\n descendant.ancestor = null;\n ancestor.descendant = descendant;\n\n query = ancestor; // go up the tree\n } else {\n util.error('When adjusting references for the selector `'+ query +'`, neither parent nor ancestor was found');\n break;\n }\n } // for\n\n self[j] = query.subject; // subject should be the root query\n } // if\n } // for\n\n // make sure for each query that the subject group matches the implicit group if any\n if( onlyThisGroup != null ){\n for(var j = 0; j < self.length; j++){\n if( self[j].group != null && self[j].group != onlyThisGroup ){\n util.error('Group `'+ self[j].group +'` conflicts with implicit group `'+ onlyThisGroup +'` in selector `'+ selector +'`');\n return;\n }\n\n self[j].group = onlyThisGroup; // set to implicit group\n }\n }\n\n } else {\n util.error('A selector must be created from a string; found ' + selector);\n return;\n }\n\n self._private.invalid = false;\n\n};\n\nvar selfn = Selector.prototype;\n\nselfn.size = function(){\n return this.length;\n};\n\nselfn.eq = function(i){\n return this[i];\n};\n\nvar queryMatches = function(query, element){\n // check group\n if( query.group != null && query.group != '*' && query.group != element._private.group ){\n return false;\n }\n\n var cy = element.cy();\n\n // check colon selectors\n var allColonSelectorsMatch = true;\n for(var k = 0; k < query.colonSelectors.length; k++){\n var sel = query.colonSelectors[k];\n\n switch(sel){\n case ':selected':\n allColonSelectorsMatch = element.selected();\n break;\n case ':unselected':\n allColonSelectorsMatch = !element.selected();\n break;\n case ':selectable':\n allColonSelectorsMatch = element.selectable();\n break;\n case ':unselectable':\n allColonSelectorsMatch = !element.selectable();\n break;\n case ':locked':\n allColonSelectorsMatch = element.locked();\n break;\n case ':unlocked':\n allColonSelectorsMatch = !element.locked();\n break;\n case ':visible':\n allColonSelectorsMatch = element.visible();\n break;\n case ':hidden':\n allColonSelectorsMatch = !element.visible();\n break;\n case ':transparent':\n allColonSelectorsMatch = element.transparent();\n break;\n case ':grabbed':\n allColonSelectorsMatch = element.grabbed();\n break;\n case ':free':\n allColonSelectorsMatch = !element.grabbed();\n break;\n case ':removed':\n allColonSelectorsMatch = element.removed();\n break;\n case ':inside':\n allColonSelectorsMatch = !element.removed();\n break;\n case ':grabbable':\n allColonSelectorsMatch = element.grabbable();\n break;\n case ':ungrabbable':\n allColonSelectorsMatch = !element.grabbable();\n break;\n case ':animated':\n allColonSelectorsMatch = element.animated();\n break;\n case ':unanimated':\n allColonSelectorsMatch = !element.animated();\n break;\n case ':parent':\n allColonSelectorsMatch = element.isNode() && element.children().nonempty();\n break;\n case ':child':\n case ':nonorphan':\n allColonSelectorsMatch = element.isNode() && element.parent().nonempty();\n break;\n case ':orphan':\n allColonSelectorsMatch = element.isNode() && element.parent().empty();\n break;\n case ':loop':\n allColonSelectorsMatch = element.isEdge() && element.data('source') === element.data('target');\n break;\n case ':simple':\n allColonSelectorsMatch = element.isEdge() && element.data('source') !== element.data('target');\n break;\n case ':active':\n allColonSelectorsMatch = element.active();\n break;\n case ':inactive':\n allColonSelectorsMatch = !element.active();\n break;\n case ':touch':\n allColonSelectorsMatch = is.touch();\n break;\n case ':backgrounding':\n allColonSelectorsMatch = element.backgrounding();\n break;\n case ':nonbackgrounding':\n allColonSelectorsMatch = !element.backgrounding();\n break;\n }\n\n if( !allColonSelectorsMatch ) break;\n }\n if( !allColonSelectorsMatch ) return false;\n\n // check id\n var allIdsMatch = true;\n for(var k = 0; k < query.ids.length; k++){\n var id = query.ids[k];\n var actualId = element._private.data.id;\n\n allIdsMatch = allIdsMatch && (id == actualId);\n\n if( !allIdsMatch ) break;\n }\n if( !allIdsMatch ) return false;\n\n // check classes\n var allClassesMatch = true;\n for(var k = 0; k < query.classes.length; k++){\n var cls = query.classes[k];\n\n allClassesMatch = allClassesMatch && element.hasClass(cls);\n\n if( !allClassesMatch ) break;\n }\n if( !allClassesMatch ) return false;\n\n // generic checking for data/metadata\n var operandsMatch = function(params){\n var allDataMatches = true;\n for(var k = 0; k < query[params.name].length; k++){\n var data = query[params.name][k];\n var operator = data.operator;\n var value = data.value;\n var field = data.field;\n var matches;\n\n if( operator != null && value != null ){\n\n var fieldVal = params.fieldValue(field);\n var fieldStr = !is.string(fieldVal) && !is.number(fieldVal) ? '' : '' + fieldVal;\n var valStr = '' + value;\n\n var caseInsensitive = false;\n if( operator.indexOf('@') >= 0 ){\n fieldStr = fieldStr.toLowerCase();\n valStr = valStr.toLowerCase();\n\n operator = operator.replace('@', '');\n caseInsensitive = true;\n }\n\n var notExpr = false;\n var handledNotExpr = false;\n if( operator.indexOf('!') >= 0 ){\n operator = operator.replace('!', '');\n notExpr = true;\n }\n\n // if we're doing a case insensitive comparison, then we're using a STRING comparison\n // even if we're comparing numbers\n if( caseInsensitive ){\n value = valStr.toLowerCase();\n fieldVal = fieldStr.toLowerCase();\n }\n\n switch(operator){\n case '*=':\n matches = fieldStr.search(valStr) >= 0;\n break;\n case '$=':\n matches = new RegExp(valStr + '$').exec(fieldStr) != null;\n break;\n case '^=':\n matches = new RegExp('^' + valStr).exec(fieldStr) != null;\n break;\n case '=':\n matches = fieldVal === value;\n break;\n case '!=':\n matches = fieldVal !== value;\n break;\n case '>':\n matches = !notExpr ? fieldVal > value : fieldVal <= value;\n handledNotExpr = true;\n break;\n case '>=':\n matches = !notExpr ? fieldVal >= value : fieldVal < value;\n handledNotExpr = true;\n break;\n case '<':\n matches = !notExpr ? fieldVal < value : fieldVal >= value;\n handledNotExpr = true;\n break;\n case '<=':\n matches = !notExpr ? fieldVal <= value : fieldVal > value;\n handledNotExpr = true;\n break;\n default:\n matches = false;\n break;\n\n }\n } else if( operator != null ){\n switch(operator){\n case '?':\n matches = params.fieldTruthy(field);\n break;\n case '!':\n matches = !params.fieldTruthy(field);\n break;\n case '^':\n matches = params.fieldUndefined(field);\n break;\n }\n } else {\n matches = !params.fieldUndefined(field);\n }\n\n if( notExpr && !handledNotExpr ){\n matches = !matches;\n handledNotExpr = true;\n }\n\n if( !matches ){\n allDataMatches = false;\n break;\n }\n } // for\n\n return allDataMatches;\n }; // operandsMatch\n\n // check data matches\n var allDataMatches = operandsMatch({\n name: 'data',\n fieldValue: function(field){\n return element._private.data[field];\n },\n fieldRef: function(field){\n return 'element._private.data.' + field;\n },\n fieldUndefined: function(field){\n return element._private.data[field] === undefined;\n },\n fieldTruthy: function(field){\n if( element._private.data[field] ){\n return true;\n }\n return false;\n }\n });\n\n if( !allDataMatches ){\n return false;\n }\n\n // check metadata matches\n var allMetaMatches = operandsMatch({\n name: 'meta',\n fieldValue: function(field){\n return element[field]();\n },\n fieldRef: function(field){\n return 'element.' + field + '()';\n },\n fieldUndefined: function(field){\n return element[field]() == null;\n },\n fieldTruthy: function(field){\n if( element[field]() ){\n return true;\n }\n return false;\n }\n });\n\n if( !allMetaMatches ){\n return false;\n }\n\n // check collection\n if( query.collection != null ){\n var matchesAny = query.collection._private.ids[ element.id() ] != null;\n\n if( !matchesAny ){\n return false;\n }\n }\n\n // check filter function\n if( query.filter != null && element.collection().filter( query.filter ).size() === 0 ){\n return false;\n }\n\n\n // check parent/child relations\n var confirmRelations = function( query, elements ){\n if( query != null ){\n var matches = false;\n\n if( !cy.hasCompoundNodes() ){\n return false;\n }\n\n elements = elements(); // make elements functional so we save cycles if query == null\n\n // query must match for at least one element (may be recursive)\n for(var i = 0; i < elements.length; i++){\n if( queryMatches( query, elements[i] ) ){\n matches = true;\n break;\n }\n }\n\n return matches;\n } else {\n return true;\n }\n };\n\n if (! confirmRelations(query.parent, function(){\n return element.parent();\n }) ){ return false; }\n\n if (! confirmRelations(query.ancestor, function(){\n return element.parents();\n }) ){ return false; }\n\n if (! confirmRelations(query.child, function(){\n return element.children();\n }) ){ return false; }\n\n if (! confirmRelations(query.descendant, function(){\n return element.descendants();\n }) ){ return false; }\n\n // we've reached the end, so we've matched everything for this query\n return true;\n}; // queryMatches\n\n// filter an existing collection\nselfn.filter = function(collection){\n var self = this;\n var cy = collection.cy();\n\n // don't bother trying if it's invalid\n if( self._private.invalid ){\n return cy.collection();\n }\n\n var selectorFunction = function(i, element){\n for(var j = 0; j < self.length; j++){\n var query = self[j];\n\n if( queryMatches(query, element) ){\n return true;\n }\n }\n\n return false;\n };\n\n if( self._private.selectorText == null ){\n selectorFunction = function(){ return true; };\n }\n\n var filteredCollection = collection.filter( selectorFunction );\n\n return filteredCollection;\n}; // filter\n\n// does selector match a single element?\nselfn.matches = function(ele){\n var self = this;\n\n // don't bother trying if it's invalid\n if( self._private.invalid ){\n return false;\n }\n\n for(var j = 0; j < self.length; j++){\n var query = self[j];\n\n if( queryMatches(query, ele) ){\n return true;\n }\n }\n\n return false;\n}; // filter\n\n// ith query to string\nselfn.toString = selfn.selector = function(){\n\n var str = '';\n\n var clean = function(obj, isValue){\n if( is.string(obj) ){\n return isValue ? '\"' + obj + '\"' : obj;\n }\n return '';\n };\n\n var queryToString = function(query){\n var str = '';\n\n if( query.subject === query ){\n str += '$';\n }\n\n var group = clean(query.group);\n str += group.substring(0, group.length - 1);\n\n for(var j = 0; j < query.data.length; j++){\n var data = query.data[j];\n\n if( data.value ){\n str += '[' + data.field + clean(data.operator) + clean(data.value, true) + ']';\n } else {\n str += '[' + clean(data.operator) + data.field + ']';\n }\n }\n\n for(var j = 0; j < query.meta.length; j++){\n var meta = query.meta[j];\n str += '[[' + meta.field + clean(meta.operator) + clean(meta.value, true) + ']]';\n }\n\n for(var j = 0; j < query.colonSelectors.length; j++){\n var sel = query.colonSelectors[i];\n str += sel;\n }\n\n for(var j = 0; j < query.ids.length; j++){\n var sel = '#' + query.ids[i];\n str += sel;\n }\n\n for(var j = 0; j < query.classes.length; j++){\n var sel = '.' + query.classes[j];\n str += sel;\n }\n\n if( query.parent != null ){\n str = queryToString( query.parent ) + ' > ' + str;\n }\n\n if( query.ancestor != null ){\n str = queryToString( query.ancestor ) + ' ' + str;\n }\n\n if( query.child != null ){\n str += ' > ' + queryToString( query.child );\n }\n\n if( query.descendant != null ){\n str += ' ' + queryToString( query.descendant );\n }\n\n return str;\n };\n\n for(var i = 0; i < this.length; i++){\n var query = this[i];\n\n str += queryToString( query );\n\n if( this.length > 1 && i < this.length - 1 ){\n str += ', ';\n }\n }\n\n return str;\n};\n\nmodule.exports = Selector;\n","'use strict';\n\nvar util = require('../util');\nvar is = require('../is');\n\nvar styfn = {};\n\n// (potentially expensive calculation)\n// apply the style to the element based on\n// - its bypass\n// - what selectors match it\nstyfn.apply = function( eles ){\n var self = this;\n\n if( self._private.newStyle ){ // clear style caches\n this._private.contextStyles = {};\n this._private.propDiffs = {};\n }\n\n for( var ie = 0; ie < eles.length; ie++ ){\n var ele = eles[ie];\n var cxtMeta = self.getContextMeta( ele );\n var cxtStyle = self.getContextStyle( cxtMeta );\n var app = self.applyContextStyle( cxtMeta, cxtStyle, ele );\n\n self.updateTransitions( ele, app.diffProps );\n self.updateStyleHints( ele );\n\n } // for elements\n\n self._private.newStyle = false;\n};\n\nstyfn.getPropertiesDiff = function( oldCxtKey, newCxtKey ){\n var self = this;\n var cache = self._private.propDiffs = self._private.propDiffs || {};\n var dualCxtKey = oldCxtKey + '-' + newCxtKey;\n var cachedVal = cache[dualCxtKey];\n\n if( cachedVal ){\n return cachedVal;\n }\n\n var diffProps = [];\n var addedProp = {};\n\n for( var i = 0; i < self.length; i++ ){\n var cxt = self[i];\n var oldHasCxt = oldCxtKey[i] === 't';\n var newHasCxt = newCxtKey[i] === 't';\n var cxtHasDiffed = oldHasCxt !== newHasCxt;\n var cxtHasMappedProps = cxt.mappedProperties.length > 0;\n\n if( cxtHasDiffed || cxtHasMappedProps ){\n var props;\n\n if( cxtHasDiffed && cxtHasMappedProps ){\n props = cxt.properties; // suffices b/c mappedProperties is a subset of properties\n } else if( cxtHasDiffed ){\n props = cxt.properties; // need to check them all\n } else if( cxtHasMappedProps ){\n props = cxt.mappedProperties; // only need to check mapped\n }\n\n for( var j = 0; j < props.length; j++ ){\n var prop = props[j];\n var name = prop.name;\n\n // if a later context overrides this property, then the fact that this context has switched/diffed doesn't matter\n // (semi expensive check since it makes this function O(n^2) on context length, but worth it since overall result\n // is cached)\n var laterCxtOverrides = false;\n for( var k = i + 1; k < self.length; k++ ){\n var laterCxt = self[k];\n var hasLaterCxt = newCxtKey[k] === 't';\n\n if( !hasLaterCxt ){ continue; } // can't override unless the context is active\n\n laterCxtOverrides = laterCxt.properties[ prop.name ] != null;\n\n if( laterCxtOverrides ){ break; } // exit early as long as one later context overrides\n }\n\n if( !addedProp[name] && !laterCxtOverrides ){\n addedProp[name] = true;\n diffProps.push( name );\n }\n } // for props\n } // if\n\n } // for contexts\n\n cache[ dualCxtKey ] = diffProps;\n return diffProps;\n};\n\nstyfn.getContextMeta = function( ele ){\n var self = this;\n var cxtKey = '';\n var diffProps;\n var prevKey = ele._private.styleCxtKey || '';\n\n if( self._private.newStyle ){\n prevKey = ''; // since we need to apply all style if a fresh stylesheet\n }\n\n // get the cxt key\n for( var i = 0; i < self.length; i++ ){\n var context = self[i];\n var contextSelectorMatches = context.selector && context.selector.matches( ele ); // NB: context.selector may be null for 'core'\n\n if( contextSelectorMatches ){\n cxtKey += 't';\n } else {\n cxtKey += 'f';\n }\n } // for context\n\n diffProps = self.getPropertiesDiff( prevKey, cxtKey );\n\n ele._private.styleCxtKey = cxtKey;\n\n return {\n key: cxtKey,\n diffPropNames: diffProps\n };\n};\n\n// gets a computed ele style object based on matched contexts\nstyfn.getContextStyle = function( cxtMeta ){\n var cxtKey = cxtMeta.key;\n var self = this;\n var cxtStyles = this._private.contextStyles = this._private.contextStyles || {};\n\n // if already computed style, returned cached copy\n if( cxtStyles[cxtKey] ){ return cxtStyles[cxtKey]; }\n\n var style = {\n _private: {\n key: cxtKey\n }\n };\n\n for( var i = 0; i < self.length; i++ ){\n var cxt = self[i];\n var hasCxt = cxtKey[i] === 't';\n\n if( !hasCxt ){ continue; }\n\n for( var j = 0; j < cxt.properties.length; j++ ){\n var prop = cxt.properties[j];\n var styProp = style[ prop.name ] = prop;\n\n styProp.context = cxt;\n }\n }\n\n cxtStyles[cxtKey] = style;\n return style;\n};\n\nstyfn.applyContextStyle = function( cxtMeta, cxtStyle, ele ){\n var self = this;\n var diffProps = cxtMeta.diffPropNames;\n var retDiffProps = {};\n\n for( var i = 0; i < diffProps.length; i++ ){\n var diffPropName = diffProps[i];\n var cxtProp = cxtStyle[ diffPropName ];\n var eleProp = ele._private.style[ diffPropName ];\n\n // save cycles when the context prop doesn't need to be applied\n if( !cxtProp || eleProp === cxtProp ){ continue; }\n\n var retDiffProp = retDiffProps[ diffPropName ] = {\n prev: eleProp\n };\n\n self.applyParsedProperty( ele, cxtProp );\n\n retDiffProp.next = ele._private.style[ diffPropName ];\n\n if( retDiffProp.next && retDiffProp.next.bypass ){\n retDiffProp.next = retDiffProp.next.bypassed;\n }\n }\n\n return {\n diffProps: retDiffProps\n };\n};\n\nstyfn.updateStyleHints = function(ele){\n var _p = ele._private;\n var self = this;\n var style = _p.style;\n\n if( ele.removed() ){ return; }\n\n // set whether has pie or not; for greater efficiency\n var hasPie = false;\n if( _p.group === 'nodes' && self._private.hasPie ){\n for( var i = 1; i <= self.pieBackgroundN; i++ ){ // 1..N\n var size = _p.style['pie-' + i + '-background-size'].value;\n\n if( size > 0 ){\n hasPie = true;\n break;\n }\n }\n }\n\n _p.hasPie = hasPie;\n\n var transform = style['text-transform'].strValue;\n var content = style['label'].strValue;\n var fStyle = style['font-style'].strValue;\n var size = style['font-size'].pfValue + 'px';\n var family = style['font-family'].strValue;\n // var variant = style['font-variant'].strValue;\n var weight = style['font-weight'].strValue;\n var valign = style['text-valign'].strValue;\n var halign = style['text-valign'].strValue;\n var oWidth = style['text-outline-width'].pfValue;\n var wrap = style['text-wrap'].strValue;\n var wrapW = style['text-max-width'].pfValue;\n _p.labelKey = fStyle +'$'+ size +'$'+ family +'$'+ weight +'$'+ content +'$'+ transform +'$'+ valign +'$'+ halign +'$'+ oWidth + '$' + wrap + '$' + wrapW;\n _p.fontKey = fStyle +'$'+ weight +'$'+ size +'$'+ family;\n\n var width = style['width'].pfValue;\n var height = style['height'].pfValue;\n var borderW = style['border-width'].pfValue;\n _p.boundingBoxKey = width +'$'+ height +'$'+ borderW;\n\n if( ele._private.group === 'edges' ){\n var cpss = style['control-point-step-size'].pfValue;\n var cpd = style['control-point-distances'] ? style['control-point-distances'].pfValue.join('_') : undefined;\n var cpw = style['control-point-weights'].value.join('_');\n var curve = style['curve-style'].strValue;\n var sd = style['segment-distances'] ? style['segment-distances'].pfValue.join('_') : undefined;\n var sw = style['segment-weights'].value.join('_');\n\n _p.boundingBoxKey += '$'+ cpss +'$'+ cpd +'$'+ cpw +'$'+ sd +'$'+ sw +'$'+ curve;\n }\n\n _p.styleKey = Date.now();\n};\n\n// apply a property to the style (for internal use)\n// returns whether application was successful\n//\n// now, this function flattens the property, and here's how:\n//\n// for parsedProp:{ bypass: true, deleteBypass: true }\n// no property is generated, instead the bypass property in the\n// element's style is replaced by what's pointed to by the `bypassed`\n// field in the bypass property (i.e. restoring the property the\n// bypass was overriding)\n//\n// for parsedProp:{ mapped: truthy }\n// the generated flattenedProp:{ mapping: prop }\n//\n// for parsedProp:{ bypass: true }\n// the generated flattenedProp:{ bypassed: parsedProp }\nstyfn.applyParsedProperty = function( ele, parsedProp ){\n var self = this;\n var prop = parsedProp;\n var style = ele._private.style;\n var fieldVal, flatProp;\n var types = self.types;\n var type = self.properties[ prop.name ].type;\n var propIsBypass = prop.bypass;\n var origProp = style[ prop.name ];\n var origPropIsBypass = origProp && origProp.bypass;\n var _p = ele._private;\n\n // can't apply auto to width or height unless it's a parent node\n if( (parsedProp.name === 'height' || parsedProp.name === 'width') && ele.isNode() ){\n if( parsedProp.value === 'auto' && !ele.isParent() ){\n return false;\n } else if( parsedProp.value !== 'auto' && ele.isParent() ){\n prop = parsedProp = this.parse( parsedProp.name, 'auto', propIsBypass );\n }\n }\n\n // check if we need to delete the current bypass\n if( propIsBypass && prop.deleteBypass ){ // then this property is just here to indicate we need to delete\n var currentProp = style[ prop.name ];\n\n // can only delete if the current prop is a bypass and it points to the property it was overriding\n if( !currentProp ){\n return true; // property is already not defined\n } else if( currentProp.bypass && currentProp.bypassed ){ // then replace the bypass property with the original\n\n // because the bypassed property was already applied (and therefore parsed), we can just replace it (no reapplying necessary)\n style[ prop.name ] = currentProp.bypassed;\n return true;\n\n } else {\n return false; // we're unsuccessful deleting the bypass\n }\n }\n\n var printMappingErr = function(){\n util.error('Do not assign mappings to elements without corresponding data (e.g. ele `'+ ele.id() +'` for property `'+ prop.name +'` with data field `'+ prop.field +'`); try a `['+ prop.field +']` selector to limit scope to elements with `'+ prop.field +'` defined');\n };\n\n // put the property in the style objects\n switch( prop.mapped ){ // flatten the property if mapped\n case types.mapData:\n case types.mapLayoutData:\n case types.mapScratch:\n\n var isLayout = prop.mapped === types.mapLayoutData;\n var isScratch = prop.mapped === types.mapScratch;\n\n // flatten the field (e.g. data.foo.bar)\n var fields = prop.field.split(\".\");\n var fieldVal;\n\n if( isScratch || isLayout ){\n fieldVal = _p.scratch;\n } else {\n fieldVal = _p.data;\n }\n\n for( var i = 0; i < fields.length && fieldVal; i++ ){\n var field = fields[i];\n fieldVal = fieldVal[ field ];\n }\n\n var percent;\n if( !is.number(fieldVal) ){ // then keep the mapping but assume 0% for now\n percent = 0;\n } else {\n percent = (fieldVal - prop.fieldMin) / (prop.fieldMax - prop.fieldMin);\n }\n\n // make sure to bound percent value\n if( percent < 0 ){\n percent = 0;\n } else if( percent > 1 ){\n percent = 1;\n }\n\n if( type.color ){\n var r1 = prop.valueMin[0];\n var r2 = prop.valueMax[0];\n var g1 = prop.valueMin[1];\n var g2 = prop.valueMax[1];\n var b1 = prop.valueMin[2];\n var b2 = prop.valueMax[2];\n var a1 = prop.valueMin[3] == null ? 1 : prop.valueMin[3];\n var a2 = prop.valueMax[3] == null ? 1 : prop.valueMax[3];\n\n var clr = [\n Math.round( r1 + (r2 - r1)*percent ),\n Math.round( g1 + (g2 - g1)*percent ),\n Math.round( b1 + (b2 - b1)*percent ),\n Math.round( a1 + (a2 - a1)*percent )\n ];\n\n flatProp = { // colours are simple, so just create the flat property instead of expensive string parsing\n bypass: prop.bypass, // we're a bypass if the mapping property is a bypass\n name: prop.name,\n value: clr,\n strValue: 'rgb(' + clr[0] + ', ' + clr[1] + ', ' + clr[2] + ')'\n };\n\n } else if( type.number ){\n var calcValue = prop.valueMin + (prop.valueMax - prop.valueMin) * percent;\n flatProp = this.parse( prop.name, calcValue, prop.bypass, true );\n\n } else {\n return false; // can only map to colours and numbers\n }\n\n if( !flatProp ){ // if we can't flatten the property, then use the origProp so we still keep the mapping itself\n flatProp = this.parse( prop.name, origProp.strValue, prop.bypass, true );\n }\n\n if( !flatProp ){ printMappingErr(); }\n flatProp.mapping = prop; // keep a reference to the mapping\n prop = flatProp; // the flattened (mapped) property is the one we want\n\n break;\n\n // direct mapping\n case types.data:\n case types.layoutData:\n case types.scratch:\n var isLayout = prop.mapped === types.layoutData;\n var isScratch = prop.mapped === types.scratch;\n\n // flatten the field (e.g. data.foo.bar)\n var fields = prop.field.split(\".\");\n var fieldVal;\n\n if( isScratch || isLayout ){\n fieldVal = _p.scratch;\n } else {\n fieldVal = _p.data;\n }\n\n if( fieldVal ){ for( var i = 0; i < fields.length; i++ ){\n var field = fields[i];\n fieldVal = fieldVal[ field ];\n } }\n\n flatProp = this.parse( prop.name, fieldVal, prop.bypass, true );\n\n if( !flatProp ){ // if we can't flatten the property, then use the origProp so we still keep the mapping itself\n var flatPropVal = origProp ? origProp.strValue : '';\n\n flatProp = this.parse( prop.name, flatPropVal, prop.bypass, true );\n }\n\n if( !flatProp ){ printMappingErr(); }\n flatProp.mapping = prop; // keep a reference to the mapping\n prop = flatProp; // the flattened (mapped) property is the one we want\n\n break;\n\n case types.fn:\n var fn = prop.value;\n var fnRetVal = fn( ele );\n\n flatProp = this.parse( prop.name, fnRetVal, prop.bypass, true );\n flatProp.mapping = prop; // keep a reference to the mapping\n prop = flatProp; // the flattened (mapped) property is the one we want\n\n break;\n\n case undefined:\n break; // just set the property\n\n default:\n return false; // not a valid mapping\n }\n\n // if the property is a bypass property, then link the resultant property to the original one\n if( propIsBypass ){\n if( origPropIsBypass ){ // then this bypass overrides the existing one\n prop.bypassed = origProp.bypassed; // steal bypassed prop from old bypass\n } else { // then link the orig prop to the new bypass\n prop.bypassed = origProp;\n }\n\n style[ prop.name ] = prop; // and set\n\n } else { // prop is not bypass\n if( origPropIsBypass ){ // then keep the orig prop (since it's a bypass) and link to the new prop\n origProp.bypassed = prop;\n } else { // then just replace the old prop with the new one\n style[ prop.name ] = prop;\n }\n }\n\n return true;\n};\n\n// updates the visual style for all elements (useful for manual style modification after init)\nstyfn.update = function(){\n var cy = this._private.cy;\n var eles = cy.elements();\n\n eles.updateStyle();\n};\n\n// just update the functional properties (i.e. mappings) in the elements'\n// styles (less expensive than recalculation)\nstyfn.updateMappers = function( eles ){\n var self = this;\n\n for( var i = 0; i < eles.length; i++ ){ // for each ele\n var ele = eles[i];\n var style = ele._private.style;\n\n for( var j = 0; j < self.properties.length; j++ ){ // for each prop\n var prop = self.properties[j];\n var propInStyle = style[ prop.name ];\n\n if( propInStyle && propInStyle.mapping ){\n var mapping = propInStyle.mapping;\n this.applyParsedProperty( ele, mapping ); // reapply the mapping property\n }\n }\n\n this.updateStyleHints( ele );\n }\n};\n\n// diffProps : { name => { prev, next } }\nstyfn.updateTransitions = function( ele, diffProps, isBypass ){\n var self = this;\n var _p = ele._private;\n var style = _p.style;\n var props = style['transition-property'].value;\n var duration = style['transition-duration'].pfValue;\n var delay = style['transition-delay'].pfValue;\n var css = {};\n\n if( props.length > 0 && duration > 0 ){\n\n // build up the style to animate towards\n var anyPrev = false;\n for( var i = 0; i < props.length; i++ ){\n var prop = props[i];\n var styProp = style[ prop ];\n var diffProp = diffProps[ prop ];\n\n if( !diffProp ){ continue; }\n\n var prevProp = diffProp.prev;\n var fromProp = prevProp;\n var toProp = diffProp.next != null ? diffProp.next : styProp;\n var diff = false;\n var initVal;\n var initDt = 0.000001; // delta time % value for initVal (allows animating out of init zero opacity)\n\n if( !fromProp ){ continue; }\n\n // consider px values\n if( is.number( fromProp.pfValue ) && is.number( toProp.pfValue ) ){\n diff = toProp.pfValue - fromProp.pfValue; // nonzero is truthy\n initVal = fromProp.pfValue + initDt * diff;\n\n // consider numerical values\n } else if( is.number( fromProp.value ) && is.number( toProp.value ) ){\n diff = toProp.value - fromProp.value; // nonzero is truthy\n initVal = fromProp.value + initDt * diff;\n\n // consider colour values\n } else if( is.array( fromProp.value ) && is.array( toProp.value ) ){\n diff = fromProp.value[0] !== toProp.value[0]\n || fromProp.value[1] !== toProp.value[1]\n || fromProp.value[2] !== toProp.value[2]\n ;\n\n initVal = fromProp.strValue;\n }\n\n // the previous value is good for an animation only if it's different\n if( diff ){\n css[ prop ] = toProp.strValue; // to val\n this.applyBypass( ele, prop, initVal ); // from val\n anyPrev = true;\n }\n\n } // end if props allow ani\n\n // can't transition if there's nothing previous to transition from\n if( !anyPrev ){ return; }\n\n _p.transitioning = true;\n\n ele.stop();\n\n if( delay > 0 ){\n ele.delay( delay );\n }\n\n ele.animate({\n css: css\n }, {\n duration: duration,\n easing: style['transition-timing-function'].value,\n queue: false,\n complete: function(){\n if( !isBypass ){\n self.removeBypasses( ele, props );\n }\n\n _p.transitioning = false;\n }\n });\n\n } else if( _p.transitioning ){\n ele.stop();\n\n this.removeBypasses( ele, props );\n\n _p.transitioning = false;\n }\n};\n\nmodule.exports = styfn;\n","'use strict';\n\nvar is = require('../is');\nvar util = require('../util');\n\nvar styfn = {};\n\n// bypasses are applied to an existing style on an element, and just tacked on temporarily\n// returns true iff application was successful for at least 1 specified property\nstyfn.applyBypass = function( eles, name, value, updateTransitions ){\n var self = this;\n var props = [];\n var isBypass = true;\n\n // put all the properties (can specify one or many) in an array after parsing them\n if( name === \"*\" || name === \"**\" ){ // apply to all property names\n\n if( value !== undefined ){\n for( var i = 0; i < self.properties.length; i++ ){\n var prop = self.properties[i];\n var name = prop.name;\n\n var parsedProp = this.parse(name, value, true);\n\n if( parsedProp ){\n props.push( parsedProp );\n }\n }\n }\n\n } else if( is.string(name) ){ // then parse the single property\n var parsedProp = this.parse(name, value, true);\n\n if( parsedProp ){\n props.push( parsedProp );\n }\n } else if( is.plainObject(name) ){ // then parse each property\n var specifiedProps = name;\n updateTransitions = value;\n\n for( var i = 0; i < self.properties.length; i++ ){\n var prop = self.properties[i];\n var name = prop.name;\n var value = specifiedProps[ name ];\n\n if( value === undefined ){ // try camel case name too\n value = specifiedProps[ util.dash2camel(name) ];\n }\n\n if( value !== undefined ){\n var parsedProp = this.parse(name, value, true);\n\n if( parsedProp ){\n props.push( parsedProp );\n }\n }\n }\n } else { // can't do anything without well defined properties\n return false;\n }\n\n // we've failed if there are no valid properties\n if( props.length === 0 ){ return false; }\n\n // now, apply the bypass properties on the elements\n var ret = false; // return true if at least one succesful bypass applied\n for( var i = 0; i < eles.length; i++ ){ // for each ele\n var ele = eles[i];\n var style = ele._private.style;\n var diffProps = {};\n var diffProp;\n\n for( var j = 0; j < props.length; j++ ){ // for each prop\n var prop = props[j];\n\n if( updateTransitions ){\n var prevProp = style[ prop.name ];\n diffProp = diffProps[ prop.name ] = { prev: prevProp };\n }\n\n ret = this.applyParsedProperty( ele, prop ) || ret;\n\n if( updateTransitions ){\n diffProp.next = style[ prop.name ];\n }\n\n } // for props\n\n if( ret ){\n this.updateStyleHints( ele );\n }\n\n if( updateTransitions ){\n this.updateTransitions( ele, diffProps, isBypass );\n }\n } // for eles\n\n return ret;\n};\n\n// only useful in specific cases like animation\nstyfn.overrideBypass = function( eles, name, value ){\n name = util.camel2dash(name);\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var prop = ele._private.style[ name ];\n var type = this.properties[ name ].type;\n var isColor = type.color;\n var isMulti = type.mutiple;\n\n if( !prop.bypass ){ // need a bypass if one doesn't exist\n this.applyBypass( ele, name, value );\n continue;\n }\n\n prop.value = value;\n\n if( prop.pfValue != null ){\n prop.pfValue = value;\n }\n\n if( isColor ){\n prop.strValue = 'rgb(' + value.join(',') + ')';\n } else if( isMulti ){\n prop.strValue = value.join(' ');\n } else {\n prop.strValue = '' + value;\n }\n }\n};\n\nstyfn.removeAllBypasses = function( eles, updateTransitions ){\n return this.removeBypasses( eles, this.propertyNames, updateTransitions );\n};\n\nstyfn.removeBypasses = function( eles, props, updateTransitions ){\n var isBypass = true;\n\n for( var j = 0; j < eles.length; j++ ){\n var ele = eles[j];\n var diffProps = {};\n var style = ele._private.style;\n\n for( var i = 0; i < props.length; i++ ){\n var name = props[i];\n var prop = this.properties[ name ];\n var value = ''; // empty => remove bypass\n var parsedProp = this.parse(name, value, true);\n var prevProp = style[ prop.name ];\n var diffProp = diffProps[ prop.name ] = { prev: prevProp };\n\n this.applyParsedProperty(ele, parsedProp);\n\n diffProp.next = style[ prop.name ];\n } // for props\n\n this.updateStyleHints( ele );\n\n if( updateTransitions ){\n this.updateTransitions( ele, diffProps, isBypass );\n }\n } // for eles\n};\n\nmodule.exports = styfn;\n","'use strict';\n\nvar window = require('../window');\n\nvar styfn = {};\n\n// gets what an em size corresponds to in pixels relative to a dom element\nstyfn.getEmSizeInPixels = function(){\n var px = this.containerCss('font-size');\n\n if( px != null ){\n return parseFloat( px );\n } else {\n return 1; // for headless\n }\n};\n\n// gets css property from the core container\nstyfn.containerCss = function( propName ){\n var cy = this._private.cy;\n var domElement = cy.container();\n\n if( window && domElement && window.getComputedStyle ){\n return window.getComputedStyle(domElement).getPropertyValue( propName );\n }\n};\n\nmodule.exports = styfn;\n","'use strict';\n\nvar util = require('../util');\nvar is = require('../is');\n\nvar styfn = {};\n\n// gets the rendered style for an element\nstyfn.getRenderedStyle = function( ele ){\n return this.getRawStyle( ele, true );\n};\n\n// gets the raw style for an element\nstyfn.getRawStyle = function( ele, isRenderedVal ){\n var self = this;\n var ele = ele[0]; // insure it's an element\n\n if( ele ){\n var rstyle = {};\n\n for( var i = 0; i < self.properties.length; i++ ){\n var prop = self.properties[i];\n var val = self.getStylePropertyValue( ele, prop.name, isRenderedVal );\n\n if( val ){\n rstyle[ prop.name ] = val;\n rstyle[ util.dash2camel(prop.name) ] = val;\n }\n }\n\n return rstyle;\n }\n};\n\nstyfn.getStylePropertyValue = function( ele, propName, isRenderedVal ){\n var self = this;\n var ele = ele[0]; // insure it's an element\n\n if( ele ){\n var style = ele._private.style;\n var prop = self.properties[ propName ];\n var type = prop.type;\n var styleProp = style[ prop.name ];\n var zoom = ele.cy().zoom();\n\n if( styleProp ){\n var units = styleProp.units ? type.implicitUnits || 'px' : null;\n var val = units ? [].concat( styleProp.pfValue ).map(function( pfValue ){\n return ( pfValue * (isRenderedVal ? zoom : 1) ) + units;\n }).join(' ') : styleProp.strValue;\n\n return val;\n }\n }\n};\n\n// gets the value style for an element (useful for things like animations)\nstyfn.getValueStyle = function( ele ){\n var self = this;\n var rstyle = {};\n var style;\n var isEle = is.element(ele);\n\n if( isEle ){\n style = ele._private.style;\n } else {\n style = ele; // just passed the style itself\n }\n\n if( style ){\n for( var i = 0; i < self.properties.length; i++ ){\n var prop = self.properties[i];\n var styleProp = style[ prop.name ] || style[ util.dash2camel(prop.name) ];\n\n if( styleProp !== undefined ){ // then make a prop of it\n if( is.plainObject( styleProp ) ){\n styleProp = this.parse( prop.name, styleProp.strValue );\n } else {\n styleProp = this.parse( prop.name, styleProp );\n }\n }\n\n if( styleProp ){\n rstyle[ prop.name ] = styleProp;\n rstyle[ util.dash2camel(prop.name) ] = styleProp;\n }\n }\n }\n\n return rstyle;\n};\n\nstyfn.getPropsList = function( propsObj ){\n var self = this;\n var rstyle = [];\n var style = propsObj;\n var props = self.properties;\n\n if( style ){\n for( var name in style ){\n var val = style[name];\n var prop = props[name] || props[ util.camel2dash(name) ];\n var styleProp = this.parse( prop.name, val );\n\n rstyle.push( styleProp );\n }\n }\n\n return rstyle;\n};\n\nmodule.exports = styfn;\n","'use strict';\n\nvar is = require('../is');\nvar util = require('../util');\nvar Selector = require('../selector');\n\nvar Style = function( cy ){\n\n if( !(this instanceof Style) ){\n return new Style(cy);\n }\n\n if( !is.core(cy) ){\n util.error('A style must have a core reference');\n return;\n }\n\n this._private = {\n cy: cy,\n coreStyle: {},\n newStyle: true\n };\n\n this.length = 0;\n\n this.addDefaultStylesheet();\n};\n\nvar styfn = Style.prototype;\n\nstyfn.instanceString = function(){\n return 'style';\n};\n\n// remove all contexts\nstyfn.clear = function(){\n for( var i = 0; i < this.length; i++ ){\n this[i] = undefined;\n }\n this.length = 0;\n this._private.newStyle = true;\n\n return this; // chaining\n};\n\nstyfn.resetToDefault = function(){\n this.clear();\n this.addDefaultStylesheet();\n\n return this;\n};\n\n// builds a style object for the 'core' selector\nstyfn.core = function(){\n return this._private.coreStyle;\n};\n\n// create a new context from the specified selector string and switch to that context\nstyfn.selector = function( selectorStr ){\n // 'core' is a special case and does not need a selector\n var selector = selectorStr === 'core' ? null : new Selector( selectorStr );\n\n var i = this.length++; // new context means new index\n this[i] = {\n selector: selector,\n properties: [],\n mappedProperties: [],\n index: i\n };\n\n return this; // chaining\n};\n\n// add one or many css rules to the current context\nstyfn.css = function(){\n var self = this;\n var args = arguments;\n\n switch( args.length ){\n case 1:\n var map = args[0];\n\n for( var i = 0; i < self.properties.length; i++ ){\n var prop = self.properties[i];\n var mapVal = map[ prop.name ];\n\n if( mapVal === undefined ){\n mapVal = map[ util.dash2camel(prop.name) ];\n }\n\n if( mapVal !== undefined ){\n this.cssRule( prop.name, mapVal );\n }\n }\n\n break;\n\n case 2:\n this.cssRule( args[0], args[1] );\n break;\n\n default:\n break; // do nothing if args are invalid\n }\n\n return this; // chaining\n};\nstyfn.style = styfn.css;\n\n// add a single css rule to the current context\nstyfn.cssRule = function( name, value ){\n // name-value pair\n var property = this.parse( name, value );\n\n // add property to current context if valid\n if( property ){\n var i = this.length - 1;\n this[i].properties.push( property );\n this[i].properties[ property.name ] = property; // allow access by name as well\n\n if( property.name.match(/pie-(\\d+)-background-size/) && property.value ){\n this._private.hasPie = true;\n }\n\n if( property.mapped ){\n this[i].mappedProperties.push( property );\n }\n\n // add to core style if necessary\n var currentSelectorIsCore = !this[i].selector;\n if( currentSelectorIsCore ){\n this._private.coreStyle[ property.name ] = property;\n }\n }\n\n return this; // chaining\n};\n\n// static function\nStyle.fromJson = function( cy, json ){\n var style = new Style( cy );\n\n style.fromJson( json );\n\n return style;\n};\n\nStyle.fromString = function( cy, string ){\n return new Style( cy ).fromString( string );\n};\n\n[\n require('./apply'),\n require('./bypass'),\n require('./container'),\n require('./get-for-ele'),\n require('./json'),\n require('./string-sheet'),\n require('./properties'),\n require('./parse')\n].forEach(function( props ){\n util.extend( styfn, props );\n});\n\n\nStyle.types = styfn.types;\nStyle.properties = styfn.properties;\n\nmodule.exports = Style;\n","'use strict';\n\nvar styfn = {};\n\nstyfn.applyFromJson = function( json ){\n var style = this;\n\n for( var i = 0; i < json.length; i++ ){\n var context = json[i];\n var selector = context.selector;\n var props = context.style || context.css;\n\n style.selector( selector ); // apply selector\n\n for( var name in props ){\n var value = props[name];\n\n style.css( name, value ); // apply property\n }\n }\n\n return style;\n};\n\n// accessible cy.style() function\nstyfn.fromJson = function( json ){\n var style = this;\n\n style.resetToDefault();\n style.applyFromJson( json );\n\n return style;\n};\n\n// get json from cy.style() api\nstyfn.json = function(){\n var json = [];\n\n for( var i = this.defaultLength; i < this.length; i++ ){\n var cxt = this[i];\n var selector = cxt.selector;\n var props = cxt.properties;\n var css = {};\n\n for( var j = 0; j < props.length; j++ ){\n var prop = props[j];\n css[ prop.name ] = prop.strValue;\n }\n\n json.push({\n selector: !selector ? 'core' : selector.toString(),\n style: css\n });\n }\n\n return json;\n};\n\nmodule.exports = styfn;\n","'use strict';\n\nvar util = require('../util');\nvar is = require('../is');\n\nvar styfn = {};\n\n// a caching layer for property parsing\nstyfn.parse = function( name, value, propIsBypass, propIsFlat ){\n var argHash = [ name, value, propIsBypass, propIsFlat ].join('$');\n var propCache = this.propCache = this.propCache || {};\n var ret;\n var impl = parseImpl.bind( this );\n\n if( !(ret = propCache[argHash]) ){\n ret = propCache[argHash] = impl( name, value, propIsBypass, propIsFlat );\n }\n\n // always need a copy since props are mutated later in their lifecycles\n ret = util.copy( ret );\n\n if( ret ){\n ret.value = util.copy( ret.value ); // because it could be an array, e.g. colour\n }\n\n return ret;\n};\n\n// parse a property; return null on invalid; return parsed property otherwise\n// fields :\n// - name : the name of the property\n// - value : the parsed, native-typed value of the property\n// - strValue : a string value that represents the property value in valid css\n// - bypass : true iff the property is a bypass property\nvar parseImpl = function( name, value, propIsBypass, propIsFlat ){\n var self = this;\n\n name = util.camel2dash( name ); // make sure the property name is in dash form (e.g. 'property-name' not 'propertyName')\n\n var property = self.properties[ name ];\n var passedValue = value;\n var types = self.types;\n\n if( !property ){ return null; } // return null on property of unknown name\n if( value === undefined || value === null ){ return null; } // can't assign null\n\n // the property may be an alias\n if( property.alias ){\n property = property.pointsTo;\n name = property.name;\n }\n\n var valueIsString = is.string(value);\n if( valueIsString ){ // trim the value to make parsing easier\n value = value.trim();\n }\n\n var type = property.type;\n if( !type ){ return null; } // no type, no luck\n\n // check if bypass is null or empty string (i.e. indication to delete bypass property)\n if( propIsBypass && (value === '' || value === null) ){\n return {\n name: name,\n value: value,\n bypass: true,\n deleteBypass: true\n };\n }\n\n // check if value is a function used as a mapper\n if( is.fn(value) ){\n return {\n name: name,\n value: value,\n strValue: 'fn',\n mapped: types.fn,\n bypass: propIsBypass\n };\n }\n\n // check if value is mapped\n var data, mapData, layoutData, mapLayoutData, scratch, mapScratch;\n if( !valueIsString || propIsFlat ){\n // then don't bother to do the expensive regex checks\n\n } else if(\n ( data = new RegExp( types.data.regex ).exec( value ) ) ||\n ( layoutData = new RegExp( types.layoutData.regex ).exec( value ) ) ||\n ( scratch = new RegExp( types.scratch.regex ).exec( value ) )\n ){\n if( propIsBypass ){ return false; } // mappers not allowed in bypass\n\n var mapped;\n if( data ){\n mapped = types.data;\n } else if( layoutData ){\n mapped = types.layoutData;\n } else {\n mapped = types.scratch;\n }\n\n data = data || layoutData || scratch;\n\n return {\n name: name,\n value: data,\n strValue: '' + value,\n mapped: mapped,\n field: data[1],\n bypass: propIsBypass\n };\n\n } else if(\n ( mapData = new RegExp( types.mapData.regex ).exec( value ) ) ||\n ( mapLayoutData = new RegExp( types.mapLayoutData.regex ).exec( value ) ) ||\n ( mapScratch = new RegExp( types.mapScratch.regex ).exec( value ) )\n ){\n if( propIsBypass ){ return false; } // mappers not allowed in bypass\n if( type.multiple ){ return false; } // impossible to map to num\n\n var mapped;\n if( mapData ){\n mapped = types.mapData;\n } else if( mapLayoutData ){\n mapped = types.mapLayoutData;\n } else {\n mapped = types.mapScratch;\n }\n\n mapData = mapData || mapLayoutData || mapScratch;\n\n // we can map only if the type is a colour or a number\n if( !(type.color || type.number) ){ return false; }\n\n var valueMin = this.parse( name, mapData[4] ); // parse to validate\n if( !valueMin || valueMin.mapped ){ return false; } // can't be invalid or mapped\n\n var valueMax = this.parse( name, mapData[5] ); // parse to validate\n if( !valueMax || valueMax.mapped ){ return false; } // can't be invalid or mapped\n\n // check if valueMin and valueMax are the same\n if( valueMin.value === valueMax.value ){\n return false; // can't make much of a mapper without a range\n\n } else if( type.color ){\n var c1 = valueMin.value;\n var c2 = valueMax.value;\n\n var same = c1[0] === c2[0] // red\n && c1[1] === c2[1] // green\n && c1[2] === c2[2] // blue\n && ( // optional alpha\n c1[3] === c2[3] // same alpha outright\n || (\n (c1[3] == null || c1[3] === 1) // full opacity for colour 1?\n &&\n (c2[3] == null || c2[3] === 1) // full opacity for colour 2?\n )\n )\n ;\n\n if( same ){ return false; } // can't make a mapper without a range\n }\n\n return {\n name: name,\n value: mapData,\n strValue: '' + value,\n mapped: mapped,\n field: mapData[1],\n fieldMin: parseFloat( mapData[2] ), // min & max are numeric\n fieldMax: parseFloat( mapData[3] ),\n valueMin: valueMin.value,\n valueMax: valueMax.value,\n bypass: propIsBypass\n };\n }\n\n if( type.multiple && propIsFlat !== 'multiple' ){\n var vals;\n\n if( valueIsString ){\n vals = value.split(/\\s+/);\n } else if( is.array(value) ){\n vals = value;\n } else {\n vals = [ value ];\n }\n\n if( type.evenMultiple && vals.length % 2 !== 0 ){ return null; }\n\n var valArr = vals.map(function( v ){\n var p = self.parse( name, v, propIsBypass, 'multiple' );\n\n if( p.pfValue != null ){\n return p.pfValue;\n } else {\n return p.value;\n }\n });\n\n return {\n name: name,\n value: valArr,\n pfValue: valArr,\n strValue: valArr.join(' '),\n bypass: propIsBypass,\n units: type.number && !type.unitless ? type.implicitUnits || 'px' : undefined\n };\n }\n\n // several types also allow enums\n var checkEnums = function(){\n for( var i = 0; i < type.enums.length; i++ ){\n var en = type.enums[i];\n\n if( en === value ){\n return {\n name: name,\n value: value,\n strValue: '' + value,\n bypass: propIsBypass\n };\n }\n }\n\n return null;\n };\n\n // check the type and return the appropriate object\n if( type.number ){\n var units;\n var implicitUnits = 'px'; // not set => px\n\n if( type.units ){ // use specified units if set\n units = type.units;\n }\n\n if( type.implicitUnits ){\n implicitUnits = type.implicitUnits;\n }\n\n if( !type.unitless ){\n if( valueIsString ){\n var unitsRegex = 'px|em' + (type.allowPercent ? '|\\\\%' : '');\n if( units ){ unitsRegex = units; } // only allow explicit units if so set\n var match = value.match( '^(' + util.regex.number + ')(' + unitsRegex + ')?' + '$' );\n\n if( match ){\n value = match[1];\n units = match[2] || implicitUnits;\n }\n\n } else if( !units || type.implicitUnits ) {\n units = implicitUnits; // implicitly px if unspecified\n }\n }\n\n value = parseFloat( value );\n\n // if not a number and enums not allowed, then the value is invalid\n if( isNaN(value) && type.enums === undefined ){\n return null;\n }\n\n // check if this number type also accepts special keywords in place of numbers\n // (i.e. `left`, `auto`, etc)\n if( isNaN(value) && type.enums !== undefined ){\n value = passedValue;\n\n return checkEnums();\n }\n\n // check if value must be an integer\n if( type.integer && !is.integer(value) ){\n return null;\n }\n\n // check value is within range\n if( (type.min !== undefined && value < type.min)\n || (type.max !== undefined && value > type.max)\n ){\n return null;\n }\n\n var ret = {\n name: name,\n value: value,\n strValue: '' + value + (units ? units : ''),\n units: units,\n bypass: propIsBypass\n };\n\n // normalise value in pixels\n if( type.unitless || (units !== 'px' && units !== 'em') ){\n ret.pfValue = value;\n } else {\n ret.pfValue = ( units === 'px' || !units ? (value) : (this.getEmSizeInPixels() * value) );\n }\n\n // normalise value in ms\n if( units === 'ms' || units === 's' ){\n ret.pfValue = units === 'ms' ? value : 1000 * value;\n }\n\n // normalise value in rad\n if( units === 'deg' || units === 'rad' ){\n ret.pfValue = units === 'rad' ? value : value * Math.PI/180;\n }\n\n return ret;\n\n } else if( type.propList ) {\n\n var props = [];\n var propsStr = '' + value;\n\n if( propsStr === 'none' ){\n // leave empty\n\n } else { // go over each prop\n\n var propsSplit = propsStr.split(',');\n for( var i = 0; i < propsSplit.length; i++ ){\n var propName = propsSplit[i].trim();\n\n if( self.properties[propName] ){\n props.push( propName );\n }\n }\n\n if( props.length === 0 ){ return null; }\n }\n\n return {\n name: name,\n value: props,\n strValue: props.length === 0 ? 'none' : props.join(', '),\n bypass: propIsBypass\n };\n\n } else if( type.color ){\n var tuple = util.color2tuple( value );\n\n if( !tuple ){ return null; }\n\n return {\n name: name,\n value: tuple,\n strValue: '' + value,\n bypass: propIsBypass,\n roundValue: true\n };\n\n } else if( type.regex || type.regexes ){\n\n // first check enums\n if( type.enums ){\n var enumProp = checkEnums();\n\n if( enumProp ){ return enumProp; }\n }\n\n var regexes = type.regexes ? type.regexes : [ type.regex ];\n\n for( var i = 0; i < regexes.length; i++ ){\n var regex = new RegExp( regexes[i] ); // make a regex from the type string\n var m = regex.exec( value );\n\n if( m ){ // regex matches\n return {\n name: name,\n value: m,\n strValue: '' + value,\n bypass: propIsBypass\n };\n\n }\n }\n\n return null; // didn't match any\n\n } else if( type.string ){\n // just return\n return {\n name: name,\n value: value,\n strValue: '' + value,\n bypass: propIsBypass\n };\n\n } else if( type.enums ){ // check enums last because it's a combo type in others\n return checkEnums();\n\n } else {\n return null; // not a type we can handle\n }\n\n};\n\nmodule.exports = styfn;\n","'use strict';\n\nvar util = require('../util');\n\nvar styfn = {};\n\n(function(){\n var number = util.regex.number;\n var rgba = util.regex.rgbaNoBackRefs;\n var hsla = util.regex.hslaNoBackRefs;\n var hex3 = util.regex.hex3;\n var hex6 = util.regex.hex6;\n var data = function( prefix ){ return '^' + prefix + '\\\\s*\\\\(\\\\s*([\\\\w\\\\.]+)\\\\s*\\\\)$'; };\n var mapData = function( prefix ){\n var mapArg = number + '|\\\\w+|' + rgba + '|' + hsla + '|' + hex3 + '|' + hex6;\n return '^' + prefix + '\\\\s*\\\\(([\\\\w\\\\.]+)\\\\s*\\\\,\\\\s*(' + number + ')\\\\s*\\\\,\\\\s*(' + number + ')\\\\s*,\\\\s*(' + mapArg + ')\\\\s*\\\\,\\\\s*(' + mapArg + ')\\\\)$';\n };\n\n // each visual style property has a type and needs to be validated according to it\n styfn.types = {\n time: { number: true, min: 0, units: 's|ms', implicitUnits: 'ms' },\n percent: { number: true, min: 0, max: 100, units: '%', implicitUnits: '%' },\n zeroOneNumber: { number: true, min: 0, max: 1, unitless: true },\n nOneOneNumber: { number: true, min: -1, max: 1, unitless: true },\n nonNegativeInt: { number: true, min: 0, integer: true, unitless: true },\n position: { enums: ['parent', 'origin'] },\n nodeSize: { number: true, min: 0, enums: ['auto', 'label'] },\n number: { number: true, unitless: true },\n numbers: { number: true, unitless: true, multiple: true },\n size: { number: true, min: 0 },\n bidirectionalSize: { number: true }, // allows negative\n bidirectionalSizes: { number: true, multiple: true }, // allows negative\n bgSize: { number: true, min: 0, allowPercent: true },\n bgWH: { number: true, min: 0, allowPercent: true, enums: ['auto'] },\n bgPos: { number: true, allowPercent: true },\n bgRepeat: { enums: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat'] },\n bgFit: { enums: ['none', 'contain', 'cover'] },\n bgClip: { enums: ['none', 'node'] },\n color: { color: true },\n bool: { enums: ['yes', 'no'] },\n lineStyle: { enums: ['solid', 'dotted', 'dashed'] },\n borderStyle: { enums: ['solid', 'dotted', 'dashed', 'double'] },\n curveStyle: { enums: ['bezier', 'unbundled-bezier', 'haystack', 'segments'] },\n fontFamily: { regex: '^([\\\\w- \\\\\"]+(?:\\\\s*,\\\\s*[\\\\w- \\\\\"]+)*)$' },\n fontVariant: { enums: ['small-caps', 'normal'] },\n fontStyle: { enums: ['italic', 'normal', 'oblique'] },\n fontWeight: { enums: ['normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '800', '900', 100, 200, 300, 400, 500, 600, 700, 800, 900] },\n textDecoration: { enums: ['none', 'underline', 'overline', 'line-through'] },\n textTransform: { enums: ['none', 'uppercase', 'lowercase'] },\n textWrap: { enums: ['none', 'wrap'] },\n textBackgroundShape: { enums: ['rectangle', 'roundrectangle']},\n nodeShape: { enums: ['rectangle', 'roundrectangle', 'ellipse', 'triangle', 'square', 'pentagon', 'hexagon', 'heptagon', 'octagon', 'star', 'diamond', 'vee', 'rhomboid', 'polygon'] },\n compoundIncludeLabels: { enums: ['include', 'exclude'] },\n arrowShape: { enums: ['tee', 'triangle', 'triangle-tee', 'triangle-backcurve', 'half-triangle-overshot', 'vee', 'square', 'circle', 'diamond', 'none'] },\n arrowFill: { enums: ['filled', 'hollow'] },\n display: { enums: ['element', 'none'] },\n visibility: { enums: ['hidden', 'visible'] },\n valign: { enums: ['top', 'center', 'bottom'] },\n halign: { enums: ['left', 'center', 'right'] },\n text: { string: true },\n data: { mapping: true, regex: data('data') },\n layoutData: { mapping: true, regex: data('layoutData') },\n scratch: { mapping: true, regex: data('scratch') },\n mapData: { mapping: true, regex: mapData('mapData') },\n mapLayoutData: { mapping: true, regex: mapData('mapLayoutData') },\n mapScratch: { mapping: true, regex: mapData('mapScratch') },\n fn: { mapping: true, fn: true },\n url: { regex: '^url\\\\s*\\\\(\\\\s*([^\\\\s]+)\\\\s*\\\\s*\\\\)|none|(.+)$' },\n propList: { propList: true },\n angle: { number: true, units: 'deg|rad', implicitUnits: 'rad' },\n textRotation: { enums: ['none', 'autorotate'] },\n polygonPointList: { number: true, multiple: true, evenMultiple: true, min: -1, max: 1, unitless: true },\n easing: {\n regexes: [\n '^(spring)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*,\\\\s*(' + number + ')\\\\s*\\\\)$',\n '^(cubic-bezier)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*,\\\\s*(' + number + ')\\\\s*,\\\\s*(' + number + ')\\\\s*,\\\\s*(' + number + ')\\\\s*\\\\)$'\n ],\n enums: [\n 'linear',\n 'ease', 'ease-in', 'ease-out', 'ease-in-out',\n 'ease-in-sine', 'ease-out-sine', 'ease-in-out-sine',\n 'ease-in-quad', 'ease-out-quad', 'ease-in-out-quad',\n 'ease-in-cubic', 'ease-out-cubic', 'ease-in-out-cubic',\n 'ease-in-quart', 'ease-out-quart', 'ease-in-out-quart',\n 'ease-in-quint', 'ease-out-quint', 'ease-in-out-quint',\n 'ease-in-expo', 'ease-out-expo', 'ease-in-out-expo',\n 'ease-in-circ', 'ease-out-circ', 'ease-in-out-circ'\n ]\n }\n };\n\n // define visual style properties\n var t = styfn.types;\n var props = styfn.properties = [\n // labels\n { name: 'text-valign', type: t.valign },\n { name: 'text-halign', type: t.halign },\n { name: 'color', type: t.color },\n { name: 'label', type: t.text },\n { name: 'text-outline-color', type: t.color },\n { name: 'text-outline-width', type: t.size },\n { name: 'text-outline-opacity', type: t.zeroOneNumber },\n { name: 'text-opacity', type: t.zeroOneNumber },\n { name: 'text-background-color', type: t.color },\n { name: 'text-background-opacity', type: t.zeroOneNumber },\n { name: 'text-border-opacity', type: t.zeroOneNumber },\n { name: 'text-border-color', type: t.color },\n { name: 'text-border-width', type: t.size },\n { name: 'text-border-style', type: t.borderStyle },\n { name: 'text-background-shape', type: t.textBackgroundShape},\n // { name: 'text-decoration', type: t.textDecoration }, // not supported in canvas\n { name: 'text-transform', type: t.textTransform },\n { name: 'text-wrap', type: t.textWrap },\n { name: 'text-max-width', type: t.size },\n { name: 'text-events', type: t.bool },\n\n // { name: 'text-rotation', type: t.angle }, // TODO disabled b/c rotation breaks bounding boxes\n { name: 'font-family', type: t.fontFamily },\n { name: 'font-style', type: t.fontStyle },\n // { name: 'font-variant', type: t.fontVariant }, // not useful\n { name: 'font-weight', type: t.fontWeight },\n { name: 'font-size', type: t.size },\n { name: 'min-zoomed-font-size', type: t.size },\n { name: 'edge-text-rotation', type: t.textRotation },\n\n // behaviour\n { name: 'events', type: t.bool },\n\n // visibility\n { name: 'display', type: t.display },\n { name: 'visibility', type: t.visibility },\n { name: 'opacity', type: t.zeroOneNumber },\n { name: 'z-index', type: t.nonNegativeInt },\n\n // overlays\n { name: 'overlay-padding', type: t.size },\n { name: 'overlay-color', type: t.color },\n { name: 'overlay-opacity', type: t.zeroOneNumber },\n\n // shadows\n { name: 'shadow-blur', type: t.size },\n { name: 'shadow-color', type: t.color },\n { name: 'shadow-opacity', type: t.zeroOneNumber },\n { name: 'shadow-offset-x', type: t.bidirectionalSize },\n { name: 'shadow-offset-y', type: t.bidirectionalSize },\n\n // label shadows\n { name: 'text-shadow-blur', type: t.size },\n { name: 'text-shadow-color', type: t.color },\n { name: 'text-shadow-opacity', type: t.zeroOneNumber },\n { name: 'text-shadow-offset-x', type: t.bidirectionalSize },\n { name: 'text-shadow-offset-y', type: t.bidirectionalSize },\n\n // transition anis\n { name: 'transition-property', type: t.propList },\n { name: 'transition-duration', type: t.time },\n { name: 'transition-delay', type: t.time },\n { name: 'transition-timing-function', type: t.easing },\n\n // node body\n { name: 'height', type: t.nodeSize },\n { name: 'width', type: t.nodeSize },\n { name: 'shape', type: t.nodeShape },\n { name: 'shape-polygon-points', type: t.polygonPointList },\n { name: 'background-color', type: t.color },\n { name: 'background-opacity', type: t.zeroOneNumber },\n { name: 'background-blacken', type: t.nOneOneNumber },\n { name: 'padding-left', type: t.size },\n { name: 'padding-right', type: t.size },\n { name: 'padding-top', type: t.size },\n { name: 'padding-bottom', type: t.size },\n\n // node border\n { name: 'border-color', type: t.color },\n { name: 'border-opacity', type: t.zeroOneNumber },\n { name: 'border-width', type: t.size },\n { name: 'border-style', type: t.borderStyle },\n\n // node background images\n { name: 'background-image', type: t.url },\n { name: 'background-image-opacity', type: t.zeroOneNumber },\n { name: 'background-position-x', type: t.bgPos },\n { name: 'background-position-y', type: t.bgPos },\n { name: 'background-repeat', type: t.bgRepeat },\n { name: 'background-fit', type: t.bgFit },\n { name: 'background-clip', type: t.bgClip },\n { name: 'background-width', type: t.bgWH },\n { name: 'background-height', type: t.bgWH },\n\n // compound props\n { name: 'position', type: t.position },\n { name: 'compound-sizing-wrt-labels', type: t.compoundIncludeLabels },\n\n // edge line\n { name: 'line-style', type: t.lineStyle },\n { name: 'line-color', type: t.color },\n { name: 'curve-style', type: t.curveStyle },\n { name: 'haystack-radius', type: t.zeroOneNumber },\n { name: 'control-point-step-size', type: t.size },\n { name: 'control-point-distances', type: t.bidirectionalSizes },\n { name: 'control-point-weights', type: t.numbers },\n { name: 'segment-distances', type: t.bidirectionalSizes },\n { name: 'segment-weights', type: t.numbers },\n\n // these are just for the core\n { name: 'selection-box-color', type: t.color },\n { name: 'selection-box-opacity', type: t.zeroOneNumber },\n { name: 'selection-box-border-color', type: t.color },\n { name: 'selection-box-border-width', type: t.size },\n { name: 'active-bg-color', type: t.color },\n { name: 'active-bg-opacity', type: t.zeroOneNumber },\n { name: 'active-bg-size', type: t.size },\n { name: 'outside-texture-bg-color', type: t.color },\n { name: 'outside-texture-bg-opacity', type: t.zeroOneNumber }\n ];\n\n // define aliases\n var aliases = styfn.aliases = [\n { name: 'content', pointsTo: 'label' },\n { name: 'control-point-distance', pointsTo: 'control-point-distances' },\n { name: 'control-point-weight', pointsTo: 'control-point-weights' }\n ];\n\n // pie backgrounds for nodes\n styfn.pieBackgroundN = 16; // because the pie properties are numbered, give access to a constant N (for renderer use)\n props.push({ name: 'pie-size', type: t.bgSize });\n for( var i = 1; i <= styfn.pieBackgroundN; i++ ){\n props.push({ name: 'pie-'+i+'-background-color', type: t.color });\n props.push({ name: 'pie-'+i+'-background-size', type: t.percent });\n props.push({ name: 'pie-'+i+'-background-opacity', type: t.zeroOneNumber });\n }\n\n // edge arrows\n var arrowPrefixes = styfn.arrowPrefixes = ['source', 'mid-source', 'target', 'mid-target'];\n [\n { name: 'arrow-shape', type: t.arrowShape },\n { name: 'arrow-color', type: t.color },\n { name: 'arrow-fill', type: t.arrowFill }\n ].forEach(function( prop ){\n arrowPrefixes.forEach(function( prefix ){\n var name = prefix + '-' + prop.name;\n var type = prop.type;\n\n props.push({ name: name, type: type });\n });\n }, {});\n\n // list of property names\n styfn.propertyNames = props.map(function(p){ return p.name; });\n\n // allow access of properties by name ( e.g. style.properties.height )\n for( var i = 0; i < props.length; i++ ){\n var prop = props[i];\n\n props[ prop.name ] = prop; // allow lookup by name\n }\n\n // map aliases\n for( var i = 0; i < aliases.length; i++ ){\n var alias = aliases[i];\n var pointsToProp = props[ alias.pointsTo ];\n var aliasProp = {\n name: alias.name,\n alias: true,\n pointsTo: pointsToProp\n };\n\n // add alias prop for parsing\n props.push( aliasProp );\n\n props[ alias.name ] = aliasProp; // allow lookup by name\n }\n})();\n\n// adds the default stylesheet to the current style\nstyfn.addDefaultStylesheet = function(){\n // fill the style with the default stylesheet\n this\n .selector('node, edge') // common properties\n .css( util.extend( {\n 'events': 'yes',\n 'text-events': 'no',\n 'text-valign': 'top',\n 'text-halign': 'center',\n 'color': '#000',\n 'text-outline-color': '#000',\n 'text-outline-width': 0,\n 'text-outline-opacity': 1,\n 'text-opacity': 1,\n 'text-decoration': 'none',\n 'text-transform': 'none',\n 'text-wrap': 'none',\n 'text-max-width': 9999,\n 'text-background-color': '#000',\n 'text-background-opacity': 0,\n 'text-border-opacity': 0,\n 'text-border-width': 0,\n 'text-border-style': 'solid',\n 'text-border-color':'#000',\n 'text-background-shape':'rectangle',\n 'font-family': 'Helvetica Neue, Helvetica, sans-serif',\n 'font-style': 'normal',\n // 'font-variant': fontVariant,\n 'font-weight': 'normal',\n 'font-size': 16,\n 'min-zoomed-font-size': 0,\n 'edge-text-rotation': 'none',\n 'visibility': 'visible',\n 'display': 'element',\n 'opacity': 1,\n 'z-index': 0,\n 'label': '',\n 'overlay-opacity': 0,\n 'overlay-color': '#000',\n 'overlay-padding': 10,\n 'shadow-opacity': 0,\n 'shadow-color': '#000',\n 'shadow-blur': 10,\n 'shadow-offset-x': 0,\n 'shadow-offset-y': 0,\n 'text-shadow-opacity': 0,\n 'text-shadow-color': '#000',\n 'text-shadow-blur': 5,\n 'text-shadow-offset-x': 0,\n 'text-shadow-offset-y': 0,\n 'transition-property': 'none',\n 'transition-duration': 0,\n 'transition-delay': 0,\n 'transition-timing-function': 'linear',\n\n // node props\n 'background-blacken': 0,\n 'background-color': '#888',\n 'background-opacity': 1,\n 'background-image': 'none',\n 'background-image-opacity': 1,\n 'background-position-x': '50%',\n 'background-position-y': '50%',\n 'background-repeat': 'no-repeat',\n 'background-fit': 'none',\n 'background-clip': 'node',\n 'background-width': 'auto',\n 'background-height': 'auto',\n 'border-color': '#000',\n 'border-opacity': 1,\n 'border-width': 0,\n 'border-style': 'solid',\n 'height': 30,\n 'width': 30,\n 'shape': 'ellipse',\n 'shape-polygon-points': '-1, -1, 1, -1, 1, 1, -1, 1',\n\n // compound props\n 'padding-top': 0,\n 'padding-bottom': 0,\n 'padding-left': 0,\n 'padding-right': 0,\n 'position': 'origin',\n 'compound-sizing-wrt-labels': 'include'\n }, {\n // node pie bg\n 'pie-size': '100%'\n }, [\n { name: 'pie-{{i}}-background-color', value: 'black' },\n { name: 'pie-{{i}}-background-size', value: '0%' },\n { name: 'pie-{{i}}-background-opacity', value: 1 }\n ].reduce(function( css, prop ){\n for( var i = 1; i <= styfn.pieBackgroundN; i++ ){\n var name = prop.name.replace('{{i}}', i);\n var val = prop.value;\n\n css[ name ] = val;\n }\n\n return css;\n }, {}), {\n // edge props\n 'line-style': 'solid',\n 'line-color': '#ddd',\n 'control-point-step-size': 40,\n 'control-point-weights': 0.5,\n 'segment-weights': 0.5,\n 'segment-distances': 20,\n 'curve-style': 'bezier',\n 'haystack-radius': 0.8\n }, [\n { name: 'arrow-shape', value: 'none' },\n { name: 'arrow-color', value: '#ddd' },\n { name: 'arrow-fill', value: 'filled' }\n ].reduce(function( css, prop ){\n styfn.arrowPrefixes.forEach(function( prefix ){\n var name = prefix + '-' + prop.name;\n var val = prop.value;\n\n css[ name ] = val;\n });\n\n return css;\n }, {}) ) )\n .selector('$node > node') // compound (parent) node properties\n .css({\n 'width': 'auto',\n 'height': 'auto',\n 'shape': 'rectangle',\n 'padding-top': 10,\n 'padding-right': 10,\n 'padding-left': 10,\n 'padding-bottom': 10\n })\n .selector('edge') // just edge properties\n .css({\n 'width': 1\n })\n .selector(':active')\n .css({\n 'overlay-color': 'black',\n 'overlay-padding': 10,\n 'overlay-opacity': 0.25\n })\n .selector('core') // just core properties\n .css({\n 'selection-box-color': '#ddd',\n 'selection-box-opacity': 0.65,\n 'selection-box-border-color': '#aaa',\n 'selection-box-border-width': 1,\n 'active-bg-color': 'black',\n 'active-bg-opacity': 0.15,\n 'active-bg-size': 30,\n 'outside-texture-bg-color': '#000',\n 'outside-texture-bg-opacity': 0.125\n })\n ;\n\n this.defaultLength = this.length;\n};\n\nmodule.exports = styfn;\n","'use strict';\n\nvar util = require('../util');\nvar Selector = require('../selector');\n\nvar styfn = {};\n\nstyfn.applyFromString = function( string ){\n var self = this;\n var style = this;\n var remaining = '' + string;\n var selAndBlockStr;\n var blockRem;\n var propAndValStr;\n\n // remove comments from the style string\n remaining = remaining.replace(/[/][*](\\s|.)+?[*][/]/g, '');\n\n function removeSelAndBlockFromRemaining(){\n // remove the parsed selector and block from the remaining text to parse\n if( remaining.length > selAndBlockStr.length ){\n remaining = remaining.substr( selAndBlockStr.length );\n } else {\n remaining = '';\n }\n }\n\n function removePropAndValFromRem(){\n // remove the parsed property and value from the remaining block text to parse\n if( blockRem.length > propAndValStr.length ){\n blockRem = blockRem.substr( propAndValStr.length );\n } else {\n blockRem = '';\n }\n }\n\n while(true){\n var nothingLeftToParse = remaining.match(/^\\s*$/);\n if( nothingLeftToParse ){ break; }\n\n var selAndBlock = remaining.match(/^\\s*((?:.|\\s)+?)\\s*\\{((?:.|\\s)+?)\\}/);\n\n if( !selAndBlock ){\n util.error('Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: ' + remaining);\n break;\n }\n\n selAndBlockStr = selAndBlock[0];\n\n // parse the selector\n var selectorStr = selAndBlock[1];\n if( selectorStr !== 'core' ){\n var selector = new Selector( selectorStr );\n if( selector._private.invalid ){\n util.error('Skipping parsing of block: Invalid selector found in string stylesheet: ' + selectorStr);\n\n // skip this selector and block\n removeSelAndBlockFromRemaining();\n continue;\n }\n }\n\n // parse the block of properties and values\n var blockStr = selAndBlock[2];\n var invalidBlock = false;\n blockRem = blockStr;\n var props = [];\n\n while(true){\n var nothingLeftToParse = blockRem.match(/^\\s*$/);\n if( nothingLeftToParse ){ break; }\n\n var propAndVal = blockRem.match(/^\\s*(.+?)\\s*:\\s*(.+?)\\s*;/);\n\n if( !propAndVal ){\n util.error('Skipping parsing of block: Invalid formatting of style property and value definitions found in:' + blockStr);\n invalidBlock = true;\n break;\n }\n\n propAndValStr = propAndVal[0];\n var propStr = propAndVal[1];\n var valStr = propAndVal[2];\n\n var prop = self.properties[ propStr ];\n if( !prop ){\n util.error('Skipping property: Invalid property name in: ' + propAndValStr);\n\n // skip this property in the block\n removePropAndValFromRem();\n continue;\n }\n\n var parsedProp = style.parse( propStr, valStr );\n\n if( !parsedProp ){\n util.error('Skipping property: Invalid property definition in: ' + propAndValStr);\n\n // skip this property in the block\n removePropAndValFromRem();\n continue;\n }\n\n props.push({\n name: propStr,\n val: valStr\n });\n removePropAndValFromRem();\n }\n\n if( invalidBlock ){\n removeSelAndBlockFromRemaining();\n break;\n }\n\n // put the parsed block in the style\n style.selector( selectorStr );\n for( var i = 0; i < props.length; i++ ){\n var prop = props[i];\n style.css( prop.name, prop.val );\n }\n\n removeSelAndBlockFromRemaining();\n }\n\n return style;\n};\n\nstyfn.fromString = function( string ){\n var style = this;\n\n style.resetToDefault();\n style.applyFromString( string );\n\n return style;\n};\n\nmodule.exports = styfn;\n","'use strict';\n\nvar is = require('./is');\nvar util = require('./util');\nvar Style = require('./style');\n\n// a dummy stylesheet object that doesn't need a reference to the core\n// (useful for init)\nvar Stylesheet = function(){\n if( !(this instanceof Stylesheet) ){\n return new Stylesheet();\n }\n\n this.length = 0;\n};\n\nvar sheetfn = Stylesheet.prototype;\n\nsheetfn.instanceString = function(){\n return 'stylesheet';\n};\n\n// just store the selector to be parsed later\nsheetfn.selector = function( selector ){\n var i = this.length++;\n\n this[i] = {\n selector: selector,\n properties: []\n };\n\n return this; // chaining\n};\n\n// just store the property to be parsed later\nsheetfn.css = function( name, value ){\n var i = this.length - 1;\n\n if( is.string(name) ){\n this[i].properties.push({\n name: name,\n value: value\n });\n } else if( is.plainObject(name) ){\n var map = name;\n\n for( var j = 0; j < Style.properties.length; j++ ){\n var prop = Style.properties[j];\n var mapVal = map[ prop.name ];\n\n if( mapVal === undefined ){ // also try camel case name\n mapVal = map[ util.dash2camel(prop.name) ];\n }\n\n if( mapVal !== undefined ){\n var name = prop.name;\n var value = mapVal;\n\n this[i].properties.push({\n name: name,\n value: value\n });\n }\n }\n }\n\n return this; // chaining\n};\n\nsheetfn.style = sheetfn.css;\n\n// generate a real style object from the dummy stylesheet\nsheetfn.generateStyle = function( cy ){\n var style = new Style(cy);\n\n for( var i = 0; i < this.length; i++ ){\n var context = this[i];\n var selector = context.selector;\n var props = context.properties;\n\n style.selector(selector); // apply selector\n\n for( var j = 0; j < props.length; j++ ){\n var prop = props[j];\n\n style.css( prop.name, prop.value ); // apply property\n }\n }\n\n return style;\n};\n\nmodule.exports = Stylesheet;\n","// cross-env thread/worker\n// NB : uses (heavyweight) processes on nodejs so best not to create too many threads\n\n'use strict';\n\nvar window = require('./window');\nvar util = require('./util');\nvar Promise = require('./promise');\nvar Event = require('./event');\nvar define = require('./define');\nvar is = require('./is');\n\nvar Thread = function( opts ){\n if( !(this instanceof Thread) ){\n return new Thread( opts );\n }\n\n var _p = this._private = {\n requires: [],\n files: [],\n queue: null,\n pass: [],\n disabled: false\n };\n\n if( is.plainObject(opts) ){\n if( opts.disabled != null ){\n _p.disabled = !!opts.disabled;\n }\n }\n\n};\n\nvar thdfn = Thread.prototype; // short alias\n\nvar stringifyFieldVal = function( val ){\n var valStr = is.fn( val ) ? val.toString() : \"JSON.parse('\" + JSON.stringify(val) + \"')\";\n\n return valStr;\n};\n\n// allows for requires with prototypes and subobjs etc\nvar fnAsRequire = function( fn ){\n var req;\n var fnName;\n\n if( is.object(fn) && fn.fn ){ // manual fn\n req = fnAs( fn.fn, fn.name );\n fnName = fn.name;\n fn = fn.fn;\n } else if( is.fn(fn) ){ // auto fn\n req = fn.toString();\n fnName = fn.name;\n } else if( is.string(fn) ){ // stringified fn\n req = fn;\n } else if( is.object(fn) ){ // plain object\n if( fn.proto ){\n req = '';\n } else {\n req = fn.name + ' = {};';\n }\n\n fnName = fn.name;\n fn = fn.obj;\n }\n\n req += '\\n';\n\n var protoreq = function( val, subname ){\n if( val.prototype ){\n var protoNonempty = false;\n for( var prop in val.prototype ){ protoNonempty = true; break; } // jshint ignore:line\n\n if( protoNonempty ){\n req += fnAsRequire( {\n name: subname,\n obj: val,\n proto: true\n }, val );\n }\n }\n };\n\n // pull in prototype\n if( fn.prototype && fnName != null ){\n\n for( var name in fn.prototype ){\n var protoStr = '';\n\n var val = fn.prototype[ name ];\n var valStr = stringifyFieldVal( val );\n var subname = fnName + '.prototype.' + name;\n\n protoStr += subname + ' = ' + valStr + ';\\n';\n\n if( protoStr ){\n req += protoStr;\n }\n\n protoreq( val, subname ); // subobject with prototype\n }\n\n }\n\n // pull in properties for obj/fns\n if( !is.string(fn) ){ for( var name in fn ){\n var propsStr = '';\n\n if( fn.hasOwnProperty(name) ){\n var val = fn[ name ];\n var valStr = stringifyFieldVal( val );\n var subname = fnName + '[\"' + name + '\"]';\n\n propsStr += subname + ' = ' + valStr + ';\\n';\n }\n\n if( propsStr ){\n req += propsStr;\n }\n\n protoreq( val, subname ); // subobject with prototype\n } }\n\n return req;\n};\n\nvar isPathStr = function( str ){\n return is.string(str) && str.match(/\\.js$/);\n};\n\nutil.extend(thdfn, {\n\n instanceString: function(){ return 'thread'; },\n\n require: function( fn, as ){\n var requires = this._private.requires;\n\n if( isPathStr(fn) ){\n this._private.files.push( fn );\n\n return this;\n }\n\n if( as ){\n if( is.fn(fn) ){\n fn = { name: as, fn: fn };\n } else {\n fn = { name: as, obj: fn };\n }\n } else {\n if( is.fn(fn) ){\n if( !fn.name ){\n throw 'The function name could not be automatically determined. Use thread.require( someFunction, \"someFunction\" )';\n }\n\n fn = { name: fn.name, fn: fn };\n }\n }\n\n requires.push( fn );\n\n return this; // chaining\n },\n\n pass: function( data ){\n this._private.pass.push( data );\n\n return this; // chaining\n },\n\n run: function( fn, pass ){ // fn used like main()\n var self = this;\n var _p = this._private;\n pass = pass || _p.pass.shift();\n\n if( _p.stopped ){\n throw 'Attempted to run a stopped thread! Start a new thread or do not stop the existing thread and reuse it.';\n }\n\n if( _p.running ){\n return ( _p.queue = _p.queue.then(function(){ // inductive step\n return self.run( fn, pass );\n }) );\n }\n\n var useWW = window != null && !_p.disabled;\n var useNode = !window && typeof module !== 'undefined' && !_p.disabled;\n\n self.trigger('run');\n\n var runP = new Promise(function( resolve, reject ){\n\n _p.running = true;\n\n var threadTechAlreadyExists = _p.ran;\n\n var fnImplStr = is.string( fn ) ? fn : fn.toString();\n\n // worker code to exec\n var fnStr = '\\n' + ( _p.requires.map(function( r ){\n return fnAsRequire( r );\n }) ).concat( _p.files.map(function( f ){\n if( useWW ){\n var wwifyFile = function( file ){\n if( file.match(/^\\.\\//) || file.match(/^\\.\\./) ){\n return window.location.origin + window.location.pathname + file;\n } else if( file.match(/^\\//) ){\n return window.location.origin + '/' + file;\n }\n return file;\n };\n\n return 'importScripts(\"' + wwifyFile(f) + '\");';\n } else if( useNode ) {\n return 'eval( require(\"fs\").readFileSync(\"' + f + '\", { encoding: \"utf8\" }) );';\n } else {\n throw 'External file `' + f + '` can not be required without any threading technology.';\n }\n }) ).concat([\n '( function(){',\n 'var ret = (' + fnImplStr + ')(' + JSON.stringify(pass) + ');',\n 'if( ret !== undefined ){ resolve(ret); }', // assume if ran fn returns defined value (incl. null), that we want to resolve to it\n '} )()\\n'\n ]).join('\\n');\n\n // because we've now consumed the requires, empty the list so we don't dupe on next run()\n _p.requires = [];\n _p.files = [];\n\n if( useWW ){\n var fnBlob, fnUrl;\n\n // add normalised thread api functions\n if( !threadTechAlreadyExists ){\n var fnPre = fnStr + '';\n\n fnStr = [\n 'function _ref_(o){ return eval(o); };',\n 'function broadcast(m){ return message(m); };', // alias\n 'function message(m){ postMessage(m); };',\n 'function listen(fn){',\n ' self.addEventListener(\"message\", function(m){ ',\n ' if( typeof m === \"object\" && (m.data.$$eval || m.data === \"$$start\") ){',\n ' } else { ',\n ' fn( m.data );',\n ' }',\n ' });',\n '};',\n 'self.addEventListener(\"message\", function(m){ if( m.data.$$eval ){ eval( m.data.$$eval ); } });',\n 'function resolve(v){ postMessage({ $$resolve: v }); };',\n 'function reject(v){ postMessage({ $$reject: v }); };'\n ].join('\\n');\n\n fnStr += fnPre;\n\n fnBlob = new Blob([ fnStr ], {\n type: 'application/javascript'\n });\n fnUrl = window.URL.createObjectURL( fnBlob );\n }\n // create webworker and let it exec the serialised code\n var ww = _p.webworker = _p.webworker || new Worker( fnUrl );\n\n if( threadTechAlreadyExists ){ // then just exec new run() code\n ww.postMessage({\n $$eval: fnStr\n });\n }\n\n // worker messages => events\n var cb;\n ww.addEventListener('message', cb = function( m ){\n var isObject = is.object(m) && is.object( m.data );\n\n if( isObject && ('$$resolve' in m.data) ){\n ww.removeEventListener('message', cb); // done listening b/c resolve()\n\n resolve( m.data.$$resolve );\n } else if( isObject && ('$$reject' in m.data) ){\n ww.removeEventListener('message', cb); // done listening b/c reject()\n\n reject( m.data.$$reject );\n } else {\n self.trigger( new Event(m, { type: 'message', message: m.data }) );\n }\n }, false);\n\n if( !threadTechAlreadyExists ){\n ww.postMessage('$$start'); // start up the worker\n }\n\n } else if( useNode ){\n // create a new process\n\n if( !_p.child ){\n _p.child = ( require('child_process').fork( require('path').join(__dirname, 'thread-node-fork') ) );\n }\n\n var child = _p.child;\n\n // child process messages => events\n var cb;\n child.on('message', cb = function( m ){\n if( is.object(m) && ('$$resolve' in m) ){\n child.removeListener('message', cb); // done listening b/c resolve()\n\n resolve( m.$$resolve );\n } else if( is.object(m) && ('$$reject' in m) ){\n child.removeListener('message', cb); // done listening b/c reject()\n\n reject( m.$$reject );\n } else {\n self.trigger( new Event({}, { type: 'message', message: m }) );\n }\n });\n\n // ask the child process to eval the worker code\n child.send({\n $$eval: fnStr\n });\n\n } else { // use a fallback mechanism using a timeout\n\n var promiseResolve = resolve;\n var promiseReject = reject;\n\n var timer = _p.timer = _p.timer || {\n\n listeners: [],\n\n exec: function(){\n // as a string so it can't be mangled by minifiers and processors\n fnStr = [\n 'function _ref_(o){ return eval(o); };',\n 'function broadcast(m){ return message(m); };',\n 'function message(m){ self.trigger( new Event({}, { type: \"message\", message: m }) ); };',\n 'function listen(fn){ timer.listeners.push( fn ); };',\n 'function resolve(v){ promiseResolve(v); };',\n 'function reject(v){ promiseReject(v); };'\n ].join('\\n') + fnStr;\n\n // the .run() code\n eval( fnStr ); // jshint ignore:line\n },\n\n message: function( m ){\n var ls = timer.listeners;\n\n for( var i = 0; i < ls.length; i++ ){\n var fn = ls[i];\n\n fn( m );\n }\n }\n\n };\n\n timer.exec();\n }\n\n }).then(function( v ){\n _p.running = false;\n _p.ran = true;\n\n self.trigger('ran');\n\n return v;\n });\n\n if( _p.queue == null ){\n _p.queue = runP; // i.e. first step of inductive promise chain (for queue)\n }\n\n return runP;\n },\n\n // send the thread a message\n message: function( m ){\n var _p = this._private;\n\n if( _p.webworker ){\n _p.webworker.postMessage( m );\n }\n\n if( _p.child ){\n _p.child.send( m );\n }\n\n if( _p.timer ){\n _p.timer.message( m );\n }\n\n return this; // chaining\n },\n\n stop: function(){\n var _p = this._private;\n\n if( _p.webworker ){\n _p.webworker.terminate();\n }\n\n if( _p.child ){\n _p.child.kill();\n }\n\n if( _p.timer ){\n // nothing we can do if we've run a timeout\n }\n\n _p.stopped = true;\n\n return this.trigger('stop'); // chaining\n },\n\n stopped: function(){\n return this._private.stopped;\n }\n\n});\n\n// turns a stringified function into a (re)named function\nvar fnAs = function( fn, name ){\n var fnStr = fn.toString();\n fnStr = fnStr.replace(/function\\s*?\\S*?\\s*?\\(/, 'function ' + name + '(');\n\n return fnStr;\n};\n\nvar defineFnal = function( opts ){\n opts = opts || {};\n\n return function fnalImpl( fn, arg1 ){\n var fnStr = fnAs( fn, '_$_$_' + opts.name );\n\n this.require( fnStr );\n\n return this.run( [\n 'function( data ){',\n ' var origResolve = resolve;',\n ' var res = [];',\n ' ',\n ' resolve = function( val ){',\n ' res.push( val );',\n ' };',\n ' ',\n ' var ret = data.' + opts.name + '( _$_$_' + opts.name + ( arguments.length > 1 ? ', ' + JSON.stringify(arg1) : '' ) + ' );',\n ' ',\n ' resolve = origResolve;',\n ' resolve( res.length > 0 ? res : ret );',\n '}'\n ].join('\\n') );\n };\n};\n\nutil.extend(thdfn, {\n reduce: defineFnal({ name: 'reduce' }),\n\n reduceRight: defineFnal({ name: 'reduceRight' }),\n\n map: defineFnal({ name: 'map' })\n});\n\n// aliases\nvar fn = thdfn;\nfn.promise = fn.run;\nfn.terminate = fn.halt = fn.stop;\nfn.include = fn.require;\n\n// pull in event apis\nutil.extend(thdfn, {\n on: define.on(),\n one: define.on({ unbindSelfOnTrigger: true }),\n off: define.off(),\n trigger: define.trigger()\n});\n\ndefine.eventAliasesOn( thdfn );\n\nmodule.exports = Thread;\n","'use strict';\n\nvar is = require('../is');\n\nmodule.exports = {\n // get [r, g, b] from #abc or #aabbcc\n hex2tuple: function( hex ){\n if( !(hex.length === 4 || hex.length === 7) || hex[0] !== \"#\" ){ return; }\n\n var shortHex = hex.length === 4;\n var r, g, b;\n var base = 16;\n\n if( shortHex ){\n r = parseInt( hex[1] + hex[1], base );\n g = parseInt( hex[2] + hex[2], base );\n b = parseInt( hex[3] + hex[3], base );\n } else {\n r = parseInt( hex[1] + hex[2], base );\n g = parseInt( hex[3] + hex[4], base );\n b = parseInt( hex[5] + hex[6], base );\n }\n\n return [r, g, b];\n },\n\n // get [r, g, b, a] from hsl(0, 0, 0) or hsla(0, 0, 0, 0)\n hsl2tuple: function( hsl ){\n var ret;\n var h, s, l, a, r, g, b;\n function hue2rgb(p, q, t){\n if(t < 0) t += 1;\n if(t > 1) t -= 1;\n if(t < 1/6) return p + (q - p) * 6 * t;\n if(t < 1/2) return q;\n if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;\n return p;\n }\n\n var m = new RegExp(\"^\" + this.regex.hsla + \"$\").exec(hsl);\n if( m ){\n\n // get hue\n h = parseInt( m[1] );\n if( h < 0 ){\n h = ( 360 - (-1*h % 360) ) % 360;\n } else if( h > 360 ){\n h = h % 360;\n }\n h /= 360; // normalise on [0, 1]\n\n s = parseFloat( m[2] );\n if( s < 0 || s > 100 ){ return; } // saturation is [0, 100]\n s = s/100; // normalise on [0, 1]\n\n l = parseFloat( m[3] );\n if( l < 0 || l > 100 ){ return; } // lightness is [0, 100]\n l = l/100; // normalise on [0, 1]\n\n a = m[4];\n if( a !== undefined ){\n a = parseFloat( a );\n\n if( a < 0 || a > 1 ){ return; } // alpha is [0, 1]\n }\n\n // now, convert to rgb\n // code from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript\n if( s === 0 ){\n r = g = b = Math.round(l * 255); // achromatic\n } else {\n var q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n var p = 2 * l - q;\n r = Math.round( 255 * hue2rgb(p, q, h + 1/3) );\n g = Math.round( 255 * hue2rgb(p, q, h) );\n b = Math.round( 255 * hue2rgb(p, q, h - 1/3) );\n }\n\n ret = [r, g, b, a];\n }\n\n return ret;\n },\n\n // get [r, g, b, a] from rgb(0, 0, 0) or rgba(0, 0, 0, 0)\n rgb2tuple: function( rgb ){\n var ret;\n\n var m = new RegExp(\"^\" + this.regex.rgba + \"$\").exec(rgb);\n if( m ){\n ret = [];\n\n var isPct = [];\n for( var i = 1; i <= 3; i++ ){\n var channel = m[i];\n\n if( channel[ channel.length - 1 ] === \"%\" ){\n isPct[i] = true;\n }\n channel = parseFloat( channel );\n\n if( isPct[i] ){\n channel = channel/100 * 255; // normalise to [0, 255]\n }\n\n if( channel < 0 || channel > 255 ){ return; } // invalid channel value\n\n ret.push( Math.floor(channel) );\n }\n\n var atLeastOneIsPct = isPct[1] || isPct[2] || isPct[3];\n var allArePct = isPct[1] && isPct[2] && isPct[3];\n if( atLeastOneIsPct && !allArePct ){ return; } // must all be percent values if one is\n\n var alpha = m[4];\n if( alpha !== undefined ){\n alpha = parseFloat( alpha );\n\n if( alpha < 0 || alpha > 1 ){ return; } // invalid alpha value\n\n ret.push( alpha );\n }\n }\n\n return ret;\n },\n\n colorname2tuple: function( color ){\n return this.colors[ color.toLowerCase() ];\n },\n\n color2tuple: function( color ){\n return ( is.array(color) ? color : null )\n || this.colorname2tuple(color)\n || this.hex2tuple(color)\n || this.rgb2tuple(color)\n || this.hsl2tuple(color);\n },\n\n colors: {\n // special colour names\n transparent: [0, 0, 0, 0], // NB alpha === 0\n\n // regular colours\n aliceblue: [240, 248, 255],\n antiquewhite: [250, 235, 215],\n aqua: [0, 255, 255],\n aquamarine: [127, 255, 212],\n azure: [240, 255, 255],\n beige: [245, 245, 220],\n bisque: [255, 228, 196],\n black: [0, 0, 0],\n blanchedalmond: [255, 235, 205],\n blue: [0, 0, 255],\n blueviolet: [138, 43, 226],\n brown: [165, 42, 42],\n burlywood: [222, 184, 135],\n cadetblue: [95, 158, 160],\n chartreuse: [127, 255, 0],\n chocolate: [210, 105, 30],\n coral: [255, 127, 80],\n cornflowerblue: [100, 149, 237],\n cornsilk: [255, 248, 220],\n crimson: [220, 20, 60],\n cyan: [0, 255, 255],\n darkblue: [0, 0, 139],\n darkcyan: [0, 139, 139],\n darkgoldenrod: [184, 134, 11],\n darkgray: [169, 169, 169],\n darkgreen: [0, 100, 0],\n darkgrey: [169, 169, 169],\n darkkhaki: [189, 183, 107],\n darkmagenta: [139, 0, 139],\n darkolivegreen: [85, 107, 47],\n darkorange: [255, 140, 0],\n darkorchid: [153, 50, 204],\n darkred: [139, 0, 0],\n darksalmon: [233, 150, 122],\n darkseagreen: [143, 188, 143],\n darkslateblue: [72, 61, 139],\n darkslategray: [47, 79, 79],\n darkslategrey: [47, 79, 79],\n darkturquoise: [0, 206, 209],\n darkviolet: [148, 0, 211],\n deeppink: [255, 20, 147],\n deepskyblue: [0, 191, 255],\n dimgray: [105, 105, 105],\n dimgrey: [105, 105, 105],\n dodgerblue: [30, 144, 255],\n firebrick: [178, 34, 34],\n floralwhite: [255, 250, 240],\n forestgreen: [34, 139, 34],\n fuchsia: [255, 0, 255],\n gainsboro: [220, 220, 220],\n ghostwhite: [248, 248, 255],\n gold: [255, 215, 0],\n goldenrod: [218, 165, 32],\n gray: [128, 128, 128],\n grey: [128, 128, 128],\n green: [0, 128, 0],\n greenyellow: [173, 255, 47],\n honeydew: [240, 255, 240],\n hotpink: [255, 105, 180],\n indianred: [205, 92, 92],\n indigo: [75, 0, 130],\n ivory: [255, 255, 240],\n khaki: [240, 230, 140],\n lavender: [230, 230, 250],\n lavenderblush: [255, 240, 245],\n lawngreen: [124, 252, 0],\n lemonchiffon: [255, 250, 205],\n lightblue: [173, 216, 230],\n lightcoral: [240, 128, 128],\n lightcyan: [224, 255, 255],\n lightgoldenrodyellow: [250, 250, 210],\n lightgray: [211, 211, 211],\n lightgreen: [144, 238, 144],\n lightgrey: [211, 211, 211],\n lightpink: [255, 182, 193],\n lightsalmon: [255, 160, 122],\n lightseagreen: [32, 178, 170],\n lightskyblue: [135, 206, 250],\n lightslategray: [119, 136, 153],\n lightslategrey: [119, 136, 153],\n lightsteelblue: [176, 196, 222],\n lightyellow: [255, 255, 224],\n lime: [0, 255, 0],\n limegreen: [50, 205, 50],\n linen: [250, 240, 230],\n magenta: [255, 0, 255],\n maroon: [128, 0, 0],\n mediumaquamarine: [102, 205, 170],\n mediumblue: [0, 0, 205],\n mediumorchid: [186, 85, 211],\n mediumpurple: [147, 112, 219],\n mediumseagreen: [60, 179, 113],\n mediumslateblue: [123, 104, 238],\n mediumspringgreen: [0, 250, 154],\n mediumturquoise: [72, 209, 204],\n mediumvioletred: [199, 21, 133],\n midnightblue: [25, 25, 112],\n mintcream: [245, 255, 250],\n mistyrose: [255, 228, 225],\n moccasin: [255, 228, 181],\n navajowhite: [255, 222, 173],\n navy: [0, 0, 128],\n oldlace: [253, 245, 230],\n olive: [128, 128, 0],\n olivedrab: [107, 142, 35],\n orange: [255, 165, 0],\n orangered: [255, 69, 0],\n orchid: [218, 112, 214],\n palegoldenrod: [238, 232, 170],\n palegreen: [152, 251, 152],\n paleturquoise: [175, 238, 238],\n palevioletred: [219, 112, 147],\n papayawhip: [255, 239, 213],\n peachpuff: [255, 218, 185],\n peru: [205, 133, 63],\n pink: [255, 192, 203],\n plum: [221, 160, 221],\n powderblue: [176, 224, 230],\n purple: [128, 0, 128],\n red: [255, 0, 0],\n rosybrown: [188, 143, 143],\n royalblue: [65, 105, 225],\n saddlebrown: [139, 69, 19],\n salmon: [250, 128, 114],\n sandybrown: [244, 164, 96],\n seagreen: [46, 139, 87],\n seashell: [255, 245, 238],\n sienna: [160, 82, 45],\n silver: [192, 192, 192],\n skyblue: [135, 206, 235],\n slateblue: [106, 90, 205],\n slategray: [112, 128, 144],\n slategrey: [112, 128, 144],\n snow: [255, 250, 250],\n springgreen: [0, 255, 127],\n steelblue: [70, 130, 180],\n tan: [210, 180, 140],\n teal: [0, 128, 128],\n thistle: [216, 191, 216],\n tomato: [255, 99, 71],\n turquoise: [64, 224, 208],\n violet: [238, 130, 238],\n wheat: [245, 222, 179],\n white: [255, 255, 255],\n whitesmoke: [245, 245, 245],\n yellow: [255, 255, 0],\n yellowgreen: [154, 205, 50]\n }\n};\n","'use strict';\n\nvar is = require('../is');\nvar math = require('../math');\n\nvar util = {\n\n falsify: function(){ return false; },\n\n zeroify: function(){ return 0; },\n\n noop: function(){},\n\n /* jshint ignore:start */\n error: function( msg ){\n if( console.error ){\n console.error.apply( console, arguments );\n\n if( console.trace ){ console.trace(); }\n } else {\n console.log.apply( console, arguments );\n\n if( console.trace ){ console.trace(); }\n }\n },\n /* jshint ignore:end */\n\n clone: function( obj ){\n return this.extend( {}, obj );\n },\n\n // gets a shallow copy of the argument\n copy: function( obj ){\n if( obj == null ){\n return obj;\n } if( is.array(obj) ){\n return obj.slice();\n } else if( is.plainObject(obj) ){\n return this.clone( obj );\n } else {\n return obj;\n }\n }\n\n};\n\nutil.makeBoundingBox = math.makeBoundingBox.bind( math );\n\nutil._staticEmptyObject = {};\n\nutil.staticEmptyObject = function(){\n return util._staticEmptyObject;\n};\n\nutil.extend = Object.assign != null ? Object.assign : function( tgt ){\n var args = arguments;\n\n for( var i = 1; i < args.length; i++ ){\n var obj = args[i];\n\n for( var k in obj ){\n tgt[k] = obj[k];\n }\n }\n\n return tgt;\n};\n\n[\n require('./colors'),\n require('./maps'),\n { memoize: require('./memoize') },\n require('./regex'),\n require('./strings'),\n require('./timing')\n].forEach(function( req ){\n util.extend( util, req );\n});\n\nmodule.exports = util;\n","'use strict';\n\nvar is = require('../is');\n\nmodule.exports = {\n // has anything been set in the map\n mapEmpty: function( map ){\n var empty = true;\n\n if( map != null ){\n for(var i in map){ // jshint ignore:line\n empty = false;\n break;\n }\n }\n\n return empty;\n },\n\n // pushes to the array at the end of a map (map may not be built)\n pushMap: function( options ){\n var array = this.getMap(options);\n\n if( array == null ){ // if empty, put initial array\n this.setMap( this.extend({}, options, {\n value: [ options.value ]\n }) );\n } else {\n array.push( options.value );\n }\n },\n\n // sets the value in a map (map may not be built)\n setMap: function( options ){\n var obj = options.map;\n var key;\n var keys = options.keys;\n var l = keys.length;\n\n for(var i = 0; i < l; i++){\n var key = keys[i];\n\n if( is.plainObject( key ) ){\n this.error('Tried to set map with object key');\n }\n\n if( i < keys.length - 1 ){\n\n // extend the map if necessary\n if( obj[key] == null ){\n obj[key] = {};\n }\n\n obj = obj[key];\n } else {\n // set the value\n obj[key] = options.value;\n }\n }\n },\n\n // gets the value in a map even if it's not built in places\n getMap: function( options ){\n var obj = options.map;\n var keys = options.keys;\n var l = keys.length;\n\n for(var i = 0; i < l; i++){\n var key = keys[i];\n\n if( is.plainObject( key ) ){\n this.error('Tried to get map with object key');\n }\n\n obj = obj[key];\n\n if( obj == null ){\n return obj;\n }\n }\n\n return obj;\n },\n\n // deletes the entry in the map\n deleteMap: function( options ){\n var obj = options.map;\n var keys = options.keys;\n var l = keys.length;\n var keepChildren = options.keepChildren;\n\n for(var i = 0; i < l; i++){\n var key = keys[i];\n\n if( is.plainObject( key ) ){\n this.error('Tried to delete map with object key');\n }\n\n var lastKey = i === options.keys.length - 1;\n if( lastKey ){\n\n if( keepChildren ){ // then only delete child fields not in keepChildren\n for( var child in obj ){\n if( !keepChildren[child] ){\n obj[child] = undefined;\n }\n }\n } else {\n obj[key] = undefined;\n }\n\n } else {\n obj = obj[key];\n }\n }\n }\n};\n","'use strict';\n\nmodule.exports = function memoize( fn, keyFn ){\n var self = this;\n var cache = {};\n\n if( !keyFn ){\n keyFn = function(){\n if( arguments.length === 1 ){\n return arguments[0];\n }\n\n var args = [];\n\n for( var i = 0; i < arguments.length; i++ ){\n args.push( arguments[i] );\n }\n\n return args.join('$');\n };\n }\n\n return function memoizedFn(){\n var args = arguments;\n var ret;\n var k = keyFn.apply( self, args );\n\n if( !(ret = cache[k]) ){\n ret = cache[k] = fn.apply( self, args );\n }\n\n return ret;\n };\n};\n","'use strict';\n\nvar number = \"(?:[-+]?(?:(?:\\\\d+|\\\\d*\\\\.\\\\d+)(?:[Ee][+-]?\\\\d+)?))\";\n\nvar rgba = \"rgb[a]?\\\\((\"+ number +\"[%]?)\\\\s*,\\\\s*(\"+ number +\"[%]?)\\\\s*,\\\\s*(\"+ number +\"[%]?)(?:\\\\s*,\\\\s*(\"+ number +\"))?\\\\)\";\nvar rgbaNoBackRefs = \"rgb[a]?\\\\((?:\"+ number +\"[%]?)\\\\s*,\\\\s*(?:\"+ number +\"[%]?)\\\\s*,\\\\s*(?:\"+ number +\"[%]?)(?:\\\\s*,\\\\s*(?:\"+ number +\"))?\\\\)\";\n\nvar hsla = \"hsl[a]?\\\\((\"+ number +\")\\\\s*,\\\\s*(\"+ number +\"[%])\\\\s*,\\\\s*(\"+ number +\"[%])(?:\\\\s*,\\\\s*(\"+ number +\"))?\\\\)\";\nvar hslaNoBackRefs = \"hsl[a]?\\\\((?:\"+ number +\")\\\\s*,\\\\s*(?:\"+ number +\"[%])\\\\s*,\\\\s*(?:\"+ number +\"[%])(?:\\\\s*,\\\\s*(?:\"+ number +\"))?\\\\)\";\n\nvar hex3 = \"\\\\#[0-9a-fA-F]{3}\";\nvar hex6 = \"\\\\#[0-9a-fA-F]{6}\";\n\nmodule.exports = {\n regex: {\n number: number,\n rgba: rgba,\n rgbaNoBackRefs: rgbaNoBackRefs,\n hsla: hsla,\n hslaNoBackRefs: hslaNoBackRefs,\n hex3: hex3,\n hex6: hex6\n }\n};\n","'use strict';\n\nvar memoize = require('./memoize');\nvar is = require('../is');\n\nmodule.exports = {\n\n camel2dash: memoize( function( str ){\n return str.replace(/([A-Z])/g, function( v ){\n return '-' + v.toLowerCase();\n });\n } ),\n\n dash2camel: memoize( function( str ){\n return str.replace(/(-\\w)/g, function( v ){\n return v[1].toUpperCase();\n });\n } ),\n\n capitalize: function(str){\n if( is.emptyString(str) ){\n return str;\n }\n\n return str.charAt(0).toUpperCase() + str.substring(1);\n }\n\n};\n","'use strict';\n\nvar window = require('../window');\nvar is = require('../is');\nvar performance = window ? window.performance : null;\n\nvar util = {};\n\nvar raf = !window ? null : ( window.requestAnimationFrame || window.mozRequestAnimationFrame ||\n window.webkitRequestAnimationFrame || window.msRequestAnimationFrame );\n\nraf = raf || function( fn ){\n if( fn ){\n setTimeout(function(){\n fn( pnow() );\n }, 1000/60);\n }\n};\n\nutil.requestAnimationFrame = function(fn){\n raf( fn );\n};\n\nvar pnow = performance && performance.now ? function(){ return performance.now(); } : function(){ return Date.now(); };\n\nutil.performanceNow = pnow;\n\n// ported lodash throttle function\nutil.throttle = function(func, wait, options) {\n var leading = true,\n trailing = true;\n\n if (options === false) {\n leading = false;\n } else if (is.plainObject(options)) {\n leading = 'leading' in options ? options.leading : leading;\n trailing = 'trailing' in options ? options.trailing : trailing;\n }\n options = options || {};\n options.leading = leading;\n options.maxWait = wait;\n options.trailing = trailing;\n\n return util.debounce(func, wait, options);\n};\n\nutil.now = function(){\n return Date.now();\n};\n\nutil.debounce = function(func, wait, options) { // ported lodash debounce function\n var util = this;\n var args,\n maxTimeoutId,\n result,\n stamp,\n thisArg,\n timeoutId,\n trailingCall,\n lastCalled = 0,\n maxWait = false,\n trailing = true;\n\n if (!is.fn(func)) {\n return;\n }\n wait = Math.max(0, wait) || 0;\n if (options === true) {\n var leading = true;\n trailing = false;\n } else if (is.plainObject(options)) {\n leading = options.leading;\n maxWait = 'maxWait' in options && (Math.max(wait, options.maxWait) || 0);\n trailing = 'trailing' in options ? options.trailing : trailing;\n }\n var delayed = function() {\n var remaining = wait - (util.now() - stamp);\n if (remaining <= 0) {\n if (maxTimeoutId) {\n clearTimeout(maxTimeoutId);\n }\n var isCalled = trailingCall;\n maxTimeoutId = timeoutId = trailingCall = undefined;\n if (isCalled) {\n lastCalled = util.now();\n result = func.apply(thisArg, args);\n if (!timeoutId && !maxTimeoutId) {\n args = thisArg = null;\n }\n }\n } else {\n timeoutId = setTimeout(delayed, remaining);\n }\n };\n\n var maxDelayed = function() {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n maxTimeoutId = timeoutId = trailingCall = undefined;\n if (trailing || (maxWait !== wait)) {\n lastCalled = util.now();\n result = func.apply(thisArg, args);\n if (!timeoutId && !maxTimeoutId) {\n args = thisArg = null;\n }\n }\n };\n\n return function() {\n args = arguments;\n stamp = util.now();\n thisArg = this;\n trailingCall = trailing && (timeoutId || !leading);\n\n if (maxWait === false) {\n var leadingCall = leading && !timeoutId;\n } else {\n if (!maxTimeoutId && !leading) {\n lastCalled = stamp;\n }\n var remaining = maxWait - (stamp - lastCalled),\n isCalled = remaining <= 0;\n\n if (isCalled) {\n if (maxTimeoutId) {\n maxTimeoutId = clearTimeout(maxTimeoutId);\n }\n lastCalled = stamp;\n result = func.apply(thisArg, args);\n }\n else if (!maxTimeoutId) {\n maxTimeoutId = setTimeout(maxDelayed, remaining);\n }\n }\n if (isCalled && timeoutId) {\n timeoutId = clearTimeout(timeoutId);\n }\n else if (!timeoutId && wait !== maxWait) {\n timeoutId = setTimeout(delayed, wait);\n }\n if (leadingCall) {\n isCalled = true;\n result = func.apply(thisArg, args);\n }\n if (isCalled && !timeoutId && !maxTimeoutId) {\n args = thisArg = null;\n }\n return result;\n };\n};\n\nmodule.exports = util;\n","module.exports = ( typeof window === 'undefined' ? null : window );\n"]} \ No newline at end of file diff --git a/dependencies/cytoscape.js-2.5.4/cytoscape.min.js b/dependencies/cytoscape.js-2.5.4/cytoscape.min.js new file mode 100644 index 0000000..5927473 --- /dev/null +++ b/dependencies/cytoscape.js-2.5.4/cytoscape.min.js @@ -0,0 +1,26 @@ +/*! + * This file is part of Cytoscape.js 2.5.4. + * + * Cytoscape.js is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * Cytoscape.js is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License along with + * Cytoscape.js. If not, see . + */ +!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var t;t="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,t.cytoscape=e()}}(function(){var define,module,exports;return function e(t,r,n){function i(o,s){if(!r[o]){if(!t[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(a)return a(o,!0);var u=new Error("Cannot find module '"+o+"'");throw u.code="MODULE_NOT_FOUND",u}var c=r[o]={exports:{}};t[o][0].call(c.exports,function(e){var r=t[o][1][e];return i(r?r:e)},c,c.exports,e,t,r,n)}return r[o].exports}for(var a="function"==typeof require&&require,o=0;oa&&(n=a,r=i)}return r},a=this._private.cy;if(null==e||null==e.root)return void 0;var o=n.string(e.root)?this.filter(e.root)[0]:e.root[0];if(null==e.goal)return void 0;var s=n.string(e.goal)?this.filter(e.goal)[0]:e.goal[0];if(null!=e.heuristic&&n.fn(e.heuristic))var l=e.heuristic;else var l=function(){return 0};if(null!=e.weight&&n.fn(e.weight))var u=e.weight;else var u=function(e){return 1};if(null!=e.directed)var c=e.directed;else var c=!1;var d=[],h=[o.id()],p={},v={},f={},g={};f[o.id()]=0,g[o.id()]=l(o);for(var y=this.edges().stdFilter(function(e){return!e.isLoop()}),m=this.nodes(),b=0;h.length>0;){var x=i(h,g),w=a.getElementById(h[x]);if(b++,w.id()==s.id()){var _=r(o.id(),s.id(),p,[]);return _.reverse(),{found:!0,distance:f[w.id()],path:t.spawn(_),steps:b}}d.push(w.id()),h.splice(x,1);var E=w.connectedEdges();c&&(E=E.stdFilter(function(e){return e.data("source")===w.id()})),E=E.intersect(y);for(var D=0;Dh;h++)d[u[h].id()]=h;for(var p=[],v=[],f=[],h=0;c>h;h++)u[h].id()===o.id()?p[h]=0:p[h]=1/0,v[h]=void 0;for(var g=!1,h=1;c>h;h++){g=!1;for(var y=0;yh;h++)_.push(u[h].id());var E={distanceTo:function(e){if(n.string(e))var t=s.filter(e)[0].id();else var t=e.id();return p[d[t]]},pathTo:function(e){var r=function(e,t,r,n,i,a){for(;;){if(i.push(s.getElementById(n[r])),i.push(a[r]),t===r)return i;var o=e[r];if("undefined"==typeof o)return void 0;r=o}};if(n.string(e))var i=s.filter(e)[0].id();else var i=e.id();var a=[],l=r(v,d[o.id()],d[i],_,a,f);return null!=l&&l.reverse(),t.spawn(l)},hasNegativeWeightCycle:!1};return E}};t.exports=a},{"../../is":77,"../../util":94}],4:[function(e,t,r){"use strict";var n=e("../../is"),i={betweennessCentrality:function(e){if(e=e||{},null!=e.weight&&n.fn(e.weight))var t=e.weight,r=!0;else var r=!1;if(null!=e.directed&&n.bool(e.directed))var i=e.directed;else var i=!1;for(var a=function(e,t){e.unshift(t);for(var r=0;f[e[r]]0;){var y=g.pop();h.push(y),r?l[y].forEach(function(e){if(o.$("#"+y).edgesTo(e).length>0)var r=o.$("#"+y).edgesTo(e)[0];else var r=e.edgesTo("#"+y)[0];var n=t.apply(r,[r]);f[e.id()]>f[y]+n&&(f[e.id()]=f[y]+n,g.indexOf(e.id())<0?a(g,e.id()):(g.splice(g.indexOf(e.id()),1),a(g,e.id())),v[e.id()]=0,p[e.id()]=[]),f[e.id()]==f[y]+n&&(v[e.id()]=v[e.id()]+v[y],p[e.id()].push(y))}):l[y].forEach(function(e){f[e.id()]==Number.POSITIVE_INFINITY&&(g.unshift(e.id()),f[e.id()]=f[y]+1),f[e.id()]==f[y]+1&&(v[e.id()]=v[e.id()]+v[y],p[e.id()].push(y))})}for(var m={},c=0;c0;){var b=h.pop();p[b].forEach(function(e){m[e]=m[e]+v[e]/v[b]*(1+m[b]),b!=s[d].id()&&(u[b]=u[b]+m[b])})}}var x=0;for(var w in u)xu||!i)&&(o=u,i=l)}return{edge:i,dist:o}};f.size()>0;){var b=f.pop(),x=p(b),w=b.id();if(c[w]=x,x===Math.Infinite)break;for(var _=b.neighborhood().intersect(h),g=0;g<_.length;g++){var E=_[g],D=E.id(),S=m(b,E),k=x+S.dist;k0)for(r.unshift(t);u[i.id()];){var a=u[i.id()];r.unshift(a.edge),r.unshift(a.node),i=a.node}return o.collection(r)}}}};o.bfs=o.breadthFirstSearch,o.dfs=o.depthFirstSearch,t.exports=o},{"../../heap":75,"../../is":77}],6:[function(e,t,r){"use strict";var n=e("../../is"),i={closenessCentralityNormalized:function(e){e=e||{};var t=this.cy(),r=e.harmonic;void 0===r&&(r=!0);for(var i={},a=0,o=this.nodes(),s=this.floydWarshall({weight:e.weight,directed:e.directed}),l=0;la&&(a=u),i[o[l].id()]=u}return{closeness:function(e){if(n.string(e))var e=t.filter(e)[0].id();else var e=e.id();return i[e]/a}}},closenessCentrality:function(e){if(e=e||{},null==e.root)return void 0;if(n.string(e.root))var t=this.filter(e.root)[0];else var t=e.root[0];if(null!=e.weight&&n.fn(e.weight))var r=e.weight;else var r=function(){return 1};if(null!=e.directed&&n.bool(e.directed))var i=e.directed;else var i=!1;var a=e.harmonic;void 0===a&&(a=!0);for(var o=this.dijkstra({root:t,weight:r,directed:i}),s=0,l=this.nodes(),u=0;ud;d++){var h=a[d],p=this.degreeCentrality(i.extend({},e,{root:h}));ud;d++){var h=a[d],p=this.degreeCentrality(i.extend({},e,{root:h}));fu;u++)l[o[u].id()]=u;for(var c=[],u=0;s>u;u++){for(var d=new Array(s),h=0;s>h;h++)u==h?d[h]=0:d[h]=1/0;c.push(d)}var p=[],v=[],f=function(e){for(var t=0;s>t;t++){for(var r=new Array(s),n=0;s>n;n++)r[n]=void 0;e.push(r)}};f(p),f(v);for(var u=0;um&&(c[g][y]=m,p[g][y]=y,v[g][y]=a[u])}if(!i)for(var u=0;um&&(c[g][y]=m,p[g][y]=y,v[g][y]=a[u])}for(var b=0;s>b;b++)for(var u=0;s>u;u++)for(var h=0;s>h;h++)c[u][b]+c[b][h]u;u++)x.push(o[u].id());var w={distance:function(e,r){if(n.string(e))var i=t.filter(e)[0].id();else var i=e.id();if(n.string(r))var a=t.filter(r)[0].id();else var a=r.id();return c[l[i]][l[a]]},path:function(e,r){var i=function(e,r,n,i,a){if(e===r)return t.getElementById(i[e]);if(void 0===n[e][r])return void 0;for(var o=[t.getElementById(i[e])],s=e;e!==r;){s=e,e=n[e][r];var l=a[s][e];o.push(l),o.push(t.getElementById(i[e]))}return o};if(n.string(e))var a=t.filter(e)[0].id();else var a=e.id();if(n.string(r))var o=t.filter(r)[0].id();else var o=r.id();var s=i(l[a],l[o],p,x,v);return t.collection(s)}};return w}};t.exports=i},{"../../is":77}],9:[function(e,t,r){"use strict";var n=e("../../util"),i={};[e("./bfs-dfs"),e("./a-star"),e("./floyd-warshall"),e("./bellman-ford"),e("./kerger-stein"),e("./page-rank"),e("./degree-centrality"),e("./closeness-centrality"),e("./betweenness-centrality")].forEach(function(e){n.extend(i,e)}),t.exports=i},{"../../util":94,"./a-star":2,"./bellman-ford":3,"./betweenness-centrality":4,"./bfs-dfs":5,"./closeness-centrality":6,"./degree-centrality":7,"./floyd-warshall":8,"./kerger-stein":10,"./page-rank":11}],10:[function(e,t,r){"use strict";var n=e("../../util"),i={kargerStein:function(e){var t=this;e=e||{};var r=function(e,t,r){for(var n=r[e],i=n[1],a=n[2],o=t[i],s=t[a],l=r.filter(function(e){return t[e[1]]===o&&t[e[2]]===s?!1:t[e[1]]===s&&t[e[2]]===o?!1:!0}),u=0;u=n)return t;var o=Math.floor(Math.random()*t.length),s=r(o,e,t);return i(e,s,n-1,a)},a=this._private.cy,o=this.edges().stdFilter(function(e){return!e.isLoop()}),s=this.nodes(),l=s.length,u=o.length,c=Math.ceil(Math.pow(Math.log(l)/Math.LN2,2)),d=Math.floor(l/Math.sqrt(2));if(2>l)return void n.error("At least 2 nodes are required for Karger-Stein algorithm");for(var h={},p=0;l>p;p++)h[s[p].id()]=p;for(var v=[],p=0;u>p;p++){var f=o[p];v.push([p,h[f.source().id()],h[f.target().id()]])}for(var g,y=1/0,m=[],p=0;l>p;p++)m.push(p);for(var b=0;c>=b;b++){var x=m.slice(0),w=i(x,v,l,d),_=x.slice(0),E=i(x,w,d,2),D=i(_,w,d,2);E.length<=D.length&&E.lengthn;n++)r+=e[n];for(var n=0;t>n;n++)e[n]=e[n]/r};if(null!=e&&null!=e.dampingFactor)var r=e.dampingFactor;else var r=.8;if(null!=e&&null!=e.precision)var i=e.precision;else var i=1e-6;if(null!=e&&null!=e.iterations)var a=e.iterations;else var a=200;if(null!=e&&null!=e.weight&&n.fn(e.weight))var o=e.weight;else var o=function(e){return 1};for(var s=this._private.cy,l=this.edges().stdFilter(function(e){return!e.isLoop()}),u=this.nodes(),c=u.length,d=l.length,h={},p=0;c>p;p++)h[u[p].id()]=p;for(var v=[],f=[],g=(1-r)/c,p=0;c>p;p++){for(var y=[],m=0;c>m;m++)y.push(0);v.push(y),f.push(0)}for(var p=0;d>p;p++){var b=l[p],x=h[b.source().id()],w=h[b.target().id()],_=o.apply(b,[b]);v[w][x]+=_,f[x]+=_}for(var E=1/c+g,m=0;c>m;m++)if(0===f[m])for(var p=0;c>p;p++)v[p][m]=E;else for(var p=0;c>p;p++)v[p][m]=v[p][m]/f[m]+g;for(var D,S=[],k=[],p=0;c>p;p++)S.push(1),k.push(0);for(var T=0;a>T;T++){for(var P=k.slice(0),p=0;c>p;p++)for(var m=0;c>m;m++)P[p]+=v[p][m]*S[m];t(P),D=S,S=P;for(var C=0,p=0;c>p;p++)C+=Math.pow(D[p]-S[p],2);if(i>C)break}var N={rank:function(e){if(n.string(e))var t=s.filter(e)[0].id();else var t=e.id();return S[h[t]]}};return N}};t.exports=i},{"../../is":77}],12:[function(e,t,r){"use strict";var n=e("../define"),i={animate:n.animate(),animation:n.animation(),animated:n.animated(),clearQueue:n.clearQueue(),delay:n.delay(),delayAnimation:n.delayAnimation(),stop:n.stop()};t.exports=i},{"../define":41}],13:[function(e,t,r){"use strict";var n=e("../util"),i={classes:function(e){e=e.match(/\S+/g)||[];for(var t=this,r=[],i={},a=0;a0&&this.spawn(r).updateStyle().trigger("class"),t},addClass:function(e){return this.toggleClass(e,!0)},hasClass:function(e){var t=this[0];return null!=t&&t._private.classes[e]?!0:!1},toggleClass:function(e,t){for(var r=e.match(/\S+/g)||[],n=this,i=[],a=0,o=n.length;o>a;a++)for(var s=n[a],l=!1,u=0;u0&&this.spawn(i).updateStyle().trigger("class"),n},removeClass:function(e){return this.toggleClass(e,!1)},flashClass:function(e,t){var r=this;if(null==t)t=250;else if(0===t)return r;return r.addClass(e),setTimeout(function(){r.removeClass(e)},t),r}};t.exports=i},{"../util":94}],14:[function(e,t,r){"use strict";var n={allAre:function(e){return this.filter(e).length===this.length},is:function(e){return this.filter(e).length>0},some:function(e,t){for(var r=0;r0},allAreNeighbors:function(e){return e=this.cy().collection(e),this.neighborhood().intersect(e).length===e.length}};n.allAreNeighbours=n.allAreNeighbors,t.exports=n},{}],15:[function(e,t,r){"use strict";var n={parent:function(e){for(var t=[],r=this._private.cy,n=0;n0&&t.push(a)}return this.spawn(t,{unique:!0}).filter(e)},parents:function(e){for(var t=[],r=this.parent();r.nonempty();){for(var n=0;ne}),maxDegree:i("degree",function(e,t){return e>t}),minIndegree:i("indegree",function(e,t){return t>e}),maxIndegree:i("indegree",function(e,t){return e>t}),minOutdegree:i("outdegree",function(e,t){return t>e}),maxOutdegree:i("outdegree",function(e,t){return e>t})}),a.extend(o,{totalDegree:function(e){for(var t=0,r=this.nodes(),n=0;n0?this.add(s):this;t?l.trigger("position"):l.rtrigger("position")}return this},silentPositions:function(e){return this.positions(e,!0)},renderedPosition:function(e,t){var r=this[0],n=this.cy(),i=n.zoom(),a=n.pan(),s=o.plainObject(e)?e:void 0,l=void 0!==s||void 0!==t&&o.string(e);if(r&&r.isNode()){if(!l){var u=r._private.position;return s={x:u.x*i+a.x,y:u.y*i+a.y},void 0===e?s:s[e]}for(var c=0;c0,d=c;c&&(u=u[0]);var h=d?u._private.position:{x:0,y:0};return i={x:l.x-h.x,y:l.y-h.y},void 0===e?i:i[e]}for(var p=0;p0,d=c;c&&(u=u[0]);var h=d?u._private.position:{x:0,y:0};void 0!==t?r._private.position[e]=t+h[e]:void 0!==i&&(r._private.position={x:i.x+h.x,y:i.y+h.y})}this.rtrigger("position")}else if(!a)return void 0;return this},renderedBoundingBox:function(e){var t=this.boundingBox(e),r=this.cy(),n=r.zoom(),i=r.pan(),a=t.x1*n+i.x,o=t.x2*n+i.x,s=t.y1*n+i.y,l=t.y2*n+i.y;return{x1:a,x2:o,y1:s,y2:l,w:o-a,h:l-s}},updateCompoundBounds:function(){function e(e){var t=e.children(),n=e._private.style,i="include"===n["compound-sizing-wrt-labels"].value,a=t.boundingBox({includeLabels:i,includeEdges:!0}),o={top:n["padding-top"].pfValue,bottom:n["padding-bottom"].pfValue,left:n["padding-left"].pfValue,right:n["padding-right"].pfValue},s=e._private.position,l=!1;"auto"===n.width.value&&(e._private.autoWidth=a.w,s.x=(a.x1+a.x2-o.left+o.right)/2,l=!0),"auto"===n.height.value&&(e._private.autoHeight=a.h,s.y=(a.y1+a.y2-o.top+o.bottom)/2,l=!0),l&&r.push(e)}var t=this.cy();if(!t.styleEnabled()||!t.hasCompoundNodes())return t.collection();for(var r=[],n=this.parent();n.nonempty();){for(var i=0;iv?v:u,c=f>c?f:c,d=d>g?g:d,h=y>h?y:h}else if(x.isEdge()&&o){S=!0;var M=w.source,B=M._private,z=B.position,O=w.target,I=O._private,L=I.position,A=w.rstyle||{},T=0,R=0;if(i&&(T=_.width.pfValue,R=T/2),v=z.x,f=L.x,g=z.y,y=L.y,v>f){var V=v;v=f,f=V}if(g>y){var V=g;g=y,y=V}if(v-=R,f+=R,g-=R,y+=R,u=u>v?v:u,c=f>c?f:c,d=d>g?g:d,h=y>h?y:h,i)for(var F=A.bezierPts||A.linePts||[],j=0;jv?v:u,c=f>c?f:c,d=d>g?g:d,h=y>h?y:h}if(i&&"haystack"===_["curve-style"].strValue){var X=A.haystackPts;if(v=X[0].x,g=X[0].y,f=X[1].x,y=X[1].y,v>f){var V=v;v=f,f=V}if(g>y){var V=g;g=y,y=V}u=u>v?v:u,c=f>c?f:c,d=d>g?g:d,h=y>h?y:h}}if(i){var w=x._private,_=w.style,A=w.rstyle,Y=_.label.strValue,$=_["font-size"],H=_["text-halign"],W=_["text-valign"],Z=A.labelWidth,U=A.labelHeight,G=A.labelX,K=A.labelY,J=x.isEdge(),Q="autorotate"===_["edge-text-rotation"].strValue;if(l&&Y&&$&&null!=U&&null!=Z&&null!=G&&null!=K&&H&&W){var ee,te,re,ne,ie=U,ae=Z;if(J){if(ee=G-ae/2,te=G+ae/2,re=K-ie/2,ne=K+ie/2,Q){var oe=w.rscratch.labelAngle,se=Math.cos(oe),le=Math.sin(oe),ue=function(e,t){return e-=G,t-=K,{x:e*se-t*le+G,y:e*le+t*se+K}},ce=ue(ee,re),de=ue(ee,ne),he=ue(te,re),pe=ue(te,ne);ee=Math.min(ce.x,de.x,he.x,pe.x),te=Math.max(ce.x,de.x,he.x,pe.x),re=Math.min(ce.y,de.y,he.y,pe.y),ne=Math.max(ce.y,de.y,he.y,pe.y)}}else{switch(H.value){case"left":ee=G-ae,te=G;break;case"center":ee=G-ae/2,te=G+ae/2;break;case"right":ee=G,te=G+ae}switch(W.value){case"top":re=K-ie,ne=K;break;case"center":re=K-ie/2,ne=K+ie/2;break;case"bottom":re=K,ne=K+ie}}u=u>ee?ee:u,c=te>c?te:c,d=d>re?re:d,h=ne>h?ne:h}}}}var ve=function(e){return e===1/0||e===-(1/0)?0:e};return u=ve(u),c=ve(c),d=ve(d),h=ve(h),{x1:u,x2:c,y1:d,y2:h,w:c-u,h:h-d}}};var l=function(e){e.uppercaseName=s.capitalize(e.name),e.autoName="auto"+e.uppercaseName,e.labelName="label"+e.uppercaseName,e.outerName="outer"+e.uppercaseName,e.uppercaseOuterName=s.capitalize(e.outerName),n[e.name]=function(){var t=this[0],r=t._private,n=r.cy,i=n._private.styleEnabled;if(t){if(!i)return 1;var a=r.style[e.name];switch(a.strValue){case"auto":return r[e.autoName]||0;case"label":return r.rstyle[e.labelName]||0;default:return a.pfValue}}},n["outer"+e.uppercaseName]=function(){var t=this[0],r=t._private,n=r.cy,i=n._private.styleEnabled;if(t){if(i){var a=r.style,o=t[e.name](),s=a["border-width"].pfValue,l=a[e.paddings[0]].pfValue+a[e.paddings[1]].pfValue;return o+s+l}return 1}},n["rendered"+e.uppercaseName]=function(){var t=this[0];if(t){var r=t[e.name]();return r*this.cy().zoom()}},n["rendered"+e.uppercaseOuterName]=function(){var t=this[0];if(t){var r=t[e.outerName]();return r*this.cy().zoom()}}};l({name:"width",paddings:["padding-left","padding-right"]}),l({name:"height",paddings:["padding-top","padding-bottom"]}),n.modelPosition=n.point=n.position,n.modelPositions=n.points=n.positions,n.renderedPoint=n.renderedPosition,n.relativePoint=n.relativePosition,n.boundingbox=n.boundingBox,n.renderedBoundingbox=n.renderedBoundingBox,t.exports=i},{"../define":41,"../is":77,"../util":94}],19:[function(e,t,r){"use strict";var n=e("../util"),i=e("../is"),a=function(e,t,r){if(!(this instanceof a))return new a(e,t,r);var o=this;if(r=void 0===r||r?!0:!1,void 0===e||void 0===t||!i.core(e))return void n.error("An element must have a core reference and parameters set");var s=t.group; +if(null==s&&(s=null!=t.data.source&&null!=t.data.target?"edges":"nodes"),"nodes"!==s&&"edges"!==s)return void n.error("An element must be of type `nodes` or `edges`; you specified `"+s+"`");if(this.length=1,this[0]=this,this._private={cy:e,single:!0,data:t.data||{},position:t.position||{},autoWidth:void 0,autoHeight:void 0,listeners:[],group:s,style:{},rstyle:{},styleCxts:[],removed:!0,selected:t.selected?!0:!1,selectable:void 0===t.selectable?!0:t.selectable?!0:!1,locked:t.locked?!0:!1,grabbed:!1,grabbable:void 0===t.grabbable?!0:t.grabbable?!0:!1,active:!1,classes:{},animation:{current:[],queue:[]},rscratch:{},scratch:t.scratch||{},edges:[],children:[]},t.renderedPosition){var l=t.renderedPosition,u=e.pan(),c=e.zoom();this._private.position={x:(l.x-u.x)/c,y:(l.y-u.y)/c}}if(i.string(t.classes))for(var d=t.classes.split(/\s+/),h=0,p=d.length;p>h;h++){var v=d[h];v&&""!==v&&(o._private.classes[v]=!0)}(t.style||t.css)&&e.style().applyBypass(this,t.style||t.css),(void 0===r||r)&&this.restore()};t.exports=a},{"../is":77,"../util":94}],20:[function(e,t,r){"use strict";var n=e("../define"),i={on:n.on(),one:n.on({unbindSelfOnTrigger:!0}),once:n.on({unbindAllBindersOnTrigger:!0}),off:n.off(),trigger:n.trigger(),rtrigger:function(e,t){return 0!==this.length?(this.cy().notify({type:e,collection:this}),this.trigger(e,t),this):void 0}};n.eventAliasesOn(i),t.exports=i},{"../define":41}],21:[function(e,t,r){"use strict";var n=e("../is"),i=e("../selector"),a={nodes:function(e){return this.filter(function(e,t){return t.isNode()}).filter(e)},edges:function(e){return this.filter(function(e,t){return t.isEdge()}).filter(e)},filter:function(e){if(n.fn(e)){for(var t=[],r=0;r1&&!i){var a=this.length-1,o=this[a];this[a]=void 0,this[n]=o,t.indexes[o.id()]=n}return this.length--,this},unmerge:function(e){var t=this._private.cy;if(!e)return this;if(n.string(e)){var r=e;e=t.elements(r)}for(var i=0;in&&(n=s,r=o)}return{value:n,ele:r}},min:function(e,t){for(var r,n=1/0,i=this,a=0;as&&(n=s,r=o)}return{value:n,ele:r}}},o=a;o.u=o["|"]=o["+"]=o.union=o.or=o.add,o["\\"]=o["!"]=o["-"]=o.difference=o.relativeComplement=o.subtract=o.not,o.n=o["&"]=o["."]=o.and=o.intersection=o.intersect,o["^"]=o["(+)"]=o["(-)"]=o.symmetricDifference=o.symdiff=o.xor,o.fnFilter=o.filterFn=o.stdFilter,o.complement=o.abscomp=o.absoluteComplement,t.exports=a},{"../is":77,"../selector":81}],22:[function(e,t,r){"use strict";var n={isNode:function(){return"nodes"===this.group()},isEdge:function(){return"edges"===this.group()},isLoop:function(){return this.isEdge()&&this.source().id()===this.target().id()},isSimple:function(){return this.isEdge()&&this.source().id()!==this.target().id()},group:function(){var e=this[0];return e?e._private.group:void 0}};t.exports=n},{}],23:[function(e,t,r){"use strict";var n=e("../util"),i=e("../is"),a=e("./element"),o={prefix:"ele",id:0,generate:function(e,t,r){var n=(i.element(t)?t._private:t,null!=r?r:this.prefix+this.id);if(e.getElementById(n).empty())this.id++;else for(;!e.getElementById(n).empty();)n=this.prefix+ ++this.id;return n}},s=function(e,t,r){if(!(this instanceof s))return new s(e,t,r);if(void 0===e||!i.core(e))return void n.error("A collection must have a reference to the core");var l={},u={},c=!1;if(t){if(t.length>0&&i.plainObject(t[0])&&!i.element(t[0])){c=!0;for(var d=[],h={},p=0,v=t.length;v>p;p++){var f=t[p];null==f.data&&(f.data={});var g=f.data;if(null==g.id)g.id=o.generate(e,f);else if(0!==e.getElementById(g.id).length||h[g.id])continue;var y=new a(e,f,!1);d.push(y),h[g.id]=!0}t=d}}else t=[];this.length=0;for(var p=0,v=t.length;v>p;p++){var m=t[p];if(m){var b=m._private.data.id;(!r||r.unique&&!l[b])&&(l[b]=m,u[b]=this.length,this[this.length]=m,this.length++)}}this._private={cy:e,ids:l,indexes:u},c&&this.restore()},l=a.prototype=s.prototype;l.instanceString=function(){return"collection"},l.spawn=function(e,t,r){return i.core(e)||(r=t,t=e,e=this.cy()),new s(e,t,r)},l.cy=function(){return this._private.cy},l.element=function(){return this[0]},l.collection=function(){return i.collection(this)?this:new s(this._private.cy,[this])},l.unique=function(){return new s(this._private.cy,this,{unique:!0})},l.getElementById=function(e){var t=this._private.cy,r=this._private.ids[e];return r?r:new s(t)},l.json=function(e){var t=this.element(),r=this.cy();if(null==t&&e)return this;if(null==t)return void 0;var a=t._private;if(i.plainObject(e)){r.startBatch(),e.data&&t.data(e.data),e.position&&t.position(e.position);var o=function(r,n,i){var o=e[r];null!=o&&o!==a[r]&&(o?t[n]():t[i]())};return o("removed","remove","restore"),o("selected","select","unselect"),o("selectable","selectify","unselectify"),o("locked","lock","unlock"),o("grabbable","grabify","ungrabify"),null!=e.classes&&t.classes(e.classes),r.endBatch(),this}if(void 0===e){var s={data:n.copy(a.data),position:n.copy(a.position),group:a.group,removed:a.removed,selected:a.selected,selectable:a.selectable,locked:a.locked,grabbable:a.grabbable,classes:null},l=[];for(var u in a.classes)a.classes[u]&&l.push(u);return s.classes=l.join(" "),s}},l.jsons=function(){for(var e=[],t=0;tp;p++){var f=t[p];f.isNode()?(u.push(f),d++):(c.push(f),h++)}l=u.concat(c);for(var p=0,v=l.length;v>p;p++){var f=l[p];if(f.removed()){var g=f._private,y=g.data;if(void 0===y.id)y.id=o.generate(a,f);else if(i.number(y.id))y.id=""+y.id;else{if(i.emptyString(y.id)||!i.string(y.id)){n.error("Can not create element with invalid string ID `"+y.id+"`");continue}if(0!==a.getElementById(y.id).length){n.error("Can not create second element with ID `"+y.id+"`");continue}}var m=y.id;if(f.isNode()){var b=f,x=g.position;null==x.x&&(x.x=0),null==x.y&&(x.y=0)}if(f.isEdge()){for(var w=f,_=["source","target"],E=_.length,D=!1,S=0;E>S;S++){var k=_[S],T=y[k];i.number(T)&&(T=y[k]=""+y[k]),null==T||""===T?(n.error("Can not create edge `"+m+"` with unspecified "+k),D=!0):a.getElementById(T).empty()&&(n.error("Can not create edge `"+m+"` with nonexistant "+k+" `"+T+"`"),D=!0)}if(D)continue;var P=a.getElementById(y.source),C=a.getElementById(y.target);P._private.edges.push(w),C._private.edges.push(w),w._private.source=P,w._private.target=C}g.ids={},g.ids[m]=f,g.removed=!1,a.addToPool(f),r.push(f)}}for(var p=0;d>p;p++){var b=l[p],y=b._private.data;i.number(y.parent)&&(y.parent=""+y.parent);var N=y.parent,M=null!=N;if(M){var B=a.getElementById(N);if(B.empty())y.parent=void 0;else{for(var z=!1,O=B;!O.empty();){if(b.same(O)){z=!0,y.parent=void 0;break}O=O.parent()}z||(B[0]._private.children.push(b),b._private.parent=B[0],a._private.hasCompoundNodes=!0)}}}if(r=new s(a,r),r.length>0){var I=r.add(r.connectedNodes()).add(r.parent());I.updateStyle(e),e?r.rtrigger("add"):r.trigger("add")}return t},l.removed=function(){var e=this[0];return e&&e._private.removed},l.inside=function(){var e=this[0];return e&&!e._private.removed},l.remove=function(e){function t(e){for(var t=e._private.edges,r=0;rh;h++){var v=o[h];n(v)}for(var h=0;h0&&(e&&this.cy().notify({type:"remove",collection:b}),b.trigger("remove"));for(var x={},h=0;h0,a=t.getElementById(n).length>0;if(i||a){var o=this.jsons();this.remove();for(var s=0;s0;if(c){var o=this.jsons(),d=this.descendants(),h=d.merge(d.add(this).connectedEdges());this.remove();for(var s=0;se&&(e=n+e),0>t&&(t=n+t);for(var i=e;i>=0&&t>i&&n>i;i++)r.push(this[i]);return this.spawn(r)},size:function(){return this.length},eq:function(e){return this[e]||this.spawn()},first:function(){return this[0]||this.spawn()},last:function(){return this[this.length-1]||this.spawn()},empty:function(){return 0===this.length},nonempty:function(){return!this.empty()},sort:function(e){if(!n.fn(e))return this;var t=this.toArray().sort(e);return this.spawn(t)},sortByZIndex:function(){return this.sort(i)},zDepth:function(){var e=this[0];if(!e)return void 0;var t=e._private,r=t.group;if("nodes"===r){var n=t.data.parent?e.parents().size():0;return e.isParent()?n:Number.MAX_VALUE}var i=t.source,a=t.target,o=i.zDepth(),s=a.zDepth();return Math.max(o,s,0)}};t.exports=a},{"../is":77,"./zsort":29}],25:[function(e,t,r){"use strict";var n=e("../is"),i=e("../util"),a={layoutPositions:function(e,t,r){var i=this.nodes(),a=this.cy();if(e.trigger({type:"layoutstart",layout:e}),e.animations=[],t.animate){for(var o=0;o0?this.add(i):this;return e?a.rtrigger("style"):a.trigger("style"),this},updateMappers:function(e){var t=this._private.cy,r=t.style();if(e=e||void 0===e?!0:!1,!t.styleEnabled())return this;r.updateMappers(this);var n=this.updateCompoundBounds(),i=n.length>0?this.add(n):this;return e?i.rtrigger("style"):i.trigger("style"),this},renderedCss:function(e){var t=this.cy();if(!t.styleEnabled())return this;var r=this[0];if(r){var n=r.cy().style().getRenderedStyle(r);return void 0===e?n:n[e]}},css:function(e,t){var r=this.cy();if(!r.styleEnabled())return this;var i=!1,a=r.style();if(n.plainObject(e)){var o=e;a.applyBypass(this,o,i);var s=this.updateCompoundBounds(),l=s.length>0?this.add(s):this;l.rtrigger("style")}else if(n.string(e)){if(void 0===t){var u=this[0];return u?a.getStylePropertyValue(u,e):void 0}a.applyBypass(this,e,t,i);var s=this.updateCompoundBounds(),l=s.length>0?this.add(s):this;l.rtrigger("style")}else if(void 0===e){var u=this[0];return u?a.getRawStyle(u):void 0}return this},removeCss:function(e){var t=this.cy();if(!t.styleEnabled())return this;var r=!1,n=t.style(),i=this;if(void 0===e)for(var a=0;a0?this.add(s):this;return l.rtrigger("style"),this},show:function(){return this.css("display","element"),this},hide:function(){return this.css("display","none"),this},visible:function(){var e=this.cy();if(!e.styleEnabled())return!0;var t=this[0],r=e.hasCompoundNodes();if(t){var n=t._private.style;if("visible"!==n.visibility.value||"element"!==n.display.value)return!1;if("nodes"===t._private.group){if(!r)return!0;var i=t._private.data.parent?t.parents():null;if(i)for(var a=0;a0;a||r.push(i)}}return this.spawn(r,{unique:!0}).filter(e)},leaves:function(e){for(var t=this,r=[],n=0;n0;a||r.push(i)}}return this.spawn(r,{unique:!0}).filter(e)},outgoers:function(e){for(var t=this,r=[],n=0;n0&&t.push(c[0]),t.push(s[0])}return this.spawn(t,{unique:!0}).filter(e)},closedNeighborhood:function(e){return this.neighborhood().add(this).filter(e)},openNeighborhood:function(e){return this.neighborhood(e)}}),l.neighbourhood=l.neighborhood,l.closedNeighbourhood=l.closedNeighborhood,l.openNeighbourhood=l.openNeighborhood,o.extend(l,{source:function(e){var t,r=this[0];return r&&(t=r._private.source),t&&e?t.filter(e):t},target:function(e){var t,r=this[0];return r&&(t=r._private.target),t&&e?t.filter(e):t},sources:n({attr:"source"}),targets:n({attr:"target"})}),o.extend(l,{edgesWith:i(),edgesTo:i({thisIs:"source"})}),o.extend(l,{connectedEdges:function(e){for(var t=[],r=this,n=0;n0);return n.map(function(e){return e.closedNeighborhood()})}}),t.exports=l},{"../is":77,"../util":94}],29:[function(e,t,r){"use strict";var n=function(e,t){var r=e.cy(),n=e._private,i=t._private,a=n.style["z-index"].value-i.style["z-index"].value,o=0,s=0,l=r.hasCompoundNodes(),u="nodes"===n.group,c="edges"===n.group,d="nodes"===i.group,h="edges"===i.group;l&&(o=e.zDepth(),s=t.zDepth());var p=o-s,v=0===p;return v?u&&h?1:c&&d?-1:0===a?n.index-i.index:a:p};t.exports=n},{}],30:[function(e,t,r){"use strict";var n=e("../is"),i=e("../util"),a=e("../collection"),o=e("../collection/element"),s=e("../window"),l=(s?s.document:null,e("../extensions/renderer/null"),{add:function(e){var t,r=this;if(n.elementOrCollection(e)){var s=e;if(s._private.cy===r)t=s.restore();else{for(var l=[],u=0;uu;u++){var v=h[u],f=d[v];if(n.array(f))for(var g=0,y=f.length;y>g;g++){var m=i.extend({group:v},f[g]);l.push(m)}}t=new a(r,l)}else{var m=e;t=new o(r,m).collection()}return t},remove:function(e){if(n.elementOrCollection(e))e=e;else if(n.string(e)){var t=e;e=this.$(t)}return e.remove()},load:function(e,t,r){var a=this;a.notifications(!1);var o=a.elements();o.length>0&&o.remove(),null!=e&&(n.plainObject(e)||n.array(e))&&a.add(e),a.one("layoutready",function(e){a.notifications(!0),a.trigger(e),a.notify({type:"load",collection:a.elements()}),a.one("load",t),a.trigger("load")}).one("layoutstop",function(){a.one("done",r),a.trigger("done")});var s=i.extend({},a._private.options.layout);return s.eles=a.$(),a.layout(s),this}});t.exports=l},{"../collection":23,"../collection/element":19,"../extensions/renderer/null":73,"../is":77,"../util":94,"../window":100}],31:[function(e,t,r){"use strict";var n=e("../define"),i=e("../util"),a=e("../is"),o={animate:n.animate(),animation:n.animation(),animated:n.animated(),clearQueue:n.clearQueue(),delay:n.delay(),delayAnimation:n.delayAnimation(),stop:n.stop(),addToAnimationPool:function(e){var t=this;t.styleEnabled()&&t._private.aniEles.merge(e)},stopAnimationLoop:function(){this._private.animationsRunning=!1},startAnimationLoop:function(){function e(){c._private.animationsRunning&&i.requestAnimationFrame(function(r){t(r),e()})}function t(e){function t(t,i){var o=t._private,s=o.animation.current,l=o.animation.queue,u=!1;if(0===s.length){var c=l.shift();c&&s.push(c)}for(var d=function(e){for(var t=e.length-1;t>=0;t--){var r=e[t];r()}e.splice(0,e.length)},h=s.length-1;h>=0;h--){var p=s[h],v=p._private;v.stopped?(s.splice(h,1),v.hooked=!1,v.playing=!1,v.started=!1,d(v.frames)):(v.playing||v.applying)&&(v.playing&&v.applying&&(v.applying=!1),v.started||r(t,p,e),n(t,p,e,i),v.applying&&(v.applying=!1),d(v.frames),p.completed()&&(s.splice(h,1),v.hooked=!1,v.playing=!1,v.started=!1,d(v.completes)),u=!0)}return i||0!==s.length||0!==l.length||a.push(t),u}for(var i=c._private.aniEles,a=[],o=!1,s=0;s0){var p=i.updateCompoundBounds();h=p.length>0?i.add(p):i}c.notify({type:"draw",collection:h})}i.unmerge(a)}function r(e,t,r){var n=a.core(e),i=!n,o=e,s=c._private.style,l=t._private;if(i){var u=o._private.position;l.startPosition=l.startPosition||{x:u.x,y:u.y},l.startStyle=l.startStyle||s.getValueStyle(o)}if(n){var d=c._private.pan;l.startPan=l.startPan||{x:d.x,y:d.y},l.startZoom=null!=l.startZoom?l.startZoom:c._private.zoom}l.started=!0,l.startTime=r-l.progress*l.duration}function n(e,t,r,n){var i=c._private.style,s=!n,l=e._private,d=t._private,p=d.easing,v=d.startTime;if(!d.easingImpl)if(null==p)d.easingImpl=h.linear;else{var f;if(a.string(p)){var g=i.parse("transition-timing-function",p);f=g.value}else f=p;var y,m;a.string(f)?(y=f,m=[]):(y=f[1],m=f.slice(2).map(function(e){return+e})),m.length>0?("spring"===y&&m.push(d.duration),d.easingImpl=h[y].apply(null,m)):d.easingImpl=h[y]}var b,x=d.easingImpl;if(b=0===d.duration?1:(r-v)/d.duration,d.applying&&(b=d.progress),0>b?b=0:b>1&&(b=1),null==d.delay){var w=d.startPosition,_=d.position,E=l.position;_&&s&&(o(w.x,_.x)&&(E.x=u(w.x,_.x,b,x)),o(w.y,_.y)&&(E.y=u(w.y,_.y,b,x)));var D=d.startPan,S=d.pan,k=l.pan,T=null!=S&&n;T&&(o(D.x,S.x)&&(k.x=u(D.x,S.x,b,x)),o(D.y,S.y)&&(k.y=u(D.y,S.y,b,x)),e.trigger("pan"));var P=d.startZoom,C=d.zoom,N=null!=C&&n;N&&(o(P,C)&&(l.zoom=u(P,C,b,x)),e.trigger("zoom")),(T||N)&&e.trigger("viewport");var M=d.style;if(M&&s)for(var B=0;Br?r=0:r>1&&(r=1);var i,o;if(i=null!=e.pfValue||null!=e.value?null!=e.pfValue?e.pfValue:e.value:e,o=null!=t.pfValue||null!=t.value?null!=t.pfValue?t.pfValue:t.value:t,a.number(i)&&a.number(o))return n(i,o,r);if(a.array(i)&&a.array(o)){for(var s=[],l=0;ld&&Math.abs(s.v)>d))break;return a?function(e){return u[e*(u.length-1)|0]}:c}}(),h={linear:function(e,t,r){return e+(t-e)*r},ease:l(.25,.1,.25,1),"ease-in":l(.42,0,1,1),"ease-out":l(0,0,.58,1),"ease-in-out":l(.42,0,.58,1),"ease-in-sine":l(.47,0,.745,.715),"ease-out-sine":l(.39,.575,.565,1),"ease-in-out-sine":l(.445,.05,.55,.95),"ease-in-quad":l(.55,.085,.68,.53),"ease-out-quad":l(.25,.46,.45,.94),"ease-in-out-quad":l(.455,.03,.515,.955),"ease-in-cubic":l(.55,.055,.675,.19),"ease-out-cubic":l(.215,.61,.355,1),"ease-in-out-cubic":l(.645,.045,.355,1),"ease-in-quart":l(.895,.03,.685,.22),"ease-out-quart":l(.165,.84,.44,1),"ease-in-out-quart":l(.77,0,.175,1),"ease-in-quint":l(.755,.05,.855,.06),"ease-out-quint":l(.23,1,.32,1),"ease-in-out-quint":l(.86,0,.07,1),"ease-in-expo":l(.95,.05,.795,.035),"ease-out-expo":l(.19,1,.22,1),"ease-in-out-expo":l(1,0,0,1),"ease-in-circ":l(.6,.04,.98,.335),"ease-out-circ":l(.075,.82,.165,1),"ease-in-out-circ":l(.785,.135,.15,.86),spring:function(e,t,r){var n=d(e,t,r);return function(e,t,r){return e+(t-e)*n(r)}},"cubic-bezier":function(e,t,r,n){return l(e,t,r,n)}}}}};t.exports=o},{"../define":41,"../is":77,"../util":94}],32:[function(e,t,r){"use strict";var n=e("../define"),i={on:n.on(),one:n.on({unbindSelfOnTrigger:!0}),once:n.on({unbindAllBindersOnTrigger:!0}),off:n.off(),trigger:n.trigger()};n.eventAliasesOn(i),t.exports=i},{"../define":41}],33:[function(e,t,r){"use strict";var n={png:function(e){var t=this._private.renderer;return e=e||{},t.png(e)},jpg:function(e){var t=this._private.renderer;return e=e||{},e.bg=e.bg||"#fff",t.jpg(e)}};n.jpeg=n.jpg,t.exports=n},{}],34:[function(e,t,r){"use strict";var n=e("../window"),i=e("../util"),a=e("../collection"),o=e("../is"),s=e("../promise"),l=e("../define"),u=function(e){if(!(this instanceof u))return new u(e);var t=this;e=i.extend({},e);var r=e.container;r&&!o.htmlElement(r)&&o.htmlElement(r[0])&&(r=r[0]);var l=r?r._cyreg:null;l=l||{},l&&l.cy&&(l.cy.destroy(),l={});var c=l.readies=l.readies||[];r&&(r._cyreg=l),l.cy=t;var d=void 0!==n&&void 0!==r&&!e.headless,h=e;h.layout=i.extend({name:d?"grid":"null"},h.layout),h.renderer=i.extend({ +name:d?"canvas":"null"},h.renderer);var p=function(e,t,r){return void 0!==t?t:void 0!==r?r:e},v=this._private={container:r,ready:!1,initrender:!1,options:h,elements:[],id2index:{},listeners:[],onRenders:[],aniEles:a(this),scratch:{},layout:null,renderer:null,notificationsEnabled:!0,minZoom:1e-50,maxZoom:1e50,zoomingEnabled:p(!0,h.zoomingEnabled),userZoomingEnabled:p(!0,h.userZoomingEnabled),panningEnabled:p(!0,h.panningEnabled),userPanningEnabled:p(!0,h.userPanningEnabled),boxSelectionEnabled:p(!0,h.boxSelectionEnabled),autolock:p(!1,h.autolock,h.autolockNodes),autoungrabify:p(!1,h.autoungrabify,h.autoungrabifyNodes),autounselectify:p(!1,h.autounselectify),styleEnabled:void 0===h.styleEnabled?d:h.styleEnabled,zoom:o.number(h.zoom)?h.zoom:1,pan:{x:o.plainObject(h.pan)&&o.number(h.pan.x)?h.pan.x:0,y:o.plainObject(h.pan)&&o.number(h.pan.y)?h.pan.y:0},animation:{current:[],queue:[]},hasCompoundNodes:!1,deferredExecQueue:[]},f=h.selectionType;void 0===f||"additive"!==f&&"single"!==f?v.selectionType="single":v.selectionType=f,o.number(h.minZoom)&&o.number(h.maxZoom)&&h.minZoom0?h.wheelSensitivity:1,motionBlur:void 0===h.motionBlur?!0:h.motionBlur,motionBlurOpacity:void 0===h.motionBlurOpacity?.05:h.motionBlurOpacity,pixelRatio:o.number(h.pixelRatio)&&h.pixelRatio>0?h.pixelRatio:void 0,desktopTapThreshold:void 0===h.desktopTapThreshold?4:h.desktopTapThreshold,touchTapThreshold:void 0===h.touchTapThreshold?8:h.touchTapThreshold},h.renderer));var y=[h.style,h.elements];g(function(e){var r=e[0],n=e[1];v.styleEnabled&&t.setStyle(r),h.initrender&&(t.on("initrender",h.initrender),t.on("initrender",function(){v.initrender=!0})),t.load(n,function(){t.startAnimationLoop(),v.ready=!0,o.fn(h.ready)&&t.on("ready",h.ready);for(var e=0;e0;)t.removeChild(t.childNodes[0]);return e},getElementById:function(e){var t=this._private.id2index[e];return void 0!==t?this._private.elements[t]:a(this)},selectionType:function(){return this._private.selectionType},hasCompoundNodes:function(){return this._private.hasCompoundNodes},styleEnabled:function(){return this._private.styleEnabled},addToPool:function(e){for(var t=this._private.elements,r=this._private.id2index,n=0;n0&&l>0&&!isNaN(r.w)&&!isNaN(r.h)&&r.w>0&&r.h>0){o=Math.min((s-2*t)/r.w,(l-2*t)/r.h),o=o>this._private.maxZoom?this._private.maxZoom:o,o=othis._private.maxZoom?this._private.maxZoom:r,r=rt.maxZoom||!t.zoomingEnabled?o=!0:(t.zoom=l,a.push("zoom"))}if(i&&(!o||!e.cancelOnFailedZoom)&&t.panningEnabled){var u=e.pan;n.number(u.x)&&(t.pan.x=u.x,s=!1),n.number(u.y)&&(t.pan.y=u.y,s=!1),s||a.push("pan")}return a.length>0&&(a.push("viewport"),this.trigger(a.join(" ")),this.notify({type:"viewport"})),this},center:function(e){var t=this.getCenterPan(e);return t&&(this._private.pan=t,this.trigger("pan viewport"),this.notify({type:"viewport"})),this},getCenterPan:function(e,t){if(this._private.panningEnabled){if(n.string(e)){var r=e;e=this.elements(r)}else n.elementOrCollection(e)||(e=this.elements());var i=e.boundingBox(),a=this.width(),o=this.height();t=void 0===t?this._private.zoom:t;var s={x:(a-t*(i.x1+i.x2))/2,y:(o-t*(i.y1+i.y2))/2};return s}},reset:function(){return this._private.panningEnabled&&this._private.zoomingEnabled?(this.viewport({pan:{x:0,y:0},zoom:1}),this):this},width:function(){var e=this._private.container;return e?e.clientWidth:1},height:function(){var e=this._private.container;return e?e.clientHeight:1},extent:function(){var e=this._private.pan,t=this._private.zoom,r=this.renderedExtent(),n={x1:(r.x1-e.x)/t,x2:(r.x2-e.x)/t,y1:(r.y1-e.y)/t,y2:(r.y2-e.y)/t};return n.w=n.x2-n.x1,n.h=n.y2-n.y1,n},renderedExtent:function(){var e=this.width(),t=this.height();return{x1:0,y1:0,x2:e,y2:t,w:e,h:t}}};i.centre=i.center,i.autolockNodes=i.autolock,i.autoungrabifyNodes=i.autoungrabify,t.exports=i},{"../is":77}],41:[function(e,t,r){"use strict";var n=e("./util"),i=e("./is"),a=e("./selector"),o=e("./promise"),s=e("./event"),l=e("./animation"),u={data:function(e){var t={field:"data",bindingEvent:"data",allowBinding:!1,allowSetting:!1,allowGetting:!1,settingEvent:"data",settingTriggersEvent:!1,triggerFnName:"trigger",immutableKeys:{},updateStyle:!1,onSet:function(e){},canSet:function(e){return!0}};return e=n.extend({},t,e),function(t,r){var n=e,a=this,o=void 0!==a.length,s=o?a:[a],l=o?a[0]:a;if(i.string(t)){if(n.allowGetting&&void 0===r){var u;return l&&(u=l._private[n.field][t]),u}if(n.allowSetting&&void 0!==r){var c=!n.immutableKeys[t];if(c){for(var d=0,h=s.length;h>d;d++)n.canSet(s[d])&&(s[d]._private[n.field][t]=r);n.updateStyle&&a.updateStyle(),n.onSet(a),n.settingTriggersEvent&&a[n.triggerFnName](n.settingEvent)}}}else if(n.allowSetting&&i.plainObject(t)){var p,v,f=t;for(p in f){v=f[p];var c=!n.immutableKeys[p];if(c)for(var d=0,h=s.length;h>d;d++)n.canSet(s[d])&&(s[d]._private[n.field][p]=v)}n.updateStyle&&a.updateStyle(),n.onSet(a),n.settingTriggersEvent&&a[n.triggerFnName](n.settingEvent)}else if(n.allowBinding&&i.fn(t)){var g=t;a.bind(n.bindingEvent,g)}else if(n.allowGetting&&void 0===t){var u;return l&&(u=l._private[n.field]),u}return a}},removeData:function(e){var t={field:"data",event:"data",triggerFnName:"trigger",triggerEvent:!1,immutableKeys:{}};return e=n.extend({},t,e),function(t){var r=e,n=this,a=void 0!==n.length,o=a?n:[n];if(i.string(t)){for(var s=t.split(/\s+/),l=s.length,u=0;l>u;u++){var c=s[u];if(!i.emptyString(c)){var d=!r.immutableKeys[c];if(d)for(var h=0,p=o.length;p>h;h++)o[h]._private[r.field][c]=void 0}}r.triggerEvent&&n[r.triggerFnName](r.event)}else if(void 0===t){for(var h=0,p=o.length;p>h;h++){var v=o[h]._private[r.field];for(var c in v){var f=!r.immutableKeys[c];f&&(v[c]=void 0)}}r.triggerEvent&&n[r.triggerFnName](r.event)}return n}},event:{regex:/(\w+)(\.\w+)?/,optionalTypeRegex:/(\w+)?(\.\w+)?/,falseCallback:function(){return!1}},on:function(e){var t={unbindSelfOnTrigger:!1,unbindAllBindersOnTrigger:!1};return e=n.extend({},t,e),function(t,r,n,o){var s=this,l=void 0!==s.length,c=l?s:[s],d=i.string(t),h=e;if(i.plainObject(r)?(o=n,n=r,r=void 0):(i.fn(r)||r===!1)&&(o=r,n=void 0,r=void 0),(i.fn(n)||n===!1)&&(o=n,n=void 0),!i.fn(o)&&o!==!1&&d)return s;if(d){var p={};p[t]=o,t=p}for(var v in t)if(o=t[v],o===!1&&(o=u.event.falseCallback),i.fn(o)){v=v.split(/\s+/);for(var f=0;f0:void 0}},clearQueue:function(e){var t={};return e=n.extend({},t,e),function(){var e=this,t=void 0!==e.length,r=t?e:[e],n=this._private.cy||this;if(!n.styleEnabled())return this;for(var i=0;i0;){var g=n.collection();i.bfs({roots:f[0],visit:function(e,t,r,n,i){g=g.add(r)},directed:!1}),f=f.not(g),v.push(g)}e=n.collection();for(var d=0;dP;){for(var C=k.shift(),N=C.neighborhood().nodes(),M=!1,d=0;dd;d++)for(var B=x[d],R=B.length,V=0;R>V;V++){var p=B[V],F=p._private.scratch.breadthfirst,j=O(p);j&&(F.intEle=j,A.push(p))}for(var d=0;dx.length-1;)x.push([]);x[X].push(p),F.depth=X,F.index=x[X].length-1}z()}var Y=0;if(r.avoidOverlap){for(var d=0;du||0===t)&&(n+=l/c,i++)}return i=Math.max(1,i),n/=i,0===i&&(n=void 0),U[e.id()]=n,n},K=function(e,t){var r=G(e),n=G(t);return r-n},J=0;3>J;J++){for(var d=0;d0&&x[0].length<=3?c/2:0),h=2*Math.PI/x[i].length*a;return 0===i&&1===x[0].length&&(d=1),{x:ee.x+d*Math.cos(h),y:ee.y+d*Math.sin(h)}}return{x:ee.x+(a+1-(o+1)/2)*s,y:(i+1)*l}}var p={x:ee.x+(a+1-(o+1)/2)*s,y:(i+1)*l};return t?p:p},re={},d=x.length-1;d>=0;d--)for(var B=x[d],V=0;V1&&t.avoidOverlap){p*=1.75;var b=Math.cos(h)-Math.cos(0),x=Math.sin(h)-Math.sin(0),w=Math.sqrt(p*p/(b*b+x*x));l=Math.max(w,l)}var _=function(e,r){var n=t.startAngle+e*h*(i?1:-1),a=l*Math.cos(n),o=l*Math.sin(n),s={x:c.x+a,y:c.y+o +};return s};return s.layoutPositions(this,t,_),this},t.exports=n},{"../../is":77,"../../math":79,"../../util":94}],47:[function(e,t,r){"use strict";function n(e){this.options=i.extend({},o,e)}var i=e("../../util"),a=e("../../math"),o={fit:!0,padding:30,startAngle:1.5*Math.PI,sweep:void 0,clockwise:!0,equidistant:!1,minNodeSpacing:10,boundingBox:void 0,avoidOverlap:!0,height:void 0,width:void 0,concentric:function(e){return e.degree()},levelWidth:function(e){return e.maxDegree()/4},animate:!1,animationDuration:500,animationEasing:void 0,ready:void 0,stop:void 0};n.prototype.run=function(){for(var e=this.options,t=e,r=void 0!==t.counterclockwise?!t.counterclockwise:t.clockwise,n=e.cy,i=t.eles,o=i.nodes().not(":parent"),s=a.makeBoundingBox(t.boundingBox?t.boundingBox:{x1:0,y1:0,w:n.width(),h:n.height()}),l={x:s.x1+s.w/2,y:s.y1+s.h/2},u=[],c=t.startAngle,d=0,h=0;h0){var x=Math.abs(m[0].value-b.value);x>=g&&(m=[],y.push(m))}m.push(b)}var w=d+t.minNodeSpacing;if(!t.avoidOverlap){var _=y.length>0&&y[0].length>1,E=Math.min(s.w,s.h)/2-w,D=E/(y.length+_?1:0);w=Math.min(w,D)}for(var S=0,h=0;h1&&t.avoidOverlap){var C=Math.cos(P)-Math.cos(0),N=Math.sin(P)-Math.sin(0),M=Math.sqrt(w*w/(C*C+N*N));S=Math.max(M,S)}k.r=S,S+=w}if(t.equidistant){for(var B=0,S=0,h=0;ha;a++)for(var o=e.layoutNodes[e.idToIndex[n[a]]],l=a+1;i>l;l++){var u=e.layoutNodes[e.idToIndex[n[l]]];s(o,u,e,t)}},s=function(e,t,r,n){var i=e.cmptId,a=t.cmptId;if(i===a||r.isCompound){var o=t.positionX-e.positionX,s=t.positionY-e.positionY;if(0!==o||0!==s){var c=l(e,t,o,s);if(c>0)var d=n.nodeOverlap*c,h=Math.sqrt(o*o+s*s),p=d*o/h,v=d*s/h;else var f=u(e,o,s),g=u(t,-1*o,-1*s),y=g.x-f.x,m=g.y-f.y,b=y*y+m*m,h=Math.sqrt(b),d=(e.nodeRepulsion+t.nodeRepulsion)/b,p=d*y/h,v=d*m/h;e.isLocked||(e.offsetX-=p,e.offsetY-=v),t.isLocked||(t.offsetX+=p,t.offsetY+=v)}}},l=function(e,t,r,n){if(r>0)var i=e.maxX-t.minX;else var i=t.maxX-e.minX;if(n>0)var a=e.maxY-t.minY;else var a=t.maxY-e.minY;return i>=0&&a>=0?Math.sqrt(i*i+a*a):0},u=function(e,t,r){var n=e.positionX,i=e.positionY,a=e.height||1,o=e.width||1,s=r/t,l=a/o,u={};do{if(0===t&&r>0){u.x=n,u.y=i+a/2;break}if(0===t&&0>r){u.x=n,u.y=i+a/2;break}if(t>0&&s>=-1*l&&l>=s){u.x=n+o/2,u.y=i+o*r/2/t;break}if(0>t&&s>=-1*l&&l>=s){u.x=n-o/2,u.y=i-o*r/2/t;break}if(r>0&&(-1*l>=s||s>=l)){u.x=n+a*t/2/r,u.y=i+a/2;break}if(0>r&&(-1*l>=s||s>=l)){u.x=n-a*t/2/r,u.y=i-a/2;break}}while(!1);return u},c=function(e,t){for(var r=0;rc;c++){var d=e.layoutNodes[e.idToIndex[i[c]]];if(!d.isLocked){var h=o-d.positionX,p=s-d.positionY,v=Math.sqrt(h*h+p*p);if(v>r){var f=t.gravity*h/v,g=t.gravity*p/v;d.offsetX+=f,d.offsetY+=g}}}}},h=function(e,t){var r=[],n=0,i=-1;for(r.push.apply(r,e.graphSet[0]),i+=e.graphSet[0].length;i>=n;){var a=r[n++],o=e.idToIndex[a],s=e.layoutNodes[o],l=s.children;if(0r)var i={x:r*e/n,y:r*t/n};else var i={x:e,y:t};return i},f=function(e,t){var r=e.parentId;if(null!=r){var n=t.layoutNodes[t.idToIndex[r]],i=!1;return(null==n.maxX||e.maxX+n.padRight>n.maxX)&&(n.maxX=e.maxX+n.padRight,i=!0),(null==n.minX||e.minX-n.padLeftn.maxY)&&(n.maxY=e.maxY+n.padBottom,i=!0),(null==n.minY||e.minY-n.padTopy&&(v+=g+t.componentSpacing,p=0,f=0,g=0)}},y=function(e){return i?!1:(a(r,n,e),r.temperature=r.temperature*n.coolingFactor,r.temperature=b;){var E=m[b++],D=a.idToIndex[E],v=a.layoutNodes[D],S=v.children;if(S.length>0){a.graphSet.push(S);for(var c=0;cn.count?0:n.graph},h=function(e,t,r,n){var i=n.graphSet[r];if(-1s){var f=d(),g=h();(f-1)*g>=s?d(f-1):(g-1)*f>=s&&h(g-1)}else for(;s>c*u;){var f=d(),g=h();(g+1)*f>=s?h(g+1):d(f+1)}var y=o.w/c,m=o.h/u;if(t.condense&&(y=0,m=0),t.avoidOverlap)for(var b=0;b=c&&(N=0,C++)},B={},b=0;b=o&&s>=e&&t>=l&&u>=t;return c},o=function(e,t,r,n,i){var a=e*Math.cos(n)-t*Math.sin(n),o=e*Math.sin(n)+t*Math.cos(n),s=a*r,l=o*r,u=s+i.x,c=l+i.y;return{x:u,y:c}},s=function(e,t,r,n){for(var i=[],a=0;a(s=i.sqDistanceToFiniteLine(e,t,E[D],E[D+1],E[D+2],E[D+3]))&&d.push(n);else if("bezier"===h.edgeType||"multibezier"===h.edgeType||"self"===h.edgeType||"compound"===h.edgeType)for(var E=h.allpts,D=0;D+5(s=i.sqDistanceToQuadraticBezier(e,t,E[D],E[D+1],E[D+2],E[D+3],E[D+4],E[D+5]))&&d.push(n);if(w&&_()&&0===d.length||d[d.length-1]!==n)for(var b=b||o.source,x=x||o.target,S=f.width.pfValue,k=l.getArrowWidth(S),T=[{name:"source",x:h.arrowStartX,y:h.arrowStartY,angle:h.srcArrowAngle},{name:"target",x:h.arrowEndX,y:h.arrowEndY,angle:h.tgtArrowAngle},{name:"mid-source",x:h.midX,y:h.midY,angle:h.midsrcArrowAngle},{name:"mid-target",x:h.midX,y:h.midY,angle:h.midtgtArrowAngle}],D=0;D0&&d[d.length-1]===n&&(a(b),a(x))}}function s(r){var n=r._private,a=g;if("no"!==n.style["text-events"].strValue)if("edges"===n.group&&"autorotate"===n.style["edge-text-rotation"].strValue){var o=n.rstyle,s=o.labelWidth+2*a,l=o.labelHeight+2*a,u=o.labelX,c=o.labelY,h=n.rscratch.labelAngle,p=Math.cos(h),v=Math.sin(h),f=function(e,t){return e-=u,t-=c,{x:e*p-t*v+u,y:e*v+t*p+c}},y=u-s/2,m=u+s/2,b=c-l/2,x=c+l/2,w=f(y,b),_=f(y,x),E=f(m,b),D=f(m,x),S=[w.x,w.y,E.x,E.y,D.x,D.y,_.x,_.y];i.pointInsidePolygonPoints(e,t,S)&&d.push(r)}else{var k=r.boundingBox({includeLabels:!0,includeNodes:!1,includeEdges:!1});k.x1-=a,k.y1-=a,k.x2+=a,k.y2+=a,k.w=k.x2-k.x1,k.h=k.y2-k.y1,i.inBoundingBox(k,e,t)&&d.push(r)}}for(var l=this,u=this,c=u.getCachedZSortedEles(),d=[],h=u.cy.zoom(),p=u.cy.hasCompoundNodes(),v=(n?24:8)/h,f=(n?8:2)/h,g=(n?8:2)/h,y=c.length-1;y>=0;y--){var m=c[y],b=m._private;if(d.length>0)break;"nodes"===b.group?a(m):o(m),s(m)}return d.length>0?d[d.length-1]:null},s.getAllInBox=function(e,t,r,n){var a=this.getCachedNodes(),o=this.getCachedEdges(),s=[],l=Math.min(e,r),u=Math.max(e,r),c=Math.min(t,n),d=Math.max(t,n);e=l,r=u,t=c,n=d;for(var h=i.makeBoundingBox({x1:e,y1:t,x2:r,y2:n}),p=0;po){for(var h=u.split(/\s+/),p="",v=0;v=m?p+=f+" ":(s.push(p),p=f+" ")}p.match(/^\s+$/)||s.push(p)}else s.push(u)}i.labelWrapCachedLines=s,i.labelWrapCachedText=r=s.join("\n"),i.labelWrapKey=i.labelKey}return r},s.calculateLabelDimensions=function(e,t,r){var n=this,i=e._private.style,a=i["font-style"].strValue,o=i["font-size"].pfValue+"px",s=i["font-family"].strValue,l=i["font-weight"].strValue,u=e._private.labelKey;r&&(u+="$@$"+r);var c=n.labelDimCache||(n.labelDimCache={});if(c[u])return c[u];var d=this.labelCalcDiv;d||(d=this.labelCalcDiv=document.createElement("div"),document.body.appendChild(d));var h=d.style;return h.fontFamily=s,h.fontStyle=a,h.fontSize=o,h.fontWeight=l,h.position="absolute",h.left="-9999px",h.top="-9999px",h.zIndex="-1",h.visibility="hidden",h.pointerEvents="none",h.padding="0",h.lineHeight="1","wrap"===i["text-wrap"].value?h.whiteSpace="pre":h.whiteSpace="normal",d.textContent=t,c[u]={width:d.clientWidth,height:d.clientHeight},c[u]},s.recalculateRenderedStyle=function(e){for(var t=[],r=[],n={},i=0;ib?b+"$-$"+m:m+"$-$"+b,y&&(t="unbundled$-$"+v.id),null==s[t]&&(s[t]=[],l.push(t)),s[t].push(h),y&&(s[t].hasUnbundled=!0)}else u.push(h)}for(var x,w,_,E,D,S,k,T,P,C,N,M,B,z,O=0;OE.data.id){var L=x;x=w,w=L}if(D=_.position,S=E.position,k=x.outerWidth(),T=x.outerHeight(),P=w.outerWidth(),C=w.outerHeight(),N=r.nodeShapes[this.getNodeShape(x)],M=r.nodeShapes[this.getNodeShape(w)],z=!1,I.length>1&&x!==w||I.hasUnbundled){var A=N.intersectLine(D.x,D.y,k,T,S.x,S.y,0),R=M.intersectLine(S.x,S.y,P,C,D.x,D.y,0),V={x1:A[0],x2:R[0],y1:A[1],y2:R[1]},F=R[1]-A[1],j=R[0]-A[0],q=Math.sqrt(j*j+F*F),X={ +x:j,y:F},Y={x:X.x/q,y:X.y/q};B={x:-Y.y,y:Y.x},(M.checkPoint(A[0],A[1],0,P,C,S.x,S.y)||N.checkPoint(R[0],R[1],0,k,T,D.x,D.y))&&(B={},z=!0)}for(var h,$,H,d=0;dIe;Ie++){var Le=Be[Ie],Ae=ze[Ie],Re=1-Le,Ve=Le,Fe={x:V.x1*Re+V.x2*Ve,y:V.y1*Re+V.y2*Ve};H.segpts.push(Fe.x+B.x*Ae,Fe.y+B.y*Ae)}}else if(I.length%2!==1||d!==Math.floor(I.length/2)||y){var je=y;H.edgeType=je?"multibezier":"bezier",H.ctrlpts=[];for(var qe=0;ee>qe;qe++){var Xe,Ye=(.5-I.length/2+d)*te,$e=i.signum(Ye);je&&(re=J?J.pfValue[qe]:te,ne=Q.value[qe]),Xe=y?re:void 0!==re?$e*re:void 0;var He=void 0!==Xe?Xe:Ye,Re=!ie||y?1-ne:ne,Ve=!ie||y?ne:1-ne,Fe={x:V.x1*Re+V.x2*Ve,y:V.y1*Re+V.y2*Ve};H.ctrlpts.push(Fe.x+B.x*He,Fe.y+B.y*He)}}else H.edgeType="straight";this.findEndpoints(h);var We=!a.number(H.startX)||!a.number(H.startY),Ze=!a.number(H.arrowStartX)||!a.number(H.arrowStartY),Ue=!a.number(H.endX)||!a.number(H.endY),Ge=!a.number(H.arrowEndX)||!a.number(H.arrowEndY),Ke=3,Je=this.getArrowWidth(K.width.pfValue)*this.arrowShapeHeight,Qe=Ke*Je;if("bezier"===H.edgeType){var et=i.distance({x:H.ctrlpts[0],y:H.ctrlpts[1]},{x:H.startX,y:H.startY}),tt=Qe>et,rt=i.distance({x:H.ctrlpts[0],y:H.ctrlpts[1]},{x:H.endX,y:H.endY}),nt=Qe>rt,it=!1;if(We||Ze||tt){it=!0;var at={x:H.ctrlpts[0]-D.x,y:H.ctrlpts[1]-D.y},ot=Math.sqrt(at.x*at.x+at.y*at.y),st={x:at.x/ot,y:at.y/ot},lt=Math.max(k,T),ut={x:H.ctrlpts[0]+2*st.x*lt,y:H.ctrlpts[1]+2*st.y*lt},ct=N.intersectLine(D.x,D.y,k,T,ut.x,ut.y,0);tt?(H.ctrlpts[0]=H.ctrlpts[0]+st.x*(Qe-et),H.ctrlpts[1]=H.ctrlpts[1]+st.y*(Qe-et)):(H.ctrlpts[0]=ct[0]+st.x*Qe,H.ctrlpts[1]=ct[1]+st.y*Qe)}if(Ue||Ge||nt){it=!0;var at={x:H.ctrlpts[0]-S.x,y:H.ctrlpts[1]-S.y},ot=Math.sqrt(at.x*at.x+at.y*at.y),st={x:at.x/ot,y:at.y/ot},lt=Math.max(k,T),ut={x:H.ctrlpts[0]+2*st.x*lt,y:H.ctrlpts[1]+2*st.y*lt},dt=M.intersectLine(S.x,S.y,P,C,ut.x,ut.y,0);nt?(H.ctrlpts[0]=H.ctrlpts[0]+st.x*(Qe-rt),H.ctrlpts[1]=H.ctrlpts[1]+st.y*(Qe-rt)):(H.ctrlpts[0]=dt[0]+st.x*Qe,H.ctrlpts[1]=dt[1]+st.y*Qe)}it&&this.findEndpoints(h)}if("multibezier"===H.edgeType||"bezier"===H.edgeType||"self"===H.edgeType||"compound"===H.edgeType){H.allpts=[],H.allpts.push(H.startX,H.startY);for(var qe=0;qe+1c[0]&&i.clientXc[1]&&i.clientY=e.desktopTapThreshold2){var I=!e.dragData.didDrag;I&&e.redrawHint("eles",!0),e.dragData.didDrag=!0;for(var L=[],A=0;A0&&e.redrawHint("eles",!0),e.dragData.possibleDragElements=h=[]),t(d,["mouseup","tapend","vmouseup"],n,{cyPosition:{x:l[0],y:l[1]}}),e.dragData.didDrag||e.hoverData.dragged||t(d,["click","tap","vclick"],n,{cyPosition:{x:l[0],y:l[1]}}),d!=p||e.dragData.didDrag||e.hoverData.selecting||null!=d&&d._private.selectable&&(e.hoverData.dragging||("additive"===s.selectionType()||v?d.selected()?d.unselect():d.select():v||(s.$(":selected").unmerge(d).unselect(),d.select())),e.redrawHint("eles",!0)),e.hoverData.selecting){var y=[],m=e.getAllInBox(u[0],u[1],u[2],u[3]);e.redrawHint("select",!0),m.length>0&&e.redrawHint("eles",!0);for(var b=0;b=0&&k>=g&&m>=0&&k>=m&&y>=0&&T>=y&&b>=0&&T>=b;var p=n.pan(),v=n.zoom();x=N(g,y,m,b),w=M(g,y,m,b),_=[(g+m)/2,(y+b)/2],E=[(_[0]-p.x)/v,(_[1]-p.y)/v];var f=200,C=f*f;if(C>w&&!r.touches[2]){var B=e.findNearestElement(s[0],s[1],!0,!0),z=e.findNearestElement(s[2],s[3],!0,!0);return B&&B.isNode()?(B.activate().trigger(a(r,{type:"cxttapstart",cyPosition:{x:s[0],y:s[1]}})),e.touchData.start=B):z&&z.isNode()?(z.activate().trigger(a(r,{type:"cxttapstart",cyPosition:{x:s[0],y:s[1]}})),e.touchData.start=z):(n.trigger(a(r,{type:"cxttapstart",cyPosition:{x:s[0],y:s[1]}})),e.touchData.start=null),e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxt=!0,e.touchData.cxtDragged=!1,e.data.bgActivePosistion=void 0,void e.redraw()}}if(r.touches[2]);else if(r.touches[1]);else if(r.touches[0]){var O=e.findNearestElement(s[0],s[1],!0,!0);if(null!=O&&(O.activate(),e.touchData.start=O,O.isNode()&&e.nodeIsDraggable(O))){var I=e.dragData.touchDragEles=[];if(e.redrawHint("eles",!0),e.redrawHint("drag",!0),O.selected())for(var L=n.$(function(){return this.isNode()&&this.selected()}),A=0;A=Y||V>=q){e.touchData.cxt=!1,e.touchData.start&&(e.touchData.start.unactivate(),e.touchData.start=null),e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var $=a(r,{type:"cxttapend",cyPosition:{x:c[0],y:c[1]}});e.touchData.start?e.touchData.start.trigger($):l.trigger($)}}if(s&&e.touchData.cxt){var $=a(r,{type:"cxtdrag",cyPosition:{x:c[0],y:c[1]}});e.data.bgActivePosistion=void 0,e.redrawHint("select",!0),e.touchData.start?e.touchData.start.trigger($):l.trigger($),e.touchData.start&&(e.touchData.start._private.grabbed=!1),e.touchData.cxtDragged=!0;var H=e.findNearestElement(c[0],c[1],!0,!0);e.touchData.cxtOver&&H===e.touchData.cxtOver||(e.touchData.cxtOver&&e.touchData.cxtOver.trigger(a(r,{type:"cxtdragout",cyPosition:{x:c[0],y:c[1]}})),e.touchData.cxtOver=H,H&&H.trigger(a(r,{type:"cxtdragover",cyPosition:{x:c[0],y:c[1]}})))}else if(s&&r.touches[2]&&l.boxSelectionEnabled())r.preventDefault(),e.data.bgActivePosistion=void 0,this.lastThreeTouch=+new Date,e.touchData.selecting=!0,e.redrawHint("select",!0),i&&0!==i.length&&void 0!==i[0]?(i[2]=(c[0]+c[2]+c[4])/3,i[3]=(c[1]+c[3]+c[5])/3):(i[0]=(c[0]+c[2]+c[4])/3,i[1]=(c[1]+c[3]+c[5])/3,i[2]=(c[0]+c[2]+c[4])/3+1,i[3]=(c[1]+c[3]+c[5])/3+1),i[4]=1,e.touchData.selecting=!0,e.redraw();else if(s&&r.touches[1]&&l.zoomingEnabled()&&l.panningEnabled()&&l.userZoomingEnabled()&&l.userPanningEnabled()){r.preventDefault(),e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var W=e.dragData.touchDragEles;if(W){e.redrawHint("drag",!0);for(var Z=0;Z=e.touchTapThreshold2){for(var W=e.dragData.touchDragEles,pe=!e.dragData.didDrag,ve=0;vee.touchTapThreshold2&&(e.touchData.singleTouchMoved=!0);if(s&&(null==de||de.isEdge())&&l.panningEnabled()&&l.userPanningEnabled()){r.preventDefault(),e.swipePanning?l.panBy({x:v[0]*h,y:v[1]*h}):O>=e.touchTapThreshold2&&(e.swipePanning=!0,l.panBy({x:k*h,y:C*h}),de&&(de.unactivate(),e.data.bgActivePosistion||(e.data.bgActivePosistion={x:c[0],y:c[1]}),e.redrawHint("select",!0),e.touchData.start=null));var p=e.projectIntoViewport(r.touches[0].clientX,r.touches[0].clientY);c[0]=p[0],c[1]=p[1]}}for(var f=0;f0?e.redrawHint("eles",!0):e.redraw()}var x=!1;if(null!=n&&(n._private.active=!1,x=!0,n.unactivate()),r.touches[2])e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);else if(r.touches[1]);else if(r.touches[0]);else if(!r.touches[0]){e.data.bgActivePosistion=void 0,e.redrawHint("select",!0);var w=e.dragData.touchDragEles;if(null!=n){var _=n._private.grabbed;c(w),e.redrawHint("drag",!0),e.redrawHint("eles",!0),_&&n.trigger("free"),t(n,["touchend","tapend","vmouseup"],r,{cyPosition:{x:d[0],y:d[1]}}),n.unactivate(),e.touchData.start=null}else{var E=e.findNearestElement(d[0],d[1],!0,!0);t(E,["touchend","tapend","vmouseup"],r,{cyPosition:{x:d[0],y:d[1]}})}var D=e.touchData.startPosition[0]-d[0],S=D*D,k=e.touchData.startPosition[1]-d[1],T=k*k,P=S+T,C=P*u*u;null!=n&&!e.dragData.didDrag&&n._private.selectable&&C=e*e+t*t}},e("triangle",n.generateUnitNgonPointsFitToSquare(3,0)),e("square",n.generateUnitNgonPointsFitToSquare(4,0)),t.rectangle=t.square,t.roundrectangle={name:"roundrectangle",points:n.generateUnitNgonPointsFitToSquare(4,0),draw:function(e,t,n,i,a){r.nodeShapeImpl(this.name)(e,t,n,i,a)},intersectLine:function(e,t,r,i,a,o,s){return n.roundRectangleIntersectLine(a,o,e,t,r,i,s)},checkPoint:function(e,t,r,i,a,o,s){var l=n.getRoundRectangleRadius(i,a);if(n.pointInsidePolygon(e,t,this.points,o,s,i,a-2*l,[0,-1],r))return!0;if(n.pointInsidePolygon(e,t,this.points,o,s,i-2*l,a,[0,-1],r))return!0;var u=function(e,t,r,n,i,a,o){return e-=r,t-=n,e/=i/2+o,t/=a/2+o,1>=e*e+t*t};return u(e,t,o-i/2+l,s-a/2+l,2*l,2*l,r)?!0:u(e,t,o+i/2-l,s-a/2+l,2*l,2*l,r)?!0:u(e,t,o+i/2-l,s+a/2-l,2*l,2*l,r)?!0:u(e,t,o-i/2+l,s+a/2-l,2*l,2*l,r)?!0:!1}},e("diamond",[0,1,1,0,0,-1,-1,0]),e("pentagon",n.generateUnitNgonPointsFitToSquare(5,0)),e("hexagon",n.generateUnitNgonPointsFitToSquare(6,0)),e("heptagon",n.generateUnitNgonPointsFitToSquare(7,0)),e("octagon",n.generateUnitNgonPointsFitToSquare(8,0));var i=new Array(20),a=n.generateUnitNgonPoints(5,0),o=n.generateUnitNgonPoints(5,Math.PI/5),s=.5*(3-Math.sqrt(5));s*=1.57;for(var l=0;ll;l++)i[4*l]=a[2*l],i[4*l+1]=a[2*l+1],i[4*l+2]=o[2*l],i[4*l+3]=o[2*l+1];i=n.fitPolygonToSquare(i),e("star",i),e("vee",[-1,-1,0,-.333,1,-1,0,1]),e("rhomboid",[-1,-1,.333,-1,1,1,-.333,1]),t.makePolygon=function(r){var n,i=r.join("$"),a="polygon-"+i;return(n=t[a])?n:e(a,r)}},t.exports=i},{"../../../math":79}],61:[function(e,t,r){"use strict";var n=e("../../../util"),i={};i.timeToRender=function(){return this.redrawTotalTime/this.redrawCount};var a=1e3/60,o=1e3;i.redraw=function(e){e=e||n.staticEmptyObject();var t=this,r=e.forcedContext;void 0===t.averageRedrawTime&&(t.averageRedrawTime=0),void 0===t.lastRedrawTime&&(t.lastRedrawTime=0);var i=t.lastRedrawTime;i=a>i?a:i,i=o>i?i:o,void 0===t.lastDrawTime&&(t.lastDrawTime=0);var s=Date.now(),l=s-t.lastDrawTime,u=l>=i;return r||u&&!t.currentlyDrawing?(t.requestedFrame=!0,t.currentlyDrawing=!0,void(t.renderOptions=e)):void(t.skipFrame=!0)},i.startRenderLoop=function(){var e=this,t=function(){if(!e.destroyed){if(e.requestedFrame&&!e.skipFrame){var r=n.performanceNow();e.render(e.renderOptions);var i=e.lastRedrawTime=n.performanceNow();void 0===e.averageRedrawTime&&(e.averageRedrawTime=i-r),void 0===e.redrawCount&&(e.redrawCount=0),e.redrawCount++,void 0===e.redrawTotalTime&&(e.redrawTotalTime=0);var a=i-r;e.redrawTotalTime+=a,e.lastRedrawTime=a,e.averageRedrawTime=e.averageRedrawTime/2+a/2,e.requestedFrame=!1}e.skipFrame=!1,n.requestAnimationFrame(t)}};n.requestAnimationFrame(t)},t.exports=i},{"../../../util":94}],62:[function(e,t,r){"use strict";var n,i={};i.arrowShapeImpl=function(e){return(n||(n={polygon:function(e,t){for(var r=0;rn)){e.textAlign="center",e.textBaseline="middle";var o=t._private.rscratch;if(i.number(o.labelX)&&i.number(o.labelY)){var s,l=t._private.style,u="autorotate"===l["edge-text-rotation"].strValue;u?(s=o.labelAngle,e.translate(o.labelX,o.labelY),e.rotate(s),this.drawText(e,t,0,0),e.rotate(-s),e.translate(-o.labelX,-o.labelY)):this.drawText(e,t,o.labelX,o.labelY)}}}},a.drawNodeText=function(e,t){var r=t._private.style.label.strValue;if(r&&!r.match(/^\s+$/)){var n=t._private.style["font-size"].pfValue*t.cy().zoom(),a=t._private.style["min-zoomed-font-size"].pfValue;if(!(a>n)){var o=t._private.style["text-halign"].strValue,s=t._private.style["text-valign"].strValue,l=t._private.rscratch;if(i.number(l.labelX)&&i.number(l.labelY)){switch(o){case"left":e.textAlign="right";break;case"right":e.textAlign="left";break;default:e.textAlign="center"}switch(s){case"top":e.textBaseline="bottom";break;case"bottom":e.textBaseline="top";break;default:e.textBaseline="middle"}this.drawText(e,t,l.labelX,l.labelY)}}}},a.getFontCache=function(e){var t;this.fontCaches=this.fontCaches||[];for(var r=0;r0||b>0&&m>0){var x=4+b/2;t.isNode()&&("top"===h?i-=x:"bottom"===h&&(i+=x),"left"===d?r-=x:"right"===d&&(r+=x));var w=s.labelWidth,_=s.labelHeight,E=r;d&&("center"==d?E-=w/2:"left"==d&&(E-=w));var D=i;if(t.isNode()?"top"==h?D-=_:"center"==h&&(D-=_/2):D-=_/2,"autorotate"===o["edge-text-rotation"].strValue?(i=0,w+=4,E=r-w/2,D=i-_/2):(E-=x,D-=x,_+=2*x,w+=2*x),y>0){var S=e.fillStyle,k=o["text-background-color"].value;e.fillStyle="rgba("+k[0]+","+k[1]+","+k[2]+","+y*u+")";var T=o["text-background-shape"].strValue;"roundrectangle"==T?n(e,E,D,w,_,2):e.fillRect(E,D,w,_),e.fillStyle=S}if(b>0&&m>0){var P=e.strokeStyle,C=e.lineWidth,N=o["text-border-color"].value,M=o["text-border-style"].value;if(e.strokeStyle="rgba("+N[0]+","+N[1]+","+N[2]+","+m*u+")",e.lineWidth=b,e.setLineDash)switch(M){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"double":e.lineWidth=b/4,e.setLineDash([]);break;case"solid":e.setLineDash([])}if(e.strokeRect(E,D,w,_),"double"===M){var B=b/2;e.strokeRect(E+B,D+B,w-2*B,_-2*B)}e.setLineDash&&e.setLineDash([]),e.lineWidth=C,e.strokeStyle=P}}var z=2*o["text-outline-width"].pfValue;if(z>0&&(e.lineWidth=z),"wrap"===o["text-wrap"].value){var O=l.labelWrapCachedLines,I=s.labelHeight/O.length;switch(h){case"top":i-=(O.length-1)*I;break;case"bottom":break;default:case"center":i-=(O.length-1)*I/2}for(var L=0;L0&&e.strokeText(O[L],r,i),e.fillText(O[L],r,i),i+=I}else z>0&&e.strokeText(c,r,i),e.fillText(c,r,i);this.shadowStyle(e,"transparent",0)}}},t.exports=a},{"../../../is":77}],66:[function(e,t,r){"use strict";var n=e("../../../is"),i={};i.drawNode=function(e,t,r){var i,a,o=this,s=t._private.style,l=t._private.rscratch,u=t._private,c=u.position;if(n.number(c.x)&&n.number(c.y)){var d,h=this.usePaths(),p=e,v=!1,f=s["overlay-padding"].pfValue,g=s["overlay-opacity"].value,y=s["overlay-color"].value;if(!r||0!==g){var m=t.effectiveOpacity();if(0!==m)if(i=t.width()+s["padding-left"].pfValue+s["padding-right"].pfValue,a=t.height()+s["padding-top"].pfValue+s["padding-bottom"].pfValue,e.lineWidth=s["border-width"].pfValue,void 0!==r&&r)g>0&&(this.fillStyle(e,y[0],y[1],y[2],g),o.nodeShapes.roundrectangle.draw(e,t._private.position.x,t._private.position.y,i+2*f,a+2*f),e.fill());else{var b,x=s["background-image"].value[2]||s["background-image"].value[1];if(void 0!==x){b=this.getCachedImage(x,function(){o.data.canvasNeedsRedraw[o.NODE]=!0,o.data.canvasNeedsRedraw[o.DRAG]=!0,o.drawingImage=!0,o.redraw()});var w=u.backgrounding;u.backgrounding=!b.complete,w!==u.backgrounding&&t.updateStyle(!1)}var _=s["background-color"].value,E=s["border-color"].value,D=s["border-style"].value;this.fillStyle(e,_[0],_[1],_[2],s["background-opacity"].value*m),this.strokeStyle(e,E[0],E[1],E[2],s["border-opacity"].value*m);var S=s["shadow-blur"].pfValue,k=s["shadow-opacity"].value,T=s["shadow-color"].value,P=s["shadow-offset-x"].pfValue,C=s["shadow-offset-y"].pfValue;if(this.shadowStyle(e,T,k,S,P,C),e.lineJoin="miter",e.setLineDash)switch(D){case"dotted":e.setLineDash([1,1]);break;case"dashed":e.setLineDash([4,2]);break;case"solid":case"double":e.setLineDash([])}var N=s.shape.strValue;if(h){var M=N+"$"+i+"$"+a;e.translate(c.x,c.y),l.pathCacheKey===M?(d=e=l.pathCache,v=!0):(d=e=new Path2D,l.pathCacheKey=M,l.pathCache=d)}if(!v){var B=c;h&&(B={x:0,y:0}),o.nodeShapes[this.getNodeShape(t)].draw(e,B.x,B.y,i,a)}e=p,h?e.fill(d):e.fill(),this.shadowStyle(e,"transparent",0),void 0!==x&&b.complete&&this.drawInscribedImage(e,b,t);var z=s["background-blacken"].value,O=s["border-width"].pfValue;if(this.hasPie(t)&&(this.drawPie(e,t,m),(0!==z||0!==O)&&(h||o.nodeShapes[this.getNodeShape(t)].draw(e,c.x,c.y,i,a))),z>0?(this.fillStyle(e,0,0,0,z),h?e.fill(d):e.fill()):0>z&&(this.fillStyle(e,255,255,255,-z),h?e.fill(d):e.fill()),O>0&&(h?e.stroke(d):e.stroke(),"double"===D)){e.lineWidth=s["border-width"].pfValue/3;var I=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",h?e.stroke(d):e.stroke(),e.globalCompositeOperation=I}h&&e.translate(-c.x,-c.y),e.setLineDash&&e.setLineDash([])}}}},i.hasPie=function(e){return e=e[0],e._private.hasPie},i.drawPie=function(e,t,r){t=t[0];var n=t._private,i=t.cy().style(),a=n.style,o=a["pie-size"],s=t.width(),l=t.height(),u=n.position.x,c=n.position.y,d=Math.min(s,l)/2,h=0,p=this.usePaths();p&&(u=0,c=0),"%"===o.units?d=d*o.value/100:void 0!==o.pfValue&&(d=o.pfValue/2);for(var v=1;v<=i.pieBackgroundN;v++){var f=a["pie-"+v+"-background-size"].value,g=a["pie-"+v+"-background-color"].value,y=a["pie-"+v+"-background-opacity"].value*r,m=f/100;m+h>1&&(m=1-h);var b=1.5*Math.PI+2*Math.PI*h,x=2*Math.PI*m,w=b+x;0===f||h>=1||h+m>1||(e.beginPath(),e.moveTo(u,c),e.arc(u,c,d,b,w),e.closePath(),this.fillStyle(e,g[0],g[1],g[2],y),e.fill(),h+=m)}},t.exports=i},{"../../../is":77}],67:[function(e,t,r){"use strict";var n={},i=e("../../../util"),a=e("../../../math"),o=100;n.getPixelRatio=function(){var e=this.data.contexts[0];if(null!=this.forcedPixelRatio)return this.forcedPixelRatio;var t=e.backingStorePixelRatio||e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1;return(window.devicePixelRatio||1)/t},n.paintCache=function(e){for(var t,r=this.paintCaches=this.paintCaches||[],n=!0,i=0;i0?(e.shadowBlur=n*o,e.shadowColor="rgba("+t[0]+","+t[1]+","+t[2]+","+r+")",e.shadowOffsetX=i*o,e.shadowOffsetY=a*o):(e.shadowBlur=0,e.shadowColor="transparent"))},n.matchCanvasSize=function(e){var t=this,r=t.data,n=e.clientWidth,i=e.clientHeight,a=t.getPixelRatio(),o=t.motionBlurPxRatio;(e===t.data.bufferCanvases[t.MOTIONBLUR_BUFFER_NODE]||e===t.data.bufferCanvases[t.MOTIONBLUR_BUFFER_DRAG])&&(a=o);var s,l=n*a,u=i*a;if(l!==t.canvasWidth||u!==t.canvasHeight){t.fontCaches=null;var c=r.canvasContainer;c.style.width=n+"px",c.style.height=i+"px";for(var d=0;d=a&&(s=r.bufferCanvases[t.TEXTURE_BUFFER],t.textureMult=2,s.width=l*t.textureMult,s.height=u*t.textureMult),t.canvasWidth=l,t.canvasHeight=u}},n.renderTo=function(e,t,r,n){this.render({forcedContext:e,forcedZoom:t,forcedPan:r,drawAllLayers:!0,forcedPxRatio:n})},n.render=function(e){function t(e,t,r,n,i){var a=e.globalCompositeOperation;e.globalCompositeOperation="destination-out",h.fillStyle(e,255,255,255,h.motionBlurTransparency),e.fillRect(t,r,n,i),e.globalCompositeOperation=a}function r(e,r){var n,i,a,o;h.clearingMotionBlur||e!==f.bufferContexts[h.MOTIONBLUR_BUFFER_NODE]&&e!==f.bufferContexts[h.MOTIONBLUR_BUFFER_DRAG]?(n=C,i=T,a=h.canvasWidth,o=h.canvasHeight):(n={x:P.x*b,y:P.y*b},i=k*b,a=h.canvasWidth*b,o=h.canvasHeight*b),e.setTransform(1,0,0,1,0,0),"motionBlur"===r?t(e,0,0,a,o):s||void 0!==r&&!r||e.clearRect(0,0,a,o),l||(e.translate(n.x,n.y),e.scale(i,i)),d&&e.translate(d.x,d.y),c&&e.scale(c,c)}function n(e,t){for(var r=e.eles,n=0;nh.minMbLowQualFrames&&(h.motionBlurPxRatio=h.mbPxRBlurry)),h.clearingMotionBlur&&(h.motionBlurPxRatio=1),h.textureDrawLastFrame&&!y&&(g[h.NODE]=!0,g[h.SELECT_BOX]=!0);var D=h.getCachedEdges(),S=v.style()._private.coreStyle,k=v.zoom(),T=void 0!==c?c:k,P=v.pan(),C={x:P.x,y:P.y},N={zoom:k,pan:{x:P.x,y:P.y}},M=h.prevViewport,B=void 0===M||N.zoom!==M.zoom||N.pan.x!==M.pan.x||N.pan.y!==M.pan.y;B||w&&!x||(h.motionBlurPxRatio=1),d&&(C=d),T*=p,C.x*=p,C.y*=p;var z={drag:{nodes:[],edges:[],eles:[]},nondrag:{nodes:[],edges:[],eles:[]}};if(y||(h.textureDrawLastFrame=!1),y){h.textureDrawLastFrame=!0;var O;if(!h.textureCache){h.textureCache={},O=h.textureCache.bb=v.elements().boundingBox(),h.textureCache.texture=h.data.bufferCanvases[h.TEXTURE_BUFFER];var I=h.data.bufferContexts[h.TEXTURE_BUFFER];I.setTransform(1,0,0,1,0,0),I.clearRect(0,0,h.canvasWidth*h.textureMult,h.canvasHeight*h.textureMult),h.render({forcedContext:I,drawOnlyNodeLayer:!0,forcedPxRatio:p*h.textureMult});var N=h.textureCache.viewport={zoom:v.zoom(),pan:v.pan(),width:h.canvasWidth,height:h.canvasHeight};N.mpan={x:(0-N.pan.x)/N.zoom,y:(0-N.pan.y)/N.zoom}}g[h.DRAG]=!1,g[h.NODE]=!1;var L=f.contexts[h.NODE],A=h.textureCache.texture,N=h.textureCache.viewport;O=h.textureCache.bb,L.setTransform(1,0,0,1,0,0),m?t(L,0,0,N.width,N.height):L.clearRect(0,0,N.width,N.height);var R=S["outside-texture-bg-color"].value,V=S["outside-texture-bg-opacity"].value;h.fillStyle(L,R[0],R[1],R[2],V),L.fillRect(0,0,N.width,N.height);var k=v.zoom();r(L,!1),L.clearRect(N.mpan.x,N.mpan.y,N.width/N.zoom/p,N.height/N.zoom/p),L.drawImage(A,N.mpan.x,N.mpan.y,N.width/N.zoom/p,N.height/N.zoom/p)}else h.textureOnViewport&&!s&&(h.textureCache=null);var F=h.pinching||h.hoverData.dragging||h.swipePanning||h.data.wheelZooming||h.hoverData.draggingEles,j=h.hideEdgesOnViewport&&F,q=h.hideLabelsOnViewport&&F;if(g[h.DRAG]||g[h.NODE]||l||u){j||h.findEdgeControlPoints(D);for(var X=h.getCachedZSortedEles(),Y=v.extent(),$=0;$0&&(L.strokeStyle="rgba("+S["selection-box-border-color"].value[0]+","+S["selection-box-border-color"].value[1]+","+S["selection-box-border-color"].value[2]+","+S["selection-box-opacity"].value+")",L.strokeRect(h.selection[0],h.selection[1],h.selection[2]-h.selection[0],h.selection[3]-h.selection[1]))}if(f.bgActivePosistion&&!h.hoverData.selecting){var k=h.cy.zoom(),Q=f.bgActivePosistion;L.fillStyle="rgba("+S["active-bg-color"].value[0]+","+S["active-bg-color"].value[1]+","+S["active-bg-color"].value[2]+","+S["active-bg-opacity"].value+")",L.beginPath(),L.arc(Q.x,Q.y,S["active-bg-size"].pfValue/k,0,2*Math.PI),L.fill()}var ee=h.lastRedrawTime;if(h.showFps&&ee){ee=Math.round(ee);var te=Math.round(1e3/ee);L.setTransform(1,0,0,1,0,0),L.fillStyle="rgba(255, 0, 0, 0.75)",L.strokeStyle="rgba(255, 0, 0, 0.75)",L.lineWidth=1,L.fillText("1 frame = "+ee+" ms = "+te+" fps",0,20);var re=60;L.strokeRect(0,30,250,20),L.fillRect(0,30,250*Math.min(te/re,1),20)}l||(g[h.SELECT_BOX]=!1)}if(m&&1!==b){var ne=f.contexts[h.NODE],ie=h.data.bufferCanvases[h.MOTIONBLUR_BUFFER_NODE],ae=f.contexts[h.DRAG],oe=h.data.bufferCanvases[h.MOTIONBLUR_BUFFER_DRAG],se=function(e,r,n){e.setTransform(1,0,0,1,0,0),n||!E?e.clearRect(0,0,h.canvasWidth,h.canvasHeight):t(e,0,0,h.canvasWidth,h.canvasHeight);var i=b;e.drawImage(r,0,0,h.canvasWidth*i,h.canvasHeight*i,0,0,h.canvasWidth,h.canvasHeight)};(g[h.NODE]||U[h.NODE])&&(se(ne,ie,U[h.NODE]),g[h.NODE]=!1),(g[h.DRAG]||U[h.DRAG])&&(se(ae,oe,U[h.DRAG]),g[h.DRAG]=!1)}h.currentlyDrawing=!1,h.prevViewport=N,h.clearingMotionBlur&&(h.clearingMotionBlur=!1,h.motionBlurCleared=!0,h.motionBlur=!0),m&&(h.motionBlurTimeout=setTimeout(function(){h.motionBlurTimeout=null,h.clearedForMotionBlur[h.NODE]=!1,h.clearedForMotionBlur[h.DRAG]=!1,h.motionBlur=!1,h.clearingMotionBlur=!y,h.mbFrames=0,g[h.NODE]=!0,g[h.DRAG]=!0,h.redraw()},o)),h.drawingImage=!1,s||h.initrender||(h.initrender=!0,v.trigger("initrender")),s||v.triggerOnRender()},t.exports=n},{"../../../math":79,"../../../util":94}],68:[function(e,t,r){"use strict";var n=e("../../../math"),i={};i.drawPolygonPath=function(e,t,r,n,i,a){var o=n/2,s=i/2;e.beginPath&&e.beginPath(),e.moveTo(t+o*a[0],r+s*a[1]);for(var l=1;l0&&a>0)if(c.clearRect(0,0,i,a),e.bg&&(c.fillStyle=e.bg,c.rect(0,0,i,a),c.fill()),c.globalCompositeOperation="source-over",e.full)this.render({forcedContext:c,drawAllLayers:!0,forcedZoom:o,forcedPan:{x:-r.x1*o,y:-r.y1*o},forcedPxRatio:1});else{var d=t.pan(),h={x:d.x*o,y:d.y*o},p=t.zoom()*o;this.render({forcedContext:c,drawAllLayers:!0,forcedZoom:p,forcedPan:h,forcedPxRatio:1})}return u},i.png=function(e){return this.bufferCanvasImage(e).toDataURL("image/png")},i.jpg=function(e){return this.bufferCanvasImage(e).toDataURL("image/jpeg")},t.exports=i},{"../../../is":77}],70:[function(e,t,r){"use strict";function n(e){var t=this;t.data={canvases:new Array(s.CANVAS_LAYERS),contexts:new Array(s.CANVAS_LAYERS),canvasNeedsRedraw:new Array(s.CANVAS_LAYERS),bufferCanvases:new Array(s.BUFFER_COUNT),bufferContexts:new Array(s.CANVAS_LAYERS)},t.data.canvasContainer=document.createElement("div");var r=t.data.canvasContainer.style;t.data.canvasContainer.setAttribute("style","-webkit-tap-highlight-color: rgba(0,0,0,0);"),r.position="relative",r.zIndex="0",r.overflow="hidden";var n=e.cy.container();n.appendChild(t.data.canvasContainer),n.setAttribute("style",(n.getAttribute("style")||"")+"-webkit-tap-highlight-color: rgba(0,0,0,0);"); +for(var i=0;io;o++)this[o]=new a;this.length=t},u=l.prototype;i.extend(u,{instanceString:function(){return"fabric"},require:function(e,t){for(var r=0;re?-1:e>t?1:0},t.require(e,"_$_$_cmp"),t.spread(function(e){var t=e.sort(_$_$_cmp);resolve(t)}).then(function(t){for(var i=function(n,i,a){i=Math.min(i,r),a=Math.min(a,r);for(var o=n,s=i,l=[],u=o;a>u;u++){var c=t[n],d=t[i];s>n&&(i>=a||e(c,d)<=0)?(l.push(c),n++):(l.push(d),i++)}for(var u=0;ua;a*=2)for(var o=0;r>o;o+=2*a)i(o,o+a,o+2*a);return t})}});var c=function(e){return e=e||{},function(t,r){var n=this._private.pass.shift();return this.random().pass(n)[e.threadFn](t,r)}};i.extend(u,{randomMap:c({threadFn:"map"}),reduce:c({threadFn:"reduce"}),reduceRight:c({threadFn:"reduceRight"})});var d=u;d.promise=d.run,d.terminate=d.halt=d.stop,d.include=d.require,i.extend(u,{on:s.on(),one:s.on({unbindSelfOnTrigger:!0}),off:s.off(),trigger:s.trigger()}),s.eventAliasesOn(u),t.exports=l},{"./define":41,"./is":77,"./promise":80,"./thread":92,"./util":94,os:void 0}],75:[function(e,t,r){"use strict";(function(){var e,n,i,a,o,s,l,u,c,d,h,p,v,f,g;i=Math.floor,d=Math.min,n=function(e,t){return t>e?-1:e>t?1:0},c=function(e,t,r,a,o){var s;if(null==r&&(r=0),null==o&&(o=n),0>r)throw new Error("lo must be non-negative");for(null==a&&(a=e.length);a>r;)s=i((r+a)/2),o(t,e[s])<0?a=s:r=s+1;return[].splice.apply(e,[r,r-r].concat(t)),t},s=function(e,t,r){return null==r&&(r=n),e.push(t),f(e,0,e.length-1,r)},o=function(e,t){var r,i;return null==t&&(t=n),r=e.pop(),e.length?(i=e[0],e[0]=r,g(e,0,t)):i=r,i},u=function(e,t,r){var i;return null==r&&(r=n),i=e[0],e[0]=t,g(e,0,r),i},l=function(e,t,r){var i;return null==r&&(r=n),e.length&&r(e[0],t)<0&&(i=[e[0],t],t=i[0],e[0]=i[1],g(e,0,r)),t},a=function(e,t){var r,a,o,s,l,u;for(null==t&&(t=n),s=function(){u=[];for(var t=0,r=i(e.length/2);r>=0?r>t:t>r;r>=0?t++:t--)u.push(t);return u}.apply(this).reverse(),l=[],a=0,o=s.length;o>a;a++)r=s[a],l.push(g(e,r,t));return l},v=function(e,t,r){var i;return null==r&&(r=n),i=e.indexOf(t),-1!==i?(f(e,0,i,r),g(e,i,r)):void 0},h=function(e,t,r){var i,o,s,u,c;if(null==r&&(r=n),o=e.slice(0,t),!o.length)return o;for(a(o,r),c=e.slice(t),s=0,u=c.length;u>s;s++)i=c[s],l(o,i,r);return o.sort(r).reverse()},p=function(e,t,r){var i,s,l,u,h,p,v,f,g,y;if(null==r&&(r=n),10*t<=e.length){if(u=e.slice(0,t).sort(r),!u.length)return u;for(l=u[u.length-1],f=e.slice(t),h=0,v=f.length;v>h;h++)i=f[h],r(i,l)<0&&(c(u,i,0,null,r),u.pop(),l=u[u.length-1]);return u}for(a(e,r),y=[],s=p=0,g=d(t,e.length);g>=0?g>p:p>g;s=g>=0?++p:--p)y.push(o(e,r));return y},f=function(e,t,r,i){var a,o,s;for(null==i&&(i=n),a=e[r];r>t&&(s=r-1>>1,o=e[s],i(a,o)<0);)e[r]=o,r=s;return e[r]=a},g=function(e,t,r){var i,a,o,s,l;for(null==r&&(r=n),a=e.length,l=t,o=e[t],i=2*t+1;a>i;)s=i+1,a>s&&!(r(e[i],e[s])<0)&&(i=s),e[t]=e[i],t=i,i=2*t+1;return e[t]=o,f(e,l,t,r)},e=function(){function e(e){this.cmp=null!=e?e:n,this.nodes=[]}return e.push=s,e.pop=o,e.replace=u,e.pushpop=l,e.heapify=a,e.updateItem=v,e.nlargest=h,e.nsmallest=p,e.prototype.push=function(e){return s(this.nodes,e,this.cmp)},e.prototype.pop=function(){return o(this.nodes,this.cmp)},e.prototype.peek=function(){return this.nodes[0]},e.prototype.contains=function(e){return-1!==this.nodes.indexOf(e)},e.prototype.replace=function(e){return u(this.nodes,e,this.cmp)},e.prototype.pushpop=function(e){return l(this.nodes,e,this.cmp)},e.prototype.heapify=function(){return a(this.nodes,this.cmp)},e.prototype.updateItem=function(e){return v(this.nodes,e,this.cmp)},e.prototype.clear=function(){return this.nodes=[]},e.prototype.empty=function(){return 0===this.nodes.length},e.prototype.size=function(){return this.nodes.length},e.prototype.clone=function(){var t;return t=new e,t.nodes=this.nodes.slice(0),t},e.prototype.toArray=function(){return this.nodes.slice(0)},e.prototype.insert=e.prototype.push,e.prototype.top=e.prototype.peek,e.prototype.front=e.prototype.peek,e.prototype.has=e.prototype.contains,e.prototype.copy=e.prototype.clone,e}(),function(e,n){return"function"==typeof define&&define.amd?define([],n):"object"==typeof r?t.exports=n():e.Heap=n()}(this,function(){return e})}).call(this)},{}],76:[function(e,t,r){"use strict";var n=e("./window"),i=e("./is"),a=e("./core"),o=e("./extension"),s=e("./jquery-plugin"),l=e("./stylesheet"),u=e("./thread"),c=e("./fabric"),d=function(e){return void 0===e&&(e={}),i.plainObject(e)?new a(e):i.string(e)?o.apply(o,arguments):void 0};d.version="2.5.4",n&&n.jQuery&&s(n.jQuery,d),d.registerJquery=function(e){s(e,d)},d.stylesheet=d.Stylesheet=l,d.thread=d.Thread=u,d.fabric=d.Fabric=c,t.exports=d},{"./core":34,"./extension":43,"./fabric":74,"./is":77,"./jquery-plugin":78,"./stylesheet":91,"./thread":92,"./window":100}],77:[function(e,t,r){"use strict";var n=e("./window"),i=n?n.navigator:null,a="string",o=typeof{},s="function",l=typeof HTMLElement,u=function(e){return e&&e.instanceString&&c.fn(e.instanceString)?e.instanceString():null},c={defined:function(e){return null!=e},string:function(e){return null!=e&&typeof e==a},fn:function(e){return null!=e&&typeof e===s},array:function(e){return Array.isArray?Array.isArray(e):null!=e&&e instanceof Array},plainObject:function(e){return null!=e&&typeof e===o&&!c.array(e)&&e.constructor===Object},object:function(e){return null!=e&&typeof e===o},number:function(e){return null!=e&&"number"==typeof e&&!isNaN(e)},integer:function(e){return c.number(e)&&Math.floor(e)===e},bool:function(e){return null!=e&&typeof e==typeof!0},htmlElement:function(e){return"undefined"===l?void 0:null!=e&&e instanceof HTMLElement},elementOrCollection:function(e){return c.element(e)||c.collection(e)},element:function(e){return"collection"===u(e)&&e._private.single},collection:function(e){return"collection"===u(e)&&!e._private.single},core:function(e){return"core"===u(e)},style:function(e){return"style"===u(e)},stylesheet:function(e){return"stylesheet"===u(e)},event:function(e){return"event"===u(e)},thread:function(e){return"thread"===u(e)},fabric:function(e){return"fabric"===u(e)},emptyString:function(e){return e?c.string(e)&&(""===e||e.match(/^\s+$/))?!0:!1:!0},nonemptyString:function(e){return e&&c.string(e)&&""!==e&&!e.match(/^\s+$/)?!0:!1},domElement:function(e){return"undefined"==typeof HTMLElement?!1:e instanceof HTMLElement},boundingBox:function(e){return c.plainObject(e)&&c.number(e.x1)&&c.number(e.x2)&&c.number(e.y1)&&c.number(e.y2)},promise:function(e){return c.object(e)&&c.fn(e.then)},touch:function(){return n&&("ontouchstart"in n||n.DocumentTouch&&document instanceof DocumentTouch)},gecko:function(){return"undefined"!=typeof InstallTrigger||"MozAppearance"in document.documentElement.style},webkit:function(){return"undefined"!=typeof webkitURL||"WebkitAppearance"in document.documentElement.style},chromium:function(){return"undefined"!=typeof chrome},khtml:function(){return i&&i.vendor.match(/kde/i)},khtmlEtc:function(){return c.khtml()||c.webkit()||c.chromium()},ms:function(){return i&&i.userAgent.match(/msie|trident|edge/i)},windows:function(){return i&&i.appVersion.match(/Win/i)},mac:function(){return i&&i.appVersion.match(/Mac/i)},linux:function(){return i&&i.appVersion.match(/Linux/i)},unix:function(){return i&&i.appVersion.match(/X11/i)}};t.exports=c},{"./window":100}],78:[function(e,t,r){"use strict";var n=e("./is"),i=function(e){var t=e[0]._cyreg=e[0]._cyreg||{};return t},a=function(e,t){e&&(e.fn.cytoscape||(e.fn.cytoscape=function(r){var a=e(this);if("get"===r)return i(a).cy;if(n.fn(r)){var o=r,s=i(a).cy;if(s&&s.isReady())s.trigger("ready",[],o);else{var l=i(a),u=l.readies=l.readies||[];u.push(o)}}else if(n.plainObject(r))return a.each(function(){var n=e.extend({},r,{container:e(this)[0]});t(n)})},e.cytoscape=t,null==e.fn.cy&&null==e.cy&&(e.fn.cy=e.fn.cytoscape,e.cy=e.cytoscape)))};t.exports=a},{"./is":77}],79:[function(e,t,r){"use strict";var n={};n.signum=function(e){return e>0?1:0>e?-1:0},n.distance=function(e,t){return Math.sqrt(n.sqDistance(e,t))},n.sqDistance=function(e,t){var r=t.x-e.x,n=t.y-e.y;return r*r+n*n},n.qbezierAt=function(e,t,r,n){return(1-n)*(1-n)*e+2*(1-n)*n*t+n*n*r},n.qbezierPtAt=function(e,t,r,i){return{x:n.qbezierAt(e.x,t.x,r.x,i),y:n.qbezierAt(e.y,t.y,r.y,i)}},n.makeBoundingBox=function(e){if(null!=e.x1&&null!=e.y1){if(null!=e.x2&&null!=e.y2&&e.x2>=e.x1&&e.y2>=e.y1)return{x1:e.x1,y1:e.y1,x2:e.x2,y2:e.y2,w:e.x2-e.x1,h:e.y2-e.y1};if(null!=e.w&&null!=e.h&&e.w>=0&&e.h>=0)return{x1:e.x1,y1:e.y1,x2:e.x1+e.w,y2:e.y1+e.h,w:e.w,h:e.h}}},n.boundingBoxesIntersect=function(e,t){return e.x1>t.x2?!1:t.x1>e.x2?!1:e.x2t.y2?!1:t.y1>e.y2?!1:!0},n.inBoundingBox=function(e,t,r){return e.x1<=t&&t<=e.x2&&e.y1<=r&&r<=e.y2},n.pointInBoundingBox=function(e,t){return this.inBoundingBox(e,t.x,t.y)},n.roundRectangleIntersectLine=function(e,t,r,n,i,a,o){var s,l=this.getRoundRectangleRadius(i,a),u=i/2,c=a/2,d=r-u+l-o,h=n-c-o,p=r+u-l+o,v=h;if(s=this.finiteLinesIntersect(e,t,r,n,d,h,p,v,!1),s.length>0)return s;var f=r+u+o,g=n-c+l-o,y=f,m=n+c-l+o;if(s=this.finiteLinesIntersect(e,t,r,n,f,g,y,m,!1),s.length>0)return s;var b=r-u+l-o,x=n+c+o,w=r+u-l+o,_=x;if(s=this.finiteLinesIntersect(e,t,r,n,b,x,w,_,!1),s.length>0)return s;var E=r-u-o,D=n-c+l-o,S=E,k=n+c-l+o;if(s=this.finiteLinesIntersect(e,t,r,n,E,D,S,k,!1),s.length>0)return s;var T,P=r-u+l,C=n-c+l;if(T=this.intersectLineCircle(e,t,r,n,P,C,l+o),T.length>0&&T[0]<=P&&T[1]<=C)return[T[0],T[1]];var N=r+u-l,M=n-c+l;if(T=this.intersectLineCircle(e,t,r,n,N,M,l+o),T.length>0&&T[0]>=N&&T[1]<=M)return[T[0],T[1]];var B=r+u-l,z=n+c-l;if(T=this.intersectLineCircle(e,t,r,n,B,z,l+o),T.length>0&&T[0]>=B&&T[1]>=z)return[T[0],T[1]];var O=r-u+l,I=n+c-l;return T=this.intersectLineCircle(e,t,r,n,O,I,l+o),T.length>0&&T[0]<=O&&T[1]>=I?[T[0],T[1]]:[]},n.inLineVicinity=function(e,t,r,n,i,a,o){var s=o,l=Math.min(r,i),u=Math.max(r,i),c=Math.min(n,a),d=Math.max(n,a);return e>=l-s&&u+s>=e&&t>=c-s&&d+s>=t},n.inBezierVicinity=function(e,t,r,n,i,a,o,s,l){var u={x1:Math.min(r,o,i)-l,x2:Math.max(r,o,i)+l,y1:Math.min(n,s,a)-l,y2:Math.max(n,s,a)+l};return eu.x2||tu.y2?!1:!0},n.solveCubic=function(e,t,r,n,i){t/=e,r/=e,n/=e;var a,o,s,l,u,c,d,h;return o=(3*r-t*t)/9,s=-(27*n)+t*(9*r-2*(t*t)),s/=54,a=o*o*o+s*s,i[1]=0,d=t/3,a>0?(u=s+Math.sqrt(a),u=0>u?-Math.pow(-u,1/3):Math.pow(u,1/3),c=s-Math.sqrt(a),c=0>c?-Math.pow(-c,1/3):Math.pow(c,1/3),i[0]=-d+u+c,d+=(u+c)/2,i[4]=i[2]=-d,d=Math.sqrt(3)*(-c+u)/2,i[3]=d,void(i[5]=-d)):(i[5]=i[3]=0,0===a?(h=0>s?-Math.pow(-s,1/3):Math.pow(s,1/3),i[0]=-d+2*h,void(i[4]=i[2]=-(h+d))):(o=-o,l=o*o*o,l=Math.acos(s/Math.sqrt(l)),h=2*Math.sqrt(o),i[0]=-d+h*Math.cos(l/3),i[2]=-d+h*Math.cos((l+2*Math.PI)/3),void(i[4]=-d+h*Math.cos((l+4*Math.PI)/3))))},n.sqDistanceToQuadraticBezier=function(e,t,r,n,i,a,o,s){var l=1*r*r-4*r*i+2*r*o+4*i*i-4*i*o+o*o+n*n-4*n*a+2*n*s+4*a*a-4*a*s+s*s,u=9*r*i-3*r*r-3*r*o-6*i*i+3*i*o+9*n*a-3*n*n-3*n*s-6*a*a+3*a*s,c=3*r*r-6*r*i+r*o-r*e+2*i*i+2*i*e-o*e+3*n*n-6*n*a+n*s-n*t+2*a*a+2*a*t-s*t,d=1*r*i-r*r+r*e-i*e+n*a-n*n+n*t-a*t,h=[];this.solveCubic(l,u,c,d,h);for(var p=1e-7,v=[],f=0;6>f;f+=2)Math.abs(h[f+1])=0&&h[f]<=1&&v.push(h[f]);v.push(1),v.push(0);for(var g,y,m,b,x=-1,w=0;w=0?x>b&&(x=b,g=v[w]):(x=b,g=v[w]);return x},n.sqDistanceToFiniteLine=function(e,t,r,n,i,a){var o=[e-r,t-n],s=[i-r,a-n],l=s[0]*s[0]+s[1]*s[1],u=o[0]*o[0]+o[1]*o[1],c=o[0]*s[0]+o[1]*s[1],d=c*c/l;return 0>c?u:d>l?(e-i)*(e-i)+(t-a)*(t-a):u-d},n.pointInsidePolygonPoints=function(e,t,r){for(var n,i,a,o,s,l=0,u=0,c=0;c=e&&e>=a||e>=n&&a>=e))continue;s=(e-n)/(a-n)*(o-i)+i,s>t&&l++,t>s&&u++}return l%2===0?!1:!0},n.pointInsidePolygon=function(e,t,r,i,a,o,s,l,u){var c,d=new Array(r.length);null!=l[0]?(c=Math.atan(l[1]/l[0]),l[0]<0?c+=Math.PI/2:c=-c-Math.PI/2):c=l;for(var h=Math.cos(-c),p=Math.sin(-c),v=0;v0){var g=this.expandPolygon(d,-u);f=this.joinLines(g)}else f=d;return n.pointInsidePolygonPoints(e,t,f)},n.joinLines=function(e){for(var t,r,n,i,a,o,s,l,u=new Array(e.length/2),c=0;cu)return[];var c=u/l;return[(r-e)*c+e,(n-t)*c+t]},n.intersectLineCircle=function(e,t,r,n,i,a,o){var s=[r-e,n-t],l=[i,a],u=[e-i,t-a],c=s[0]*s[0]+s[1]*s[1],d=2*(u[0]*s[0]+u[1]*s[1]),l=u[0]*u[0]+u[1]*u[1]-o*o,h=d*d-4*c*l;if(0>h)return[];var p=(-d+Math.sqrt(h))/(2*c),v=(-d-Math.sqrt(h))/(2*c),f=Math.min(p,v),g=Math.max(p,v),y=[];if(f>=0&&1>=f&&y.push(f),g>=0&&1>=g&&y.push(g),0===y.length)return[];var m=y[0]*s[0]+e,b=y[0]*s[1]+t;if(y.length>1){if(y[0]==y[1])return[m,b];var x=y[1]*s[0]+e,w=y[1]*s[1]+t;return[m,b,x,w]}return[m,b]},n.findCircleNearPoint=function(e,t,r,n,i){var a=n-e,o=i-t,s=Math.sqrt(a*a+o*o),l=a/s,u=o/s;return[e+l*r,t+u*r]},n.findMaxSqDistanceToOrigin=function(e){for(var t,r=1e-6,n=0;nr&&(r=t);return r},n.finiteLinesIntersect=function(e,t,r,n,i,a,o,s,l){var u=(o-i)*(t-a)-(s-a)*(e-i),c=(r-e)*(t-a)-(n-t)*(e-i),d=(s-a)*(r-e)-(o-i)*(n-t);if(0!==d){var h=u/d,p=c/d;return h>=0&&1>=h&&p>=0&&1>=p?[e+h*(r-e),t+h*(n-t)]:l?[e+h*(r-e),t+h*(n-t)]:[]}return 0===u||0===c?[e,r,o].sort()[1]===o?[o,s]:[e,r,i].sort()[1]===i?[i,a]:[i,o,r].sort()[1]===r?[r,n]:[]:[]},n.polygonIntersectLine=function(e,t,r,i,a,o,s,l){for(var u,c=[],d=new Array(r.length),h=0;h0){var v=n.expandPolygon(d,-l);p=n.joinLines(v)}else p=d;for(var f,g,y,m,h=0;ha&&(a=1e-5),[t[0]+a*n[0],t[1]+a*n[1]]},n.generateUnitNgonPointsFitToSquare=function(e,t){var r=n.generateUnitNgonPoints(e,t);return r=n.fitPolygonToSquare(r)},n.fitPolygonToSquare=function(e){for(var t,r,n=e.length/2,i=1/0,a=1/0,o=-(1/0),s=-(1/0),l=0;n>l;l++)t=e[2*l],r=e[2*l+1],i=Math.min(i,t),o=Math.max(o,t),a=Math.min(a,r),s=Math.max(s,r);for(var u=2/(o-i),c=2/(s-a),l=0;n>l;l++)t=e[2*l]=e[2*l]*u,r=e[2*l+1]=e[2*l+1]*c,i=Math.min(i,t),o=Math.max(o,t),a=Math.min(a,r),s=Math.max(s,r);if(-1>a)for(var l=0;n>l;l++)r=e[2*l+1]=e[2*l+1]+(-1-a);return e},n.generateUnitNgonPoints=function(e,t){var r=1/e*2*Math.PI,n=e%2===0?Math.PI/2+r/2:Math.PI/2;n+=t;for(var i,a,o,s=new Array(2*e),l=0;e>l;l++)i=l*r+n,a=s[2*l]=Math.cos(i),o=s[2*l+1]=Math.sin(-i);return s},n.getRoundRectangleRadius=function(e,t){return Math.min(e/4,t/4,8)},t.exports=n},{}],80:[function(e,t,r){"use strict";var n=0,i=1,a=2,o=function(e){return this instanceof o?(this.id="Thenable/1.0.7",this.state=n,this.fulfillValue=void 0,this.rejectReason=void 0,this.onFulfilled=[],this.onRejected=[],this.proxy={then:this.then.bind(this)},void("function"==typeof e&&e.call(this,this.fulfill.bind(this),this.reject.bind(this)))):new o(e)};o.prototype={fulfill:function(e){return s(this,i,"fulfillValue",e)},reject:function(e){return s(this,a,"rejectReason",e)},then:function(e,t){var r=this,n=new o;return r.onFulfilled.push(c(e,n,"fulfill")),r.onRejected.push(c(t,n,"reject")),l(r),n.proxy}};var s=function(e,t,r,i){return e.state===n&&(e.state=t,e[r]=i,l(e)),e},l=function(e){e.state===i?u(e,"onFulfilled",e.fulfillValue):e.state===a&&u(e,"onRejected",e.rejectReason)},u=function(e,t,r){if(0!==e[t].length){var n=e[t];e[t]=[];var i=function(){for(var e=0;e\\?\\@\\[\\]\\^\\`\\{\\|\\}\\~]",comparatorOp:"=|\\!=|>|>=|<|<=|\\$=|\\^=|\\*=",boolOp:"\\?|\\!|\\^",string:'"(?:\\\\"|[^"])+"|'+"'(?:\\\\'|[^'])+'",number:i.regex.number,meta:"degree|indegree|outdegree",separator:"\\s*,\\s*",descendant:"\\s+",child:"\\s+>\\s+",subject:"\\$"};u.variable="(?:[\\w-]|(?:\\\\"+u.metaChar+"))+",u.value=u.string+"|"+u.number,u.className=u.variable,u.id=u.variable;for(var c=function(e){return e.replace(new RegExp("\\\\("+u.metaChar+")","g"),function(e,t,r,n){return t})},d=u.comparatorOp.split("|"),h=0;h=0||"="!==p&&(u.comparatorOp+="|\\!"+p)}var v=[{name:"group",query:!0,regex:"(node|edge|\\*)",populate:function(e){this.group="*"==e?e:e+"s"}},{name:"state",query:!0,regex:"(:selected|:unselected|:locked|:unlocked|:visible|:hidden|:transparent|:grabbed|:free|:removed|:inside|:grabbable|:ungrabbable|:animated|:unanimated|:selectable|:unselectable|:orphan|:nonorphan|:parent|:child|:loop|:simple|:active|:inactive|:touch|:backgrounding|:nonbackgrounding)",populate:function(e){this.colonSelectors.push(e)}},{name:"id",query:!0,regex:"\\#("+u.id+")",populate:function(e){this.ids.push(c(e))}},{name:"className",query:!0,regex:"\\.("+u.className+")",populate:function(e){this.classes.push(c(e))}},{name:"dataExists",query:!0,regex:"\\[\\s*("+u.variable+")\\s*\\]",populate:function(e){this.data.push({field:c(e)})}},{name:"dataCompare",query:!0,regex:"\\[\\s*("+u.variable+")\\s*("+u.comparatorOp+")\\s*("+u.value+")\\s*\\]",populate:function(e,t,r){var n=null!=new RegExp("^"+u.string+"$").exec(r);r=n?r.substring(1,r.length-1):parseFloat(r),this.data.push({field:c(e),operator:t,value:r})}},{name:"dataBool",query:!0,regex:"\\[\\s*("+u.boolOp+")\\s*("+u.variable+")\\s*\\]",populate:function(e,t){this.data.push({field:c(t),operator:e})}},{name:"metaCompare",query:!0,regex:"\\[\\[\\s*("+u.meta+")\\s*("+u.comparatorOp+")\\s*("+u.number+")\\s*\\]\\]",populate:function(e,t,r){this.meta.push({field:c(e),operator:t,value:parseFloat(r)})}},{name:"nextQuery",separator:!0,regex:u.separator,populate:function(){r[++h]=l(),s=null}},{name:"child",separator:!0,regex:u.child,populate:function(){var e=l();e.parent=this,e.subject=s,r[h]=e}},{name:"descendant",separator:!0,regex:u.descendant,populate:function(){var e=l();e.ancestor=this,e.subject=s,r[h]=e}},{name:"subject",modifier:!0,regex:u.subject,populate:function(){return null!=s&&this.subject!=this?(i.error("Redefinition of subject in selector `"+t+"`"),!1):(s=this,void(this.subject=this))}}];r._private.selectorText=t;var f=t,h=0,g=function(e){for(var t,r,i,a=0;a=0&&(d=d.toLowerCase(),h=h.toLowerCase(),s=s.replace("@",""),p=!0);var v=!1,f=!1;switch(s.indexOf("!")>=0&&(s=s.replace("!",""),v=!0),p&&(l=h.toLowerCase(),c=d.toLowerCase()),s){case"*=":a=d.search(h)>=0;break;case"$=":a=null!=new RegExp(h+"$").exec(d);break;case"^=":a=null!=new RegExp("^"+h).exec(d);break;case"=":a=c===l;break;case"!=":a=c!==l;break;case">":a=v?l>=c:c>l,f=!0;break;case">=":a=v?l>c:c>=l,f=!0;break;case"<":a=v?c>=l:l>c,f=!0;break;case"<=":a=v?c>l:l>=c,f=!0;break;default:a=!1}}else if(null!=s)switch(s){case"?":a=t.fieldTruthy(u);break;case"!":a=!t.fieldTruthy(u);break;case"^":a=t.fieldUndefined(u)}else a=!t.fieldUndefined(u);if(v&&!f&&(a=!a,f=!0),!a){r=!1;break}}return r},v=p({name:"data",fieldValue:function(e){return t._private.data[e]},fieldRef:function(e){return"element._private.data."+e},fieldUndefined:function(e){return void 0===t._private.data[e]},fieldTruthy:function(e){return t._private.data[e]?!0:!1}});if(!v)return!1;var f=p({name:"meta",fieldValue:function(e){return t[e]()},fieldRef:function(e){return"element."+e+"()"},fieldUndefined:function(e){return null==t[e]()},fieldTruthy:function(e){return t[e]()?!0:!1}});if(!f)return!1;if(null!=e.collection){var g=null!=e.collection._private.ids[t.id()];if(!g)return!1}if(null!=e.filter&&0===t.collection().filter(e.filter).size())return!1;var y=function(e,t){if(null!=e){var n=!1;if(!r.hasCompoundNodes())return!1;t=t();for(var i=0;i "+n),null!=e.ancestor&&(n=r(e.ancestor)+" "+n),null!=e.child&&(n+=" > "+r(e.child)),null!=e.descendant&&(n+=" "+r(e.descendant)),n},i=0;i1&&i0;if(h||p){var v;h&&p?v=u.properties:h?v=u.properties:p&&(v=u.mappedProperties);for(var f=0;f0){i=!0;break}}t.hasPie=i;var s=n["text-transform"].strValue,l=n.label.strValue,u=n["font-style"].strValue,o=n["font-size"].pfValue+"px",c=n["font-family"].strValue,d=n["font-weight"].strValue,h=n["text-valign"].strValue,p=n["text-valign"].strValue,v=n["text-outline-width"].pfValue,f=n["text-wrap"].strValue,g=n["text-max-width"].pfValue;t.labelKey=u+"$"+o+"$"+c+"$"+d+"$"+l+"$"+s+"$"+h+"$"+p+"$"+v+"$"+f+"$"+g,t.fontKey=u+"$"+d+"$"+o+"$"+c;var y=n.width.pfValue,m=n.height.pfValue,b=n["border-width"].pfValue;if(t.boundingBoxKey=y+"$"+m+"$"+b,"edges"===e._private.group){var x=n["control-point-step-size"].pfValue,w=n["control-point-distances"]?n["control-point-distances"].pfValue.join("_"):void 0,_=n["control-point-weights"].value.join("_"),E=n["curve-style"].strValue,D=n["segment-distances"]?n["segment-distances"].pfValue.join("_"):void 0,S=n["segment-weights"].value.join("_");t.boundingBoxKey+="$"+x+"$"+w+"$"+_+"$"+D+"$"+S+"$"+E}t.styleKey=Date.now()}},a.applyParsedProperty=function(e,t){var r,a,o=this,s=t,l=e._private.style,u=o.types,c=o.properties[s.name].type,d=s.bypass,h=l[s.name],p=h&&h.bypass,v=e._private;if(("height"===t.name||"width"===t.name)&&e.isNode()){if("auto"===t.value&&!e.isParent())return!1;"auto"!==t.value&&e.isParent()&&(s=t=this.parse(t.name,"auto",d))}if(d&&s.deleteBypass){var f=l[s.name];return f?f.bypass&&f.bypassed?(l[s.name]=f.bypassed,!0):!1:!0}var g=function(){n.error("Do not assign mappings to elements without corresponding data (e.g. ele `"+e.id()+"` for property `"+s.name+"` with data field `"+s.field+"`); try a `["+s.field+"]` selector to limit scope to elements with `"+s.field+"` defined")};switch(s.mapped){case u.mapData:case u.mapLayoutData:case u.mapScratch:var r,y=s.mapped===u.mapLayoutData,m=s.mapped===u.mapScratch,b=s.field.split(".");r=m||y?v.scratch:v.data;for(var x=0;x_?_=0:_>1&&(_=1),c.color){var E=s.valueMin[0],D=s.valueMax[0],S=s.valueMin[1],k=s.valueMax[1],T=s.valueMin[2],P=s.valueMax[2],C=null==s.valueMin[3]?1:s.valueMin[3],N=null==s.valueMax[3]?1:s.valueMax[3],M=[Math.round(E+(D-E)*_),Math.round(S+(k-S)*_),Math.round(T+(P-T)*_),Math.round(C+(N-C)*_)];a={bypass:s.bypass,name:s.name,value:M,strValue:"rgb("+M[0]+", "+M[1]+", "+M[2]+")"}}else{if(!c.number)return!1;var B=s.valueMin+(s.valueMax-s.valueMin)*_;a=this.parse(s.name,B,s.bypass,!0)}a||(a=this.parse(s.name,h.strValue,s.bypass,!0)),a||g(),a.mapping=s,s=a;break;case u.data:case u.layoutData:case u.scratch:var r,y=s.mapped===u.layoutData,m=s.mapped===u.scratch,b=s.field.split(".");if(r=m||y?v.scratch:v.data)for(var x=0;x0&&l>0){for(var d=!1,h=0;h0&&e.delay(u),e.animate({css:c},{duration:l,easing:o["transition-timing-function"].value,queue:!1,complete:function(){r||n.removeBypasses(e,s),a.transitioning=!1}})}else a.transitioning&&(e.stop(),this.removeBypasses(e,s),a.transitioning=!1)},t.exports=a},{"../is":77,"../util":94}],83:[function(e,t,r){"use strict";var n=e("../is"),i=e("../util"),a={};a.applyBypass=function(e,t,r,a){var o=this,s=[],l=!0;if("*"===t||"**"===t){if(void 0!==r)for(var u=0;ud.max)return null;var M={name:e,value:t,strValue:""+t+(T?T:""),units:T,bypass:r};return d.unitless||"px"!==T&&"em"!==T?M.pfValue=t:M.pfValue="px"!==T&&T?this.getEmSizeInPixels()*t:t,("ms"===T||"s"===T)&&(M.pfValue="ms"===T?t:1e3*t),("deg"===T||"rad"===T)&&(M.pfValue="rad"===T?t:t*Math.PI/180),M}if(d.propList){var B=[],z=""+t;if("none"===z);else{for(var O=z.split(","),I=0;I node").css({width:"auto",height:"auto",shape:"rectangle","padding-top":10,"padding-right":10,"padding-left":10,"padding-bottom":10}).selector("edge").css({width:1}).selector(":active").css({"overlay-color":"black","overlay-padding":10,"overlay-opacity":.25}).selector("core").css({"selection-box-color":"#ddd","selection-box-opacity":.65,"selection-box-border-color":"#aaa","selection-box-border-width":1,"active-bg-color":"black","active-bg-opacity":.15,"active-bg-size":30,"outside-texture-bg-color":"#000","outside-texture-bg-opacity":.125}),this.defaultLength=this.length},t.exports=i},{"../util":94}],90:[function(e,t,r){"use strict";var n=e("../util"),i=e("../selector"),a={};a.applyFromString=function(e){function t(){c=c.length>a.length?c.substr(a.length):""}function r(){o=o.length>s.length?o.substr(s.length):""}var a,o,s,l=this,u=this,c=""+e;for(c=c.replace(/[\/][*](\s|.)+?[*][\/]/g,"");;){var d=c.match(/^\s*$/);if(d)break;var h=c.match(/^\s*((?:.|\s)+?)\s*\{((?:.|\s)+?)\}/);if(!h){n.error("Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: "+c);break}a=h[0];var p=h[1];if("core"!==p){var v=new i(p);if(v._private.invalid){n.error("Skipping parsing of block: Invalid selector found in string stylesheet: "+p),t();continue}}var f=h[2],g=!1;o=f;for(var y=[];;){var d=o.match(/^\s*$/);if(d)break;var m=o.match(/^\s*(.+?)\s*:\s*(.+?)\s*;/);if(!m){n.error("Skipping parsing of block: Invalid formatting of style property and value definitions found in:"+f),g=!0;break}s=m[0];var b=m[1],x=m[2],w=l.properties[b];if(w){var _=u.parse(b,x);_?(y.push({name:b,val:x}),r()):(n.error("Skipping property: Invalid property definition in: "+s),r())}else n.error("Skipping property: Invalid property name in: "+s),r()}if(g){t();break}u.selector(p);for(var E=0;E1?", "+JSON.stringify(r):"")+" );"," "," resolve = origResolve;"," resolve( res.length > 0 ? res : ret );","}"].join("\n"))}};util.extend(thdfn,{reduce:defineFnal({name:"reduce"}),reduceRight:defineFnal({name:"reduceRight"}),map:defineFnal({name:"map"})});var fn=thdfn;fn.promise=fn.run,fn.terminate=fn.halt=fn.stop,fn.include=fn.require,util.extend(thdfn,{on:define.on(),one:define.on({unbindSelfOnTrigger:!0}),off:define.off(),trigger:define.trigger()}),define.eventAliasesOn(thdfn),module.exports=Thread},{"./define":41,"./event":42,"./is":77,"./promise":80,"./util":94,"./window":100,child_process:void 0,path:void 0}],93:[function(e,t,r){"use strict";var n=e("../is");t.exports={hex2tuple:function(e){if((4===e.length||7===e.length)&&"#"===e[0]){var t,r,n,i=4===e.length,a=16;return i?(t=parseInt(e[1]+e[1],a),r=parseInt(e[2]+e[2],a),n=parseInt(e[3]+e[3],a)):(t=parseInt(e[1]+e[2],a),r=parseInt(e[3]+e[4],a),n=parseInt(e[5]+e[6],a)),[t,r,n]}},hsl2tuple:function(e){function t(e,t,r){return 0>r&&(r+=1),r>1&&(r-=1),1/6>r?e+6*(t-e)*r:.5>r?t:2/3>r?e+(t-e)*(2/3-r)*6:e}var r,n,i,a,o,s,l,u,c=new RegExp("^"+this.regex.hsla+"$").exec(e);if(c){if(n=parseInt(c[1]),0>n?n=(360- -1*n%360)%360:n>360&&(n%=360),n/=360,i=parseFloat(c[2]),0>i||i>100)return;if(i/=100,a=parseFloat(c[3]),0>a||a>100)return;if(a/=100,o=c[4],void 0!==o&&(o=parseFloat(o),0>o||o>1))return;if(0===i)s=l=u=Math.round(255*a);else{var d=.5>a?a*(1+i):a+i-a*i,h=2*a-d;s=Math.round(255*t(h,d,n+1/3)),l=Math.round(255*t(h,d,n)),u=Math.round(255*t(h,d,n-1/3))}r=[s,l,u,o]}return r},rgb2tuple:function(e){var t,r=new RegExp("^"+this.regex.rgba+"$").exec(e);if(r){t=[];for(var n=[],i=1;3>=i;i++){var a=r[i];if("%"===a[a.length-1]&&(n[i]=!0),a=parseFloat(a),n[i]&&(a=a/100*255),0>a||a>255)return;t.push(Math.floor(a))}var o=n[1]||n[2]||n[3],s=n[1]&&n[2]&&n[3];if(o&&!s)return;var l=r[4];if(void 0!==l){if(l=parseFloat(l),0>l||l>1)return;t.push(l)}}return t},colorname2tuple:function(e){return this.colors[e.toLowerCase()]},color2tuple:function(e){return(n.array(e)?e:null)||this.colorname2tuple(e)||this.hex2tuple(e)||this.rgb2tuple(e)||this.hsl2tuple(e)},colors:{transparent:[0,0,0,0],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]}}},{"../is":77}],94:[function(e,t,r){"use strict";var n=e("../is"),i=e("../math"),a={falsify:function(){return!1},zeroify:function(){return 0},noop:function(){},error:function(e){console.error?(console.error.apply(console,arguments),console.trace&&console.trace()):(console.log.apply(console,arguments),console.trace&&console.trace())},clone:function(e){return this.extend({},e)},copy:function(e){return null==e?e:n.array(e)?e.slice():n.plainObject(e)?this.clone(e):e}};a.makeBoundingBox=i.makeBoundingBox.bind(i),a._staticEmptyObject={},a.staticEmptyObject=function(){return a._staticEmptyObject},a.extend=null!=Object.assign?Object.assign:function(e){for(var t=arguments,r=1;ro;o++){var t=i[o];n.plainObject(t)&&this.error("Tried to set map with object key"),oa;a++){var o=r[a];if(n.plainObject(o)&&this.error("Tried to get map with object key"),t=t[o],null==t)return t}return t},deleteMap:function(e){for(var t=e.map,r=e.keys,i=r.length,a=e.keepChildren,o=0;i>o;o++){var s=r[o];n.plainObject(s)&&this.error("Tried to delete map with object key");var l=o===e.keys.length-1;if(l)if(a)for(var u in t)a[u]||(t[u]=void 0);else t[s]=void 0;else t=t[s]}}}},{"../is":77}],96:[function(e,t,r){"use strict";t.exports=function(e,t){var r=this,n={};return t||(t=function(){if(1===arguments.length)return arguments[0];for(var e=[],t=0;t=r){a&&clearTimeout(a);var i=c;a=u=c=void 0,i&&(h=d.now(),o=e.apply(l,n),u||a||(n=l=null))}else u=setTimeout(g,r)},y=function(){u&&clearTimeout(u),a=u=c=void 0,(v||p!==t)&&(h=d.now(),o=e.apply(l,n),u||a||(n=l=null))};return function(){if(n=arguments,s=d.now(),l=this,c=v&&(u||!f),p===!1)var r=f&&!u;else{a||f||(h=s);var i=p-(s-h),m=0>=i;m?(a&&(a=clearTimeout(a)),h=s,o=e.apply(l,n)):a||(a=setTimeout(y,i))}return m&&u?u=clearTimeout(u):u||t===p||(u=setTimeout(g,t)),r&&(m=!0,o=e.apply(l,n)),!m||u||a||(n=l=null),o}}},t.exports=o},{"../is":77,"../window":100}],100:[function(e,t,r){t.exports="undefined"==typeof window?null:window},{}]},{},[76])(76)}); +//# sourceMappingURL=cytoscape.min.js.map diff --git a/dependencies/cytoscape.js-2.5.4/cytoscape.min.js.map b/dependencies/cytoscape.js-2.5.4/cytoscape.min.js.map new file mode 100644 index 0000000..b9b82b5 --- /dev/null +++ b/dependencies/cytoscape.js-2.5.4/cytoscape.min.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["src/animation.js","cytoscape.min.js","src/collection/algorithms/a-star.js","src/collection/algorithms/bellman-ford.js","src/collection/algorithms/betweenness-centrality.js","src/collection/algorithms/bfs-dfs.js","src/collection/algorithms/closeness-centrality.js","src/collection/algorithms/degree-centrality.js","src/collection/algorithms/floyd-warshall.js","src/collection/algorithms/index.js","src/collection/algorithms/kerger-stein.js","src/collection/algorithms/page-rank.js","src/collection/animation.js","src/collection/class.js","src/collection/comparators.js","src/collection/compounds.js","src/collection/data.js","src/collection/degree.js","src/collection/dimensions.js","src/collection/element.js","src/collection/events.js","src/collection/filter.js","src/collection/group.js","src/collection/index.js","src/collection/iteration.js","src/collection/layout.js","src/collection/style.js","src/collection/switch-functions.js","src/collection/traversing.js","src/collection/zsort.js","src/core/add-remove.js","src/core/animation.js","src/core/events.js","src/core/export.js","src/core/index.js","src/core/layout.js","src/core/notification.js","src/core/renderer.js","src/core/search.js","src/core/style.js","src/core/viewport.js","src/define.js","src/event.js","src/extension.js","src/extensions/index.js","src/extensions/layout/breadthfirst.js","src/extensions/layout/circle.js","src/extensions/layout/concentric.js","src/extensions/layout/cose.js","src/extensions/layout/grid.js","src/extensions/layout/index.js","src/extensions/layout/null.js","src/extensions/layout/preset.js","src/extensions/layout/random.js","src/extensions/renderer/base/arrow-shapes.js","src/extensions/renderer/base/cached-eles.js","src/extensions/renderer/base/coord-ele-math.js","src/extensions/renderer/base/images.js","src/extensions/renderer/base/index.js","src/extensions/renderer/base/load-listeners.js","src/extensions/renderer/base/node-shapes.js","src/extensions/renderer/base/redraw.js","src/extensions/renderer/canvas/arrow-shapes.js","src/extensions/renderer/canvas/drawing-edges.js","src/extensions/renderer/canvas/drawing-images.js","src/extensions/renderer/canvas/drawing-label-text.js","src/extensions/renderer/canvas/drawing-nodes.js","src/extensions/renderer/canvas/drawing-redraw.js","src/extensions/renderer/canvas/drawing-shapes.js","src/extensions/renderer/canvas/export-image.js","src/extensions/renderer/canvas/index.js","src/extensions/renderer/canvas/node-shapes.js","src/extensions/renderer/index.js","src/extensions/renderer/null/index.js","src/fabric.js","src/heap.js","src/index.js","src/is.js","src/jquery-plugin.js","src/math.js","src/promise.js","src/selector.js","src/style/apply.js","src/style/bypass.js","src/style/container.js","src/style/get-for-ele.js","src/style/index.js","src/style/json.js","src/style/parse.js","src/style/properties.js","src/style/string-sheet.js","src/stylesheet.js","src/thread.js","src/util/colors.js","src/util/index.js","src/util/maps.js","src/util/memoize.js","src/util/regex.js","src/util/strings.js","src/util/timing.js","src/window.js"],"names":["f","exports","module","define","amd","g","window","global","self","this","cytoscape","e","t","n","r","s","o","u","a","require","i","Error","code","l","call","length",1,"_dereq_","util","is","Promise","Animation","target","opts","opts2","_p","_private","extend","duration","style","css","started","playing","hooked","applying","progress","completes","frames","complete","fn","push","anifn","prototype","instanceString","hook","q","tAni","animation","queue","current","elementOrCollection","cy","addToAnimationPool","play","stopped","apply","pause","stop","rewind","fastforward","time","undefined","p","wasPlaying","completed","reverse","swap","b","_pa","prop","name","startStyleProp","startStyle","dash2camel","promise","type","arr","resolve","reject","./is","./promise","./util",2,"elesfn","aStar","options","eles","reconstructPath","start","end","cameFromMap","pathAcum","getElementById","previous","previousEdge","cameFromEdge","findMin","openSet","fScore","minPos","tempScore","root","source","string","filter","goal","heuristic","weight","weightFn","directed","closedSet","id","cameFrom","gScore","edges","stdFilter","isLoop","nodes","steps","cMin","rPath","found","distance","path","spawn","splice","vwEdges","connectedEdges","ele","data","intersect","w","connectedNodes","indexOf","../../is",3,"bellmanFord","numNodes","id2position","cost","predecessor","predEdge","Infinity","flag","sourceIndex","targetIndex","temp","error","pathTo","distanceTo","hasNegativeWeightCycle","position2id","res","to","toId","reconstructPathAux","fromPos","toPos","acumPath","predPos","../../util",4,"betweennessCentrality","weighted","bool","priorityInsert","unshift","d","tmp","V","A","C","outgoers","openNeighborhood","S","P","Q","Number","POSITIVE_INFINITY","v","pop","forEach","$","edgesTo","edge","edgeWeight","max","key","ret","betweenness","node","betweennessNormalized","betweennessNormalised","bc",5,"Heap","defineSearch","params","bfs","dfs","roots","std","thisArg","plainObject","visit","arguments","connectedBy","id2depth","j","isNode","shift","depth","prevEdge","prevNode","not","connectedEles","collection","unique","breadthFirstSearch","depthFirstSearch","kruskal","findSet","forest","anySame","index","toArray","sort","weightA","weightB","setU","setV","add","dijkstra","dist","prev","knownDist","getDist","setDist","updateItem","same","distBetween","smallestEdge","uvs","edgesWith","smallestDistance","size","smalletsDist","uid","Math","Infinite","neighbors","neighborhood","vid","vDist","alt","../../heap",6,"closenessCentralityNormalized","harmonic","closenesses","maxCloseness","fw","floydWarshall","currCloseness","closeness","closenessCentrality","totalDistance","cc","ccn","closenessCentralityNormalised",7,"degreeCentralityNormalized","indegrees","outdegrees","maxIndegree","maxOutdegree","currDegree","degreeCentrality","indegree","outdegree","degrees","maxDegree","degree","callingEles","alpha","number","incoming","intersection","outgoing","k_in","k_out","s_in","s_out","pow","connEdges","k","dc","dcn","degreeCentralityNormalised",8,"newRow","Array","next","edgeNext","initMatrix","from","fromId","pathArr",9,"props","./a-star","./bellman-ford","./betweenness-centrality","./bfs-dfs","./closeness-centrality","./degree-centrality","./floyd-warshall","./kerger-stein","./page-rank",10,"kargerStein","colapse","edgeIndex","nodeMap","remainingEdges","edgeInfo","sourceIn","targetIn","partition1","partition2","newEdges","slice","contractUntil","metaNodeMap","sizeLimit","floor","random","numEdges","numIter","ceil","log","LN2","stopSize","sqrt","edgeIndexes","minCut","minCutSize","originalMetaNode","iter","edgesState","metaNodeMap2","res1","res2","resEdges","map","witnessNodePartition","partitionId","cut",11,"pageRank","normalizeVector","vector","total","dampingFactor","precision","epsilon","iterations","matrix","columnSum","additionalProb","eigenvector","nullVector","diff","rank","nodeId",12,"animate","animated","clearQueue","delay","delayAnimation","../define",13,"classes","match","changed","classesMap","cls","eleClasses","changedEle","eleHasClass","eleCls","specdClass","copy","updateStyle","trigger","addClass","toggleClass","hasClass","className","classesStr","toggle","il","shouldAdd","removeClass","flashClass","setTimeout","../util",14,"allAre","selector","some","every","allAreNeighbors","allAreNeighbours",15,"parent","parents","nonempty","commonAncestors","ancestors","orphans","empty","nonorphans","children","concat","siblings","isParent","isChild","descendants","elements",16,"field","bindingEvent","allowBinding","allowSetting","settingEvent","settingTriggersEvent","triggerFnName","allowGetting","immutableKeys","removeData","event","triggerEvent","scratch","removeScratch","rscratch","removeRscratch","attr","removeAttr",17,"defineDegreeFunction","callback","includeLoops","removed","defineDegreeBoundsFunction","degreeFn","minDegree","min","minIndegree","minOutdegree","totalDegree",18,"position","validKeys","onSet","updatedEles","updateCompoundBounds","rtrigger","canSet","locked","silentPosition","positions","pos","silent","elePos","x","y","toTrigger","silentPositions","renderedPosition","dim","val","zoom","pan","rpos","setting","relativePosition","ppos","hasCompoundNodes","hasParent","relativeToParent","origin","renderedBoundingBox","bb","boundingBox","x1","x2","y1","y2","h","update","includeLabels","value","includeEdges","padding","top","pfValue","bottom","left","right","didUpdate","autoWidth","autoHeight","updated","styleEnabled","cy_p","staticEmptyObject","includeNodes","renderer","recalculateRenderedStyle","ex1","ex2","ey1","ey2","display","group","includedEle","outerWidth","halfW","outerHeight","halfH","isEdge","n1","n1_p","n1pos","n2","n2_p","n2pos","rstyle","wHalf","pts","bezierPts","linePts","pt","strValue","hpts","haystackPts","label","fontSize","halign","valign","labelWidth","labelHeight","labelX","labelY","autorotate","lx1","lx2","ly1","ly2","lh","lw","theta","labelAngle","cos","sin","rotate","px1y1","px1y2","px2y1","px2y2","noninf","defineDimFns","uppercaseName","capitalize","autoName","labelName","outerName","uppercaseOuterName","border","paddings","od","modelPosition","point","modelPositions","points","renderedPoint","relativePoint","boundingbox","renderedBoundingbox","../is",19,"Element","restore","core","single","listeners","styleCxts","selected","selectable","grabbed","grabbable","active","split","applyBypass",20,"on","one","unbindSelfOnTrigger","once","unbindAllBindersOnTrigger","off","extraParams","notify","eventAliasesOn",21,"Selector","element","toRemove","remove","ids","absoluteComplement","other","col1","col2","col1Smaller","ids2","col","xor","inOther","both","retEles","toAdd","merge","toAddEle","indexes","unmergeOne","unmergedLastEle","lastEleI","lastEle","unmerge","mapFn","filterEles","include","valFn","maxEle","minEle","union","or","difference","relativeComplement","subtract","and","symmetricDifference","symdiff","fnFilter","filterFn","complement","abscomp","../selector",22,"isSimple",23,"idFactory","prefix","generate","tryThisId","Collection","createdElements","elesIds","json","obj","startBatch","checkSwitch","trueFnName","falseFnName","obj_k","endBatch","join","jsons","clone","elesArr","notifyRenderer","restored","emptyString","fields","fieldsLength","badSourceOrTarget","src","tgt","addToPool","parentId","specifiedParent","selfAsParent","ancestor","toUpdateStyle","inside","addConnectedEdges","addChildren","alreadyAdded","elesToRemoveIds","elesToRemove","removeEdgeRef","connectedEdge","removeChildRef","removeFromPool","elesStillInside","removedElements","checkedParentId","move","struct","srcId","tgtId","srcExists","tgtExists","parentExists","descs","descsEtc","./algorithms","./animation","./class","./comparators","./compounds","./data","./degree","./dimensions","./element","./events","./filter","./group","./index","./iteration","./layout","./style","./switch-functions","./traversing",24,"zIndexSort","each","array","thisSize","eq","first","last","sortFn","sorted","sortByZIndex","zDepth","MAX_VALUE","srcDepth","tgtDepth","./zsort",25,"layoutPositions","layout","animations","lastNode","newPos","ani","animationDuration","easing","animationEasing","step","fit","ready","makeLayout","createLayout",26,"batchingStyle","bEles","batchStyleEles","updatedCompounds","toNotify","updateMappers","renderedCss","property","renstyle","getRenderedStyle","updateTransitions","getStylePropertyValue","getRawStyle","removeCss","names","removeAllBypasses","removeBypasses","show","hide","visible","pStyle","pVis","pDis","hidden","effectiveOpacity","parentOpacity","opacity","transparent","isFullAutoParent","autoW","autoH","backgrounding","bypass","renderedStyle","removeBypass","removeStyle",27,"defineSwitchFunction","args","changedEles","handler","bind","able","ableField","overrideAble","changedColl","defineSwitchSet","overrideField","autolock","autoungrabify","autounselectify","deselect","unselect","inactive",28,"defineSourceFunction","sources","defineEdgesWithFunction","otherNodes","thisIds","otherIds","edgeData","thisToOther","otherToThis","edgeConnectsThisAndOther","thisIs","defineParallelEdgesFunction","defaults","codirected","edge1","src1","srcid1","tgt1","tgtid1","srcEdges1","edge2","edge2data","tgtid2","srcid2","oppdirected","hasEdgesPointingIn","leaves","hasEdgesPointingOut","oEles","eleId","successors","sEles","sElesIds","newOutgoers","outgoer","outgoerId","incomers","predecessors","pEles","pElesIds","newIncomers","incomer","incomerId","otherNode","closedNeighborhood","neighbourhood","closedNeighbourhood","openNeighbourhood","targets","parallelEdges","codirectedEdges","components","visited","unvisited","visitInComponent","component",29,"a_p","b_p","zDiff","depthA","depthB","aIsNode","aIsEdge","bIsNode","bIsEdge","depthDiff","sameDepth",30,"corefn","document","elesByGroup","grs","elesArray","jl","load","onload","ondone","notifications","oldEles","layoutOpts","../collection","../collection/element","../extensions/renderer/null","../window",31,"aniEles","stopAnimationLoop","animationsRunning","startAnimationLoop","globalAnimationStep","requestAnimationFrame","now","handleElements","handleElement","isCore","ranAnis","callbacks","cb","ani_p","startAnimation","doneEles","ranEleAni","handledThisEle","ranCoreAni","isEles","startPosition","getValueStyle","startPan","startZoom","startTime","pEasing","easingImpl","easings","easingVals","easingProp","parse","percent","startPos","endPos","valid","ease","endPan","animatingPan","endZoom","animatingZoom","easedVal","overrideBypass","evalCubicBezier","p1","p2","one_t","tsq","cubicBezier","startProp","endProp","easingFn","easedArr","si","ei","roundValue","round","generateSpringRK4","springAccelerationForState","state","tension","friction","springEvaluateStateWithDerivative","initialState","dt","derivative","dx","dv","springIntegrateState","c","dxdt","dvdt","springRK4Factory","have_duration","last_state","initState","time_lapsed","tolerance","DT","parseFloat","abs","percentComplete","linear","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","spring","cubic-bezier",32,33,"png","jpg","bg","jpeg",34,"Core","container","htmlElement","reg","_cyreg","destroy","readies","head","headless","defVal","def","altVal","initrender","id2index","onRenders","notificationsEnabled","minZoom","maxZoom","zoomingEnabled","userZoomingEnabled","panningEnabled","userPanningEnabled","boxSelectionEnabled","autolockNodes","autoungrabifyNodes","deferredExecQueue","selType","selectionType","loadExtData","anyIsPromise","extData","datum","all","then","initRenderer","hideEdgesOnViewport","hideLabelsOnViewport","textureOnViewport","wheelSensitivity","motionBlur","motionBlurOpacity","pixelRatio","desktopTapThreshold","touchTapThreshold","thens","initStyle","initEles","setStyle","done","isReady","domEle","childNodes","removeChild","alreadyInPool","inPool","jid","idInJson","updateEles","gr","../promise","./add-remove","./export","./notification","./renderer","./search","./viewport",35,"prevLayout","run","Layout","extension",36,"batchingNotify","batchNotifyEles","bTypes","batchNotifyTypes","noNotifications","batchCount","batch","batchData",37,"renderTo","context","pxRatio","forceRender","resize","RendererProto","rOpts","init","triggerOnRender","cbs","onRender","offRender","invalidateDimensions",38,39,"Style","newStyle","stylesheet","generateStyle","fromJson","fromString","../style",40,"dims","panBy","viewportState","getFitViewport","sel","bbe","width","height","isNaN","level","z","pan1","zoom1","zoom2","pan2","posChanged","viewport","zoomDefd","panDefd","events","zoomFailed","panFailed","cancelOnFailedZoom","center","getCenterPan","reset","clientWidth","clientHeight","extent","rb","renderedExtent","centre",41,"Event","selfIsArrayLike","keys","i_a","l_a","_privateFields","validKeyToDelete","regex","optionalTypeRegex","falseCallback","eventsIsString","evts","evt","namespace","listener","delegated","selObj","binders","proto","addListener","listen","removeListener","unlisten","unbind","emit","pon","promiseOn","offArgs","onArgs","nsMatches","typeMatches","cbMatches","listenerMatches","fnToTrigger","eventsIsObject","eventsIsEvent","hasCompounds","eventArgObj","evtObj","triggerer","triggererIsElement","bubbleUp","cyTarget","cyPosition","cyRenderedPosition","lis","targetMatches","matches","binder","binderListeners","m","binderListener","isPropagationStopped","stopPropagation","preventDefault","fnParams","properties","propertiesEmpty","getPropsList","cyPan","centerPan","fitVp","jumpToEnd","anis","./event","./selector",42,"returnFalse","returnTrue","originalEvent","isDefaultPrevented","message","timeStamp","Date","stopImmediatePropagation","isImmediatePropagationStopped",43,"setExtension","registrant","ext","layoutProto","Object","create","optLayoutFns","fnName","bProto","getExtension","rProto","pName","pVal","existsInR","clientFunctions","setMap","extensions","getMap","setModule","moduleType","moduleName","modules","getModule","incExts","impl","./collection","./core","./define","./extensions",44,45,"BreadthFirstLayout","math","circle","spacingFactor","avoidOverlap","maximalAdjustments","graph","makeBoundingBox","rootsArray","unhandledNodes","currComp","pNode","comp","compRoots","depths","foundByBfs","prevId","succ","orphanNodes","maxChecks","checks","assignedDepth","assignDepthsToEles","breadthfirst","intersectsDepth","highestOther","thisInfo","highestDepthOfOther","otherInfo","adj","nDepths","elesToMove","nDepth","info","intEle","intInfo","newDepth","minDistance","nbb","cachedWeightedPercent","getWeightedPercent","eleDepth","samples","neighbor","bf","apct","bpct","times","biggestDepthSize","getPosition","isBottomDepth","depthSize","distanceX","distanceY","radiusStepSize","radius","PI","epos","../../math",46,"CircleLayout","startAngle","sweep","clockwise","counterclockwise","dTheta","dcos","dsin","rMin","getPos","rx","ry",47,"ConcentricLayout","equidistant","minNodeSpacing","concentric","levelWidth","nodeValues","maxNodeSize","levels","currentLevel","minDist","firstLvlHasMulti","maxR","rStep","rDeltaMax","rDelta",48,"CoseLayout","DEBUG","Thread","animationThreshold","refresh","componentSpacing","nodeRepulsion","nodeOverlap","idealEdgeLength","edgeElasticity","nestingFactor","gravity","initialTemp","coolingFactor","minTemp","useMultitasking","thread","disabled","debug","layoutInfo","createLayoutInfo","printLayoutInfo","randomizePositions","refreshRequested","force","refreshPositions","layoutNodes","pass","loopRet","calculateNodeForces","calculateEdgeForces","calculateGravityForces","propagateForces","updatePositions","graphSet","node1","idToIndex","node2","cmptId1","cmptId","cmptId2","isCompound","directionX","positionX","directionY","positionY","overlap","nodesOverlap","forceX","forceY","point1","findClippingPoint","point2","distanceSqr","isLocked","offsetX","offsetY","dX","dY","overlapX","maxX","minX","overlapY","maxY","minY","X","Y","H","W","dirSlope","nodeSlope","edgeSize","layoutEdges","sourceIx","sourceId","targetIx","targetId","lx","ly","idealLength","elasticity","distThreshold","centerX","centerY","dy","fx","fy","nodeIndex","offX","offY","childNode","nodeSize","tempForce","limitForce","temperature","updateAncestryBoundaries","padRight","padLeft","padBottom","padTop","separateComponents","layutInfo","cid","totalA","c1","c2","usedW","rowH","maxRowW","mainLoop","broadcast","layoutInfoUpdated","indexToGraph","id2cmptId","tempNode","tempGraph","p_id","node_id","node_ix","tempEdge","sourceGraph","targetGraph","lca","findLCA","lcaGraph","findLCA_aux","count","graphIx","nodeIx","childGraphIx","result","console","toString","set","coseBB","lnode","pctX","pctY","../../thread",49,"GridLayout","avoidOverlapPadding","condense","rows","cols","cells","splits","small","large","oRows","oCols","columns","sm","lg","cellWidth","cellHeight","cellUsed","used","row","use","moveToNextCell","id2manPos","rcPos",50,"./breadthfirst","./circle","./concentric","./cose","./grid","./null","./preset","./random",51,"NullLayout",52,"PresetLayout","posIsFn",53,"RandomLayout",54,"BRp","arrowShapeHeight","registerArrowShapes","arrowShapes","bbCollide","angle","translation","transform","xRotated","yRotated","xScaled","yScaled","xTranslated","yTranslated","transformPoints","retPts","pointsToArr","defineArrowShape","defn","collide","pointInsidePolygonPoints","roughCollide","draw","arrowShapeImpl","spacing","gap","falsify","noop","zeroify","controlPoint","ptsTrans","ctrlPt","ctrlPtTrans","pointsTee","triPts","teePts","leavePathOpen","matchEdgeWidth","getArrowWidth","../../../is","../../../math","../../../util",55,"delEleCache","eleEache","getEleCache","getCachedElements","getCachedNodes","getCachedEdges","updateElementsCache",56,"pushBezierPts","qbezierAt","p3","bpts","projectIntoViewport","clientX","clientY","offsets","findContainerClientCoords","offsetLeft","offsetTop","containerBB","getBoundingClientRect","invalidateContainerClientCoordsCache","findNearestElement","visibleElementsOnly","isTouch","checkNode","nodeThreshold","hw","hh","shape","nodeShapes","getNodeShape","checkPoint","near","checkEdge","sqDist","passedVisibilityCheck","rs","edgeThreshold","widthSq","width2","inEdgeBB","passesVisibilityCheck","edgeType","allpts","inLineVicinity","sqDistanceToFiniteLine","inBezierVicinity","sqDistanceToQuadraticBezier","eWidth","arSize","arrows","arrowStartX","arrowStartY","srcArrowAngle","arrowEndX","arrowEndY","tgtArrowAngle","midX","midY","midsrcArrowAngle","midtgtArrowAngle","ar","checkLabel","th","labelThreshold","inBoundingBox","getCachedZSortedEles","getAllInBox","box","x1c","x2c","y1c","y2c","boxBb","nodeBb","boundingBoxesIntersect","startX","startY","endX","endY","allInside","pointInBoundingBox","makePolygon","updateCachedZSortedEles","forceRecalc","lastNodes","lastZOrderCachedNodes","lastEdges","lastZOrderCachedEdges","cachedZSortedEles","projectLines","et","lpts","projectBezier","recalculateNodeLabelProjection","content","textX","textY","nodeWidth","nodeHeight","nodePos","textHalign","textValign","applyLabelDimensions","recalculateEdgeLabelProjection","text","getLabelText","labelDims","calculateLabelDimensions","textTransform","toUpperCase","toLowerCase","labelWrapKey","labelKey","labelWrapCachedText","lines","maxW","wrappedLines","line","lineDims","lineW","words","subline","word","testLine","testDims","testW","labelWrapCachedLines","extraKey","fStyle","family","cacheKey","cache","labelDimCache","div","labelCalcDiv","createElement","body","appendChild","ds","fontFamily","fontStyle","fontWeight","zIndex","visibility","pointerEvents","lineHeight","whiteSpace","textContent","handledEdge","bbStyleSame","boundingBoxKey","labelStyleSame","styleSame","posSame","nodeX","nodeY","wSame","nodeW","hSame","nodeH","srcPos","tgtPos","srcSame","srcX","srcY","tgtSame","tgtX","tgtY","positionsSame","pEdge","pId","recalculateEdgeProjections","recalculateLabelProjections","findEdgeControlPoints","pairId","hashTable","pairIds","haystackEdges","autorotateEdges","curveStyle","edgeIsUnbundled","hasUnbundled","src_p","tgt_p","srcW","srcH","tgtW","tgtH","srcShape","tgtShape","vectorNormInverse","badBezier","pairEdges","srcOutside","intersectLine","tgtOutside","midptSrcPts","vectorNorm","edge_p","edgeIndex1","lastEdgeIndex","edgeIndex2","numEdges1","lastNumEdges","numEdges2","eStyle","ctrlptDists","ctrlptWs","bezierN","stepSize","ctrlptDist","ctrlptWeight","swappedDirection","srcX1","lastSrcCtlPtX","srcX2","srcY1","lastSrcCtlPtY","srcY2","srcW1","lastSrcCtlPtW","srcW2","srcH1","lastSrcCtlPtH","srcH2","tgtX1","lastTgtCtlPtX","tgtX2","tgtY1","lastTgtCtlPtY","tgtY2","tgtW1","lastTgtCtlPtW","tgtW2","tgtH1","lastTgtCtlPtH","tgtH2","width1","lastW","lastWidth","loopDist","ctrlpts","loopW","loopaPos","loopbPos","loopPos","minCompoundStretch","compoundStretchA","compoundStretchB","segpts","segmentWs","segmentDs","segmentsN","w1","w2","adjustedMidpt","multi","manctrlptDist","normctrlptDist","sign","signum","distanceFromMidpoint","findEndpoints","badStart","badAStart","badEnd","badAEnd","minCpADistFactor","arrowW","minCpADist","startACpDist","closeStartACp","endACpDist","closeEndACp","overlapping","cpD","cpL","cpM","cpProj","srcCtrlPtIntn","tgtCtrlPtIntn","mt","i2","i1","calculateArrowAngles","haystack","halfRadius","atan","midDispY","midDispX","getAngleFromDisp","dispX","dispY","atan2","isHaystack","isMultibezier","isSegments","isSelf","i3","bp0x","bp0y","bp1x","bp1y","cpts","p0","ic","tgtArShape","srcArShape","bezier","segments","cpStart","cpEnd","srcArrowFromPt","tgtArrowFromPt","arrowEnd","shortenIntersection","edgeEnd","arrowStart","edgeStart","badLine","getArrowHeight","edgeWidth","arrowWidthCache","cachedVal","../../../collection/zsort",57,"getCachedImage","url","onLoad","imageCache","image","Image","addEventListener",58,"BaseRenderer","BR","selection","hoverData","down","downTime","triggerMode","dragging","initialPan","capture","dragData","possibleDragElements","touchData","singleTouchStartTime","singleTouchMoved","earlier","redraws","showFps","motionBlurEnabled","forcedPixelRatio","motionBlurTransparency","motionBlurPxRatio","mbPxRBlurry","minMbLowQualFrames","fullQualityMb","clearedForMotionBlur","desktopTapThreshold2","touchTapThreshold2","tapholdDuration","bindings","registerNodeShapes","types","redrawHint","matchCanvasSize","startRenderLoop","redraw","destroyed","binding","removeEventListener","useCapture","removeObserver","disconnect","./arrow-shapes","./cached-eles","./coord-ele-math","./images","./load-listeners","./node-shapes","./redraw",59,"registerBinding","nodeIsDraggable","triggerEvents","isMultSelKeyDown","shiftKey","metaKey","ctrlKey","getDragListIds","listHasId","addToList","hasId","addDescendantsToDrag","inDragLayer","innerNodes","iNode","addNodeToDrag","updateAncestorsInDragLayer","freeDraggedElements","draggedElements","dEi_p","sEdges","MutationObserver","mutns","mutn","rNodes","removedNodes","rNode","parentNode","observe","childList","debounce","invalCtnrBBOnScroll","bbCtnr","inBoxSelection","which","select","mdownPos","checkForTaphold","tapholdCancelled","clearTimeout","tapholdTimeout","cxtStarted","cxtEvt","activate","getTime","cxtDragged","grabEvent","selectedNodes","bgActivePosistion","containerPageCoords","canvasWidth","canvasHeight","cyContainer","tParent","containerIsTarget","draggingEles","disp","dx2","dy2","dist2","rdist2","multSelKeyDown","updateDragDelta","dragDelta","cxtOver","deltaP","justStartedPan","mdPos","dragged","unactivate","justStartedDrag","didDrag","dEle","dPos","updatePos","tcol","selecting","cxtTap","newlySelected","newlySelCol","wheelHandler","scrollingPage","wheelZooming","wheelTimeout","deltaY","wheelDeltaY","wheelDelta","needsWheelFix","deltaMode","scrollingPageTimeout","f1x1","f1y1","f2x1","f2y1","distance1","distance1Sq","center1","modelCenter1","containerWidth","containerHeight","twoFingersStartInside","touchstartHandler","distanceSq","touches","release","cxtDistThreshold","cxtDistThresholdSq","near1","near2","cxt","draggedEles","touchDragEles","selectedNode","pinching","touchmoveHandler","f1x2","f1y2","f2x2","f2y2","distance2Sq","factorSq","distThresholdSq","factorThreshold","factorThresholdSq","lastThreeTouch","distance2","factor","df1x","df1y","df2x","df2y","tx","ty","ctrx","ctry","start_p","draggedEle","swipePanning","touchcancelHandler","touchendHandler","ctxTapend","ctxTap","updateStartStyle","startWasGrabbed","TouchEvent","pointers","makeTouch","identifier","pointerId","pageX","pageY","radiusX","radiusY","screenX","screenY","makePointer","touch","addPointer","removePointer","updatePointer","addTouchesToEvent","pointerIsMouse","pointerType","../../../collection","../../../event",60,"generatePolygon","nodeShapeImpl","polygonIntersectLine","pointInsidePolygon","intersectLineEllipse","generateUnitNgonPointsFitToSquare","roundRectangleIntersectLine","cornerRadius","getRoundRectangleRadius","checkInEllipse","star5Points","outerPoints","generateUnitNgonPoints","innerPoints","innerRadius","fitPolygonToSquare",61,"timeToRender","redrawTotalTime","redrawCount","minRedrawLimit","maxRedrawLimit","forcedContext","averageRedrawTime","lastRedrawTime","redrawLimit","lastDrawTime","nowTime","timeElapsed","callAfterLimit","currentlyDrawing","requestedFrame","renderOptions","skipFrame","renderFn","performanceNow","render","endTime",62,"CRp","polygon","lineTo","triangle-backcurve","firstPt","quadraticCurveTo","triangle-tee","trianglePoints","teePoints","firstTeePt","moveTo","arc",63,"drawEdge","drawOverlayInstead","usePaths","overlayPadding","overlayOpacity","overlayColor","strokeStyle","lineCap","lineColor","lineStyle","lineWidth","shadowBlur","shadowOpacity","shadowColor","shadowOffsetX","shadowOffsetY","shadowStyle","drawEdgePath","drawArrowheads","canvasCxt","pathCacheHit","pathCacheKey","keyMatches","pathCache","Path2D","setLineDash","beginPath","stroke","drawArrowhead","arrowShape","gco","globalCompositeOperation","arrowClearFill","arrowFill","fillStyle","drawArrowShape","color","arrowType","fill","canvasContext","shapeImpl","arrowPathCacheKey","arrowPathCache","alreadyCached","closePath","lineJoin",64,"safeDrawImage","img","ix","iy","iw","ih","drawImage","canvasNeedsRedraw","NODE","DRAG","drawingImage","drawInscribedImage","xPos","yPos","repeat","clip","shouldClip","imgOpacity","imgW","cachedW","imgH","cachedH","offsetWidth","offsetHeight","bgW","units","bgH","scale","gAlpha","globalAlpha","save","pattern","createPattern","translate",65,"roundRect","ctx","drawEdgeText","wheel","computedSize","minSize","textAlign","textBaseline","drawText","drawNodeText","getFontCache","fontCaches","setupTextStyle","labelStyle","labelSize","labelFamily","labelWeight","outlineOpacity","outlineColor","fontCacheKey","fontKey","font","pLeft","pRight","pTop","pBottom","backgroundOpacity","borderOpacity","textBorderWidth","margin","bgWidth","bgHeight","bgX","bgY","textFill","textBackgroundColor","styleShape","fillRect","textStroke","textLineWidth","textBorderColor","textBorderStyle","strokeRect","whiteWidth","strokeText","fillText",66,"drawNode","prevBging","bgColor","borderColor","borderStyle","npos","darkness","borderWidth","hasPie","drawPie","nodeOpacity","cyStyle","pieSize","lastPercent","pieBackgroundN","angleStart","angleDelta","angleEnd",67,"motionBlurDelay","getPixelRatio","contexts","backingStore","backingStorePixelRatio","webkitBackingStorePixelRatio","mozBackingStorePixelRatio","msBackingStorePixelRatio","oBackingStorePixelRatio","devicePixelRatio","paintCache","caches","paintCaches","needToCreateCache","blur","mbPxRatio","bufferCanvases","MOTIONBLUR_BUFFER_NODE","MOTIONBLUR_BUFFER_DRAG","canvas","canvasContainer","CANVAS_LAYERS","canvases","BUFFER_COUNT","textureMult","TEXTURE_BUFFER","forcedZoom","forcedPan","drawAllLayers","forcedPxRatio","mbclear","setContextTransform","clear","ePan","eZoom","clearingMotionBlur","bufferContexts","effectivePan","effectiveZoom","setTransform","clearRect","drawElements","list","hideLabels","hideEdges","drawOnlyNodeLayer","needDraw","textureDraw","inNodeDragGesture","motionBlurFadeEffect","motionBlurTimeout","mbFrames","textureDrawLastFrame","SELECT_BOX","coreStyle","vp","prevVp","prevViewport","viewportIsDiff","drag","nondrag","textureCache","texture","mpan","outsideBgColor","outsideBgOpacity","vpManip","zEles","insideExtent","needMbClear","useBuffer","fps","maxFps","cxtNode","txtNode","cxtDrag","txtDrag","drawMotionBlur","txt","needClear","pxr","motionBlurCleared",68,"drawPolygonPath","drawRoundRectanglePath","halfWidth","halfHeight","arcTo","sin0","cos0","ellipseStepSize","drawEllipsePath","ellipse","rw","rh",69,"createBuffer","buffer","getContext","bufferCanvasImage","full","maxWidth","maxHeight","maxScaleW","maxScaleH","buffCanvas","buffCxt","rect","toDataURL",70,"CanvasRenderer","containerStyle","setAttribute","overflow","getAttribute","ms","String","topCanvas","pathsEnabled","CR","pathsImpld","path2dEnabled","./drawing-edges","./drawing-images","./drawing-label-text","./drawing-nodes","./drawing-redraw","./drawing-shapes","./export-image",71,"roundrectangle",72,"./base","./canvas",73,"NullRenderer",74,"Fabric","N","defN","navigator","hardwareConcurrency","cpus","err","fabfn","as","spreadSize","subsize","spread","runPs","runP","doneEarly","postpass","mapped","origResolve","oldLen","_$_$_fabmap","nothingInsdByResolve","incDatum","cmp","sortedSplit","_$_$_cmp","joined","eleI","eleJ","splitL","defineRandomPasser","arg1","threadFn","randomMap","reduce","reduceRight","terminate","halt","./thread","os",75,"defaultCmp","heapify","heappop","heappush","heappushpop","heapreplace","insort","nlargest","nsmallest","_siftdown","_siftup","lo","hi","mid","item","lastelt","returnitem","_ref","_i","_len","_ref1","_results","_results1","_j","elem","los","startpos","newitem","parentpos","childpos","endpos","rightpos","replace","pushpop","peek","contains","heap","insert","front","has","factory",76,"registerJquery","Stylesheet","version","jQuery","fabric","./extension","./fabric","./jquery-plugin","./stylesheet","./window",77,"typeofstr","typeofobj","typeoffn","typeofhtmlele","HTMLElement","instanceStr","defined","isArray","constructor","object","integer","nonemptyString","domElement","DocumentTouch","gecko","InstallTrigger","documentElement","webkit","webkitURL","chromium","chrome","khtml","vendor","khtmlEtc","userAgent","windows","appVersion","mac","linux","unix",78,"cyReg","$ele","$this",79,"sqDistance","qbezierPtAt","bb1","bb2","straightLineIntersections","topStartX","topStartY","topEndX","topEndY","finiteLinesIntersect","rightStartX","rightStartY","rightEndX","rightEndY","bottomStartX","bottomStartY","bottomEndX","bottomEndY","leftStartX","leftStartY","leftEndX","leftEndY","arcIntersections","topLeftCenterX","topLeftCenterY","intersectLineCircle","topRightCenterX","topRightCenterY","bottomRightCenterX","bottomRightCenterY","bottomLeftCenterX","bottomLeftCenterY","x3","y3","solveCubic","discriminant","dum1","term1","r13","acos","zeroThreshold","closestParam","curX","curY","distSquared","minDistanceSquared","offset","lineSq","hypSq","dotProduct","adjSq","up","basePoints","direction","transformedPoints","expandedLineSet","expandPolygon","joinLines","lineSet","currentLineStartX","currentLineStartY","currentLineEndX","currentLineEndY","nextLineStartX","nextLineStartY","nextLineEndX","nextLineEndY","vertices","pad","currentPointX","currentPointY","nextPointX","nextPointY","offsetLength","normalizedOffsetX","normalizedOffsetY","ellipseWradius","ellipseHradius","len","newLength","lenProportion","t1","t2","tMin","tMax","inRangeParams","nearIntersectionX","nearIntersectionY","farIntersectionX","farIntersectionY","findCircleNearPoint","farX","farY","displacementX","displacementY","unitDisplacementX","unitDisplacementY","findMaxSqDistanceToOrigin","maxSqDistance","x4","y4","infiniteLines","ua_t","ub_t","u_b","ua","ub","intersections","currentX","currentY","nextX","nextY","amount","lenRatio","sides","rotationRadians","sx","sy","increment","currentAngle",80,"STATE_PENDING","STATE_FULFILLED","STATE_REJECTED","api","executor","fulfillValue","rejectReason","onFulfilled","onRejected","proxy","fulfill","deliver","curr","resolver","execute","execute_handlers","handlers","func","setImmediate","method","TypeError","resolved","ps","resolveAll","rejectAll","vals","doneCount","isPromise",81,"onlyThisGroup","selectorText","invalid","newQuery","currentSubject","colonSelectors","meta","subject","child","descendant","tokens","metaChar","comparatorOp","boolOp","separator","variable","cleanMetaChars","str","RegExp","$1","original","ops","op","exprs","query","populate","valueIsString","exec","substring","operator","childQuery","descendantQuery","modifier","remaining","consumeExpr","expectation","expr","consumed","consumeWhitespace","check","selfn","queryMatches","allColonSelectorsMatch","allIdsMatch","actualId","allClassesMatch","operandsMatch","allDataMatches","fieldVal","fieldValue","fieldStr","valStr","caseInsensitive","notExpr","handledNotExpr","search","fieldTruthy","fieldUndefined","fieldRef","allMetaMatches","matchesAny","confirmRelations","selectorFunction","filteredCollection","clean","isValue","queryToString",82,"styfn","contextStyles","propDiffs","ie","cxtMeta","getContextMeta","cxtStyle","getContextStyle","app","applyContextStyle","diffProps","updateStyleHints","getPropertiesDiff","oldCxtKey","newCxtKey","dualCxtKey","addedProp","oldHasCxt","newHasCxt","cxtHasDiffed","cxtHasMappedProps","mappedProperties","laterCxtOverrides","laterCxt","hasLaterCxt","cxtKey","prevKey","styleCxtKey","contextSelectorMatches","diffPropNames","cxtStyles","hasCxt","styProp","retDiffProps","diffPropName","cxtProp","eleProp","retDiffProp","applyParsedProperty","bypassed","oWidth","wrap","wrapW","borderW","cpss","cpd","cpw","curve","sd","sw","styleKey","parsedProp","flatProp","propIsBypass","origProp","origPropIsBypass","deleteBypass","currentProp","printMappingErr","mapData","mapLayoutData","mapScratch","isLayout","isScratch","fieldMin","fieldMax","r1","valueMin","r2","valueMax","g1","g2","b1","b2","a1","a2","clr","calcValue","mapping","layoutData","flatPropVal","fnRetVal","propInStyle","isBypass","anyPrev","diffProp","initVal","prevProp","fromProp","toProp","initDt","transitioning",83,"specifiedProps","camel2dash","isColor","isMulti","mutiple","propertyNames",84,"getEmSizeInPixels","px","containerCss","propName","getComputedStyle","getPropertyValue",85,"isRenderedVal","styleProp","implicitUnits","isEle","propsObj",86,"addDefaultStylesheet","resetToDefault","selectorStr","mapVal","cssRule","currentSelectorIsCore","./apply","./bypass","./container","./get-for-ele","./json","./parse","./properties","./string-sheet",87,"applyFromJson","defaultLength",88,"propIsFlat","argHash","propCache","parseImpl","passedValue","alias","pointsTo","trim","multiple","evenMultiple","valArr","unitless","checkEnums","enums","en","unitsRegex","allowPercent","propList","propsStr","propsSplit","tuple","color2tuple","regexes","enumProp",89,"rgba","rgbaNoBackRefs","hsla","hslaNoBackRefs","hex3","hex6","mapArg","zeroOneNumber","nOneOneNumber","nonNegativeInt","numbers","bidirectionalSize","bidirectionalSizes","bgSize","bgWH","bgPos","bgRepeat","bgFit","bgClip","fontVariant","textDecoration","textWrap","textBackgroundShape","nodeShape","compoundIncludeLabels","textRotation","polygonPointList","aliases","arrowPrefixes","pointsToProp","aliasProp","text-events","text-valign","text-halign","text-outline-color","text-outline-width","text-outline-opacity","text-opacity","text-decoration","text-transform","text-wrap","text-max-width","text-background-color","text-background-opacity","text-border-opacity","text-border-width","text-border-style","text-border-color","text-background-shape","font-family","font-style","font-weight","font-size","min-zoomed-font-size","edge-text-rotation","z-index","overlay-opacity","overlay-color","overlay-padding","shadow-opacity","shadow-color","shadow-blur","shadow-offset-x","shadow-offset-y","text-shadow-opacity","text-shadow-color","text-shadow-blur","text-shadow-offset-x","text-shadow-offset-y","transition-property","transition-duration","transition-delay","transition-timing-function","background-blacken","background-color","background-opacity","background-image","background-image-opacity","background-position-x","background-position-y","background-repeat","background-fit","background-clip","background-width","background-height","border-color","border-opacity","border-width","border-style","shape-polygon-points","padding-top","padding-bottom","padding-left","padding-right","compound-sizing-wrt-labels","pie-size","line-style","line-color","control-point-step-size","control-point-weights","segment-weights","segment-distances","curve-style","haystack-radius","selection-box-color","selection-box-opacity","selection-box-border-color","selection-box-border-width","active-bg-color","active-bg-opacity","active-bg-size","outside-texture-bg-color","outside-texture-bg-opacity",90,"applyFromString","removeSelAndBlockFromRemaining","selAndBlockStr","substr","removePropAndValFromRem","blockRem","propAndValStr","nothingLeftToParse","selAndBlock","blockStr","invalidBlock","propAndVal","propStr",91,"sheetfn",92,"requires","files","thdfn","stringifyFieldVal","JSON","stringify","fnAsRequire","req","fnAs","protoreq","subname","protoNonempty","protoStr","hasOwnProperty","isPathStr","running","useWW","useNode","threadTechAlreadyExists","ran","fnImplStr","fnStr","wwifyFile","file","location","pathname","fnBlob","fnUrl","fnPre","Blob","URL","createObjectURL","ww","webworker","Worker","postMessage","$$eval","isObject","$$resolve","$$reject","fork","__dirname","send","promiseResolve","promiseReject","timer","eval","ls","kill","defineFnal","child_process",93,"hex2tuple","hex","shortHex","base","parseInt","hsl2tuple","hsl","hue2rgb","rgb2tuple","rgb","isPct","channel","atLeastOneIsPct","allArePct","colorname2tuple","colors","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkgrey","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightgrey","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen",94,"msg","trace","_staticEmptyObject","assign","memoize","../math","./colors","./maps","./memoize","./regex","./strings","./timing",95,"mapEmpty","pushMap","deleteMap","keepChildren","lastKey",96,"keyFn",97,98,"charAt",99,"performance","raf","mozRequestAnimationFrame","webkitRequestAnimationFrame","msRequestAnimationFrame","pnow","throttle","wait","leading","trailing","maxWait","maxTimeoutId","stamp","timeoutId","trailingCall","lastCalled","delayed","isCalled","maxDelayed","leadingCall",100],"mappings":";;;;;;;;;;;;;;;;CAgBA,SAAAA,GAAA,GAAA,gBAAAC,UAAA,mBAAAC,QAAAA,OAAAD,QAAAD,QAAA,IAAA,kBAAAG,SAAAA,OAAAC,IAAAD,UAAAH,OAAA,CAAA,GAAAK,EAAAA,GAAA,mBAAAC,QAAAA,OAAA,mBAAAC,QAAAA,OAAA,mBAAAC,MAAAA,KAAAC,KAAAJ,EAAAK,UAAAV,MAAA,WAAA,GAAAG,QAAAD,OAAAD,OAAA,OAAA,SAAAU,GAAAC,EAAAC,EAAAC,GAAA,QAAAC,GAAAC,EAAAC,GAAA,IAAAJ,EAAAG,GAAA,CAAA,IAAAJ,EAAAI,GAAA,CAAA,GAAAE,GAAA,kBAAAC,UAAAA,OAAA,KAAAF,GAAAC,EAAA,MAAAA,GAAAF,GAAA,EAAA,IAAAI,EAAA,MAAAA,GAAAJ,GAAA,EAAA,IAAAhB,GAAA,GAAAqB,OAAA,uBAAAL,EAAA,IAAA,MAAAhB,GAAAsB,KAAA,mBAAAtB,EAAA,GAAAuB,GAAAV,EAAAG,IAAAf,WAAAW,GAAAI,GAAA,GAAAQ,KAAAD,EAAAtB,QAAA,SAAAU,GAAA,GAAAE,GAAAD,EAAAI,GAAA,GAAAL,EAAA,OAAAI,GAAAF,EAAAA,EAAAF,IAAAY,EAAAA,EAAAtB,QAAAU,EAAAC,EAAAC,EAAAC,GAAA,MAAAD,GAAAG,GAAAf,QAAA,IAAA,GAAAmB,GAAA,kBAAAD,UAAAA,QAAAH,EAAA,EAAAA,EAAAF,EAAAW,OAAAT,IAAAD,EAAAD,EAAAE,GAAA,OAAAD,KAAAW,GAAA,SAAAC,EAAAzB,EAAAD,GACA,YAEA,IAAA2B,GAAAD,EAAA,UACAE,EAAAF,EAAA,QACAG,EAAAH,EAAA,aAEAI,EAAA,SAAAC,EAAAC,EAAAC,GACA,KAAAzB,eAAAsB,IACA,MAAA,IAAAA,GAAAC,EAAAC,EAAAC,EAGA,IAAAC,GAAA1B,KAAA2B,SAAAR,EAAAS,QACAC,SAAA,KACAL,EAAAC,EAEAC,GAAAH,OAAAA,EACAG,EAAAI,MAAAJ,EAAAI,OAAAJ,EAAAK,IACAL,EAAAM,SAAA,EACAN,EAAAO,SAAA,EACAP,EAAAQ,QAAA,EACAR,EAAAS,UAAA,EACAT,EAAAU,SAAA,EACAV,EAAAW,aACAX,EAAAY,UAEAZ,EAAAa,UAAAnB,EAAAoB,GAAAd,EAAAa,WACAb,EAAAW,UAAAI,KAAAf,EAAAa,UAIAvC,KAAAgB,OAAA,EACAhB,KAAA,GAAAA,MAGA0C,EAAApB,EAAAqB,SAEAxB,GAAAS,OAAAc,GAEAE,eAAA,WAAA,MAAA,aAEAC,KAAA,WACA,GAAAnB,GAAA1B,KAAA2B,QAEA,KAAAD,EAAAQ,OAAA,CAEA,GAAAY,GACAC,EAAArB,EAAAH,OAAAI,SAAAqB,SAEAF,GADApB,EAAAuB,MACAF,EAAAE,MAEAF,EAAAG,QAEAJ,EAAAL,KAAAzC,MAGAoB,EAAA+B,oBAAAzB,EAAAH,SACAG,EAAAH,OAAA6B,KAAAC,mBAAA3B,EAAAH,QAGAG,EAAAQ,QAAA,EAGA,MAAAlC,OAGAsD,KAAA,WACA,GAAA5B,GAAA1B,KAAA2B,QAeA,OAZA,KAAAD,EAAAU,WACAV,EAAAU,SAAA,GAGAV,EAAAO,SAAA,EACAP,EAAAM,SAAA,EACAN,EAAA6B,SAAA,EAEAvD,KAAA6C,OAIA7C,MAGAiC,QAAA,WACA,MAAAjC,MAAA2B,SAAAM,SAGAuB,MAAA,WACA,GAAA9B,GAAA1B,KAAA2B,QAUA,OARAD,GAAAS,UAAA,EACAT,EAAAM,SAAA,EACAN,EAAA6B,SAAA,EAEAvD,KAAA6C,OAIA7C,MAGAmC,SAAA,WACA,MAAAnC,MAAA2B,SAAAQ,UAGAsB,MAAA,WACA,GAAA/B,GAAA1B,KAAA2B,QAKA,OAHAD,GAAAO,SAAA,EACAP,EAAAM,SAAA,EAEAhC,MAGA0D,KAAA,WACA,GAAAhC,GAAA1B,KAAA2B,QAMA,OAJAD,GAAAO,SAAA,EACAP,EAAAM,SAAA,EACAN,EAAA6B,SAAA,EAEAvD,MAGA2D,OAAA,WACA,MAAA3D,MAAAoC,SAAA,IAGAwB,YAAA,WACA,MAAA5D,MAAAoC,SAAA,IAGAyB,KAAA,SAAA1D,GACA,GAAAuB,GAAA1B,KAAA2B,QAEA,OAAAmC,UAAA3D,EACAuB,EAAAU,SAAAV,EAAAG,SAEA7B,KAAAoC,SAAAjC,EAAAuB,EAAAG,WAIAO,SAAA,SAAA2B,GACA,GAAArC,GAAA1B,KAAA2B,SACAqC,EAAAtC,EAAAO,OAEA,OAAA6B,UAAAC,EACArC,EAAAU,UAEA4B,GACAhE,KAAAyD,QAGA/B,EAAAU,SAAA2B,EACArC,EAAAM,SAAA,EAEAgC,GACAhE,KAAAsD,OAIAtD,OAGAiE,UAAA,WACA,MAAA,KAAAjE,KAAA2B,SAAAS,UAGA8B,QAAA,WACA,GAAAxC,GAAA1B,KAAA2B,SACAqC,EAAAtC,EAAAO,OAEA+B,IACAhE,KAAAyD,QAGA/B,EAAAU,SAAA,EAAAV,EAAAU,SACAV,EAAAM,SAAA,CAEA,IAAAmC,GAAA,SAAA1D,EAAA2D,GACA,GAAAC,GAAA3C,EAAAjB,EAEAiB,GAAAjB,GAAAiB,EAAA0C,GACA1C,EAAA0C,GAAAC,EAGAF,GAAA,OAAA,aACAA,EAAA,MAAA,YACAA,EAAA,WAAA,gBAGA,KAAA,GAAAxD,GAAA,EAAAA,EAAAe,EAAAI,MAAAd,OAAAL,IAAA,CACA,GAAA2D,GAAA5C,EAAAI,MAAAnB,GACA4D,EAAAD,EAAAC,KACAC,EAAA9C,EAAA+C,WAAAF,EAEA7C,GAAA+C,WAAAF,GAAA7C,EAAA+C,WAAAtD,EAAAuD,WAAAH,IAAAD,EACA5C,EAAAI,MAAAnB,GAAA6D,EAOA,MAJAR,IACAhE,KAAAsD,OAGAtD,MAGA2E,QAAA,SAAAC,GACA,GAEAC,GAFAnD,EAAA1B,KAAA2B,QAIA,QAAAiD,GACA,IAAA,QACAC,EAAAnD,EAAAY,MACA,MACA,SACA,IAAA,WCEM,IAAK,YC7OXuC,EAAAnD,EAAAW,UAGA,MAAA,IAAAhB,GAAA,SAAAyD,EAAAC,GACAF,EAAApC,KAAA,WACAqC,WAOApC,EAAAH,SAAAG,EAAAuB,UAEAxE,EAAAD,QAAA8B,IAEA0D,OAAA,GAAAC,YAAA,GAAAC,SAAA,KAAAC,GAAA,SAAAjE,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,YAEAkE,GAGAC,MAAA,SAAAC,GACA,GAAAC,GAAAvF,IAEAsF,GAAAA,KAGA,IAAAE,GAAA,SAAAC,EAAAC,EAAAC,EAAAC,GAEA,GAAAH,GAAAC,EAEA,MADAE,GAAAnD,KAAAW,EAAAyC,eAAAH,IACAE,CAGA,IAAAF,IAAAC,GAAA,CAEA,GAAAG,GAAAH,EAAAD,GACAK,EAAAC,EAAAN,EAMA,OAJAE,GAAAnD,KAAAW,EAAAyC,eAAAH,IACAE,EAAAnD,KAAAW,EAAAyC,eAAAE,IAGAP,EAAAC,EACAK,EACAH,EACAC,GAIA,MAAA9B,SAIAmC,EAAA,SAAAC,EAAAC,GACA,GAAA,IAAAD,EAAAlF,OAEA,MAAA8C,OAIA,KAAA,GAFAsC,GAAA,EACAC,EAAAF,EAAAD,EAAA,IACAvF,EAAA,EAAAA,EAAAuF,EAAAlF,OAAAL,IAAA,CACA,GAAAL,GAAA6F,EAAAD,EAAAvF,GACA0F,GAAA/F,IACA+F,EAAA/F,EACA8F,EAAAzF,GAGA,MAAAyF,IAGAhD,EAAApD,KAAA2B,SAAAyB,EAGA,IAAA,MAAAkC,GAAA,MAAAA,EAAAgB,KAMA,MAAAxC,OALA,IAAAyC,GAAAnF,EAAAoF,OAAAlB,EAAAgB,MAEAtG,KAAAyG,OAAAnB,EAAAgB,MAAA,GACAhB,EAAAgB,KAAA,EAMA,IAAA,MAAAhB,EAAAoB,KAMA,MAAA5C,OALA,IAAAvC,GAAAH,EAAAoF,OAAAlB,EAAAoB,MAEA1G,KAAAyG,OAAAnB,EAAAoB,MAAA,GACApB,EAAAoB,KAAA,EAMA,IAAA,MAAApB,EAAAqB,WAAAvF,EAAAoB,GAAA8C,EAAAqB,WACA,GAAAA,GAAArB,EAAAqB,cAEA,IAAAA,GAAA,WAAA,MAAA,GAIA,IAAA,MAAArB,EAAAsB,QAAAxF,EAAAoB,GAAA8C,EAAAsB,QACA,GAAAC,GAAAvB,EAAAsB,WAGA,IAAAC,GAAA,SAAA3G,GAAA,MAAA,GAIA,IAAA,MAAAoF,EAAAwB,SACA,GAAAA,GAAAxB,EAAAwB,aAEA,IAAAA,IAAA,CAGA,IAAAC,MACAb,GAAAK,EAAAS,MACAC,KACAjB,KACAkB,KACAf,IAEAe,GAAAX,EAAAS,MAAA,EACAb,EAAAI,EAAAS,MAAAL,EAAAJ,EASA,KAPA,GAAAY,GAAAnH,KAAAmH,QAAAC,UAAA,SAAAlH,GAAA,OAAAA,EAAAmH,WACAC,EAAAtH,KAAAsH,QAGAC,EAAA,EAGArB,EAAAlF,OAAA,GAAA,CACA,GAAAoF,GAAAH,EAAAC,EAAAC,GACAqB,EAAApE,EAAAyC,eAAAK,EAAAE,GAIA,IAHAmB,IAGAC,EAAAR,MAAAzF,EAAAyF,KAAA,CACA,GAAAS,GAAAjC,EAAAe,EAAAS,KAAAzF,EAAAyF,KAAAC,KAEA,OADAQ,GAAAvD,WAEAwD,OAAA,EACAC,SAAAT,EAAAM,EAAAR,MACAY,KAAArC,EAAAsC,MAAAJ,GACAF,MAAAA,GAKAR,EAAAtE,KAAA+E,EAAAR,MAEAd,EAAA4B,OAAA1B,EAAA,EAIA,IAAA2B,GAAAP,EAAAQ,gBACAlB,KAAAiB,EAAAA,EAAAX,UAAA,SAAAa,GAAA,MAAAA,GAAAC,KAAA,YAAAV,EAAAR,QACAe,EAAAA,EAAAI,UAAAhB,EAEA,KAAA,GAAAxG,GAAA,EAAAA,EAAAoH,EAAA/G,OAAAL,IAAA,CACA,GAAAT,GAAA6H,EAAApH,GACAyH,EAAAlI,EAAAmI,iBAAAjB,UAAA,SAAAhH,GAAA,MAAAA,GAAA4G,OAAAQ,EAAAR,OAAAmB,UAAAb,EAGA,IAAA,IAAAP,EAAAuB,QAAAF,EAAApB,MAAA,CAKA,GAAAX,GAAAa,EAAAM,EAAAR,MAAAH,EAAArD,MAAAtD,GAAAA,GAQA,KAAAgG,EAAAoC,QAAAF,EAAApB,MASAX,EAAAa,EAAAkB,EAAApB,QACAE,EAAAkB,EAAApB,MAAAX,EACAF,EAAAiC,EAAApB,MAAAX,EAAAM,EAAAyB,GACAnB,EAAAmB,EAAApB,MAAAQ,EAAAR,OAXAE,EAAAkB,EAAApB,MAAAX,EACAF,EAAAiC,EAAApB,MAAAX,EAAAM,EAAAyB,GACAlC,EAAAzD,KAAA2F,EAAApB,MACAC,EAAAmB,EAAApB,MAAAQ,EAAAR,KACAhB,EAAAoC,EAAApB,MAAA9G,EAAA8G,QCvLA,OACAU,OAAA,EACAC,SAAA7D,OACA8D,KAAA9D,OACAyD,MAAAA,IAOA9H,GAAAD,QAAA4F,IAEAmD,WAAA,KAAAC,GAAA,SAAAtH,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,YACAC,EAAAD,EAAA,cAEAkE,GAGAqD,YAAA,SAAAnD,GACA,GAAAC,GAAAvF,IAKA,IAHAsF,EAAAA,MAGA,MAAAA,EAAAsB,QAAAxF,EAAAoB,GAAA8C,EAAAsB,QACA,GAAAC,GAAAvB,EAAAsB,WAGA,IAAAC,GAAA,SAAA3G,GAAA,MAAA,GAIA,IAAA,MAAAoF,EAAAwB,SACA,GAAAA,GAAAxB,EAAAwB,aAEA,IAAAA,IAAA,CAIA,IAAA,MAAAxB,EAAAgB,KAQA,MAAAxC,OAPA,IAAA1C,EAAAoF,OAAAlB,EAAAgB,MAEA,GAAAC,GAAAvG,KAAAyG,OAAAnB,EAAAgB,MAAA,OAEA,IAAAC,GAAAjB,EAAAgB,KAAA,EAaA,KAAA,GAPAlD,GAAApD,KAAA2B,SAAAyB,GACA+D,EAAAnH,KAAAmH,QAAAC,UAAA,SAAAlH,GAAA,OAAAA,EAAAmH,WACAC,EAAAtH,KAAAsH,QACAoB,EAAApB,EAAAtG,OAGA2H,KACAhI,EAAA,EAAA+H,EAAA/H,EAAAA,IACAgI,EAAArB,EAAA3G,GAAAqG,MAAArG,CAQA,KAAA,GAJAiI,MACAC,KACAC,KAEAnI,EAAA,EAAA+H,EAAA/H,EAAAA,IACA2G,EAAA3G,GAAAqG,OAAAT,EAAAS,KACA4B,EAAAjI,GAAA,EAEAiI,EAAAjI,GAAAoI,EAAAA,EAEAF,EAAAlI,GAAAmD,MAKA,KAAA,GADAkF,IAAA,EACArI,EAAA,EAAA+H,EAAA/H,EAAAA,IAAA,CACAqI,GAAA,CACA,KAAA,GAAA9I,GAAA,EAAAA,EAAAiH,EAAAnG,OAAAd,IAAA,CACA,GAAA+I,GAAAN,EAAAxB,EAAAjH,GAAAqG,SAAAS,MACAkC,EAAAP,EAAAxB,EAAAjH,GAAAqB,SAAAyF,MACAJ,EAAAC,EAAArD,MAAA2D,EAAAjH,IAAAiH,EAAAjH,KAEAiJ,EAAAP,EAAAK,GAAArC,CASA,IARAuC,EAAAP,EAAAM,KACAN,EAAAM,GAAAC,EACAN,EAAAK,GAAAD,EACAH,EAAAI,GAAA/B,EAAAjH,GACA8I,GAAA,IAIAlC,EAAA,CACA,GAAAqC,GAAAP,EAAAM,GAAAtC,CACAuC,GAAAP,EAAAK,KACAL,EAAAK,GAAAE,EACAN,EAAAI,GAAAC,EACAJ,EAAAG,GAAA9B,EAAAjH,GACA8I,GAAA,IAKA,IAAAA,EACA,MAIA,GAAAA,EAEA,IAAA,GAAA9I,GAAA,EAAAA,EAAAiH,EAAAnG,OAAAd,IAAA,CACA,GAAA+I,GAAAN,EAAAxB,EAAAjH,GAAAqG,SAAAS,MACAkC,EAAAP,EAAAxB,EAAAjH,GAAAqB,SAAAyF,MACAJ,EAAAC,EAAArD,MAAA2D,EAAAjH,IAAAiH,EAAAjH,IAEA,IAAA0I,EAAAK,GAAArC,EAAAgC,EAAAM,GAEA,MADA/H,GAAAiI,MAAA,4DACAC,OAAAvF,OACAwF,WAAAxF,OACAyF,wBAAA,GAOA,IAAA,GADAC,MACA7I,EAAA,EAAA+H,EAAA/H,EAAAA,IACA6I,EAAA/G,KAAA6E,EAAA3G,GAAAqG,KAIA,IAAAyC,IACAH,WAAA,SAAAI,GACA,GAAAtI,EAAAoF,OAAAkD,GAEA,GAAAC,GAAAvG,EAAAqD,OAAAiD,GAAA,GAAA1C,SAGA,IAAA2C,GAAAD,EAAA1C,IAGA,OAAA4B,GAAAD,EAAAgB,KAGAN,OAAA,SAAAK,GAEA,GAAAE,GAAA,SAAAf,EAAAgB,EAAAC,EAAAN,EAAAO,EAAAjB,GACA,OAAA,CAKA,GAHAiB,EAAAtH,KAAAW,EAAAyC,eAAA2D,EAAAM,KACAC,EAAAtH,KAAAqG,EAAAgB,IAEAD,IAAAC,EAEA,MAAAC,EAIA,IAAAC,GAAAnB,EAAAiB,EACA,IAAA,mBAAAE,GACA,MAAAlG,OAGAgG,GAAAE,GAKA,IAAA5I,EAAAoF,OAAAkD,GAEA,GAAAC,GAAAvG,EAAAqD,OAAAiD,GAAA,GAAA1C,SAGA,IAAA2C,GAAAD,EAAA1C,IAEA,IAAAY,MAGA6B,EAAAG,EAAAf,EACAF,EAAApC,EAAAS,MACA2B,EAAAgB,GACAH,EACA5B,EACAkB,EC7LA,ODgMA,OAAAW,GFqbUA,EAAIvF,UGrnBdqB,EAAAsC,MAAA4B,IAGAF,wBAAA,EAGA,OAAAE,IAMAhK,GAAAD,QAAA4F,IAEAmD,WAAA,GAAA0B,aAAA,KAAAC,GAAA,SAAAhJ,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,YAEAkE,GAGA+E,sBAAA,SAAA7E,GAIA,GAHAA,EAAAA,MAGA,MAAAA,EAAAsB,QAAAxF,EAAAoB,GAAA8C,EAAAsB,QACA,GAAAC,GAAAvB,EAAAsB,OACAwD,GAAA,MAEA,IAAAA,IAAA,CAIA,IAAA,MAAA9E,EAAAwB,UAAA1F,EAAAiJ,KAAA/E,EAAAwB,UACA,GAAAA,GAAAxB,EAAAwB,aAEA,IAAAA,IAAA,CAoBA,KAAA,GAjBAwD,GAAA,SAAArH,EAAAgF,GACAhF,EAAAsH,QAAAtC,EACA,KAAA,GAAAtH,GAAA,EAAA6J,EAAAvH,EAAAtC,IAAA6J,EAAAvH,EAAAtC,EAAA,KAAAA,EAAAsC,EAAAjC,OAAA,EAAAL,IAAA,CACA,GAAA8J,GAAAxH,EAAAtC,EACAsC,GAAAtC,GAAAsC,EAAAtC,EAAA,GACAsC,EAAAtC,EAAA,GAAA8J,IAIArH,EAAApD,KAAA2B,SAAAyB,GAGAsH,EAAA1K,KAAAsH,QACAqD,KACAC,KAGAjK,EAAA,EAAAA,EAAA+J,EAAA1J,OAAAL,IACAmG,EACA6D,EAAAD,EAAA/J,GAAAqG,MAAA0D,EAAA/J,GAAAkK,SAAA,QAEAF,EAAAD,EAAA/J,GAAAqG,MAAA0D,EAAA/J,GAAAmK,iBAAA,OAKA,KAAA,GAAAnK,GAAA,EAAAA,EAAA+J,EAAA1J,OAAAL,IACAiK,EAAAF,EAAA/J,GAAAqG,MAAA,CAGA,KAAA,GAAA1G,GAAA,EAAAA,EAAAoK,EAAA1J,OAAAV,IAAA,CAQA,IAAA,GAPAyK,MACAC,KACApL,KACA4K,KACAS,KAGAtK,EAAA,EAAAA,EAAA+J,EAAA1J,OAAAL,IACAqK,EAAAN,EAAA/J,GAAAqG,SACApH,EAAA8K,EAAA/J,GAAAqG,MAAA,EACAwD,EAAAE,EAAA/J,GAAAqG,MAAAkE,OAAAC,iBAQA,KALAvL,EAAA8K,EAAApK,GAAA0G,MAAA,EACAwD,EAAAE,EAAApK,GAAA0G,MAAA,EAEAiE,EAAAV,QAAAG,EAAApK,GAAA0G,MAEAiE,EAAAjK,OAAA,GAAA,CACA,GAAAoK,GAAAH,EAAAI,KACAN,GAAAtI,KAAA2I,GACAhB,EACAO,EAAAS,GAAAE,QAAA,SAAAlD,GACA,GAAAhF,EAAAmI,EAAA,IAAAH,GAAAI,QAAApD,GAAApH,OAAA,EACA,GAAAyK,GAAArI,EAAAmI,EAAA,IAAAH,GAAAI,QAAApD,GAAA,OAEA,IAAAqD,GAAArD,EAAAoD,QAAA,IAAAJ,GAAA,EAGA,IAAAM,GAAA7E,EAAArD,MAAAiI,GAAAA,GAEAjB,GAAApC,EAAApB,MAAAwD,EAAAY,GAAAM,IACAlB,EAAApC,EAAApB,MAAAwD,EAAAY,GAAAM,EACAT,EAAA3C,QAAAF,EAAApB,MAAA,EACAsD,EAAAW,EAAA7C,EAAApB,OAEAiE,EAAAnD,OAAAmD,EAAA3C,QAAAF,EAAApB,MAAA,GACAsD,EAAAW,EAAA7C,EAAApB,OAEApH,EAAAwI,EAAApB,MAAA,EACAgE,EAAA5C,EAAApB,UAEAwD,EAAApC,EAAApB,OAAAwD,EAAAY,GAAAM,IACA9L,EAAAwI,EAAApB,MAAApH,EAAAwI,EAAApB,MAAApH,EAAAwL,GACAJ,EAAA5C,EAAApB,MAAAvE,KAAA2I,MAIAT,EAAAS,GAAAE,QAAA,SAAAlD,GACAoC,EAAApC,EAAApB,OAAAkE,OAAAC,oBACAF,EAAAV,QAAAnC,EAAApB,MACAwD,EAAApC,EAAApB,MAAAwD,EAAAY,GAAA,GAEAZ,EAAApC,EAAApB,OAAAwD,EAAAY,GAAA,IACAxL,EAAAwI,EAAApB,MAAApH,EAAAwI,EAAApB,MAAApH,EAAAwL,GACAJ,EAAA5C,EAAApB,MAAAvE,KAAA2I,MAOA,IAAA,GADAlL,MACAS,EAAA,EAAAA,EAAA+J,EAAA1J,OAAAL,IACAT,EAAAwK,EAAA/J,GAAAqG,MAAA,CAGA,MAAA+D,EAAA/J,OAAA,GAAA,CACA,GAAAoH,GAAA2C,EAAAM,KACAL,GAAA5C,GAAAkD,QAAA,SAAAF,GACAlL,EAAAkL,GAAAlL,EAAAkL,GAAAxL,EAAAwL,GAAAxL,EAAAwI,IAAA,EAAAlI,EAAAkI,IACAA,GAAAsC,EAAApK,GAAA0G,OACA4D,EAAAxC,GAAAwC,EAAAxC,GAAAlI,EAAAkI,OAKA,GAAAuD,GAAA,CACA,KAAA,GAAAC,KAAAhB,GACAe,EAAAf,EAAAgB,KACAD,EAAAf,EAAAgB,GAGA,IAAAC,IACAC,YAAA,SAAAC,GACA,GAAA3K,EAAAoF,OAAAuF,GACA,GAAAA,GAAA3I,EAAAqD,OAAAsF,GAAA,GAAA/E,SAEA,IAAA+E,GAAAA,EAAA/E,IAGA,OAAA4D,GAAAmB,IAGAC,sBAAA,SAAAD,GACA,GAAA3K,EAAAoF,OAAAuF,GACA,GAAAA,GAAA3I,EAAAqD,OAAAsF,GAAA,GAAA/E,SAEA,IAAA+E,GAAAA,EAAA/E,IH2nBQ,OAAO4D,GAAEmB,GAAQJ,GI/xBzB,OAFAE,GAAAI,sBAAAJ,EAAAG,sBAEAH,GAMAzG,GAAA8G,GAAA9G,EAAA+E,sBAEA1K,EAAAD,QAAA4F,IAEAmD,WAAA,KAAA4D,GAAA,SAAAjL,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,YACAkL,EAAAlL,EAAA,cAEAmL,EAAA,SAAAC,GAOA,MANAA,IACAC,IAAAD,EAAAC,MAAAD,EAAAE,IACAA,IAAAF,EAAAE,MAAAF,EAAAC,KAIA,SAAAE,EAAAjK,EAAAsE,GACA,GAAAxB,GACAoH,EACAC,CACAvL,GAAAwL,YAAAH,KAAArL,EAAA+B,oBAAAsJ,KACAnH,EAAAmH,EACAA,EAAAnH,EAAAmH,OAAAnH,EAAAgB,KACA9D,EAAA8C,EAAAuH,MACA/F,EAAAxB,EAAAwB,SACA4F,EAAApH,EAAAoH,IACAC,EAAArH,EAAAqH,SAGA7F,EAAA,IAAAgG,UAAA9L,QAAAI,EAAAoB,GAAAA,GAAAsE,EAAAtE,EACAA,EAAApB,EAAAoB,GAAAA,GAAAA,EAAA,YAeA,KAAA,GALAkF,GARAtE,EAAApD,KAAA2B,SAAAyB,GACAgI,EAAAqB,EAAArL,EAAAoF,OAAAiG,GAAAzM,KAAAyG,OAAAgG,GAAAA,EACAxB,KACA5C,KACA0E,KACAC,KACAtC,KACAuC,EAAA,EAEA3F,EAAAtH,KAAAsH,QACAH,EAAAnH,KAAAmH,QAGAxG,EAAA,EAAAA,EAAAyK,EAAApK,OAAAL,IACAyK,EAAAzK,GAAAuM,WACAjC,EAAAV,QAAAa,EAAAzK,IAEA2L,EAAAC,MACA7B,EAAAU,EAAAzK,GAAAqG,OAAA,EAEAqB,EAAA5F,KAAA2I,EAAAzK,KAGAqM,EAAA5B,EAAAzK,GAAAqG,MAAA,EAIA,MAAA,IAAAiE,EAAAjK,QAAA,CACA,GAAAoK,GAAAkB,EAAAC,IAAAtB,EAAAkC,QAAAlC,EAAAI,KAEA,IAAAiB,EAAAE,IAAA,CACA,GAAA9B,EAAAU,EAAApE,MAAA,QAEA0D,GAAAU,EAAApE,OAAA,EAEAqB,EAAA5F,KAAA2I,GAGA,GAGAS,GAHAuB,EAAAJ,EAAA5B,EAAApE,MACAqG,EAAAN,EAAA3B,EAAApE,MACAsG,EAAA,MAAAD,EAAAvJ,OAAAuJ,EAAAhF,iBAAAkF,IAAAnC,GAAA,EASA,IALAS,EADAa,EACAlK,EAAAzB,KAAA4L,EAAAvB,EAAAiC,EAAAC,EAAAL,IAAAG,GAEA5K,EAAAzB,KAAAqK,EAAA6B,IAAAG,EAAAhC,EAAAiC,EAAAC,GAGAzB,KAAA,EAAA,CACAnE,EAAA0D,CACA,OAGA,GAAAS,KAAA,EACA,KAIA,KAAA,GADA9D,GAAAqD,EAAApD,eAAAlB,EAAA,WAAA,MAAA9G,MAAAkI,KAAA,YAAAkD,EAAApE,MAAAlD,QAAAqE,UAAAhB,GACAxG,EAAA,EAAAA,EAAAoH,EAAA/G,OAAAL,IAAA,CACA,GAAAT,GAAA6H,EAAApH,GACAyH,EAAAlI,EAAAmI,eAAA,WAAA,MAAArI,MAAAgH,OAAAoE,EAAApE,OAAAmB,UAAAb,EAEA,KAAAc,EAAApH,QAAA0J,EAAAtC,EAAApB,QACAoB,EAAAA,EAAA,GAEA6C,EAAAxI,KAAA2F,GAEAkE,EAAAC,MACA7B,EAAAtC,EAAApB,OAAA,EAEAqB,EAAA5F,KAAA2F,IAGA2E,EAAA3E,EAAApB,MAAA9G,EAEA8M,EAAA5E,EAAApB,MAAAgG,EAAA5B,EAAApE,MAAA,IAQA,IAAA,GAFAwG,MAEA7M,EAAA,EAAAA,EAAA0H,EAAArH,OAAAL,IAAA,CACA,GAAAoL,GAAA1D,EAAA1H,GACA8K,EAAAsB,EAAAhB,EAAA/E,KAEAyE,IACA+B,EAAA/K,KAAAgJ,GAGA+B,EAAA/K,KAAAsJ,GAGA,OACAnE,KAAAxE,EAAAqK,WAAAD,GAAAE,QAAA,IACAhG,MAAAtE,EAAAqK,WAAA/F,MAMAtC,GAEAuI,mBAAAtB,GAAAE,KAAA,IACAqB,iBAAAvB,GAAAG,KAAA,IAIAqB,QAAA,SAAAhH,GAKA,QAAAiH,GAAA7F,GACA,IAAA,GAAAtH,GAAA,EAAAA,EAAAoN,EAAA/M,OAAAL,IAAA,CACA,GAAA4E,GAAAwI,EAAApN,EAEA,IAAA4E,EAAAyI,QAAA/F,GACA,OACA1C,KAAAA,EACA0I,MAAAtN,IAXA,GAAAyC,GAAApD,KAAAoD,IAEAyD,GAAAzF,EAAAoB,GAAAqE,GAAAA,EAAA,WAAA,MAAA,GAmBA,KAAA,GAJA8D,GAAAvH,EAAAqK,WAAArK,MACA2K,KACAzG,EAAAtH,KAAAsH,QAEA3G,EAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IACAoN,EAAAtL,KAAA6E,EAAA3G,GAAA8M,aAWA,KAAA,GARAtG,GAAAnH,KAAAmH,QACA4D,EAAA5D,EAAA+G,UAAAC,KAAA,SAAA1N,EAAA2D,GACA,GAAAgK,GAAAvH,EAAA9F,KAAAN,EAAAA,GACA4N,EAAAxH,EAAA9F,KAAAqD,EAAAA,EAEA,OAAAgK,GAAAC,IAGA1N,EAAA,EAAAA,EAAAoK,EAAA/J,OAAAL,IAAA,CACA,GAAA8K,GAAAV,EAAApK,GACAH,EAAAiL,EAAAlF,SAAA,GACA6E,EAAAK,EAAAlK,SAAA,GACA+M,EAAAR,EAAAtN,GACA+N,EAAAT,EAAA1C,EAEAkD,GAAAL,QAAAM,EAAAN,QACAtD,EAAAA,EAAA6D,IAAA/C,GAGAsC,EAAAO,EAAAL,OAAAK,EAAA/I,KAAAiJ,IAAAD,EAAAhJ,MACAwI,EAAAjG,OAAAyG,EAAAN,MAAA,IAIA,MAAA3G,GAAAkH,IAAA7D,IAIA8D,SAAA,SAAAnI,EAAAO,EAAAC,GACA,GAAAxB,EACAlE,GAAAwL,YAAAtG,KAAAlF,EAAA+B,oBAAAmD,KACAhB,EAAAgB,EACAA,EAAAhB,EAAAgB,KACAO,EAAAvB,EAAAsB,OACAE,EAAAxB,EAAAwB,SAGA,IAAA1D,GAAApD,KAAA2B,SAAAyB,EACAyD,GAAAzF,EAAAoB,GAAAqE,GAAAA,EAAA,WAAA,MAAA,GAwBA,KAAA,GAtBAN,GAAAnF,EAAAoF,OAAAF,GAAAtG,KAAAyG,OAAAH,GAAA,GAAAA,EAAA,GACAoI,KACAC,KACAC,KAEAzH,EAAAnH,KAAAmH,QAAAV,OAAA,WAAA,OAAAzG,KAAAqH,WACAC,EAAAtH,KAAAsH,QAEAuH,EAAA,SAAA9C,GACA,MAAA2C,GAAA3C,EAAA/E,OAGA8H,EAAA,SAAA/C,EAAAvB,GACAkE,EAAA3C,EAAA/E,MAAAwD,EAEAS,EAAA8D,WAAAhD,IAGAd,EAAA,GAAAmB,GAAA,SAAA3L,EAAA2D,GACA,MAAAyK,GAAApO,GAAAoO,EAAAzK,KAGAzD,EAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IAAA,CACA,GAAAoL,GAAAzE,EAAA3G,EAEA+N,GAAA3C,EAAA/E,MAAA+E,EAAAiD,KAAAzI,GAAA,EAAAwC,EAAAA,EACAkC,EAAAxI,KAAAsJ,GAwBA,IArBA,GAAAkD,GAAA,SAAAzO,EAAA4K,GAKA,IAAA,GAFA8D,GAFAC,GAAArI,EAAAtG,EAAAgL,QAAAJ,GAAA5K,EAAA4O,UAAAhE,IAAAjD,UAAAhB,GACAkI,EAAAtG,EAAAA,EAGApI,EAAA,EAAAA,EAAAwO,EAAAnO,OAAAL,IAAA,CACA,GAAA8K,GAAA0D,EAAAxO,GACAiG,EAAAC,EAAArD,MAAAiI,GAAAA,KAEA4D,EAAAzI,IAAAsI,KACAG,EAAAzI,EACAsI,EAAAzD,GAIA,OACAA,KAAAyD,EACAR,KAAAW,IAIApE,EAAAqE,OAAA,GAAA,CACA,GAAA9O,GAAAyK,EAAAI,MACAkE,EAAAV,EAAArO,GACAgP,EAAAhP,EAAAwG,IAIA,IAFA4H,EAAAY,GAAAD,EAEAA,IAAAE,KAAAC,SACA,KAIA,KAAA,GADAC,GAAAnP,EAAAoP,eAAAzH,UAAAb,GACA3G,EAAA,EAAAA,EAAAgP,EAAA3O,OAAAL,IAAA,CACA,GAAAyK,GAAAuE,EAAAhP,GACAkP,EAAAzE,EAAApE,KACA8I,EAAAb,EAAAzO,EAAA4K,GAEA2E,EAAAR,EAAAO,EAAApB,IAEAqB,GAAAlB,EAAAzD,KACA0D,EAAA1D,EAAA2E,GAEApB,EAAAkB,IACA9D,KAAAvL,EACAiL,KAAAqE,EAAArE,QAMA,OACAnC,WAAA,SAAAyC,GACA,GAAAxK,GAAAH,EAAAoF,OAAAuF,GAAAzE,EAAAb,OAAAsF,GAAA,GAAAA,EAAA,EAEA,OAAA6C,GAAArN,EAAAyF,OAGAqC,OAAA,SAAA0C,GACA,GAAAxK,GAAAH,EAAAoF,OAAAuF,GAAAzE,EAAAb,OAAAsF,GAAA,GAAAA,EAAA,GACAhB,KACAvK,EAAAe,CAEA,IAAAA,EAAAP,OAAA,EAGA,IAFA+J,EAAAR,QAAAhJ,GAEAoN,EAAAnO,EAAAwG,OAAA,CACA,GAAAjD,GAAA4K,EAAAnO,EAAAwG,KAEA+D,GAAAR,QAAAxG,EAAA0H,MACAV,EAAAR,QAAAxG,EAAAgI,MChUAvL,EAAAuD,EAAAgI,KAIA,MAAA3I,GAAAqK,WAAA1C,MAOA3F,GAAAmH,IAAAnH,EAAAuI,mBACAvI,EAAAoH,IAAApH,EAAAwI,iBAEAnO,EAAAD,QAAA4F,IAEA4K,aAAA,GAAAzH,WAAA,KAAA0H,GAAA,SAAA/O,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,YAEAkE,GAEA8K,8BAAA,SAAA5K,GACAA,EAAAA,KAEA,IAAAlC,GAAApD,KAAAoD,KAEA+M,EAAA7K,EAAA6K,QACArM,UAAAqM,IACAA,GAAA,EASA,KAAA,GANAC,MACAC,EAAA,EACA/I,EAAAtH,KAAAsH,QACAgJ,EAAAtQ,KAAAuQ,eAAA3J,OAAAtB,EAAAsB,OAAAE,SAAAxB,EAAAwB,WAGAnG,EAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IAAA,CAEA,IAAA,GADA6P,GAAA,EACAvD,EAAA,EAAAA,EAAA3F,EAAAtG,OAAAiM,IACA,GAAAtM,GAAAsM,EAAA,CACA,GAAAzC,GAAA8F,EAAA3I,SAAAL,EAAA3G,GAAA2G,EAAA2F,GAGAuD,IADAL,EACA,EAAA3F,EAEAA,EAKA2F,IACAK,EAAA,EAAAA,GAGAA,EAAAH,IACAA,EAAAG,GAGAJ,EAAA9I,EAAA3G,GAAAqG,MAAAwJ,EAGA,OACAC,UAAA,SAAA1E,GACA,GAAA3K,EAAAoF,OAAAuF,GAEA,GAAAA,GAAA3I,EAAAqD,OAAAsF,GAAA,GAAA/E,SAGA,IAAA+E,GAAAA,EAAA/E,IAGA,OAAAoJ,GAAArE,GAAAsE,KAMAK,oBAAA,SAAApL,GAIA,GAHAA,EAAAA,MAGA,MAAAA,EAAAgB,KAQA,MAAAxC,OAPA,IAAA1C,EAAAoF,OAAAlB,EAAAgB,MAEA,GAAAA,GAAAtG,KAAAyG,OAAAnB,EAAAgB,MAAA,OAEA,IAAAA,GAAAhB,EAAAgB,KAAA,EAOA,IAAA,MAAAhB,EAAAsB,QAAAxF,EAAAoB,GAAA8C,EAAAsB,QACA,GAAAA,GAAAtB,EAAAsB,WAEA,IAAAA,GAAA,WAAA,MAAA,GAIA,IAAA,MAAAtB,EAAAwB,UAAA1F,EAAAiJ,KAAA/E,EAAAwB,UACA,GAAAA,GAAAxB,EAAAwB,aAEA,IAAAA,IAAA,CAGA,IAAAqJ,GAAA7K,EAAA6K,QACArM,UAAAqM,IACAA,GAAA,EAYA,KAAA,GARA1B,GAAAzO,KAAAyO,UACAnI,KAAAA,EACAM,OAAAA,EACAE,SAAAA,IAEA6J,EAAA,EAEArJ,EAAAtH,KAAAsH,QACA3G,EAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IACA,GAAA2G,EAAA3G,GAAAqG,MAAAV,EAAAU,KAAA,CACA,GAAAwD,GAAAiE,EAAAnF,WAAAhC,EAAA3G,GAGAgQ,IADAR,EACA,EAAA3F,EChIAA,EAKA,MAAA2F,GAAAQ,EAAA,EAAAA,GAMAvL,GAAAwL,GAAAxL,EAAAsL,oBACAtL,EAAAyL,IAAAzL,EAAA0L,8BAAA1L,EAAA8K,8BAEAzQ,EAAAD,QAAA4F,IAEAmD,WAAA,KAAAwI,GAAA,SAAA7P,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,YACAC,EAAAD,EAAA,cAEAkE,GAEA4L,2BAAA,SAAA1L,GACAA,EAAAA,KAEA,IAAAlC,GAAApD,KAAAoD,IAGA,IAAA,MAAAkC,EAAAwB,SACA,GAAAA,GAAAxB,EAAAwB,aAEA,IAAAA,IAAA,CAGA,IAAAQ,GAAAtH,KAAAsH,QACAoB,EAAApB,EAAAtG,MAEA,IAAA8F,EA2BA,CAMA,IAAA,GALAmK,MACAC,KACAC,EAAA,EACAC,EAAA,EAEAzQ,EAAA,EAAA+H,EAAA/H,EAAAA,IAAA,CACA,GAAAoL,GAAAzE,EAAA3G,GAEA0Q,EAAArR,KAAAsR,iBAAAnQ,EAAAS,UAAA0D,GAAAgB,KAAAyF,IAEAoF,GAAAE,EAAAE,WACAJ,EAAAE,EAAAE,UAEAH,EAAAC,EAAAG,YACAJ,EAAAC,EAAAG,WAEAP,EAAAlF,EAAA/E,MAAAqK,EAAAE,SACAL,EAAAnF,EAAA/E,MAAAqK,EAAAG,UAGA,OACAD,SAAA,SAAAxF,GACA,GAAA3K,EAAAoF,OAAAuF,GAEA,GAAAA,GAAA3I,EAAAqD,OAAAsF,GAAA,GAAA/E,SAGA,IAAA+E,GAAAA,EAAA/E,IAGA,OAAAiK,GAAAlF,GAAAoF,GAEAK,UAAA,SAAAzF,GACA,GAAA3K,EAAAoF,OAAAuF,GAEA,GAAAA,GAAA3I,EAAAqD,OAAAsF,GAAA,GAAA/E,SAGA,IAAA+E,GAAAA,EAAA/E,IAGA,OAAAkK,GAAAnF,GAAAqF,IAjEA,IAAA,GAHAK,MACAC,EAAA,EAEA/Q,EAAA,EAAA+H,EAAA/H,EAAAA,IAAA,CACA,GAAAoL,GAAAzE,EAAA3G,GAEA0Q,EAAArR,KAAAsR,iBAAAnQ,EAAAS,UAAA0D,GAAAgB,KAAAyF,IACA2F,GAAAL,EAAAM,SACAD,EAAAL,EAAAM,QAEAF,EAAA1F,EAAA/E,MAAAqK,EAAAM,OAGA,OACAA,OAAA,SAAA5F,GACA,GAAA3K,EAAAoF,OAAAuF,GAEA,GAAAA,GAAA3I,EAAAqD,OAAAsF,GAAA,GAAA/E,SAGA,IAAA+E,GAAAA,EAAA/E,IAGA,OAAAyK,GAAA1F,GAAA2F,KAwDAJ,iBAAA,SAAAhM,GACAA,EAAAA,KAEA,IAAAsM,GAAA5R,IAGA,IAAA,MAAAsF,GAAA,MAAAA,EAAAgB,KAGA,MAAAxC,OAFA,IAAAwC,GAAAlF,EAAAoF,OAAAlB,EAAAgB,MAAAtG,KAAAyG,OAAAnB,EAAAgB,MAAA,GAAAhB,EAAAgB,KAAA,EAMA,IAAA,MAAAhB,EAAAsB,QAAAxF,EAAAoB,GAAA8C,EAAAsB,QACA,GAAAC,GAAAvB,EAAAsB,WAGA,IAAAC,GAAA,SAAA3G,GACA,MAAA,GAKA,IAAA,MAAAoF,EAAAwB,SACA,GAAAA,GAAAxB,EAAAwB,aAEA,IAAAA,IAAA,CAIA,IAAA,MAAAxB,EAAAuM,OAAAzQ,EAAA0Q,OAAAxM,EAAAuM,OACA,GAAAA,GAAAvM,EAAAuM,UAEAA,GAAA,CAIA,IAAA/K,EAcA,CASA,IAAA,GARAiL,GAAAzL,EAAA0B,eAAA,kBAAA1B,EAAAU,KAAA,MAAAgL,aAAAJ,GACAK,EAAA3L,EAAA0B,eAAA,kBAAA1B,EAAAU,KAAA,MAAAgL,aAAAJ,GACAM,EAAAH,EAAA/Q,OACAmR,EAAAF,EAAAjR,OACAoR,EAAA,EACAC,EAAA,EAGA1R,EAAA,EAAAA,EAAAoR,EAAA/Q,OAAAL,IAAA,CACA,GAAA8K,GAAAsG,EAAApR,EACAyR,IAAAvL,EAAArD,MAAAiI,GAAAA,IAIA,IAAA,GAAA9K,GAAA,EAAAA,EAAAsR,EAAAjR,OAAAL,IAAA,CACA,GAAA8K,GAAAwG,EAAAtR,EACA0R,IAAAxL,EAAArD,MAAAiI,GAAAA,IC1LA,OACA8F,SAAA9B,KAAA6C,IAAAJ,EAAA,EAAAL,GAAApC,KAAA6C,IAAAF,EAAAP,GACAL,UAAA/B,KAAA6C,IAAAH,EAAA,EAAAN,GAAApC,KAAA6C,IAAAD,EAAAR,ID+JA,IAAA,GALAU,GAAAjM,EAAA0B,iBAAAgK,aAAAJ,GACAY,EAAAD,EAAAvR,OACAV,EAAA,EAGAK,EAAA,EAAAA,EAAA4R,EAAAvR,OAAAL,IAAA,CACA,GAAA8K,GAAA8G,EAAA5R,EACAL,IAAAuG,EAAArD,MAAAiI,GAAAA,IAGA,OACAkG,OAAAlC,KAAA6C,IAAAE,EAAA,EAAAX,GAAApC,KAAA6C,IAAAhS,EAAAuR,KC7JAzM,GAAAqN,GAAArN,EAAAkM,iBACAlM,EAAAsN,IAAAtN,EAAAuN,2BAAAvN,EAAA4L,2BAEAvR,EAAAD,QAAA4F,IAEAmD,WAAA,GAAA0B,aAAA,KAAA2I,GAAA,SAAA1R,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,YAEAkE,GAGAmL,cAAA,SAAAjL,GACAA,EAAAA,KAEA,IAAAlC,GAAApD,KAAAoD,IAGA,IAAA,MAAAkC,EAAAsB,QAAAxF,EAAAoB,GAAA8C,EAAAsB,QACA,GAAAC,GAAAvB,EAAAsB,WAGA,IAAAC,GAAA,SAAA3G,GAAA,MAAA,GAIA,IAAA,MAAAoF,EAAAwB,SACA,GAAAA,GAAAxB,EAAAwB,aAEA,IAAAA,IAAA,CASA,KAAA,GANAK,GAAAnH,KAAAmH,QAAAC,UAAA,SAAAlH,GAAA,OAAAA,EAAAmH,WACAC,EAAAtH,KAAAsH,QACAoB,EAAApB,EAAAtG,OAGA2H,KACAhI,EAAA,EAAA+H,EAAA/H,EAAAA,IACAgI,EAAArB,EAAA3G,GAAAqG,MAAArG,CAKA,KAAA,GADA+N,MACA/N,EAAA,EAAA+H,EAAA/H,EAAAA,IAAA,CAEA,IAAA,GADAkS,GAAA,GAAAC,OAAApK,GACAuE,EAAA,EAAAvE,EAAAuE,EAAAA,IACAtM,GAAAsM,EACA4F,EAAA5F,GAAA,EAEA4F,EAAA5F,GAAAlE,EAAAA,CAGA2F,GAAAjM,KAAAoQ,GAKA,GAAAE,MACAC,KAEAC,EAAA,SAAAF,GACA,IAAA,GAAApS,GAAA,EAAA+H,EAAA/H,EAAAA,IAAA,CAEA,IAAA,GADAkS,GAAA,GAAAC,OAAApK,GACAuE,EAAA,EAAAvE,EAAAuE,EAAAA,IACA4F,EAAA5F,GAAAnJ,MAEAiP,GAAAtQ,KAAAoQ,IAIAI,GAAAF,GACAE,EAAAD,EAGA,KAAA,GAAArS,GAAA,EAAAA,EAAAwG,EAAAnG,OAAAL,IAAA,CACA,GAAAsI,GAAAN,EAAAxB,EAAAxG,GAAA4F,SAAAS,MACAkC,EAAAP,EAAAxB,EAAAxG,GAAAY,SAAAyF,MACAJ,EAAAC,EAAArD,MAAA2D,EAAAxG,IAAAwG,EAAAxG,IAGA+N,GAAAzF,GAAAC,GAAAtC,IACA8H,EAAAzF,GAAAC,GAAAtC,EACAmM,EAAA9J,GAAAC,GAAAA,EACA8J,EAAA/J,GAAAC,GAAA/B,EAAAxG,IAKA,IAAAmG,EACA,IAAA,GAAAnG,GAAA,EAAAA,EAAAwG,EAAAnG,OAAAL,IAAA,CACA,GAAAsI,GAAAN,EAAAxB,EAAAxG,GAAAY,SAAAyF,MACAkC,EAAAP,EAAAxB,EAAAxG,GAAA4F,SAAAS,MACAJ,EAAAC,EAAArD,MAAA2D,EAAAxG,IAAAwG,EAAAxG,IAGA+N,GAAAzF,GAAAC,GAAAtC,IACA8H,EAAAzF,GAAAC,GAAAtC,EACAmM,EAAA9J,GAAAC,GAAAA,EACA8J,EAAA/J,GAAAC,GAAA/B,EAAAxG,IAMA,IAAA,GAAA6R,GAAA,EAAA9J,EAAA8J,EAAAA,IACA,IAAA,GAAA7R,GAAA,EAAA+H,EAAA/H,EAAAA,IACA,IAAA,GAAAsM,GAAA,EAAAvE,EAAAuE,EAAAA,IACAyB,EAAA/N,GAAA6R,GAAA9D,EAAA8D,GAAAvF,GAAAyB,EAAA/N,GAAAsM,KACAyB,EAAA/N,GAAAsM,GAAAyB,EAAA/N,GAAA6R,GAAA9D,EAAA8D,GAAAvF,GACA8F,EAAApS,GAAAsM,GAAA8F,EAAApS,GAAA6R,GAQA,KAAA,GADAhJ,MACA7I,EAAA,EAAA+H,EAAA/H,EAAAA,IACA6I,EAAA/G,KAAA6E,EAAA3G,GAAAqG,KAGA,IAAAyC,IACA9B,SAAA,SAAAuL,EAAAxJ,GACA,GAAAtI,EAAAoF,OAAA0M,GAEA,GAAAC,GAAA/P,EAAAqD,OAAAyM,GAAA,GAAAlM,SAGA,IAAAmM,GAAAD,EAAAlM,IAGA,IAAA5F,EAAAoF,OAAAkD,GAEA,GAAAC,GAAAvG,EAAAqD,OAAAiD,GAAA,GAAA1C,SAGA,IAAA2C,GAAAD,EAAA1C,IAGA,OAAA0H,GAAA/F,EAAAwK,IAAAxK,EAAAgB,KAGA/B,KAAA,SAAAsL,EAAAxJ,GACA,GAAAE,GAAA,SAAAsJ,EAAAxJ,EAAAqJ,EAAAvJ,EAAAwJ,GACA,GAAAE,IAAAxJ,EACA,MAAAtG,GAAAyC,eAAA2D,EAAA0J,GAEA,IAAApP,SAAAiP,EAAAG,GAAAxJ,GACA,MAAA5F,OAKA,KAFA,GAAA8D,IAAAxE,EAAAyC,eAAA2D,EAAA0J,KACAvE,EAAAuE,EACAA,IAAAxJ,GAAA,CACAiF,EAAAuE,EACAA,EAAAH,EAAAG,GAAAxJ,EAEA,IAAA+B,GAAAuH,EAAArE,GAAAuE,EACAtL,GAAAnF,KAAAgJ,GAEA7D,EAAAnF,KAAAW,EAAAyC,eAAA2D,EAAA0J,KAEA,MAAAtL,GAGA,IAAAxG,EAAAoF,OAAA0M,GAEA,GAAAC,GAAA/P,EAAAqD,OAAAyM,GAAA,GAAAlM,SAGA,IAAAmM,GAAAD,EAAAlM,IAGA,IAAA5F,EAAAoF,OAAAkD,GAEA,GAAAC,GAAAvG,EAAAqD,OAAAiD,GAAA,GAAA1C,SAGA,IAAA2C,GAAAD,EAAA1C,IAGA,IAAAoM,GAAAxJ,EAAAjB,EAAAwK,GPw6CsBxK,EAAYgB,GQ1mDlCoJ,EACAvJ,EACAwJ,EAEA,OAAA5P,GAAAqK,WAAA2F,IAIA,OAAA3J,IAMAhK,GAAAD,QAAA4F,IAEAmD,WAAA,KAAA8K,GAAA,SAAAnS,EAAAzB,EAAAD,GACA,YAEA,IAAA2B,GAAAD,EAAA,cAEAkE,MCpBAlE,EAAA,aACAA,EAAA,YACAA,EAAA,oBACAA,EAAA,kBACAA,EAAA,kBACAA,EAAA,eACAA,EAAA,uBACAA,EAAA,0BACAA,EAAA,6BACAoK,QAAA,SAAAgI,GACAnS,EAAAS,OAAAwD,EAAAkO,KAGA7T,EAAAD,QAAA4F,IAEA6E,aAAA,GAAAsJ,WAAA,EAAAC,iBAAA,EAAAC,2BAAA,EAAAC,YAAA,EAAAC,yBAAA,EAAAC,sBAAA,EAAAC,mBAAA,EAAAC,iBAAA,GAAAC,cAAA,KAAAC,IAAA,SAAA9S,EAAAzB,EAAAD,GACA,YAEA,IAAA2B,GAAAD,EAAA,cAEAkE,GAIA6O,YAAA,SAAA3O,GACA,GAAAC,GAAAvF,IAEAsF,GAAAA,KAKA,IAAA4O,GAAA,SAAAC,EAAAC,EAAAC,GAmBA,IAAA,GAlBAC,GAAAD,EAAAF,GACAI,EAAAD,EAAA,GACAE,EAAAF,EAAA,GACAG,EAAAL,EAAAG,GACAG,EAAAN,EAAAI,GAGAG,EAAAN,EAAA5N,OAAA,SAAAgF,GACA,MAAA2I,GAAA3I,EAAA,MAAAgJ,GAAAL,EAAA3I,EAAA,MAAAiJ,GACA,EAEAN,EAAA3I,EAAA,MAAAiJ,GAAAN,EAAA3I,EAAA,MAAAgJ,GACA,GAEA,IAIA9T,EAAA,EAAAA,EAAAgU,EAAA3T,OAAAL,IAAA,CACA,GAAA8K,GAAAkJ,EAAAhU,EACA8K,GAAA,KAAAiJ,GACAC,EAAAhU,GAAA8K,EAAAmJ,MAAA,GACAD,EAAAhU,GAAA,GAAA8T,GACAhJ,EAAA,KAAAiJ,IACAC,EAAAhU,GAAA8K,EAAAmJ,MAAA,GACAD,EAAAhU,GAAA,GAAA8T,GAKA,IAAA,GAAA9T,GAAA,EAAAA,EAAAyT,EAAApT,OAAAL,IACAyT,EAAAzT,KAAA+T,IACAN,EAAAzT,GAAA8T,EAIA,OAAAE,IAKAE,EAAA,SAAAC,EACAT,EACA/E,EACAyF,GAEA,GAAAA,GAAAzF,EACA,MAAA+E,EAIA,IAAAF,GAAA1E,KAAAuF,MAAAvF,KAAAwF,SAAAZ,EAAArT,QAGA2T,EAAAT,EAAAC,EAAAW,EAAAT,EAEA,OAAAQ,GAAAC,EACAH,EACArF,EAAA,EACAyF,IAGA3R,EAAApD,KAAA2B,SAAAyB,GACA+D,EAAAnH,KAAAmH,QAAAC,UAAA,SAAAlH,GAAA,OAAAA,EAAAmH,WACAC,EAAAtH,KAAAsH,QACAoB,EAAApB,EAAAtG,OACAkU,EAAA/N,EAAAnG,OACAmU,EAAA1F,KAAA2F,KAAA3F,KAAA6C,IAAA7C,KAAA4F,IAAA3M,GAAA+G,KAAA6F,IAAA,IACAC,EAAA9F,KAAAuF,MAAAtM,EAAA+G,KAAA+F,KAAA,GAEA,IAAA,EAAA9M,EAEA,WADAvH,GAAAiI,MAAA,2DAQA,KAAA,GADAT,MACAhI,EAAA,EAAA+H,EAAA/H,EAAAA,IACAgI,EAAArB,EAAA3G,GAAAqG,MAAArG,CAMA,KAAA,GADA8U,MACA9U,EAAA,EAAAuU,EAAAvU,EAAAA,IAAA,CACA,GAAAT,GAAAiH,EAAAxG,EACA8U,GAAAhT,MAAA9B,EAAAgI,EAAAzI,EAAAqG,SAAAS,MAAA2B,EAAAzI,EAAAqB,SAAAyF,QASA,IAAA,GAJA0O,GADAC,EAAA5M,EAAAA,EAIA6M,KACAjV,EAAA,EAAA+H,EAAA/H,EAAAA,IACAiV,EAAAnT,KAAA9B,EAIA,KAAA,GAAAkV,GAAA,EAAAV,GAAAU,EAAAA,IAAA,CAEA,GAAAf,GAAAc,EAAAhB,MAAA,GAGAkB,EAAAjB,EAAAC,EAAAW,EAAA/M,EAAA6M,GAGAQ,EAAAjB,EAAAF,MAAA,GAGAoB,EAAAnB,EAAAC,EAAAgB,EAAAP,EAAA,GACAU,EAAApB,EAAAkB,EAAAD,EAAAP,EAAA,EAGAS,GAAAhV,QAAAiV,EAAAjV,QAAAgV,EAAAhV,OAAA2U,GACAA,EAAAK,EAAAhV,OACA0U,GAAAM,EAAAlB,IACAmB,EAAAjV,QAAAgV,EAAAhV,QAAAiV,EAAAjV,OAAA2U,IACAA,EAAAM,EAAAjV,OACA0U,GAAAO,EAAAF,IAYA,IAAA,GANAG,GAAAR,EAAA,GAAAS,IAAA,SAAAjW,GAAA,MAAAiH,GAAAjH,EAAA,MACAuU,KACAC,KAGA0B,EAAAV,EAAA,GAAA,GACA/U,EAAA,EAAAA,EAAA+U,EAAA,GAAA1U,OAAAL,IAAA,CACA,GAAA0V,GAAAX,EAAA,GAAA/U,EACA0V,KAAAD,EACA3B,EAAAhS,KAAA6E,EAAA3G,ITooDQ+T,EAAWjS,KAAK6E,EAAM3G,IU5yD9B,GAAAkL,IACAyK,IAAA/Q,EAAAsC,MAAAzE,EAAA8S,GACAzB,WAAAlP,EAAAsC,MAAA4M,GACAC,WAAAnP,EAAAsC,MAAA6M,GAGA,OAAA7I,IAKApM,GAAAD,QAAA4F,IAEA6E,aAAA,KAAAsM,IAAA,SAAArV,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,YAEAkE,GAEAoR,SAAA,SAAAlR,GACAA,EAAAA,KAEA,IAAAmR,GAAA,SAAAC,GAKA,IAAA,GAJA1V,GAAA0V,EAAA1V,OAGA2V,EAAA,EACAhW,EAAA,EAAAK,EAAAL,EAAAA,IACAgW,GAAAD,EAAA/V,EAIA,KAAA,GAAAA,GAAA,EAAAK,EAAAL,EAAAA,IACA+V,EAAA/V,GAAA+V,EAAA/V,GAAAgW,EAKA,IAAA,MAAArR,GACA,MAAAA,EAAAsR,cACA,GAAAA,GAAAtR,EAAAsR,kBAEA,IAAAA,GAAA,EAIA,IAAA,MAAAtR,GACA,MAAAA,EAAAuR,UACA,GAAAC,GAAAxR,EAAAuR,cAEA,IAAAC,GAAA,IAIA,IAAA,MAAAxR,GACA,MAAAA,EAAAyR,WACA,GAAA5B,GAAA7P,EAAAyR,eAEA,IAAA5B,GAAA,GAIA,IAAA,MAAA7P,GACA,MAAAA,EAAAsB,QACAxF,EAAAoB,GAAA8C,EAAAsB,QACA,GAAAC,GAAAvB,EAAAsB,WAGA,IAAAC,GAAA,SAAA3G,GAAA,MAAA,GAaA,KAAA,GAVAkD,GAAApD,KAAA2B,SAAAyB,GACA+D,EAAAnH,KAAAmH,QAAAC,UAAA,SAAAlH,GAAA,OAAAA,EAAAmH,WACAC,EAAAtH,KAAAsH,QACAoB,EAAApB,EAAAtG,OACAkU,EAAA/N,EAAAnG,OAKA2H,KACAhI,EAAA,EAAA+H,EAAA/H,EAAAA,IACAgI,EAAArB,EAAA3G,GAAAqG,MAAArG,CAWA,KAAA,GALAqW,MACAC,KACAC,GAAA,EAAAN,GAAAlO,EAGA/H,EAAA,EAAA+H,EAAA/H,EAAAA,IAAA,CAEA,IAAA,GADAkS,MACA5F,EAAA,EAAAvE,EAAAuE,EAAAA,IACA4F,EAAApQ,KAAA,EAEAuU,GAAAvU,KAAAoQ,GACAoE,EAAAxU,KAAA,GAIA,IAAA,GAAA9B,GAAA,EAAAuU,EAAAvU,EAAAA,IAAA,CACA,GAAA8K,GAAAtE,EAAAxG,GACAL,EAAAqI,EAAA8C,EAAAlF,SAAAS,MACA7G,EAAAwI,EAAA8C,EAAAlK,SAAAyF,MACAoB,EAAAvB,EAAArD,MAAAiI,GAAAA,GAGAuL,GAAA7W,GAAAG,IAAA8H,EAGA6O,EAAA3W,IAAA8H,EAOA,IAAA,GAFArE,GAAA,EAAA2E,EAAAwO,EAEAjK,EAAA,EAAAvE,EAAAuE,EAAAA,IACA,GAAA,IAAAgK,EAAAhK,GAEA,IAAA,GAAAtM,GAAA,EAAA+H,EAAA/H,EAAAA,IACAqW,EAAArW,GAAAsM,GAAAlJ,MAIA,KAAA,GAAApD,GAAA,EAAA+H,EAAA/H,EAAAA,IACAqW,EAAArW,GAAAsM,GAAA+J,EAAArW,GAAAsM,GAAAgK,EAAAhK,GAAAiK,CAYA,KAAA,GAJApR,GAFAqR,KACAC,KAKAzW,EAAA,EAAA+H,EAAA/H,EAAAA,IACAwW,EAAA1U,KAAA,GACA2U,EAAA3U,KAAA,EAGA,KAAA,GAAAoT,GAAA,EAAAV,EAAAU,EAAAA,IAAA,CAKA,IAAA,GAHA1M,GAAAiO,EAAAxC,MAAA,GAGAjU,EAAA,EAAA+H,EAAA/H,EAAAA,IACA,IAAA,GAAAsM,GAAA,EAAAvE,EAAAuE,EAAAA,IACA9D,EAAAxI,IAAAqW,EAAArW,GAAAsM,GAAAkK,EAAAlK,EAIAwJ,GAAAtN,GACArD,EAAAqR,EACAA,EAAAhO,CAIA,KAAA,GAFAkO,GAAA,EAEA1W,EAAA,EAAA+H,EAAA/H,EAAAA,IACA0W,GAAA5H,KAAA6C,IAAAxM,EAAAnF,GAAAwW,EAAAxW,GAAA,EAIA,IAAAmW,EAAAO,EACA,MAKA,GAAA5N,IACA6N,KAAA,SAAAvL,GACA,GAAA3K,EAAAoF,OAAAuF,GVkzDU,GAAIwL,GAAUnU,EAAGqD,OAAOsF,GAAM,GAAI/E,SWp+D5C,IAAAuQ,GAAAxL,EAAA/E,IAEA,OAAAmQ,GAAAxO,EAAA4O,KAKA,OAAA9N,IAKAhK,GAAAD,QAAA4F,IXy+DGmD,WAAW,KAAKiP,IAAI,SAAStW,EAAQzB,EAAOD,GYv/D/C,YAEA,IAAAE,GAAAwB,EAAA,aAEAkE,GACAqS,QAAA/X,EAAA+X,UACAzU,UAAAtD,EAAAsD,YACA0U,SAAAhY,EAAAgY,WACAC,WAAAjY,EAAAiY,aACAC,MAAAlY,EAAAkY,QACAC,eAAAnY,EAAAmY,iBACAnU,KAAAhE,EAAAgE,OAGAjE,GAAAD,QAAA4F,IAEA0S,YAAA,KAAAC,IAAA,SAAA7W,EAAAzB,EAAAD,GACA,YAEA,IAAA2B,GAAAD,EAAA,WAEAkE,GACA4S,QAAA,SAAAA,GACAA,EAAAA,EAAAC,MAAA,WAMA,KAAA,GALAlY,GAAAC,KACAkY,KACAC,KAGAxX,EAAA,EAAAA,EAAAqX,EAAAhX,OAAAL,IAAA,CACA,GAAAyX,GAAAJ,EAAArX,EAEAwX,GAAAC,IAAA,EAIA,IAAA,GAAAnL,GAAA,EAAAA,EAAAlN,EAAAiB,OAAAiM,IAAA,CAOA,IAAA,GANAhF,GAAAlI,EAAAkN,GACAvL,EAAAuG,EAAAtG,SACA0W,EAAA3W,EAAAsW,QACAM,GAAA,EAGA3X,EAAA,EAAAA,EAAAqX,EAAAhX,OAAAL,IAAA,CACA,GAAAyX,GAAAJ,EAAArX,GACA4X,EAAAF,EAAAD,EAEA,KAAAG,EAAA,CACAD,GAAA,CACA,QAKA,IAAAA,EAAA,IAAA,GAAAE,KAAAH,GAAA,CACA,GAAAE,GAAAF,EAAAG,GACAC,EAAAN,EAAAK,EAEA,IAAAD,IAAAE,EAAA,CACAH,GAAA,CACA,QAIAA,IACA5W,EAAAsW,QAAA7W,EAAAuX,KAAAP,GAEAD,EAAAzV,KAAAwF,IAYA,MAPAiQ,GAAAlX,OAAA,GACAhB,KAAA6H,MAAAqQ,GACAS,cACAC,QAAA,SAIA7Y,GAGA8Y,SAAA,SAAAb,GACA,MAAAhY,MAAA8Y,YAAAd,GAAA,IAGAe,SAAA,SAAAC,GACA,GAAA/Q,GAAAjI,KAAA,EACA,OAAA,OAAAiI,GAAAA,EAAAtG,SAAAqW,QAAAgB,IAAA,GAAA,GAGAF,YAAA,SAAAG,EAAAC,GAKA,IAAA,GAJAlB,GAAAiB,EAAAhB,MAAA,YACAlY,EAAAC,KACAkY,KAEAvX,EAAA,EAAAwY,EAAApZ,EAAAiB,OAAAmY,EAAAxY,EAAAA,IAIA,IAAA,GAHAsH,GAAAlI,EAAAY,GACA2X,GAAA,EAEArL,EAAA,EAAAA,EAAA+K,EAAAhX,OAAAiM,IAAA,CACA,GAAAmL,GAAAJ,EAAA/K,GACAoL,EAAApQ,EAAAtG,SAAAqW,QACAe,EAAAV,EAAAD,GACAgB,EAAAF,GAAApV,SAAAoV,IAAAH,CAEAK,IACAf,EAAAD,IAAA,EAEAW,GAAAT,IACAJ,EAAAzV,KAAAwF,GACAqQ,GAAA,KAGAD,EAAAD,IAAA,EAEAW,IAAAT,IACAJ,EAAAzV,KAAAwF,GACAqQ,GAAA,IAeA,MAPAJ,GAAAlX,OAAA,GACAhB,KAAA6H,MAAAqQ,GACAS,cACAC,QAAA,SAIA7Y,GAGAsZ,YAAA,SAAArB,GACA,MAAAhY,MAAA8Y,YAAAd,GAAA,IAGAsB,WAAA,SAAAtB,EAAAnW,GACA,GAAA9B,GAAAC,IZ0/DI,IAAgB,MAAZ6B,EavoERA,EAAA,QACA,IAAA,IAAAA,EACA,MAAA9B,EAQA,OALAA,GAAA8Y,SAAAb,GACAuB,WAAA,WACAxZ,EAAAsZ,YAAArB,IACAnW,GAEA9B,GAIAN,GAAAD,QAAA4F,IAEAoU,UAAA,KAAAC,IAAA,SAAAvY,EAAAzB,EAAAD,GACA,YAEA,IAAA4F,IACAsU,OAAA,SAAAC,GACA,MAAA3Z,MAAAyG,OAAAkT,GAAA3Y,SAAAhB,KAAAgB,QAGAI,GAAA,SAAAuY,GACA,MAAA3Z,MAAAyG,OAAAkT,GAAA3Y,OAAA,GAGA4Y,KAAA,SAAApX,EAAAmK,GACA,IAAA,GAAAhM,GAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAkL,GAAAc,EAAAnK,EAAAgB,MAAAmJ,GAAA3M,KAAAW,GAAAA,EAAAX,OAAAwC,EAAAxC,KAAAW,GAAAA,EAAAX,KAEA,IAAA6L,EACA,OAAA,EAIA,OAAA,GAGAgO,MAAA,SAAArX,EAAAmK,GACA,IAAA,GAAAhM,GAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAkL,GAAAc,EAAAnK,EAAAgB,MAAAmJ,GAAA3M,KAAAW,GAAAA,EAAAX,OAAAwC,EAAAxC,KAAAW,GAAAA,EAAAX,KAEA,KAAA6L,EACA,OAAA,EAIA,OAAA,GAGAmD,KAAA,SAAAvB,GAIA,MAHAA,GAAAzN,KAAAoD,KAAAqK,WAAAA,GAGAzN,KAAAgB,SAAAyM,EAAAzM,QACA,EAGAhB,KAAAmI,UAAAsF,GAAAzM,SAAAhB,KAAAgB,Qb2oEEgN,QAAS,SAAUP,GcrsErB,MAFAA,GAAAzN,KAAAoD,KAAAqK,WAAAA,GAEAzN,KAAAmI,UAAAsF,GAAAzM,OAAA,GAGA8Y,gBAAA,SAAArM,GAGA,MAFAA,GAAAzN,KAAAoD,KAAAqK,WAAAA,GAEAzN,KAAA4P,eAAAzH,UAAAsF,GAAAzM,SAAAyM,EAAAzM,QAIAoE,GAAA2U,iBAAA3U,EAAA0U,gBAEAra,EAAAD,QAAA4F,OAEA4U,IAAA,SAAA9Y,EAAAzB,EAAAD,GACA,YAEA,IAAA4F,IACA6U,OAAA,SAAAN,GAIA,IAAA,GAHAO,MACA9W,EAAApD,KAAA2B,SAAAyB,GAEAzC,EAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAsH,GAAAjI,KAAAW,GACAsZ,EAAA7W,EAAAyC,eAAAoC,EAAAtG,SAAAuG,KAAA+R,OAEAA,GAAA3K,OAAA,GACA4K,EAAAzX,KAAAwX,GAIA,MAAAja,MAAA6H,MAAAqS,GAAAxM,QAAA,IAAAjH,OAAAkT,IAGAO,QAAA,SAAAP,GAIA,IAHA,GAAAO,MAEA3U,EAAAvF,KAAAia,SACA1U,EAAA4U,YAAA,CACA,IAAA,GAAAxZ,GAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,EACAuZ,GAAAzX,KAAAwF,GAGA1C,EAAAA,EAAA0U,SAGA,MAAAja,MAAA6H,MAAAqS,GAAAxM,QAAA,IAAAjH,OAAAkT,IAGAS,gBAAA,SAAAT,GAGA,IAAA,GAFAU,GAEA1Z,EAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAsH,GAAAjI,KAAAW,GACAuZ,EAAAjS,EAAAiS,SAEAG,GAAAA,GAAAH,EAEAG,EAAAA,EAAAlS,UAAA+R,GAGA,MAAAG,GAAA5T,OAAAkT,IAGAW,QAAA,SAAAX,GACA,MAAA3Z,MAAAoH,UAAA,SAAAa,GACA,MAAAA,GAAAiF,UAAAjF,EAAAgS,SAAAM,UACA9T,OAAAkT,IAGAa,WAAA,SAAAb,GACA,MAAA3Z,MAAAoH,UAAA,SAAAa,GACA,MAAAA,GAAAiF,UAAAjF,EAAAgS,SAAAE,aACA1T,OAAAkT,IAGAc,SAAA,SAAAd,GAGA,IAAA,GAFAc,MAEA9Z,EAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAsH,GAAAjI,KAAAW,EACA8Z,GAAAA,EAAAC,OAAAzS,EAAAtG,SAAA8Y,UAGA,MAAAza,MAAA6H,MAAA4S,GAAA/M,QAAA,IAAAjH,OAAAkT,IAGAgB,SAAA,SAAAhB,GACA,MAAA3Z,MAAAia,SAAAQ,WAAAlN,IAAAvN,MAAAyG,OAAAkT,IAGAiB,SAAA,WACA,GAAA3S,GAAAjI,KAAA,EAEA,OAAAiI,GACA,IAAAA,EAAAtG,SAAA8Y,SAAAzZ,OADA,QAKA6Z,QAAA,WACA,GAAA5S,GAAAjI,KAAA,EAEA,OAAAiI,GACAnE,SAAAmE,EAAAtG,SAAAuG,KAAA+R,QAAA,IAAAhS,EAAAgS,SAAAjZ,OADA,QAKA8Z,YAAA,SAAAnB,GAGA,QAAAnL,GAAAjJ,GACA,IAAA,GAAA5E,GAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,EAEAoa,GAAAtY,KAAAwF,Gd0sEYA,EAAIwS,WAAWN,Ye/zE3B3L,EAAAvG,EAAAwS,aD+GA,GAAAM,KCxGA,OAFAvM,GAAAxO,KAAAya,YAEAza,KAAA6H,MAAAkT,GAAArN,QAAA,IAAAjH,OAAAkT,IAKAvU,GAAAiV,UAAAjV,EAAA8U,QAEAza,EAAAD,QAAA4F,OAEA4V,IAAA,SAAA9Z,EAAAzB,EAAAD,GACA,YAEA,IACAgD,GAAA4C,EADA1F,EAAAwB,EAAA,YAGAsB,GAAA4C,GAEA8C,KAAAxI,EAAAwI,MACA+S,MAAA,OACAC,aAAA,OACAC,cAAA,EACAC,cAAA,EACAC,aAAA,OACAC,sBAAA,EACAC,cAAA,UACAC,cAAA,EACAC,eACAzU,IAAA,EACAT,QAAA,EACAhF,QAAA,EACA0Y,QAAA,GAEAtB,aAAA,IAGA+C,WAAAhc,EAAAgc,YACAT,MAAA,OACAU,MAAA,OACAJ,cAAA,UACAK,cAAA,EACAH,eACAzU,IAAA,EACAT,QAAA,EACAhF,QAAA,EACA0Y,QAAA,GAEAtB,aAAA,IAGAkD,QAAAnc,EAAAwI,MACA+S,MAAA,UACAC,aAAA,UACAC,cAAA,EACAC,cAAA,EACAC,aAAA,UACAC,sBAAA,EACAC,cAAA,UACAC,cAAA,EACA7C,aAAA,IAGAmD,cAAApc,EAAAgc,YACAT,MAAA,UACAU,MAAA,UACAJ,cAAA,UACAK,cAAA,EACAjD,aAAA,IAGAoD,SAAArc,EAAAwI,MACA+S,MAAA,WACAE,cAAA,EACAC,cAAA,EACAE,sBAAA,EACAE,cAAA,IAGAQ,eAAAtc,EAAAgc,YACAT,MAAA,WACAW,cAAA,ICtFA5U,GAAA,WACA,GAAAiB,GAAAjI,KAAA,EAEA,OAAAiI,GACAA,EAAAtG,SAAAuG,KAAAlB,GADA,SAQAxE,EAAAyZ,KAAAzZ,EAAA0F,KACA1F,EAAA0Z,WAAA1Z,EAAAkZ,WAEAjc,EAAAD,QAAA4F,IAEA0S,YAAA,KAAAqE,IAAA,SAAAjb,EAAAzB,EAAAD,GACA,YAMA,SAAA4c,GAAAC,GACA,MAAA,UAAAC,GACA,GAAAvc,GAAAC,IAMA,IAJA8D,SAAAwY,IACAA,GAAA,GAGA,IAAAvc,EAAAiB,QAEAjB,EAAAmN,WAAAnN,EAAAwc,UAAA,CAKA,IAAA,GAJA5K,GAAA,EACA5F,EAAAhM,EAAA,GACAiI,EAAA+D,EAAApK,SAAAwF,MAEAxG,EAAA,EAAAA,EAAAqH,EAAAhH,OAAAL,IAAA,CACA,GAAA8K,GAAAzD,EAAArH,IAEA2b,IAAA7Q,EAAApE,YAIAsK,GAAA0K,EAAAtQ,EAAAN,IAGA,MAAAkG,KAiCA,QAAA6K,GAAAC,EAAAJ,GACA,MAAA,UAAAC,GAIA,IAAA,GAHAzQ,GACAvE,EAAAtH,KAAAsH,QAEA3G,EAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IAAA,CACA,GAAAsH,GAAAX,EAAA3G,GACAgR,EAAA1J,EAAAwU,GAAAH,EACAxY,UAAA6N,GAAA7N,SAAA+H,IAAAwQ,EAAA1K,EAAA9F,KACAA,EAAA8F,GAIA,MAAA9F,IA3EA,GAAA1K,GAAAD,EAAA,WAEAkE,IAkCAjE,GAAAS,OAAAwD,GACAuM,OAAAyK,EAAA,SAAArQ,EAAAN,GACA,MAAAA,GAAAlF,SAAAyI,KAAAvD,EAAAlK,UACA,EAEA,IAIAgQ,SAAA6K,EAAA,SAAArQ,EAAAN,GACA,MAAAA,GAAAlK,SAAAyN,KAAAjD,GACA,EAEA,IAIAyF,UAAA4K,EAAA,SAAArQ,EAAAN,GACA,MAAAA,GAAAlF,SAAAyI,KAAAjD,GACA,EAEA,MAsBA5K,EAAAS,OAAAwD,GACAsX,UAAAF,EAAA,SAAA,SAAA7K,EAAAgL,GACA,MAAAA,GAAAhL,IAGAD,UAAA8K,EAAA,SAAA,SAAA7K,EAAAhG,GACA,MAAAgG,GAAAhG,IAGAiR,YAAAJ,EAAA,WAAA,SAAA7K,EAAAgL,GACA,MAAAA,GAAAhL,IAGAR,YAAAqL,EAAA,WAAA,SAAA7K,EAAAhG,GACA,MAAAgG,GAAAhG,IAGAkR,aAAAL,EAAA,YAAA,SAAA7K,EAAAgL,GACA,MAAAA,GAAAhL,IAGAP,aAAAoL,EAAA,YAAA,SAAA7K,EAAAhG,GACA,MAAAgG,GAAAhG,MCvHAxK,EAAAS,OAAAwD,GACA0X,YAAA,SAAAR,GAIA,IAAA,GAHA3F,GAAA,EACArP,EAAAtH,KAAAsH,QAEA3G,EAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IACAgW,GAAArP,EAAA3G,GAAAgR,OAAA2K,EAGA,OAAA3F,MAIAlX,EAAAD,QAAA4F,IAEAoU,UAAA,KAAAuD,IAAA,SAAA7b,EAAAzB,EAAAD,GACA,YAEA,IAGAgD,GAAA4C,EAHA1F,EAAAwB,EAAA,aACAE,EAAAF,EAAA,SACAC,EAAAD,EAAA,UAGAsB,GAAA4C,GAEA4X,SAAAtd,EAAAwI,MACA+S,MAAA,WACAC,aAAA,WACAC,cAAA,EACAC,cAAA,EACAC,aAAA,WACAC,sBAAA,EACAC,cAAA,WACAC,cAAA,EACAyB,WAAA,IAAA,KACAC,MAAA,SAAA3X,GACA,GAAA4X,GAAA5X,EAAA6X,sBACAD,GAAAE,SAAA,aAEAC,OAAA,SAAArV,GACA,OAAAA,EAAAsV,WAAAtV,EAAA2S,cAKA4C,eAAA9d,EAAAwI,MACA+S,MAAA,WACAC,aAAA,WACAC,cAAA,EACAC,cAAA,EACAC,aAAA,WACAC,sBAAA,EACAC,cAAA,UACAC,cAAA,EACAyB,WAAA,IAAA,KACAC,MAAA,SAAA3X,GACAA,EAAA6X,wBAEAE,OAAA,SAAArV,GACA,OAAAA,EAAAsV,WAAAtV,EAAA2S,cAIA6C,UAAA,SAAAC,EAAAC,GACA,GAAAvc,EAAAwL,YAAA8Q,GACA1d,KAAAgd,SAAAU,OAEA,IAAAtc,EAAAoB,GAAAkb,GAAA,CAGA,IAAA,GAFAlb,GAAAkb,EAEA/c,EAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAsH,GAAAjI,KAAAW,GAEA+c,EAAAlb,EAAAgB,MAAAyE,GAAAtH,EAAAsH,GAEA,IAAAyV,IAAAzV,EAAAsV,WAAAtV,EAAA2S,WAAA,CACA,GAAAgD,GAAA3V,EAAAtG,SAAAqb,QACAY,GAAAC,EAAAH,EAAAG,EACAD,EAAAE,EAAAJ,EAAAI,GAIA,GAAAX,GAAAnd,KAAAod,uBACAW,EAAAZ,EAAAnc,OAAA,EAAAhB,KAAAwO,IAAA2O,GAAAnd,IAEA2d,GACAI,EAAAnF,QAAA,YAEAmF,EAAAV,SAAA,YAIA,MAAArd,OAGAge,gBAAA,SAAAN,GACA,MAAA1d,MAAAyd,UAAAC,GAAA,IAIAO,iBAAA,SAAAC,EAAAC,GACA,GAAAlW,GAAAjI,KAAA,GACAoD,EAAApD,KAAAoD,KACAgb,EAAAhb,EAAAgb,OACAC,EAAAjb,EAAAib,MACAC,EAAAld,EAAAwL,YAAAsR,GAAAA,EAAApa,OACAya,EAAAza,SAAAwa,GAAAxa,SAAAqa,GAAA/c,EAAAoF,OAAA0X,EAEA,IAAAjW,GAAAA,EAAAiF,SAAA,CACA,IAAAqR,EAeA,CACA,GAAAb,GAAAzV,EAAAtG,SAAAqb,QAMA,OALAsB,IACAT,EAAAH,EAAAG,EAAAO,EAAAC,EAAAR,EACAC,EAAAJ,EAAAI,EAAAM,EAAAC,EAAAP,GAGAha,SAAAoa,EACAI,EAEAA,EAAAJ,GAxBA,IAAA,GAAAvd,GAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAsH,GAAAjI,KAAAW,EAEAmD,UAAAqa,EACAlW,EAAAtG,SAAAqb,SAAAkB,IAAAC,EAAAE,EAAAH,IAAAE,EACAta,SAAAwa,IACArW,EAAAtG,SAAAqb,UACAa,GAAAS,EAAAT,EAAAQ,EAAAR,GAAAO,EACAN,GAAAQ,EAAAR,EAAAO,EAAAP,GAAAM,IAKApe,KAAAqd,SAAA,gBAcA,KAAAkB,EACA,MAAAza,OAGA,OAAA9D,OAIAwe,iBAAA,SAAAN,EAAAC,GACA,GAAAlW,GAAAjI,KAAA,GACAoD,EAAApD,KAAAoD,KACAqb,EAAArd,EAAAwL,YAAAsR,GAAAA,EAAApa,OACAya,EAAAza,SAAA2a,GAAA3a,SAAAqa,GAAA/c,EAAAoF,OAAA0X,GACAQ,EAAAtb,EAAAsb,kBAEA,IAAAzW,GAAAA,EAAAiF,SAAA,CACA,IAAAqR,EAyBA,CACA,GAAAb,GAAAzV,EAAAtG,SAAAqb,SACA/C,EAAAyE,EAAAzW,EAAAgS,SAAA,KACA0E,EAAA1E,GAAAA,EAAAjZ,OAAA,EACA4d,EAAAD,CAEAA,KACA1E,EAAAA,EAAA,GAGA,IAAA4E,GAAAD,EAAA3E,EAAAtY,SAAAqb,UAAAa,EAAA,EAAAC,EAAA,EAOA,OALAW,IACAZ,EAAAH,EAAAG,EAAAgB,EAAAhB,EACAC,EAAAJ,EAAAI,EAAAe,EAAAf,GAGAha,SAAAoa,EACAO,EAEAA,EAAAP,GA5CA,IAAA,GAAAvd,GAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAsH,GAAAjI,KAAAW,GACAsZ,EAAAyE,EAAAzW,EAAAgS,SAAA,KACA0E,EAAA1E,GAAAA,EAAAjZ,OAAA,EACA4d,EAAAD,CAEAA,KACA1E,EAAAA,EAAA,GAGA,IAAA4E,GAAAD,EAAA3E,EAAAtY,SAAAqb,UAAAa,EAAA,EAAAC,EAAA,EAEAha,UAAAqa,EACAlW,EAAAtG,SAAAqb,SAAAkB,GAAAC,EAAAU,EAAAX,GACApa,SAAA2a,IACAxW,EAAAtG,SAAAqb,UACAa,EAAAY,EAAAZ,EAAAgB,EAAAhB,EACAC,EAAAW,EAAAX,EAAAe,EAAAf,IAKA9d,KAAAqd,SAAA,gBAyBA,KAAAkB,EACA,MAAAza,OAGA,OAAA9D,OAGA8e,oBAAA,SAAAxZ,GACA,GAAAyZ,GAAA/e,KAAAgf,YAAA1Z,GACAlC,EAAApD,KAAAoD,KACAgb,EAAAhb,EAAAgb,OACAC,EAAAjb,EAAAib,MAEAY,EAAAF,EAAAE,GAAAb,EAAAC,EAAAR,EACAqB,EAAAH,EAAAG,GAAAd,EAAAC,EAAAR,EACAsB,EAAAJ,EAAAI,GAAAf,EAAAC,EAAAP,EACAsB,EAAAL,EAAAK,GAAAhB,EAAAC,EAAAP,CAEA,QACAmB,GAAAA,EACAC,GAAAA,EACAC,GAAAA,EACAC,GAAAA,EACAhX,EAAA8W,EAAAD,EACAI,EAAAD,EAAAD,IAIA/B,qBAAA,WAOA,QAAAkC,GAAArF,GACA,GAAAQ,GAAAR,EAAAQ,WACA3Y,EAAAmY,EAAAtY,SAAAG,MACAyd,EAAA,YAAAzd,EAAA,8BAAA0d,MACAT,EAAAtE,EAAAuE,aAAAO,cAAAA,EAAAE,cAAA,IACAC,GACAC,IAAA7d,EAAA,eAAA8d,QACAC,OAAA/d,EAAA,kBAAA8d,QACAE,KAAAhe,EAAA,gBAAA8d,QACAG,MAAAje,EAAA,iBAAA8d,SAEAlC,EAAAzD,EAAAtY,SAAAqb,SACAgD,GAAA,CAEA,UAAAle,EAAA,MAAA0d,QACAvF,EAAAtY,SAAAse,UAAAlB,EAAA3W,EACAsV,EAAAG,GAAAkB,EAAAE,GAAAF,EAAAG,GAAAQ,EAAAI,KAAAJ,EAAAK,OAAA,EACAC,GAAA,GAGA,SAAAle,EAAA,OAAA0d,QACAvF,EAAAtY,SAAAue,WAAAnB,EAAAM,EACA3B,EAAAI,GAAAiB,EAAAI,GAAAJ,EAAAK,GAAAM,EAAAC,IAAAD,EAAAG,QAAA,EACAG,GAAA,GAGAA,GACAG,EAAA1d,KAAAwX,GAjCA,GAAA7W,GAAApD,KAAAoD,IAEA,KAAAA,EAAAgd,iBAAAhd,EAAAsb,mBAAA,MAAAtb,GAAAqK,YAqCA,KAnCA,GAAA0S,MAkCA5a,EAAAvF,KAAAia,SACA1U,EAAA4U,YAAA,CAGA,IAAA,GAAAxZ,GAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,EAEA2e,GAAArX,GAIA1C,EAAAA,EAAA0U,SAIA,MAAAja,MAAA6H,MAAAsY,IAIAnB,YAAA,SAAA1Z,GACA,GAAAC,GAAAvF,KACAoD,EAAAmC,EAAA5D,SAAAyB,GACAid,EAAAjd,EAAAzB,SACAye,EAAAC,EAAAD,YAEA9a,GAAAA,GAAAnE,EAAAmf,mBAEA,IAAAC,GAAAzc,SAAAwB,EAAAib,cAAA,EAAAjb,EAAAib,aACAd,EAAA3b,SAAAwB,EAAAma,cAAA,EAAAna,EAAAma,aACAF,EAAAzb,SAAAwB,EAAAia,eAAA,EAAAja,EAAAia,aAGAa,IACAC,EAAAG,SAAAC,yBAAAzgB,KASA,KAAA,GANAif,GAAAlW,EAAAA,EACAmW,IAAAnW,EAAAA,GACAoW,EAAApW,EAAAA,EACAqW,IAAArW,EAAAA,GAGApI,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAKA+f,GAAAC,EAAAC,EAAAC,EAAAhD,EAAAC,EALA7V,EAAA1C,EAAA5E,GACAe,EAAAuG,EAAAtG,SACAG,EAAAJ,EAAAI,MACAgf,EAAAV,EAAA1e,EAAAI,MAAA,QAAA0d,MAAA,UACAtS,EAAA,UAAAxL,EAAAqf,MAEAC,GAAA,CAEA,IAAA,SAAAF,EAAA,CAEA,GAAA5T,GAAAqT,EAAA,CACAS,GAAA,CAEA,IAAAtD,GAAAhc,EAAAsb,QACAa,GAAAH,EAAAG,EACAC,EAAAJ,EAAAI,CACA,IAAA1V,GAAAH,EAAAgZ,aACAC,EAAA9Y,EAAA,EACAiX,EAAApX,EAAAkZ,cACAC,EAAA/B,EAAA,CAKAqB,GAAA7C,EAAAqD,EACAP,EAAA9C,EAAAqD,EACAN,EAAA9C,EAAAsD,EACAP,EAAA/C,EAAAsD,EAEAnC,EAAAA,EAAAyB,EAAAA,EAAAzB,EACAC,EAAAyB,EAAAzB,EAAAyB,EAAAzB,EACAC,EAAAA,EAAAyB,EAAAA,EAAAzB,EACAC,EAAAyB,EAAAzB,EAAAyB,EAAAzB,MAEA,IAAAnX,EAAAoZ,UAAA5B,EAAA,CACAuB,GAAA,CAEA,IAAAM,GAAA5f,EAAA6E,OACAgb,EAAAD,EAAA3f,SACA6f,EAAAD,EAAAvE,SAEAyE,EAAA/f,EAAAH,OACAmgB,EAAAD,EAAA9f,SACAggB,EAAAD,EAAA1E,SAMA4E,EAAAlgB,EAAAkgB,WACAxZ,EAAA,EACAyZ,EAAA,CAYA,IAVAzB,IACAhY,EAAAtG,EAAA,MAAA8d,QACAiC,EAAAzZ,EAAA,GAGAsY,EAAAc,EAAA3D,EACA8C,EAAAgB,EAAA9D,EACA+C,EAAAY,EAAA1D,EACA+C,EAAAc,EAAA7D,EAEA4C,EAAAC,EAAA,CACA,GAAAxX,GAAAuX,CACAA,GAAAC,EACAA,EAAAxX,EAGA,GAAAyX,EAAAC,EAAA,CACA,GAAA1X,GAAAyX,CACAA,GAAAC,EACAA,EAAA1X,EAiBA,GAbAuX,GAAAmB,EACAlB,GAAAkB,EACAjB,GAAAiB,EACAhB,GAAAgB,EAEA5C,EAAAA,EAAAyB,EAAAA,EAAAzB,EACAC,EAAAyB,EAAAzB,EAAAyB,EAAAzB,EACAC,EAAAA,EAAAyB,EAAAA,EAAAzB,EACAC,EAAAyB,EAAAzB,EAAAyB,EAAAzB,EAKAgB,EAGA,IAAA,GAFA0B,GAAAF,EAAAG,WAAAH,EAAAI,YAEA/U,EAAA,EAAAA,EAAA6U,EAAA9gB,OAAAiM,IAAA,CACA,GAAAgV,GAAAH,EAAA7U,EAEAyT,GAAAuB,EAAApE,EAAAgE,EACAlB,EAAAsB,EAAApE,EAAAgE,EACAjB,EAAAqB,EAAAnE,EAAA+D,EACAhB,EAAAoB,EAAAnE,EAAA+D,EAEA5C,EAAAA,EAAAyB,EAAAA,EAAAzB,EACAC,EAAAyB,EAAAzB,EAAAyB,EAAAzB,EACAC,EAAAA,EAAAyB,EAAAA,EAAAzB,EACAC,EAAAyB,EAAAzB,EAAAyB,EAAAzB,EAOA,GAAAgB,GAAA,aAAAte,EAAA,eAAAogB,SAAA,CACA,GAAAC,GAAAP,EAAAQ,WAOA,IALA1B,EAAAyB,EAAA,GAAAtE,EACA+C,EAAAuB,EAAA,GAAArE,EACA6C,EAAAwB,EAAA,GAAAtE,EACAgD,EAAAsB,EAAA,GAAArE,EAEA4C,EAAAC,EAAA,CACA,GAAAxX,GAAAuX,CACAA,GAAAC,EACAA,EAAAxX,EAGA,GAAAyX,EAAAC,EAAA,CACA,GAAA1X,GAAAyX,CACAA,GAAAC,EACAA,EAAA1X,EAGA8V,EAAAA,EAAAyB,EAAAA,EAAAzB,EACAC,EAAAyB,EAAAzB,EAAAyB,EAAAzB,EACAC,EAAAA,EAAAyB,EAAAA,EAAAzB,EACAC,EAAAyB,EAAAzB,EAAAyB,EAAAzB,GASA,GAAAgB,EAAA,CAEA,GAAA1e,GAAAuG,EAAAtG,SACAG,EAAAJ,EAAAI,MACA8f,EAAAlgB,EAAAkgB,OACAS,EAAAvgB,EAAA,MAAAogB,SACAI,EAAAxgB,EAAA,aACAygB,EAAAzgB,EAAA,eACA0gB,EAAA1gB,EAAA,eACA2gB,EAAAb,EAAAa,WACAC,EAAAd,EAAAc,YACAC,EAAAf,EAAAe,OACAC,EAAAhB,EAAAgB,OACAvB,EAAApZ,EAAAoZ,SACAwB,EAAA,eAAA/gB,EAAA,sBAAAogB,QAEA,IAAA3C,GAAA8C,GAAAC,GAAA,MAAAI,GAAA,MAAAD,GAAA,MAAAE,GAAA,MAAAC,GAAAL,GAAAC,EAAA,CACA,GAEAM,IAAAC,GAAAC,GAAAC,GAFAC,GAAAR,EACAS,GAAAV,CAGA,IAAApB,GAMA,GALAyB,GAAAH,EAAAQ,GAAA,EACAJ,GAAAJ,EAAAQ,GAAA,EACAH,GAAAJ,EAAAM,GAAA,EACAD,GAAAL,EAAAM,GAAA,EAEAL,EAAA,CACA,GAAAO,IAAA1hB,EAAAqa,SAAAsH,WACAC,GAAA7T,KAAA6T,IAAAF,IACAG,GAAA9T,KAAA8T,IAAAH,IAEAI,GAAA,SAAA3F,EAAAC,GAIA,MAHAD,IAAA8E,EACA7E,GAAA8E,GAGA/E,EAAAA,EAAAyF,GAAAxF,EAAAyF,GAAAZ,EACA7E,EAAAD,EAAA0F,GAAAzF,EAAAwF,GAAAV,IAIAa,GAAAD,GAAAV,GAAAE,IACAU,GAAAF,GAAAV,GAAAG,IACAU,GAAAH,GAAAT,GAAAC,IACAY,GAAAJ,GAAAT,GAAAE,GAEAH,IAAArT,KAAAkN,IAAA8G,GAAA5F,EAAA6F,GAAA7F,EAAA8F,GAAA9F,EAAA+F,GAAA/F,GACAkF,GAAAtT,KAAA9D,IAAA8X,GAAA5F,EAAA6F,GAAA7F,EAAA8F,GAAA9F,EAAA+F,GAAA/F,GACAmF,GAAAvT,KAAAkN,IAAA8G,GAAA3F,EAAA4F,GAAA5F,EAAA6F,GAAA7F,EAAA8F,GAAA9F,GACAmF,GAAAxT,KAAA9D,IAAA8X,GAAA3F,EAAA4F,GAAA5F,EAAA6F,GAAA7F,EAAA8F,GAAA9F,QAEA,CACA,OAAAyE,EAAA/C,OACA,IAAA,OACAsD,GAAAH,EAAAQ,GACAJ,GAAAJ,CACA,MAEA,KAAA,SACAG,GAAAH,EAAAQ,GAAA,EACAJ,GAAAJ,EAAAQ,GAAA,CACA,MAEA,KAAA,QACAL,GAAAH,EACAI,GAAAJ,EAAAQ,GAIA,OAAAX,EAAAhD,OACA,IAAA,MACAwD,GAAAJ,EAAAM,GACAD,GAAAL,CACA,MAEA,KAAA,SACAI,GAAAJ,EAAAM,GAAA,EACAD,GAAAL,EAAAM,GAAA,CACA,MAEA,KAAA,SACAF,GAAAJ,EACAK,GAAAL,EAAAM,IAKAjE,EAAAA,EAAA6D,GAAAA,GAAA7D,EACAC,EAAA6D,GAAA7D,EAAA6D,GAAA7D,EACAC,EAAAA,EAAA6D,GAAAA,GAAA7D,EACAC,EAAA6D,GAAA7D,EAAA6D,GAAA7D,KAKA,GAAAyE,IAAA,SAAAhG,GACA,MAAAA,KAAA9U,EAAAA,GAAA8U,MAAA9U,EAAAA,GACA,EAGA8U,EAQA,OALAoB,GAAA4E,GAAA5E,GACAC,EAAA2E,GAAA3E,GACAC,EAAA0E,GAAA1E,GACAC,EAAAyE,GAAAzE,IAGAH,GAAAA,EACAC,GAAAA,EACAC,GAAAA,EACAC,GAAAA,EACAhX,EAAA8W,EAAAD,EACAI,EAAAD,EAAAD,IAKA,IAAA2E,GAAA,SAAAtiB,GACAA,EAAAuiB,cAAA5iB,EAAA6iB,WAAAxiB,EAAA+C,MACA/C,EAAAyiB,SAAA,OAAAziB,EAAAuiB,cACAviB,EAAA0iB,UAAA,QAAA1iB,EAAAuiB,cACAviB,EAAA2iB,UAAA,QAAA3iB,EAAAuiB,cACAviB,EAAA4iB,mBAAAjjB,EAAA6iB,WAAAxiB,EAAA2iB,WAEA3hB,EAAAhB,EAAA+C,MAAA,WACA,GAAA0D,GAAAjI,KAAA,GACA0B,EAAAuG,EAAAtG,SACAyB,EAAA1B,EAAA0B,GACAgd,EAAAhd,EAAAzB,SAAAye,YAEA,IAAAnY,EAAA,CACA,IAAAmY,EAYA,MAAA,EAXA,IAAA5V,GAAA9I,EAAAI,MAAAN,EAAA+C,KAEA,QAAAiG,EAAA0X,UACA,IAAA,OACA,MAAAxgB,GAAAF,EAAAyiB,WAAA,CACA,KAAA,QACA,MAAAviB,GAAAkgB,OAAApgB,EAAA0iB,YAAA,CACA,SACA,MAAA1Z,GAAAoV,WAQApd,EAAA,QAAAhB,EAAAuiB,eAAA,WACA,GAAA9b,GAAAjI,KAAA,GACA0B,EAAAuG,EAAAtG,SACAyB,EAAA1B,EAAA0B,GACAgd,EAAAhd,EAAAzB,SAAAye,YAEA,IAAAnY,EAAA,CACA,GAAAmY,EAAA,CACA,GAAAte,GAAAJ,EAAAI,MACAoc,EAAAjW,EAAAzG,EAAA+C,QACA8f,EAAAviB,EAAA,gBAAA8d,QACAF,EAAA5d,EAAAN,EAAA8iB,SAAA,IAAA1E,QAAA9d,EAAAN,EAAA8iB,SAAA,IAAA1E,OAEA,OAAA1B,GAAAmG,EAAA3E,EAEA,MAAA,KAKAld,EAAA,WAAAhB,EAAAuiB,eAAA,WACA,GAAA9b,GAAAjI,KAAA,EAEA,IAAAiI,EAAA,CACA,GAAAuC,GAAAvC,EAAAzG,EAAA+C,OACA,OAAAiG,GAAAxK,KAAAoD,KAAAgb,SAIA5b,EAAA,WAAAhB,EAAA4iB,oBAAA,WACA,GAAAnc,GAAAjI,KAAA,EAEA,IAAAiI,EAAA,CACA,GAAAsc,GAAAtc,EAAAzG,EAAA2iB,YACA,OAAAI,GAAAvkB,KAAAoD,KAAAgb,SAKA0F,IACAvf,KAAA,QACA+f,UAAA,eAAA,mBCroBAR,GACAvf,KAAA,SACA+f,UAAA,cAAA,oBAIA9hB,EAAAgiB,cAAAhiB,EAAAiiB,MAAAjiB,EAAAwa,SACAxa,EAAAkiB,eAAAliB,EAAAmiB,OAAAniB,EAAAib,UACAjb,EAAAoiB,cAAApiB,EAAAyb,iBACAzb,EAAAqiB,cAAAriB,EAAAgc,iBACAhc,EAAAsiB,YAAAtiB,EAAAwc,YACAxc,EAAAuiB,oBAAAviB,EAAAsc,oBAEArf,EAAAD,QAAA4F,IAEA0S,YAAA,GAAAkN,QAAA,GAAAxL,UAAA,KAAAyL,IAAA,SAAA/jB,EAAAzB,EAAAD,GACA,YAEA,IAAA2B,GAAAD,EAAA,WACAE,EAAAF,EAAA,SAGAgkB,EAAA,SAAA9hB,EAAAkJ,EAAA6Y,GACA,KAAAnlB,eAAAklB,IACA,MAAA,IAAAA,GAAA9hB,EAAAkJ,EAAA6Y,EAGA,IAAAplB,GAAAC,IAGA,IAFAmlB,EAAArhB,SAAAqhB,GAAAA,GAAA,GAAA,EAEArhB,SAAAV,GAAAU,SAAAwI,IAAAlL,EAAAgkB,KAAAhiB,GAEA,WADAjC,GAAAiI,MAAA,2DAIA,IAAA2X,GAAAzU,EAAAyU;AAYA,GATA,MAAAA,IAEAA,EADA,MAAAzU,EAAApE,KAAA3B,QAAA,MAAA+F,EAAApE,KAAA3G,OACA,QAEA,SAKA,UAAAwf,GAAA,UAAAA,EAEA,WADA5f,GAAAiI,MAAA,iEAAA2X,EAAA,IAwCA,IAnCA/gB,KAAAgB,OAAA,EACAhB,KAAA,GAAAA,KAGAA,KAAA2B,UACAyB,GAAAA,EACAiiB,QAAA,EACAnd,KAAAoE,EAAApE,SACA8U,SAAA1Q,EAAA0Q,aACAiD,UAAAnc,OACAoc,WAAApc,OACAwhB,aACAvE,MAAAA,EACAjf,SACA8f,UACA2D,aACAhJ,SAAA,EACAiJ,SAAAlZ,EAAAkZ,UAAA,GAAA,EACAC,WAAA3hB,SAAAwI,EAAAmZ,YAAA,EAAAnZ,EAAAmZ,YAAA,GAAA,EACAlI,OAAAjR,EAAAiR,QAAA,GAAA,EACAmI,SAAA,EACAC,UAAA7hB,SAAAwI,EAAAqZ,WAAA,EAAArZ,EAAAqZ,WAAA,GAAA,EACAC,QAAA,EACA5N,WACAhV,WACAE,WACAD,UAEA8Y,YACAF,QAAAvP,EAAAuP,YACA1U,SACAsT,aAIAnO,EAAA2R,iBAAA,CACA,GAAAK,GAAAhS,EAAA2R,iBACAI,EAAAjb,EAAAib,MACAD,EAAAhb,EAAAgb,MAEApe,MAAA2B,SAAAqb,UACAa,GAAAS,EAAAT,EAAAQ,EAAAR,GAAAO,EACAN,GAAAQ,EAAAR,EAAAO,EAAAP,GAAAM,GAIA,GAAAhd,EAAAoF,OAAA8F,EAAA0L,SAEA,IAAA,GADAA,GAAA1L,EAAA0L,QAAA6N,MAAA,OACAllB,EAAA,EAAAG,EAAAkX,EAAAhX,OAAAF,EAAAH,EAAAA,IAAA,CACA,GAAAyX,GAAAJ,EAAArX,EACAyX,IAAA,KAAAA,ICxGArY,EAAA4B,SAAAqW,QAAAI,IAAA,IAIA9L,EAAAxK,OAAAwK,EAAAvK,MACAqB,EAAAtB,QAAAgkB,YAAA9lB,KAAAsM,EAAAxK,OAAAwK,EAAAvK,MAGA+B,SAAAqhB,GAAAA,IACAnlB,KAAAmlB,UAKA1lB,GAAAD,QAAA0lB,IAEAF,QAAA,GAAAxL,UAAA,KAAAuM,IAAA,SAAA7kB,EAAAzB,EAAAD,GACA,YAEA,IAAAE,GAAAwB,EAAA,aAEAkE,GACA4gB,GAAAtmB,EAAAsmB,KACAC,IAAAvmB,EAAAsmB,IAAAE,qBAAA,IACAC,KAAAzmB,EAAAsmB,IAAAI,2BAAA,IACAC,IAAA3mB,EAAA2mB,MACAzN,QAAAlZ,EAAAkZ,UAEAyE,SAAA,SAAA1B,EAAA2K,GACA,MAAA,KAAAtmB,KAAAgB,QC5BAhB,KAAAoD,KAAAmjB,QACA3hB,KAAA+W,EACAlO,WAAAzN,OAGAA,KAAA4Y,QAAA+C,EAAA2K,GACAtmB,MDsBA,QCjBAN,GAAA8mB,eAAAphB,GAEA3F,EAAAD,QAAA4F,IAEA0S,YAAA,KAAA2O,IAAA,SAAAvlB,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,SACAwlB,EAAAxlB,EAAA,eAEAkE,GACAkC,MAAA,SAAAqS,GACA,MAAA3Z,MAAAyG,OAAA,SAAA9F,EAAAgmB,GACA,MAAAA,GAAAzZ,WACAzG,OAAAkT,IAGAxS,MAAA,SAAAwS,GACA,MAAA3Z,MAAAyG,OAAA,SAAA9F,EAAAgmB,GACA,MAAAA,GAAAtF,WACA5a,OAAAkT,IAGAlT,OAAA,SAAAA,GACA,GAAArF,EAAAoB,GAAAiE,GAAA,CAGA,IAAA,GAFAsU,MAEApa,EAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAsH,GAAAjI,KAAAW,EAEA8F,GAAAjD,MAAAyE,GAAAtH,EAAAsH,KACA8S,EAAAtY,KAAAwF,GAIA,MAAAjI,MAAA6H,MAAAkT,GAEA,MAAA3Z,GAAAoF,OAAAC,IAAArF,EAAA+B,oBAAAsD,GACAigB,EAAAjgB,GAAAA,OAAAzG,MAEA8D,SAAA2C,EACAzG,KAGAA,KAAA6H,SAGA0F,IAAA,SAAAqZ,GACA,GAAAA,EAEA,CAEAxlB,EAAAoF,OAAAogB,KACAA,EAAA5mB,KAAAyG,OAAAmgB,GAKA,KAAA,GAFA7L,MAEApa,EAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAgmB,GAAA3mB,KAAAW,GAEAkmB,EAAAD,EAAAjlB,SAAAmlB,IAAAH,EAAA3f,KACA6f,IACA9L,EAAAtY,KAAAkkB,GAIA,MAAA3mB,MAAA6H,MAAAkT,GAlBA,MAAA/a,OAuBA+mB,mBAAA,WACA,GAAA3jB,GAAApD,KAAA2B,SAAAyB,EAEA,OAAAA,GAAA2X,WAAAxN,IAAAvN,OAGAmI,UAAA,SAAA6e,GAEA,GAAA5lB,EAAAoF,OAAAwgB,GAAA,CACA,GAAArN,GAAAqN,CACA,OAAAhnB,MAAAyG,OAAAkT,GAWA,IAAA,GARAoB,MACAkM,EAAAjnB,KACAknB,EAAAF,EACAG,EAAAnnB,KAAAgB,OAAAgmB,EAAAhmB,OAEAomB,EAAAD,EAAAD,EAAAvlB,SAAAmlB,IAAAG,EAAAtlB,SAAAmlB,IACAO,EAAAF,EAAAF,EAAAC,EAEAvmB,EAAA,EAAAA,EAAA0mB,EAAArmB,OAAAL,IAAA,CACA,GAAAqG,GAAAqgB,EAAA1mB,GAAAgB,SAAAuG,KAAAlB,GACAiB,EAAAmf,EAAApgB,EAEAiB,IACA8S,EAAAtY,KAAAwF,GAIA,MAAAjI,MAAA6H,MAAAkT,IAGAuM,IAAA,SAAAN,GACA,GAAA5jB,GAAApD,KAAA2B,SAAAyB,EAEAhC,GAAAoF,OAAAwgB,KACAA,EAAA5jB,EAAAmI,EAAAyb,GAGA,IAAAjM,MACAkM,EAAAjnB,KACAknB,EAAAF,EAEAxY,EAAA,SAAA6Y,EAAAL,GAEA,IAAA,GAAArmB,GAAA,EAAAA,EAAA0mB,EAAArmB,OAAAL,IAAA,CACA,GAAAsH,GAAAof,EAAA1mB,GACAqG,EAAAiB,EAAAtG,SAAAuG,KAAAlB,GACAugB,EAAAP,EAAArlB,SAAAmlB,IAAA9f,EAEAugB,IACAxM,EAAAtY,KAAAwF,IASA,OAHAuG,GAAAyY,EAAAC,GACA1Y,EAAA0Y,EAAAD,GAEAjnB,KAAA6H,MAAAkT,IAGA1D,KAAA,SAAA2P,GACA,GAAA5jB,GAAApD,KAAA2B,SAAAyB,EAEAhC,GAAAoF,OAAAwgB,KACAA,EAAA5jB,EAAAmI,EAAAyb,GAGA,IAAAlH,MACAC,KACAyH,KACAP,EAAAjnB,KACAknB,EAAAF,EAEAxY,EAAA,SAAA6Y,EAAAL,EAAAS,GAEA,IAAA,GAAA9mB,GAAA,EAAAA,EAAA0mB,EAAArmB,OAAAL,IAAA,CACA,GAAAsH,GAAAof,EAAA1mB,GACAqG,EAAAiB,EAAAtG,SAAAuG,KAAAlB,GACAugB,EAAAP,EAAArlB,SAAAmlB,IAAA9f,EAEAugB,GACAC,EAAA/kB,KAAAwF,GAEAwf,EAAAhlB,KAAAwF,IASA,OAHAuG,GAAAyY,EAAAC,EAAApH,GACAtR,EAAA0Y,EAAAD,EAAAlH,IAGAD,KAAA9f,KAAA6H,MAAAiY,GAAApS,QAAA,IACAqS,MAAA/f,KAAA6H,MAAAkY,GAAArS,QAAA,IACA8Z,KAAAxnB,KAAA6H,MAAA2f,GAAA9Z,QAAA,MAIAc,IAAA,SAAAkZ,GACA,GAAAtkB,GAAApD,KAAA2B,SAAAyB,EAEA,KAAAskB,EACA,MAAA1nB,KAGA,IAAAoB,EAAAoF,OAAAkhB,GAAA,CACA,GAAA/N,GAAA+N,CACAA,GAAAtkB,EAAA2X,SAAApB,GAKA,IAAA,GAFAoB,MAEApa,EAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IACAoa,EAAAtY,KAAAzC,KAAAW,GAGA,KAAA,GAAAA,GAAA,EAAAA,EAAA+mB,EAAA1mB,OAAAL,IAAA,CAEA,GAAA6N,IAAAxO,KAAA2B,SAAAmlB,IAAAY,EAAA/mB,GAAAqG,KACAwH,IACAuM,EAAAtY,KAAAilB,EAAA/mB,IAIA,MAAAX,MAAA6H,MAAAkT,IAIA4M,MAAA,SAAAD,GACA,GAAAhmB,GAAA1B,KAAA2B,SACAyB,EAAA1B,EAAA0B,EAEA,KAAAskB,EACA,MAAA1nB,KAGA,IAAAoB,EAAAoF,OAAAkhB,GAAA,CACA,GAAA/N,GAAA+N,CACAA,GAAAtkB,EAAA2X,SAAApB,GAGA,IAAA,GAAAhZ,GAAA,EAAAA,EAAA+mB,EAAA1mB,OAAAL,IAAA,CACA,GAAAinB,GAAAF,EAAA/mB,GACAqG,EAAA4gB,EAAA5gB,KACAwH,GAAA9M,EAAAolB,IAAA9f,EAEA,IAAAwH,EAAA,CACA,GAAAP,GAAAjO,KAAAgB,QAEAhB,MAAAiO,GAAA2Z,EACAlmB,EAAAolB,IAAA9f,GAAA4gB,EACAlmB,EAAAmmB,QAAA7gB,GAAAiH,GAIA,MAAAjO,OAIA8nB,WAAA,SAAA7f,GACAA,EAAAA,EAAA,EAEA,IAAAvG,GAAA1B,KAAA2B,SACAqF,EAAAiB,EAAAjB,KACArG,EAAAe,EAAAmmB,QAAA7gB,EAEA,IAAA,MAAArG,EACA,MAAAX,KAIAA,MAAAW,GAAAmD,OACApC,EAAAolB,IAAA9f,GAAAlD,OACApC,EAAAmmB,QAAA7gB,GAAAlD,MAEA,IAAAikB,GAAApnB,IAAAX,KAAAgB,OAAA,CAGA,IAAAhB,KAAAgB,OAAA,IAAA+mB,EAAA,CACA,GAAAC,GAAAhoB,KAAAgB,OAAA,EACAinB,EAAAjoB,KAAAgoB,EAEAhoB,MAAAgoB,GAAAlkB,OACA9D,KAAAW,GAAAsnB,EACAvmB,EAAAmmB,QAAAI,EAAAjhB,MAAArG,EAMA,MAFAX,MAAAgB,SAEAhB,MAIAkoB,QAAA,SAAAtB,GACA,GAAAxjB,GAAApD,KAAA2B,SAAAyB,EAEA,KAAAwjB,EACA,MAAA5mB,KAGA,IAAAoB,EAAAoF,OAAAogB,GAAA,CACA,GAAAjN,GAAAiN,CACAA,GAAAxjB,EAAA2X,SAAApB,GAGA,IAAA,GAAAhZ,GAAA,EAAAA,EAAAimB,EAAA5lB,OAAAL,IACAX,KAAA8nB,WAAAlB,EAAAjmB,GAGA,OAAAX,OAGAmW,IAAA,SAAAgS,EAAAxb,GAIA,IAAA,GAHA9H,MACAU,EAAAvF,KAEAW,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,GACAkL,EAAAc,EAAAwb,EAAA3kB,MAAAmJ,GAAA1E,EAAAtH,EAAA4E,IAAA4iB,EAAAlgB,EAAAtH,EAAA4E,EAEAV,GAAApC,KAAAoJ,GAGA,MAAAhH,IAGAuC,UAAA,SAAA5E,EAAAmK,GAIA,IAAA,GAHAyb,MACA7iB,EAAAvF,KAEAW,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,GACA0nB,EAAA1b,EAAAnK,EAAAgB,MAAAmJ,GAAA1E,EAAAtH,EAAA4E,IAAA/C,EAAAyF,EAAAtH,EAAA4E,EAEA8iB,IACAD,EAAA3lB,KAAAwF,GAIA,MAAAjI,MAAA6H,MAAAugB,IAGAzc,IAAA,SAAA2c,EAAA3b,GAKA,IAAA,GAHA4b,GADA5c,IAAA5C,EAAAA,GAEAxD,EAAAvF,KAEAW,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,GACAwd,EAAAxR,EAAA2b,EAAA9kB,MAAAmJ,GAAA1E,EAAAtH,EAAA4E,IAAA+iB,EAAArgB,EAAAtH,EAAA4E,EAEA4Y,GAAAxS,IACAA,EAAAwS,EACAoK,EAAAtgB,GAIA,OACAuX,MAAA7T,EACA1D,IAAAsgB,IAIA5L,IAAA,SAAA2L,EAAA3b,GAKA,IAAA,GAHA6b,GADA7L,EAAA5T,EAAAA,EAEAxD,EAAAvF,KAEAW,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,GACAwd,EAAAxR,EAAA2b,EAAA9kB,MAAAmJ,GAAA1E,EAAAtH,EAAA4E,IAAA+iB,EAAArgB,EAAAtH,EAAA4E,EAEAoX,GAAAwB,IACAxB,EAAAwB,EACAqK,EAAAvgB,GAIA,OpBsyGMuX,MAAO7C,EqBtpHb1U,IAAAugB,KAMAhmB,EAAA4C,CACA5C,GAAA,EAAAA,EAAA,KAAAA,EAAA,KAAAA,EAAAimB,MAAAjmB,EAAAkmB,GAAAlmB,EAAAgM,IACAhM,EAAA,MAAAA,EAAA,KAAAA,EAAA,KAAAA,EAAAmmB,WAAAnmB,EAAAomB,mBAAApmB,EAAAqmB,SAAArmB,EAAA+K,IACA/K,EAAA,EAAAA,EAAA,KAAAA,EAAA,KAAAA,EAAAsmB,IAAAtmB,EAAAwP,aAAAxP,EAAA2F,UACA3F,EAAA,KAAAA,EAAA,OAAAA,EAAA,OAAAA,EAAAumB,oBAAAvmB,EAAAwmB,QAAAxmB,EAAA8kB,IACA9kB,EAAAymB,SAAAzmB,EAAA0mB,SAAA1mB,EAAA4E,UACA5E,EAAA2mB,WAAA3mB,EAAA4mB,QAAA5mB,EAAAukB,mBAEAtnB,EAAAD,QAAA4F,IAEA4f,QAAA,GAAAqE,cAAA,KAAAC,IAAA,SAAApoB,EAAAzB,EAAAD,GACA,YAEA,IAAA4F,IACA8H,OAAA,WACA,MAAA,UAAAlN,KAAA+gB,SAGAM,OAAA,WACA,MAAA,UAAArhB,KAAA+gB,SAGA1Z,OAAA,WACA,MAAArH,MAAAqhB,UAAArhB,KAAAuG,SAAAS,OAAAhH,KAAAuB,SAAAyF,MC7BAuiB,SAAA,WACA,MAAAvpB,MAAAqhB,UAAArhB,KAAAuG,SAAAS,OAAAhH,KAAAuB,SAAAyF,MAGA+Z,MAAA,WACA,GAAA9Y,GAAAjI,KAAA,EAEA,OAAAiI,GACAA,EAAAtG,SAAAof,MADA,QAOAthB,GAAAD,QAAA4F,OAEAokB,IAAA,SAAAtoB,EAAAzB,EAAAD,GACA,YAEA,IAAA2B,GAAAD,EAAA,WACAE,EAAAF,EAAA,SAEAgkB,EAAAhkB,EAAA,aAGAuoB,GACAC,OAAA,MACA1iB,GAAA,EACA2iB,SAAA,SAAAvmB,EAAAujB,EAAAiD,GACA,GACA5iB,IADA5F,EAAAulB,QAAAA,GAAAA,EAAAhlB,SAAAglB,EACA,MAAAiD,EAAAA,EAAA5pB,KAAA0pB,OAAA1pB,KAAAgH,GAEA,IAAA5D,EAAAyC,eAAAmB,GAAAuT,QACAva,KAAAgH,SAEA,OAAA5D,EAAAyC,eAAAmB,GAAAuT,SACAvT,EAAAhH,KAAA0pB,UAAA1pB,KAAAgH,EAIA,OAAAA,KAKA6iB,EAAA,SAAAzmB,EAAA2X,EAAAzV,GACA,KAAAtF,eAAA6pB,IACA,MAAA,IAAAA,GAAAzmB,EAAA2X,EAAAzV,EAGA,IAAAxB,SAAAV,IAAAhC,EAAAgkB,KAAAhiB,GAEA,WADAjC,GAAAiI,MAAA,iDAIA,IAAA0d,MACAe,KACAiC,GAAA,CAEA,IAAA/O,GAEA,GAAAA,EAAA/Z,OAAA,GAAAI,EAAAwL,YAAAmO,EAAA,MAAA3Z,EAAAulB,QAAA5L,EAAA,IAAA,CACA+O,GAAA,CAMA,KAAA,GAHAvkB,MACAwkB,KAEAppB,EAAA,EAAAG,EAAAia,EAAA/Z,OAAAF,EAAAH,EAAAA,IAAA,CACA,GAAAqpB,GAAAjP,EAAApa,EAEA,OAAAqpB,EAAA9hB,OACA8hB,EAAA9hB,QAGA,IAAAA,GAAA8hB,EAAA9hB,IAGA,IAAA,MAAAA,EAAAlB,GACAkB,EAAAlB,GAAAyiB,EAAAE,SAAAvmB,EAAA4mB,OACA,IAAA,IAAA5mB,EAAAyC,eAAAqC,EAAAlB,IAAAhG,QAAA+oB,EAAA7hB,EAAAlB,IACA,QAGA,IAAAiB,GAAA,GAAAid,GAAA9hB,EAAA4mB,GAAA,EACAzkB,GAAA9C,KAAAwF,GACA8hB,EAAA7hB,EAAAlB,KAAA,EAGA+T,EAAAxV,OA7BAwV,KAgCA/a,MAAAgB,OAAA,CAEA,KAAA,GAAAL,GAAA,EAAAG,EAAAia,EAAA/Z,OAAAF,EAAAH,EAAAA,IAAA,CACA,GAAAgmB,GAAA5L,EAAApa,EACA,IAAAgmB,EAAA,CAEA,GAAA3f,GAAA2f,EAAAhlB,SAAAuG,KAAAlB,KAEA1B,GAAAA,EAAAoI,SAAAoZ,EAAA9f,MACA8f,EAAA9f,GAAA2f,EACAkB,EAAA7gB,GAAAhH,KAAAgB,OAEAhB,KAAAA,KAAAgB,QAAA2lB,EACA3mB,KAAAgB,WAIAhB,KAAA2B,UACAyB,GAAAA,EACA0jB,IAAAA,EACAe,QAAAA,GAIAiC,GACA9pB,KAAAmlB,WASA/f,EAAA8f,EAAAviB,UAAAknB,EAAAlnB,SAEAyC,GAAAxC,eAAA,WACA,MAAA,cAGAwC,EAAAyC,MAAA,SAAAzE,EAAAmC,EAAA/D,GAOA,MANAJ,GAAAgkB,KAAAhiB,KACA5B,EAAA+D,EACAA,EAAAnC,EACAA,EAAApD,KAAAoD,MAGA,GAAAymB,GAAAzmB,EAAAmC,EAAA/D,IAGA4D,EAAAhC,GAAA,WACA,MAAApD,MAAA2B,SAAAyB,IAGAgC,EAAAuhB,QAAA,WACA,MAAA3mB,MAAA,IAGAoF,EAAAqI,WAAA,WACA,MAAArM,GAAAqM,WAAAzN,MACAA,KAEA,GAAA6pB,GAAA7pB,KAAA2B,SAAAyB,IAAApD,QAIAoF,EAAAsI,OAAA,WACA,MAAA,IAAAmc,GAAA7pB,KAAA2B,SAAAyB,GAAApD,MAAA0N,QAAA,KAGAtI,EAAAS,eAAA,SAAAmB,GACA,GAAA5D,GAAApD,KAAA2B,SAAAyB,GACA6E,EAAAjI,KAAA2B,SAAAmlB,IAAA9f,EAEA,OAAAiB,GAAAA,EAAA,GAAA4hB,GAAAzmB,IAGAgC,EAAA4kB,KAAA,SAAAC,GACA,GAAAhiB,GAAAjI,KAAA2mB,UACAvjB,EAAApD,KAAAoD,IAEA,IAAA,MAAA6E,GAAAgiB,EAAA,MAAAjqB,KAEA,IAAA,MAAAiI,EAAA,MAAAnE,OAEA,IAAAC,GAAAkE,EAAAtG,QAEA,IAAAP,EAAAwL,YAAAqd,GAAA,CAEA7mB,EAAA8mB,aAEAD,EAAA/hB,MACAD,EAAAC,KAAA+hB,EAAA/hB,MAGA+hB,EAAAjN,UACA/U,EAAA+U,SAAAiN,EAAAjN,SAKA,IAAAmN,GAAA,SAAA3X,EAAA4X,EAAAC,GACA,GAAAC,GAAAL,EAAAzX,EAEA,OAAA8X,GAAAA,IAAAvmB,EAAAyO,KACA8X,EACAriB,EAAAmiB,KAEAniB,EAAAoiB,MAqBA,OAhBAF,GAAA,UAAA,SAAA,WAEAA,EAAA,WAAA,SAAA,YAEAA,EAAA,aAAA,YAAA,eAEAA,EAAA,SAAA,OAAA,UAEAA,EAAA,YAAA,UAAA,aAEA,MAAAF,EAAAjS,SACA/P,EAAA+P,QAAAiS,EAAAjS,SAGA5U,EAAAmnB,WAEAvqB,KAEA,GAAA8D,SAAAmmB,EAAA,CAEA,GAAAD,IACA9hB,KAAA/G,EAAAuX,KAAA3U,EAAAmE,MACA8U,SAAA7b,EAAAuX,KAAA3U,EAAAiZ,UACA+D,MAAAhd,EAAAgd,MACAxE,QAAAxY,EAAAwY,QACAiJ,SAAAzhB,EAAAyhB,SACAC,WAAA1hB,EAAA0hB,WACAlI,OAAAxZ,EAAAwZ,OACAoI,UAAA5hB,EAAA4hB,UACA3N,QAAA,MAGAA,IACA,KAAA,GAAAI,KAAArU,GAAAiU,QACAjU,EAAAiU,QAAAI,IACAJ,EAAAvV,KAAA2V,EAKA,OAFA4R,GAAAhS,QAAAA,EAAAwS,KAAA,KAEAR,IAIA5kB,EAAAqlB,MAAA,WAGA,IAAA,GAFAA,MAEA9pB,EAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAsH,GAAAjI,KAAAW,GACAqpB,EAAA/hB,EAAA+hB,MAEAS,GAAAhoB,KAAAunB,GAGA,MAAAS,IAGArlB,EAAAslB,MAAA,WAIA,IAAA,GAHAtnB,GAAApD,KAAAoD,KACAunB,KAEAhqB,EAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAsH,GAAAjI,KAAAW,GACAqpB,EAAA/hB,EAAA+hB,OACAU,EAAA,GAAAxF,GAAA9hB,EAAA4mB,GAAA,EAEAW,GAAAloB,KAAAioB,GAGA,MAAA,IAAAb,GAAAzmB,EAAAunB,IAEAvlB,EAAAsT,KAAAtT,EAAAslB,MAEAtlB,EAAA+f,QAAA,SAAAyF,GACA,GAAA7qB,GAAAC,KACA6qB,KACAznB,EAAArD,EAAAqD,IAEAU,UAAA8mB,IACAA,GAAA,EASA,KAAA,GAJA7P,MACAzT,KAAAH,KACAuB,EAAA,EACAwM,EAAA,EACAvU,EAAA,EAAAG,EAAAf,EAAAiB,OAAAF,EAAAH,EAAAA,IAAA,CACA,GAAAsH,GAAAlI,EAAAY,EAGAsH,GAAAiF,UACA5F,EAAA7E,KAAAwF,GACAS,MAEAvB,EAAA1E,KAAAwF,GACAiN,KAIA6F,EAAAzT,EAAAoT,OAAAvT,EAGA,KAAA,GAAAxG,GAAA,EAAAG,EAAAia,EAAA/Z,OAAAF,EAAAH,EAAAA,IAAA,CACA,GAAAsH,GAAA8S,EAAApa,EAEA,IAAAsH,EAAAsU,UAAA,CAKA,GAAA5a,GAAAsG,EAAAtG,SACAuG,EAAAvG,EAAAuG,IAGA,IAAApE,SAAAoE,EAAAlB,GACAkB,EAAAlB,GAAAyiB,EAAAE,SAAAvmB,EAAA6E,OAEA,IAAA7G,EAAA0Q,OAAA5J,EAAAlB,IACAkB,EAAAlB,GAAA,GAAAkB,EAAAlB,OAEA,CAAA,GAAA5F,EAAA0pB,YAAA5iB,EAAAlB,MAAA5F,EAAAoF,OAAA0B,EAAAlB,IAAA,CACA7F,EAAAiI,MAAA,kDAAAlB,EAAAlB,GAAA,IAGA,UACA,GAAA,IAAA5D,EAAAyC,eAAAqC,EAAAlB,IAAAhG,OAAA,CACAG,EAAAiI,MAAA,0CAAAlB,EAAAlB,GAAA,IAGA,WAGA,GAAAA,GAAAkB,EAAAlB,EAEA,IAAAiB,EAAAiF,SAAA,CACA,GAAAnB,GAAA9D,EACAyV,EAAA/b,EAAAqb,QAIA,OAAAU,EAAAG,IACAH,EAAAG,EAAA,GAGA,MAAAH,EAAAI,IACAJ,EAAAI,EAAA,GAIA,GAAA7V,EAAAoZ,SAAA,CAMA,IAAA,GAJA5V,GAAAxD,EACA8iB,GAAA,SAAA,UACAC,EAAAD,EAAA/pB,OACAiqB,GAAA,EACAhe,EAAA,EAAA+d,EAAA/d,EAAAA,IAAA,CAEA,GAAAgO,GAAA8P,EAAA9d,GACAkR,EAAAjW,EAAA+S,EAEA7Z,GAAA0Q,OAAAqM,KACAA,EAAAjW,EAAA+S,GAAA,GAAA/S,EAAA+S,IAGA,MAAAkD,GAAA,KAAAA,GAEAhd,EAAAiI,MAAA,wBAAApC,EAAA,sBAAAiU,GACAgQ,GAAA,GACA7nB,EAAAyC,eAAAsY,GAAA5D,UAEApZ,EAAAiI,MAAA,wBAAApC,EAAA,sBAAAiU,EAAA,KAAAkD,EAAA,KACA8M,GAAA,GAIA,GAAAA,EAAA,QAEA,IAAAC,GAAA9nB,EAAAyC,eAAAqC,EAAA3B,QACA4kB,EAAA/nB,EAAAyC,eAAAqC,EAAA3G,OAEA2pB,GAAAvpB,SAAAwF,MAAA1E,KAAAgJ,GACA0f,EAAAxpB,SAAAwF,MAAA1E,KAAAgJ,GAEAA,EAAA9J,SAAA4E,OAAA2kB,EACAzf,EAAA9J,SAAAJ,OAAA4pB,EAKAxpB,EAAAmlB,OACAnlB,EAAAmlB,IAAA9f,GAAAiB,EAEAtG,EAAA4a,SAAA,EACAnZ,EAAAgoB,UAAAnjB,GAEA4iB,EAAApoB,KAAAwF,IAIA,IAAA,GAAAtH,GAAA,EAAA+H,EAAA/H,EAAAA,IAAA,CACA,GAAAoL,GAAAgP,EAAApa,GACAuH,EAAA6D,EAAApK,SAAAuG,IAEA9G,GAAA0Q,OAAA5J,EAAA+R,UACA/R,EAAA+R,OAAA,GAAA/R,EAAA+R,OAGA,IAAAoR,GAAAnjB,EAAA+R,OAEAqR,EAAA,MAAAD,CAEA,IAAAC,EAAA,CACA,GAAArR,GAAA7W,EAAAyC,eAAAwlB,EAEA,IAAApR,EAAAM,QAEArS,EAAA+R,OAAAnW,WACA,CAGA,IAFA,GAAAynB,IAAA,EACAC,EAAAvR,GACAuR,EAAAjR,SAAA,CACA,GAAAxO,EAAAiD,KAAAwc,GAAA,CAEAD,GAAA,EACArjB,EAAA+R,OAAAnW,MAGA,OAGA0nB,EAAAA,EAAAvR,SAGAsR,IAEAtR,EAAA,GAAAtY,SAAA8Y,SAAAhY,KAAAsJ,GACAA,EAAApK,SAAAsY,OAAAA,EAAA,GAGA7W,EAAAzB,SAAA+c,kBAAA,KAOA,GADAmM,EAAA,GAAAhB,GAAAzmB,EAAAynB,GACAA,EAAA7pB,OAAA,EAAA,CAEA,GAAAyqB,GAAAZ,EAAArc,IAAAqc,EAAAxiB,kBAAAmG,IAAAqc,EAAA5Q,SACAwR,GAAA9S,YAAAiS,GAEAA,EACAC,EAAAxN,SAAA,OAEAwN,EAAAjS,QAAA,OAIA,MAAA7Y,IAGAqF,EAAAmX,QAAA,WACA,GAAAtU,GAAAjI,KAAA,EACA,OAAAiI,IAAAA,EAAAtG,SAAA4a,SAGAnX,EAAAsmB,OAAA,WACA,GAAAzjB,GAAAjI,KAAA,EACA,OAAAiI,KAAAA,EAAAtG,SAAA4a,SAGAnX,EAAAyhB,OAAA,SAAA+D,GAYA,QAAAe,GAAA5f,GAEA,IAAA,GADA5E,GAAA4E,EAAApK,SAAAwF,MACAxG,EAAA,EAAAA,EAAAwG,EAAAnG,OAAAL,IACA6N,EAAArH,EAAAxG,IAMA,QAAAirB,GAAA7f,GAGA,IAAA,GAFA0O,GAAA1O,EAAApK,SAAA8Y,SAEA9Z,EAAA,EAAAA,EAAA8Z,EAAAzZ,OAAAL,IACA6N,EAAAiM,EAAA9Z,IAIA,QAAA6N,GAAAvG,GACA,GAAA4jB,GAAAC,EAAA7jB,EAAAjB,KACA6kB,KAGAC,EAAA7jB,EAAAjB,OAAA,EAGAiB,EAAAiF,UACA6e,EAAAtpB,KAAAwF,GAEA0jB,EAAA1jB,GACA2jB,EAAA3jB,IAEA8jB,EAAAxhB,QAAAtC,IAaA,QAAA+jB,GAAAjgB,EAAAN,GAEA,IAAA,GADAzD,GAAA+D,EAAApK,SAAAwF,MACA8F,EAAA,EAAAA,EAAAjF,EAAAhH,OAAAiM,IAAA,CACA,GAAAgf,GAAAjkB,EAAAiF,EAEA,IAAAxB,IAAAwgB,EAAA,CACAjkB,EAAAF,OAAAmF,EAAA,EACA,SAKA,QAAAif,GAAAjS,EAAAhS,GACAA,EAAAA,EAAA,GACAgS,EAAAA,EAAA,EAGA,KAAA,GAFAQ,GAAAR,EAAAtY,SAAA8Y,SAEAxN,EAAA,EAAAA,EAAAwN,EAAAzZ,OAAAiM,IACA,GAAAwN,EAAAxN,GAAA,KAAAhF,EAAA,GAAA,CACAwS,EAAA3S,OAAAmF,EAAA,EACA,QA3EA,GAAAlN,GAAAC,KACAuc,KACAwP,KACAD,KACA1oB,EAAArD,EAAA4B,SAAAyB,EAEAU,UAAA8mB,IACAA,GAAA,EA0CA,KAAA,GAAAjqB,GAAA,EAAAG,EAAAf,EAAAiB,OAAAF,EAAAH,EAAAA,IAAA,CACA,GAAAsH,GAAAlI,EAAAY,EAEA6N,GAAAvG,GA4BA,IAAA,GAAAtH,GAAA,EAAAA,EAAAorB,EAAA/qB,OAAAL,IAAA,CACA,GAAAsH,GAAA8jB,EAAAprB,EAWA,IARAsH,EAAAtG,SAAA4a,SAAA,EAGAnZ,EAAA+oB,eAAAlkB,GAGAsU,EAAA9Z,KAAAwF,GAEAA,EAAAoZ,SAAA,CACA,GAAA6J,GAAAjjB,EAAA1B,SAAA,GACA4kB,EAAAljB,EAAA1G,SAAA,EAEAyqB,GAAAd,EAAAjjB,GACA+jB,EAAAb,EAAAljB,OAEA,CACA,GAAAgS,GAAAhS,EAAAgS,QAEA,KAAAA,EAAAjZ,QACAkrB,EAAAjS,EAAAhS,IAMA,GAAAmkB,GAAAhpB,EAAAzB,SAAAoZ,QACA3X,GAAAzB,SAAA+c,kBAAA,CACA,KAAA,GAAA/d,GAAA,EAAAA,EAAAyrB,EAAAprB,OAAAL,IAAA,CACA,GAAAsH,GAAAmkB,EAAAzrB,EAEA,IAAAsH,EAAA2S,WAAA,CACAxX,EAAAzB,SAAA+c,kBAAA,CACA,QAIA,GAAA2N,GAAA,GAAAxC,GAAA7pB,KAAAoD,KAAAmZ,EACA8P,GAAA/c,OAAA,IAGAsb,GACA5qB,KAAAoD,KAAAmjB,QACA3hB,KAAA,SACA6I,WAAA4e,IAIAA,EAAAzT,QAAA,UAKA,KAAA,GADA0T,MACA3rB,EAAA,EAAAA,EAAAorB,EAAA/qB,OAAAL,IAAA,CACA,GAAAsH,GAAA8jB,EAAAprB,GACAuM,EAAA,UAAAjF,EAAAtG,SAAAof,MACAsK,EAAApjB,EAAAtG,SAAAuG,KAAA+R,MAEA,IAAA/M,GAAApJ,SAAAunB,IAAAiB,EAAAjB,GAAA,CACAiB,EAAAjB,IAAA,CACA,IAAApR,GAAA7W,EAAAyC,eAAAwlB,EAEApR,IAAA,IAAAA,EAAAjZ,SAAAiZ,EAAAtY,SAAA4a,SAAA,IAAAtC,EAAAQ,WAAAzZ,QACAiZ,EAAAtB,eAKA,MAAA,IAAAkR,GAAAzmB,EAAAmZ,IAGAnX,EAAAmnB,KAAA,SAAAC,GACA,GAAAppB,GAAApD,KAAA2B,SAAAyB,EAEA,IAAAU,SAAA0oB,EAAAjmB,QAAAzC,SAAA0oB,EAAAjrB,OAAA,CACA,GAAAkrB,GAAAD,EAAAjmB,OACAmmB,EAAAF,EAAAjrB,OACAorB,EAAAvpB,EAAAyC,eAAA4mB,GAAAzrB,OAAA,EACA4rB,EAAAxpB,EAAAyC,eAAA6mB,GAAA1rB,OAAA,CAEA,IAAA2rB,GAAAC,EAAA,CACA,GAAAnC,GAAAzqB,KAAAyqB,OAEAzqB,MAAA6mB,QAEA,KAAA,GAAAlmB,GAAA,EAAAA,EAAA8pB,EAAAzpB,OAAAL,IAAA,CACA,GAAAqpB,GAAAS,EAAA9pB,EAEA,WAAAqpB,EAAAjJ,QACA4L,IAAA3C,EAAA9hB,KAAA3B,OAAAkmB,GACAG,IAAA5C,EAAA9hB,KAAA3G,OAAAmrB,IAIA,MAAAtpB,GAAAoL,IAAAic,QAGA,IAAA3mB,SAAA0oB,EAAAvS,OAAA,CACA,GAAAoR,GAAAmB,EAAAvS,OACA4S,EAAA,OAAAxB,GAAAjoB,EAAAyC,eAAAwlB,GAAArqB,OAAA,CAEA,IAAA6rB,EAAA,CACA,GAAApC,GAAAzqB,KAAAyqB,QACAqC,EAAA9sB,KAAA8a,cACAiS,EAAAD,EAAAnF,MAAAmF,EAAAte,IAAAxO,MAAAgI,iBAEAhI,MAAA6mB,QAEA,KAAA,GAAAlmB,GAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAqpB,GAAAS,EAAA9pB,EAEA,WAAAqpB,EAAAjJ,QACAiJ,EAAA9hB,KAAA+R,OAAA,OAAAoR,EAAAvnB,OAAAunB,IAKA,MAAAjoB,GAAAoL,IAAAic,GAAA9C,MAAAoF,EAAA5H,WAGA,MAAAnlB,QAIAkB,EAAA,gBACAA,EAAA,eACAA,EAAA,WACAA,EAAA,iBACAA,EAAA,eACAA,EAAA,UtBwrHEA,EAAQ,YuB32IVA,EAAA,gBACAA,EAAA,YACAA,EAAA,YACAA,EAAA,WACAA,EAAA,WACAA,EAAA,eACAA,EAAA,YACAA,EAAA,WACAA,EAAA,sBACAA,EAAA,iBACAoK,QAAA,SAAAgI,GACAnS,EAAAS,OAAAwD,EAAAkO,KAGA7T,EAAAD,QAAAqqB,IAEA7E,QAAA,GAAAxL,UAAA,GAAAwT,eAAA,EAAAC,cAAA,GAAAC,UAAA,GAAAC,gBAAA,GAAAC,cAAA,GAAAC,SAAA,GAAAC,WAAA,GAAAC,eAAA,GAAAC,YAAA,GAAAC,WAAA,GAAAC,WAAA,GAAAC,UAAA,GAAAC,UAAA,GAAAC,cAAA,GAAAC,WAAA,GAAAC,UAAA,GAAAC,qBAAA,GAAAC,eAAA,KAAAC,IAAA,SAAAhtB,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,SACAitB,EAAAjtB,EAAA,WAEAkE,GACAgpB,KAAA,SAAA5rB,GACA,GAAApB,EAAAoB,GAAAA,GACA,IAAA,GAAA7B,GAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAsH,GAAAjI,KAAAW,GACAkL,EAAArJ,EAAAgB,MAAAyE,GAAAtH,EAAAsH,GAEA,IAAA4D,KAAA,EAAA,MAGA,MAAA7L,OAGAsL,QAAA,SAAA9I,EAAAmK,GACA,GAAAvL,EAAAoB,GAAAA,GAEA,IAAA,GAAA7B,GAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAsH,GAAAjI,KAAAW,GACAkL,EAAAc,EAAAnK,EAAAgB,MAAAmJ,GAAA1E,EAAAtH,EAAAX,OAAAwC,EAAAyF,EAAAtH,EAAAX,KAEA,IAAA6L,KAAA,EAAA,MAIA,MAAA7L,OAGAkO,QAAA,WAGA,IAAA,GAFAmgB,MAEA1tB,EAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IACA0tB,EAAA5rB,KAAAzC,KAAAW,GAGA,OAAA0tB,IAGAzZ,MAAA,SAAAnP,EAAAC,GACA,GAAA2oB,MACAC,EAAAtuB,KAAAgB,MAEA,OAAA0E,IACAA,EAAA4oB,GAGA,MAAA7oB,IACAA,EAAA,GAGA,EAAAA,IACAA,EAAA6oB,EAAA7oB,GAGA,EAAAC,IACAA,EAAA4oB,EAAA5oB,EAGA,KAAA,GAAA/E,GAAA8E,EAAA9E,GAAA,GAAA+E,EAAA/E,GAAA2tB,EAAA3tB,EAAAA,IACA0tB,EAAA5rB,KAAAzC,KAAAW,GAGA,OAAAX,MAAA6H,MAAAwmB,IAGA/e,KAAA,WACA,MAAAtP,MAAAgB,QAGAutB,GAAA,SAAA5tB,GACA,MAAAX,MAAAW,IAAAX,KAAA6H,SAGA2mB,MAAA,WACA,MAAAxuB,MAAA,IAAAA,KAAA6H,SAGA4mB,KAAA,WACA,MAAAzuB,MAAAA,KAAAgB,OAAA,IAAAhB,KAAA6H,SAGA0S,MAAA,WACA,MAAA,KAAAva,KAAAgB,QAGAmZ,SAAA,WACA,OAAAna,KAAAua,SAGApM,KAAA,SAAAugB,GACA,IAAAttB,EAAAoB,GAAAksB,GACA,MAAA1uB,KAGA,IAAA2uB,GAAA3uB,KAAAkO,UAAAC,KAAAugB,EAEA,OAAA1uB,MAAA6H,MAAA8mB,IAGAC,aAAA,WACA,MAAA5uB,MAAAmO,KAAAggB,IAGAU,OAAA,WACA,GAAA5mB,GAAAjI,KAAA,EACA,KAAAiI,EAAA,MAAAnE,OAGA,IAAApC,GAAAuG,EAAAtG,SACAof,EAAArf,EAAAqf,KAEA,IAAA,UAAAA,EAAA,CACA,GAAA3T,GAAA1L,EAAAwG,KAAA+R,OAAAhS,EAAAiS,UAAA5K,OAAA,CAEA,OAAArH,GAAA2S,WCrIAxN,ExBk/IelC,OAAO4jB,UwBh/ItB,GAAA5D,GAAAxpB,EAAA6E,OACA4kB,EAAAzpB,EAAAH,OACAwtB,EAAA7D,EAAA2D,SACAG,EAAA7D,EAAA0D,QAEA,OAAApf,MAAA9D,IAAAojB,EAAAC,EAAA,IAKAvvB,GAAAD,QAAA4F,IAEA4f,QAAA,GAAAiK,UAAA,KAAAC,IAAA,SAAAhuB,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,SACAC,EAAAD,EAAA,WAEAkE,GAGA+pB,gBAAA,SAAAC,EAAA9pB,EAAA9C,GACA,GAAA8E,GAAAtH,KAAAsH,QACAlE,EAAApD,KAAAoD,IAMA,IAJAgsB,EAAAxW,SAAAhU,KAAA,cAAAwqB,OAAAA,IAEAA,EAAAC,cAEA/pB,EAAAmS,QAAA,CACA,IAAA,GAAA9W,GAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IAAA,CACA,GAAAoL,GAAAzE,EAAA3G,GACA2uB,EAAA3uB,IAAA2G,EAAAtG,OAAA,EAEAuuB,EAAA/sB,EAAAzB,KAAAgL,EAAApL,EAAAoL,GACA2R,EAAA3R,EAAAiR,UAEA5b,GAAA0Q,OAAA4L,EAAAG,IAAAzc,EAAA0Q,OAAA4L,EAAAI,IACA/R,EAAAyR,gBAAAK,EAAA,EAAAC,EAAA,GAGA,IAAA0R,GAAAzjB,EAAA/I,WACAga,SAAAuS,EACA1tB,SAAAyD,EAAAmqB,kBACAC,OAAApqB,EAAAqqB,gBACAC,KAAAN,EAAA,WACAhqB,EAAAuqB,KACAzsB,EAAAysB,IAAAvqB,EAAAC,KAAAD,EAAAoa,UAFA5b,OAKAvB,SAAA+sB,EAAA,WACA,MAAAhqB,EAAA8Y,MACAhb,EAAAgb,KAAA9Y,EAAA8Y,MAGA9Y,EAAA+Y,KACAjb,EAAAib,IAAA/Y,EAAA+Y,KAGA/Y,EAAAuqB,KACAzsB,EAAAysB,IAAAvqB,EAAAC,KAAAD,EAAAoa,SAGA0P,EAAAnJ,IAAA,aAAA3gB,EAAA5B,MACA0rB,EAAAxW,SAAAhU,KAAA,aAAAwqB,OAAAA,KAdAtrB,QAkBAsrB,GAAAC,WAAA5sB,KAAA+sB,GAEAA,EAAAlsB,OAGA8rB,EAAAnJ,IAAA,cAAA3gB,EAAAwqB,OACAV,EAAAxW,SAAAhU,KAAA,cAAAwqB,OAAAA,QAEA9nB,GAAAmW,UAAAjb,GAEA8C,EAAAuqB,KACAzsB,EAAAysB,IAAAvqB,EAAAC,KAAAD,EAAAoa,SAGA,MAAApa,EAAA8Y,MACAhb,EAAAgb,KAAA9Y,EAAA8Y,MAGA9Y,EAAA+Y,KACAjb,EAAAib,IAAA/Y,EAAA+Y,KAGA+Q,EAAAnJ,IAAA,cAAA3gB,EAAAwqB,OACAV,EAAAxW,SAAAhU,KAAA,cAAAwqB,OAAAA,IAEAA,EAAAnJ,IAAA,aAAA3gB,EAAA5B,MACA0rB,EAAAxW,SAAAhU,KAAA,aAAAwqB,OAAAA,GAGA,OAAApvB,OAGAovB,OAAA,SAAA9pB,GACA,GAAAlC,GAAApD,KAAAoD,IAMA,OAJAA,GAAAgsB,OAAAjuB,EAAAS,UAAA0D,GACAC,KAAAvF,QAGAA,MC9GA+vB,WAAA,SAAAzqB,GACA,GAAAlC,GAAApD,KAAAoD,IAEA,OAAAA,GAAA2sB,WAAA5uB,EAAAS,UAAA0D,GACAC,KAAAvF,SAOAoF,GAAA4qB,aAAA5qB,EAAA2qB,WAEAtwB,EAAAD,QAAA4F,IAEA4f,QAAA,GAAAxL,UAAA,KAAAyW,IAAA,SAAA/uB,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,SAEAkE,GAGAuT,YAAA,SAAAiS,GACA,GAAAxnB,GAAApD,KAAA2B,SAAAyB,EAEA,KAAAA,EAAAgd,eAAA,MAAApgB,KAEA,IAAAoD,EAAAzB,SAAAuuB,cAAA,CACA,GAAAC,GAAA/sB,EAAAzB,SAAAyuB,cAIA,OAFAD,GAAAxI,MAAA3nB,MAEAA,KAGA,GAAA8B,GAAAsB,EAAAtB,OACA8oB,GAAAA,GAAA9mB,SAAA8mB,GAAA,GAAA,EAEA9oB,EAAA0B,MAAAxD,KAEA,IAAAqwB,GAAArwB,KAAAod,uBACAkT,EAAAD,EAAArvB,OAAA,EAAAhB,KAAAwO,IAAA6hB,GAAArwB,IAOA,OALA4qB,GACA0F,EAAAjT,SAAA,SAEAiT,EAAA1X,QAAA,SAEA5Y,MAIAuwB,cAAA,SAAA3F,GACA,GAAAxnB,GAAApD,KAAA2B,SAAAyB,GACAtB,EAAAsB,EAAAtB,OAGA,IAFA8oB,EAAAA,GAAA9mB,SAAA8mB,GAAA,GAAA,GAEAxnB,EAAAgd,eAAA,MAAApgB,KAEA8B,GAAAyuB,cAAAvwB,KAEA,IAAAqwB,GAAArwB,KAAAod,uBACAkT,EAAAD,EAAArvB,OAAA,EAAAhB,KAAAwO,IAAA6hB,GAAArwB,IAOA,OALA4qB,GACA0F,EAAAjT,SAAA,SAEAiT,EAAA1X,QAAA,SAEA5Y,MAKAwwB,YAAA,SAAAC,GACA,GAAArtB,GAAApD,KAAAoD,IACA,KAAAA,EAAAgd,eAAA,MAAApgB,KAEA,IAAAiI,GAAAjI,KAAA,EAEA,IAAAiI,EAAA,CACA,GAAAyoB,GAAAzoB,EAAA7E,KAAAtB,QAAA6uB,iBAAA1oB,EAEA,OAAAnE,UAAA2sB,EACAC,EAEAA,EAAAD,KAMA1uB,IAAA,SAAAwC,EAAAib,GACA,GAAApc,GAAApD,KAAAoD,IAEA,KAAAA,EAAAgd,eAAA,MAAApgB,KAEA,IAAA4wB,IAAA,EACA9uB,EAAAsB,EAAAtB,OAEA,IAAAV,EAAAwL,YAAArI,GAAA,CACA,GAAA+O,GAAA/O,CACAzC,GAAAgkB,YAAA9lB,KAAAsT,EAAAsd,EAEA,IAAAP,GAAArwB,KAAAod,uBACAkT,EAAAD,EAAArvB,OAAA,EAAAhB,KAAAwO,IAAA6hB,GAAArwB,IACAswB,GAAAjT,SAAA,aAEA,IAAAjc,EAAAoF,OAAAjC,GAAA,CAEA,GAAAT,SAAA0b,EAAA,CACA,GAAAvX,GAAAjI,KAAA,EAEA,OAAAiI,GACAnG,EAAA+uB,sBAAA5oB,EAAA1D,GAEA,OAIAzC,EAAAgkB,YAAA9lB,KAAAuE,EAAAib,EAAAoR,EAEA,IAAAP,GAAArwB,KAAAod,uBACAkT,EAAAD,EAAArvB,OAAA,EAAAhB,KAAAwO,IAAA6hB,GAAArwB,IACAswB,GAAAjT,SAAA,aAGA,IAAAvZ,SAAAS,EAAA,CACA,GAAA0D,GAAAjI,KAAA,EAEA,OAAAiI,GACAnG,EAAAgvB,YAAA7oB,GAEA,OAIA,MAAAjI,OAGA+wB,UAAA,SAAAC,GACA,GAAA5tB,GAAApD,KAAAoD,IAEA,KAAAA,EAAAgd,eAAA,MAAApgB,KAEA,IAAA4wB,IAAA,EACA9uB,EAAAsB,EAAAtB,QACAyD,EAAAvF,IAEA,IAAA8D,SAAAktB,EACA,IAAA,GAAArwB,GAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,EAEAmB,GAAAmvB,kBAAAhpB,EAAA2oB,OAEA,CACAI,EAAAA,EAAAnL,MAAA,MAEA,KAAA,GAAAllB,GAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,EAEAmB,GAAAovB,eAAAjpB,EAAA+oB,EAAAJ,IAIA,GAAAP,GAAArwB,KAAAod,uBACAkT,EAAAD,EAAArvB,OAAA,EAAAhB,KAAAwO,IAAA6hB,GAAArwB,IAGA,OAFAswB,GAAAjT,SAAA,SAEArd,MAGAmxB,KAAA,WAEA,MADAnxB,MAAA+B,IAAA,UAAA,WACA/B,MAGAoxB,KAAA,WAEA,MADApxB,MAAA+B,IAAA,UAAA,QACA/B,MAGAqxB,QAAA,WACA,GAAAjuB,GAAApD,KAAAoD,IACA,KAAAA,EAAAgd,eAAA,OAAA,CAEA,IAAAnY,GAAAjI,KAAA,GACA0e,EAAAtb,EAAAsb,kBAEA,IAAAzW,EAAA,CACA,GAAAnG,GAAAmG,EAAAtG,SAAAG,KAEA,IACA,YAAAA,EAAA,WAAA0d,OACA,YAAA1d,EAAA,QAAA0d,MAEA,OAAA,CAGA,IAAA,UAAAvX,EAAAtG,SAAAof,MAAA,CACA,IAAArC,EAAA,OAAA,CAEA,IAAAxE,GAAAjS,EAAAtG,SAAAuG,KAAA+R,OAAAhS,EAAAiS,UAAA,IAEA,IAAAA,EACA,IAAA,GAAAvZ,GAAA,EAAAA,EAAAuZ,EAAAlZ,OAAAL,IAAA,CACA,GAAAsZ,GAAAC,EAAAvZ,GACA2wB,EAAArX,EAAAtY,SAAAG,MACAyvB,EAAAD,EAAA,WAAA9R,MACAgS,EAAAF,EAAA,QAAA9R,KAEA,IAAA,YAAA+R,GAAA,YAAAC,EACA,OAAA,EAKA,OAAA,EAEA,GAAAtG,GAAAjjB,EAAAtG,SAAA4E,OACA4kB,EAAAljB,EAAAtG,SAAAJ,MAEA,OAAA2pB,GAAAmG,WAAAlG,EAAAkG,YAMAI,OAAA,WACA,GAAAxpB,GAAAjI,KAAA,EAEA,OAAAiI,IACAA,EAAAopB,UADA,QAKAK,iBAAA,WACA,GAAAtuB,GAAApD,KAAAoD,IACA,KAAAA,EAAAgd,eAAA,MAAA,EAEA,IAAA1B,GAAAtb,EAAAsb,mBACAzW,EAAAjI,KAAA,EAEA,IAAAiI,EAAA,CACA,GAAAvG,GAAAuG,EAAAtG,SACAgwB,EAAAjwB,EAAAI,MAAA8vB,QAAApS,KAEA,KAAAd,EAAA,MAAAiT,EAEA,IAAAzX,GAAAxY,EAAAwG,KAAA+R,OAAAhS,EAAAiS,UAAA,IAEA,IAAAA,EACA,IAAA,GAAAvZ,GAAA,EAAAA,EAAAuZ,EAAAlZ,OAAAL,IAAA,CACA,GAAAsZ,GAAAC,EAAAvZ,GACAixB,EAAA3X,EAAAtY,SAAAG,MAAA8vB,QAAApS,KAEAmS,GAAAC,EAAAD,EAIA,MAAAA,KAIAE,YAAA,WACA,GAAAzuB,GAAApD,KAAAoD,IACA,KAAAA,EAAAgd,eAAA,OAAA,CAEA,IAAAnY,GAAAjI,KAAA,GACA0e,EAAAzW,EAAA7E,KAAAsb,kBAEA,OAAAzW,GACAyW,EAGA,IAAAzW,EAAAypB,mBAFA,IAAAzpB,EAAAtG,SAAAG,MAAA8vB,QAAApS,MAFA,QASAsS,iBAAA,WACA,GAAA1uB,GAAApD,KAAAoD,IACA,KAAAA,EAAAgd,eAAA,OAAA,CAEA,IAAAnY,GAAAjI,KAAA,EAEA,IAAAiI,EAAA,CACA,GAAA8pB,GAAA,SAAA9pB,EAAAtG,SAAAG,MAAA,MAAA0d,MACAwS,EAAA,SAAA/pB,EAAAtG,SAAAG,MAAA,OAAA0d,KAEA,OAAAvX,GAAA2S,YAAAmX,GAAAC,IAIAC,cAAA,WzBumJI,GAAI7uB,GAAKpD,KAAKoD,I0B/4JlB,KAAAA,EAAAgd,eAAA,OAAA,CAEA,IAAAnY,GAAAjI,KAAA,EAEA,OAAAiI,GAAAtG,SAAAswB,eAAA,GAAA,GAMA7sB,GAAA8sB,OAAA9sB,EAAAtD,MAAAsD,EAAArD,IACAqD,EAAA+sB,cAAA/sB,EAAAorB,YACAprB,EAAAgtB,aAAAhtB,EAAAitB,YAAAjtB,EAAA2rB,UAEAtxB,EAAAD,QAAA4F,IAEA4f,QAAA,KAAAsN,IAAA,SAAApxB,EAAAzB,EAAAD,GACA,YAIA,SAAA+yB,GAAAjmB,GACA,MAAA,YACA,GAAAkmB,GAAA1lB,UACA2lB,IAGA,IAAA,IAAAD,EAAAxxB,OAAA,CACA,GAAAkH,GAAAsqB,EAAA,GACAE,EAAAF,EAAA,EACAxyB,MAAA2yB,KAAArmB,EAAAqP,MAAAzT,EAAAwqB,OAIA,IAAA,IAAAF,EAAAxxB,OAAA,CACA,GAAA0xB,GAAAF,EAAA,EACAxyB,MAAA2yB,KAAArmB,EAAAqP,MAAA+W,OAIA,IAAA,IAAAF,EAAAxxB,OAAA,CACA,IAAA,GAAAL,GAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAsH,GAAAjI,KAAAW,GACAiyB,GAAAtmB,EAAAumB,WAAA5qB,EAAAtG,SAAA2K,EAAAumB,WACA3a,EAAAjQ,EAAAtG,SAAA2K,EAAA2O,QAAA3O,EAAAkT,KAEA,IAAAlT,EAAAwmB,aAAA,CACA,GAAAA,GAAAxmB,EAAAwmB,aAAA7qB,EAEA,IAAAnE,SAAAgvB,IACAF,EAAAE,GAEAA,GAAA,MAAA9yB,MAIA4yB,IACA3qB,EAAAtG,SAAA2K,EAAA2O,OAAA3O,EAAAkT,MAEAtH,GACAua,EAAAhwB,KAAAwF,IAKA,GAAA8qB,GAAA/yB,KAAA6H,MAAA4qB,EACAM,GAAApa,cACAoa,EAAAna,QAAAtM,EAAAqP,OAGA,MAAA3b,OAIA,QAAAgzB,GAAA1mB,GACAlH,EAAAkH,EAAA2O,OAAA,WACA,GAAAhT,GAAAjI,KAAA,EAEA,IAAAiI,EAAA,CACA,GAAAqE,EAAA2mB,cAAA,CACA,GAAA9U,GAAA7R,EAAA2mB,cAAAhrB,EAEA,IAAAnE,SAAAqa,EACA,MAAAA,GAIA,MAAAlW,GAAAtG,SAAA2K,EAAA2O,SAIA7V,EAAAkH,EAAA0Z,IAAAuM,GACA5W,MAAArP,EAAA0Z,GACA/K,MAAA3O,EAAA2O,MACA4X,UAAAvmB,EAAAumB,UACAC,aAAAxmB,EAAAwmB,aACAtT,OAAA,IAGApa,EAAAkH,EAAA+Z,KAAAkM,GACA5W,MAAArP,EAAA+Z,IACApL,MAAA3O,EAAA2O,MACA4X,UAAAvmB,EAAAumB,UACAC,aAAAxmB,EAAAwmB,aACAtT,OAAA,IArFA,GAAApa,KAyFA4tB,IACA/X,MAAA,SACAgY,cAAA,SAAAhrB,GACA,MAAAA,GAAA7E,KAAA8vB,YAAA,EAAApvB,QAEAkiB,GAAA,OACAK,IAAA,WAGA2M,GACA/X,MAAA,YACAgY,cAAA,SAAAhrB,GACA,MAAAA,GAAA7E,KAAA+vB,iBAAA,EAAArvB,QAEAkiB,GAAA,UACAK,IAAA,cAGA2M,GACA/X,MAAA,WACA4X,UAAA,aACAC,aAAA,SAAA7qB,GACA,MAAAA,GAAA7E,KAAAgwB,mBAAA,EAAAtvB,QAEAkiB,GAAA,SACAK,IAAA,aAGA2M,GACA/X,MAAA,aACAgY,cAAA,SAAAhrB,GACA,MAAAA,GAAA7E,KAAAgwB,mBAAA,EAAAtvB,QAEAkiB,GAAA,YACAK,IAAA,gBAGAjhB,EAAAiuB,SAAAjuB,EAAAkuB,SAEAluB,EAAAsgB,QAAA,WACA,GAAAzd,GAAAjI,KAAA,EACA,OAAAiI,GACAA,EAAAtG,SAAA+jB,QADA,QCpJAsN,GACA/X,MAAA,SACA+K,GAAA,WACAK,IAAA,eAGAjhB,EAAAmuB,SAAA,WACA,GAAAtrB,GAAAjI,KAAA,EACA,OAAAiI,IACAA,EAAAtG,SAAAikB,OADA,QAKAnmB,EAAAD,QAAA4F,OAEAouB,IAAA,SAAAtyB,EAAAzB,EAAAD,GACA,YAgQA,SAAAi0B,GAAAnnB,GACA,MAAA,UAAAqN,GAGA,IAAA,GAFA+Z,MAEA/yB,EAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAsH,GAAAjI,KAAAW,GACAuqB,EAAAjjB,EAAAtG,SAAA2K,EAAA2P,KAEAiP,IACAwI,EAAAjxB,KAAAyoB,GAIA,MAAAlrB,MAAA6H,MAAA6rB,GAAAhmB,QAAA,IAAAjH,OAAAkT,IAYA,QAAAga,GAAArnB,GAEA,MAAA,UAAAsnB,GACA,GAAA7Y,MACA3X,EAAApD,KAAA2B,SAAAyB,GACAW,EAAAuI,KAGAlL,GAAAoF,OAAAotB,KACAA,EAAAxwB,EAAAmI,EAAAqoB,GAMA,KAAA,GAHAC,GAAA7zB,KAAA2B,SAAAmlB,IACAgN,EAAAF,EAAAjyB,SAAAmlB,IAEAzH,EAAA,EAAAA,EAAAuU,EAAA5yB,OAAAqe,IAGA,IAAA,GAFAlY,GAAAysB,EAAAvU,GAAA1d,SAAAwF,MAEAxG,EAAA,EAAAA,EAAAwG,EAAAnG,OAAAL,IAAA,CACA,GAAA8K,GAAAtE,EAAAxG,GACAozB,EAAAtoB,EAAA9J,SAAAuG,KACA8rB,EAAAH,EAAAE,EAAAxtB,SAAAutB,EAAAC,EAAAxyB,QACA0yB,EAAAH,EAAAC,EAAAxtB,SAAAstB,EAAAE,EAAAxyB,QACA2yB,EAAAF,GAAAC,CAEA,IAAAC,EAAA,CAEA,GAAAnwB,EAAAowB,OAAA,CACA,GAAA,WAAApwB,EAAAowB,SAAAH,EAAA,QAEA,IAAA,WAAAjwB,EAAAowB,SAAAF,EAAA,SAGAlZ,EAAAtY,KAAAgJ,IAIA,MAAAzL,MAAA6H,MAAAkT,GAAArN,QAAA,KA8CA,QAAA0mB,GAAA9nB,GACA,GAAA+nB,IACAC,YAAA,EAIA,OAFAhoB,GAAAnL,EAAAS,UAAAyyB,EAAA/nB,GAEA,SAAAqN,GAMA,IAAA,GALAoB,MACA5T,EAAAnH,KAAAmH,QACApD,EAAAuI,EAGA3L,EAAA,EAAAA,EAAAwG,EAAAnG,OAAAL,IASA,IAAA,GARA4zB,GAAAptB,EAAAxG,GACA6zB,EAAAD,EAAAhuB,SAAA,GACAkuB,EAAAD,EAAAxtB,KACA0tB,EAAAH,EAAAhzB,SAAA,GACAozB,EAAAD,EAAA1tB,KACA4tB,EAAAJ,EAAA7yB,SAAAwF,MAGA8F,EAAA,EAAAA,EAAA2nB,EAAA5zB,OAAAiM,IAAA,CACA,GAAA4nB,GAAAD,EAAA3nB,GACA6nB,EAAAD,EAAAlzB,SAAAuG,KACA6sB,EAAAD,EAAAvzB,OACAyzB,EAAAF,EAAAvuB,OAEA+tB,EAAAS,IAAAJ,GAAAK,IAAAP,EACAQ,EAAAR,IAAAM,GAAAJ,IAAAK,GAEAjxB,EAAAuwB,YAAAA,IAAAvwB,EAAAuwB,aAAAA,GAAAW,KACAla,EAAAtY,KAAAoyB,GAKA,MAAA70B,MAAA6H,MAAAkT,GAAArN,QAAA,IAAAjH,OAAAkT,IA9YA,GAAAxY,GAAAD,EAAA,WACAE,EAAAF,EAAA,SAEAkE,IAEAjE,GAAAS,OAAAwD,GAEAqH,MAAA,SAAAkN,GAIA,IAAA,GAHApU,GAAAvF,KACAyM,KAEA9L,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,EACA,IAAAsH,EAAAiF,SAAA,CAIA,GAAAgoB,GAAAjtB,EAAAD,eAAA,WACA,MAAAhI,MAAAkI,KAAA,YAAAD,EAAAjB,MAAAhH,KAAAkI,KAAA,YAAAD,EAAAjB,OACAhG,OAAA,CAEAk0B,IACAzoB,EAAAhK,KAAAwF,IAIA,MAAAjI,MAAA6H,MAAA4E,GAAAiB,QAAA,IAAAjH,OAAAkT,IAIAwb,OAAA,SAAAxb,GAIA,IAAA,GAHApU,GAAAvF,KACAm1B,KAEAx0B,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,EACA,IAAAsH,EAAAiF,SAAA,CAIA,GAAAkoB,GAAAntB,EAAAD,eAAA,WACA,MAAAhI,MAAAkI,KAAA,YAAAD,EAAAjB,MAAAhH,KAAAkI,KAAA,YAAAD,EAAAjB,OACAhG,OAAA,CAEAo0B,IACAD,EAAA1yB,KAAAwF,IAIA,MAAAjI,MAAA6H,MAAAstB,GAAAznB,QAAA,IAAAjH,OAAAkT,IAKA9O,SAAA,SAAA8O,GAIA,IAAA,GAHApU,GAAAvF,KACAq1B,KAEA10B,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,GACA20B,EAAArtB,EAAAjB,IAEA,IAAAiB,EAAAiF,SAGA,IAAA,GADA/F,GAAAc,EAAAtG,SAAAwF,MACA8F,EAAA,EAAAA,EAAA9F,EAAAnG,OAAAiM,IAAA,CACA,GAAAxB,GAAAtE,EAAA8F,GACAwf,EAAAhhB,EAAA9J,SAAAuG,KAAA3B,OACAmmB,EAAAjhB,EAAA9J,SAAAuG,KAAA3G,MAEAkrB,KAAA6I,GAAA5I,IAAA4I,IACAD,EAAA5yB,KAAAgJ,GACA4pB,EAAA5yB,KAAAgJ,EAAAlK,SAAA,MAKA,MAAAvB,MAAA6H,MAAAwtB,GAAA3nB,QAAA,IAAAjH,OAAAkT,IAIA4b,WAAA,SAAA5b,GAKA,IAJA,GAAApU,GAAAvF,KACAw1B,KACAC,OAEA,CACA,GAAA5qB,GAAAtF,EAAAsF,UAEA,IAAA,IAAAA,EAAA7J,OAAA,KAGA,KAAA,GADA00B,IAAA,EACA/0B,EAAA,EAAAA,EAAAkK,EAAA7J,OAAAL,IAAA,CACA,GAAAg1B,GAAA9qB,EAAAlK,GACAi1B,EAAAD,EAAA3uB,IAEAyuB,GAAAG,KACAH,EAAAG,IAAA,EACAJ,EAAA/yB,KAAAkzB,GACAD,GAAA,GAIA,IAAAA,EAAA,KAEAnwB,GAAAsF,EAGA,MAAA7K,MAAA6H,MAAA2tB,GAAA9nB,QAAA,IAAAjH,OAAAkT,IAKAkc,SAAA,SAAAlc,GAIA,IAAA,GAHApU,GAAAvF,KACAq1B,KAEA10B,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,GACA20B,EAAArtB,EAAAjB,IAEA,IAAAiB,EAAAiF,SAGA,IAAA,GADA/F,GAAAc,EAAAtG,SAAAwF,MACA8F,EAAA,EAAAA,EAAA9F,EAAAnG,OAAAiM,IAAA,CACA,GAAAxB,GAAAtE,EAAA8F,GACAwf,EAAAhhB,EAAA9J,SAAAuG,KAAA3B,OACAmmB,EAAAjhB,EAAA9J,SAAAuG,KAAA3G,MAEAmrB,KAAA4I,GAAA7I,IAAA6I,IACAD,EAAA5yB,KAAAgJ,GACA4pB,EAAA5yB,KAAAgJ,EAAAlF,SAAA,MAKA,MAAAvG,MAAA6H,MAAAwtB,GAAA3nB,QAAA,IAAAjH,OAAAkT,IAIAmc,aAAA,SAAAnc,GAKA,IAJA,GAAApU,GAAAvF,KACA+1B,KACAC,OAEA,CACA,GAAAH,GAAAtwB,EAAAswB,UAEA,IAAA,IAAAA,EAAA70B,OAAA,KAGA,KAAA,GADAi1B,IAAA,EACAt1B,EAAA,EAAAA,EAAAk1B,EAAA70B,OAAAL,IAAA,CACA,GAAAu1B,GAAAL,EAAAl1B,GACAw1B,EAAAD,EAAAlvB,IAEAgvB,GAAAG,KACAH,EAAAG,IAAA,EACAJ,EAAAtzB,KAAAyzB,GACAD,GAAA,GAIA,IAAAA,EAAA,KAEA1wB,GAAAswB,EAGA,MAAA71B,MAAA6H,MAAAkuB,GAAAroB,QAAA,IAAAjH,OAAAkT,MAQAxY,EAAAS,OAAAwD,GACAwK,aAAA,SAAA+J,GAIA,IAAA,GAHAoB,MACAzT,EAAAtH,KAAAsH,QAEA3G,EAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IAKA,IAAA,GAJAoL,GAAAzE,EAAA3G,GACAqH,EAAA+D,EAAA/D,iBAGAiF,EAAA,EAAAA,EAAAjF,EAAAhH,OAAAiM,IAAA,CACA,GAAAxB,GAAAzD,EAAAiF,GACAie,EAAAzf,EAAA9J,SAAA4E,OACA4kB,EAAA1f,EAAA9J,SAAAJ,OACA60B,EAAArqB,IAAAmf,EAAAC,EAAAD,CAGAkL,GAAAp1B,OAAA,GACA+Z,EAAAtY,KAAA2zB,EAAA,IAIArb,EAAAtY,KAAAgJ,EAAA,IAKA,MAAAzL,MAAA6H,MAAAkT,GAAArN,QAAA,IAAAjH,OAAAkT,IAGA0c,mBAAA,SAAA1c,GACA,MAAA3Z,MAAA4P,eAAApB,IAAAxO,MAAAyG,OAAAkT,IAGA7O,iBAAA,SAAA6O,GACA,MAAA3Z,MAAA4P,aAAA+J,MAKAvU,EAAAkxB,cAAAlxB,EAAAwK,aACAxK,EAAAmxB,oBAAAnxB,EAAAixB,mBACAjxB,EAAAoxB,kBAAApxB,EAAA0F,iBAKA3J,EAAAS,OAAAwD,GACAmB,OAAA,SAAAoT,GACA,GACAuR,GADAjjB,EAAAjI,KAAA,EAOA,OAJAiI,KACAijB,EAAAjjB,EAAAtG,SAAA4E,QAGA2kB,GAAAvR,EAAAuR,EAAAzkB,OAAAkT,GAAAuR,GAGA3pB,OAAA,SAAAoY,GACA,GACAwR,GADAljB,EAAAjI,KAAA,EAOA,OAJAiI,KACAkjB,EAAAljB,EAAAtG,SAAAJ,QAGA4pB,GAAAxR,EAAAwR,EAAA1kB,OAAAkT,GAAAwR,GAGAuI,QAAAD,GACAxX,KAAA,WAGAwa,QAAAhD,GACAxX,KAAA,aAqBA9a,EAAAS,OAAAwD,GACAgK,UAAAukB,IAEAnoB,QAAAmoB,GACAQ,OAAA,aA6CAhzB,EAAAS,OAAAwD,GACA4C,eAAA,SAAA2R,GAIA,IAAA,GAHA8N,MAEAliB,EAAAvF,KACAW,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAoL,GAAAxG,EAAA5E,EACA,IAAAoL,EAAAmB,SAIA,IAAA,GAFA/F,GAAA4E,EAAApK,SAAAwF,MAEA8F,EAAA,EAAAA,EAAA9F,EAAAnG,OAAAiM,IAAA,CACA,GAAAxB,GAAAtE,EAAA8F,EACAwa,GAAAhlB,KAAAgJ,IAIA,MAAAzL,MAAA6H,MAAA4f,GAAA/Z,QAAA,IAAAjH,OAAAkT,IAGAtR,eAAA,SAAAsR,GAIA,IAAA,GAHA8N,MAEAliB,EAAAvF,KACAW,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAA8K,GAAAlG,EAAA5E,EACA8K,GAAA4V,WAEAoG,EAAAhlB,KAAAgJ,EAAAlF,SAAA,IACAkhB,EAAAhlB,KAAAgJ,EAAAlK,SAAA,KAGA,MAAAvB,MAAA6H,MAAA4f,GAAA/Z,QAAA,IAAAjH,OAAAkT,IAGA+c,cAAAtC,IAEAuC,gBAAAvC,GACAE,YAAA,MAgDAnzB,EAAAS,OAAAwD,GACAwxB,WAAA,WACA,GAAAxzB,GAAApD,KAAAoD,KACAyzB,EAAAzzB,EAAAqK,aACAqpB,EAAA92B,KAAAsH,QACAsvB,KAEAG,EAAA,SAAAhrB,EAAAirB,GACAH,EAAAlP,MAAA5b,GACA+qB,EAAA5O,QAAAnc,GACAirB,EAAArP,MAAA5b,GAGA,GAAA,CACA,GAAAirB,GAAA5zB,EAAAqK,YACAmpB,GAAAn0B,KAAAu0B,EAEA,IAAA1wB,GAAAwwB,EAAA,EACAC,GAAAzwB,EAAA0wB,GAEAh3B,KAAAuM,K3B0iKQzF,UAAU,E4Bv+KlB2F,MAAAnG,EACAuG,MAAA,SAAAlM,EAAAyM,EAAAhC,EAAAlL,EAAAM,GACAu2B,EAAA3rB,EAAA4rB,YAIAF,EAAA91B,OAAA,EAEA,OAAA41B,GAAAzgB,IAAA,SAAA6gB,GACA,MAAAA,GAAAX,0BAKA52B,EAAAD,QAAA4F,IAEA4f,QAAA,GAAAxL,UAAA,KAAAyd,IAAA,SAAA/1B,EAAAzB,EAAAD,GACA,YAEA,IAAA2uB,GAAA,SAAA1tB,EAAA2D,GACA,GAAAhB,GAAA3C,EAAA2C,KACA8zB,EAAAz2B,EAAAkB,SACAw1B,EAAA/yB,EAAAzC,SACAy1B,EAAAF,EAAAp1B,MAAA,WAAA0d,MAAA2X,EAAAr1B,MAAA,WAAA0d,MACA6X,EAAA,EACAC,EAAA,EACA5Y,EAAAtb,EAAAsb,mBACA6Y,EAAA,UAAAL,EAAAnW,MACAyW,EAAA,UAAAN,EAAAnW,MACA0W,EAAA,UAAAN,EAAApW,MACA2W,EAAA,UAAAP,EAAApW,KAGArC,KACA2Y,EAAA52B,EAAAouB,SACAyI,EAAAlzB,EAAAyqB,SAGA,IAAA8I,GAAAN,EAAAC,EACAM,EAAA,IAAAD,CAEA,OAAAC,GAEAL,GAAAG,EACA,EAEAF,GAAAC,EACA,GC/CA,IAAAL,EACAF,EAAAjpB,MAAAkpB,EAAAlpB,MAEAmpB,EAMAO,EAKAl4B,GAAAD,QAAA2uB,OAEA0J,IAAA,SAAA32B,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,SACAC,EAAAD,EAAA,WACA2oB,EAAA3oB,EAAA,iBACAgkB,EAAAhkB,EAAA,yBACArB,EAAAqB,EAAA,aAIA42B,GAHAj4B,EAAAA,EAAAk4B,SAAA,KACA72B,EAAA,gCAGAsN,IAAA,SAAAhN,GAEA,GAAAuZ,GACA3X,EAAApD,IAGA,IAAAoB,EAAA+B,oBAAA3B,GAAA,CACA,GAAA+D,GAAA/D,CAEA,IAAA+D,EAAA5D,SAAAyB,KAAAA,EACA2X,EAAAxV,EAAA4f,cAEA,CAGA,IAAA,GAFAsF,MAEA9pB,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,EACA8pB,GAAAhoB,KAAAwF,EAAA+hB,QAGAjP,EAAA,GAAA8O,GAAAzmB,EAAAqnB,QAKA,IAAArpB,EAAAitB,MAAA7sB,GAAA,CACA,GAAAipB,GAAAjpB,CAEAuZ,GAAA,GAAA8O,GAAAzmB,EAAAqnB,OAIA,IAAArpB,EAAAwL,YAAApL,KAAAJ,EAAAitB,MAAA7sB,EAAA8F,QAAAlG,EAAAitB,MAAA7sB,EAAA2F,QAAA,CAKA,IAAA,GAJA6wB,GAAAx2B,EACAipB,KAEAwN,GAAA,QAAA,SACAt3B,EAAA,EAAAwY,EAAA8e,EAAAj3B,OAAAmY,EAAAxY,EAAAA,IAAA,CACA,GAAAogB,GAAAkX,EAAAt3B,GACAu3B,EAAAF,EAAAjX,EAEA,IAAA3f,EAAAitB,MAAA6J,GAEA,IAAA,GAAAjrB,GAAA,EAAAkrB,EAAAD,EAAAl3B,OAAAm3B,EAAAlrB,EAAAA,IAAA,CACA,GAAA+c,GAAA7oB,EAAAS,QAAAmf,MAAAA,GAAAmX,EAAAjrB,GAEAwd,GAAAhoB,KAAAunB,IAKAjP,EAAA,GAAA8O,GAAAzmB,EAAAqnB,OAIA,CACA,GAAAT,GAAAxoB,CACAuZ,GAAA,GAAAmK,GAAA9hB,EAAA4mB,GAAAvc,aAGA,MAAAsN,IAGA8L,OAAA,SAAApZ,GACA,GAAArM,EAAA+B,oBAAAsK,GACAA,EAAAA,MACA,IAAArM,EAAAoF,OAAAiH,GAAA,CACA,GAAAkM,GAAAlM,CACAA,GAAAzN,KAAAuL,EAAAoO,GAGA,MAAAlM,GAAAoZ,UAGAuR,KAAA,SAAArd,EAAAsd,EAAAC,GACA,GAAAl1B,GAAApD,IAEAoD,GAAAm1B,eAAA,EAGA,IAAAC,GAAAp1B,EAAA2X,UACAyd,GAAAx3B,OAAA,GACAw3B,EAAA3R,SAGA,MAAA9L,IACA3Z,EAAAwL,YAAAmO,IAAA3Z,EAAAitB,MAAAtT,KACA3X,EAAAoL,IAAAuM,GAIA3X,EAAA6iB,IAAA,cAAA,SAAA/lB,GACAkD,EAAAm1B,eAAA,GACAn1B,EAAAwV,QAAA1Y,GAEAkD,EAAAmjB,QACA3hB,KAAA,OACA6I,WAAArK,EAAA2X,aAGA3X,EAAA6iB,IAAA,OAAAoS,G7B2hLMj1B,EAAGwV,QAAQ,U8B3pLjBqN,IAAA,aAAA,WACA7iB,EAAA6iB,IAAA,OAAAqS,GACAl1B,EAAAwV,QAAA,SAGA,IAAA6f,GAAAt3B,EAAAS,UAAAwB,EAAAzB,SAAA2D,QAAA8pB,OAKA,OAJAqJ,GAAAlzB,KAAAnC,EAAAmI,IAEAnI,EAAAgsB,OAAAqJ,GAEAz4B,OAIAP,GAAAD,QAAAs4B,IAEAY,gBAAA,GAAAC,wBAAA,GAAAC,8BAAA,GAAA5T,QAAA,GAAAxL,UAAA,GAAAqf,YAAA,MAAAC,IAAA,SAAA53B,EAAAzB,EAAAD,GACA,YAEA,IAAAE,GAAAwB,EAAA,aACAC,EAAAD,EAAA,WACAE,EAAAF,EAAA,SAEA42B,GAGArgB,QAAA/X,EAAA+X,UACAzU,UAAAtD,EAAAsD,YACA0U,SAAAhY,EAAAgY,WACAC,WAAAjY,EAAAiY,aACAC,MAAAlY,EAAAkY,QACAC,eAAAnY,EAAAmY,iBACAnU,KAAAhE,EAAAgE,OAEAL,mBAAA,SAAAkC,GACA,GAAAnC,GAAApD,IAEAoD,GAAAgd,gBAEAhd,EAAAzB,SAAAo3B,QAAApR,MAAApiB,IAGAyzB,kBAAA,WACAh5B,KAAA2B,SAAAs3B,mBAAA,GAGAC,mBAAA,WAUA,QAAAC,KACA/1B,EAAAzB,SAAAs3B,mBAEA93B,EAAAi4B,sBAAA,SAAAC,GACAC,EAAAD,GACAF,MAMA,QAAAG,GAAAD,GAIA,QAAAE,GAAAtxB,EAAAuxB,GACA,GAAA93B,GAAAuG,EAAAtG,SACAuB,EAAAxB,EAAAsB,UAAAE,QACAD,EAAAvB,EAAAsB,UAAAC,MACAw2B,GAAA,CAGA,IAAA,IAAAv2B,EAAAlC,OAAA,CACA,GAAA+R,GAAA9P,EAAAkK,OAEA4F,IACA7P,EAAAT,KAAAsQ,GAeA,IAAA,GAXA2mB,GAAA,SAAAA,GACA,IAAA,GAAAzsB,GAAAysB,EAAA14B,OAAA,EAAAiM,GAAA,EAAAA,IAAA,CACA,GAAA0sB,GAAAD,EAAAzsB,EAEA0sB,KAGAD,EAAA5xB,OAAA,EAAA4xB,EAAA14B,SAIAL,EAAAuC,EAAAlC,OAAA,EAAAL,GAAA,EAAAA,IAAA,CACA,GAAA6uB,GAAAtsB,EAAAvC,GACAi5B,EAAApK,EAAA7tB,QAEAi4B,GAAAr2B,SACAL,EAAA4E,OAAAnH,EAAA,GAEAi5B,EAAA13B,QAAA,EACA03B,EAAA33B,SAAA,EACA23B,EAAA53B,SAAA,EAEA03B,EAAAE,EAAAt3B,UAKAs3B,EAAA33B,SAAA23B,EAAAz3B,YAGAy3B,EAAA33B,SAAA23B,EAAAz3B,WACAy3B,EAAAz3B,UAAA,GAGAy3B,EAAA53B,SACA63B,EAAA5xB,EAAAunB,EAAA6J,GAGAzJ,EAAA3nB,EAAAunB,EAAA6J,EAAAG,GAEAI,EAAAz3B,WACAy3B,EAAAz3B,UAAA,GAGAu3B,EAAAE,EAAAt3B,QAEAktB,EAAAvrB,cACAf,EAAA4E,OAAAnH,EAAA,GAEAi5B,EAAA13B,QAAA,EACA03B,EAAA33B,SAAA,EACA23B,EAAA53B,SAAA,EAEA03B,EAAAE,EAAAv3B,YAGAo3B,GAAA,GAOA,MAJAD,IAAA,IAAAt2B,EAAAlC,QAAA,IAAAiC,EAAAjC,QACA84B,EAAAr3B,KAAAwF,GAGAwxB,EAKA,IAAA,GAtFAl0B,GAAAnC,EAAAzB,SAAAo3B,QACAe,KAoFAC,GAAA,EACA75B,EAAA,EAAAA,EAAAqF,EAAAvE,OAAAd,IAAA,CACA,GAAA+H,GAAA1C,EAAArF,GACA85B,EAAAT,EAAAtxB,EAEA8xB,GAAAA,GAAAC,EAGA,GAAAC,GAAAV,EAAAn2B,GAAA,EAGA,IAAA22B,GAAAE,EAAA,CACA,GAAA3J,EAEA,IAAA/qB,EAAAvE,OAAA,EAAA,CACA,GAAAmc,GAAA5X,EAAA6X,sBACAkT,GAAAnT,EAAAnc,OAAA,EAAAuE,EAAAiJ,IAAA2O,GAAA5X,EAGAnC,EAAAmjB,QACA3hB,KAAA,OACA6I,WAAA6iB,IAKA/qB,EAAA2iB,QAAA4R,GAIA,QAAAD,GAAA95B,EAAAyvB,EAAA6J,GACA,GAAAG,GAAAp4B,EAAAgkB,KAAArlB,GACAm6B,GAAAV,EACAvxB,EAAAlI,EACA+B,EAAAsB,EAAAzB,SAAAG,MACA83B,EAAApK,EAAA7tB,QAEA,IAAAu4B,EAAA,CACA,GAAAxc,GAAAzV,EAAAtG,SAAAqb,QAEA4c,GAAAO,cAAAP,EAAAO,gBACAtc,EAAAH,EAAAG,EACAC,EAAAJ,EAAAI,GAGA8b,EAAAn1B,WAAAm1B,EAAAn1B,YAAA3C,EAAAs4B,cAAAnyB,GAGA,GAAAuxB,EAAA,CACA,GAAAnb,GAAAjb,EAAAzB,SAAA0c,GAEAub,GAAAS,SAAAT,EAAAS,WACAxc,EAAAQ,EAAAR,EACAC,EAAAO,EAAAP,GAGA8b,EAAAU,UAAA,MAAAV,EAAAU,UAAAV,EAAAU,UAAAl3B,EAAAzB,SAAAyc,KAGAwb,EAAA53B,SAAA,EACA43B,EAAAW,UAAAlB,EAAAO,EAAAx3B,SAAAw3B,EAAA/3B,SAGA,QAAA+tB,GAAA7vB,EAAAyvB,EAAA6J,EAAAG,GACA,GAAA13B,GAAAsB,EAAAzB,SAAAG,MACAo4B,GAAAV,EACA93B,EAAA3B,EAAA4B,SACAi4B,EAAApK,EAAA7tB,SACA64B,EAAAZ,EAAAlK,OACA6K,EAAAX,EAAAW,SAEA,KAAAX,EAAAa,WAEA,GAAA,MAAAD,EACAZ,EAAAa,WAAAC,EAAA,WAEA,CACA,GAAAC,EAEA,IAAAv5B,EAAAoF,OAAAg0B,GAAA,CACA,GAAAI,GAAA94B,EAAA+4B,MAAA,6BAAAL,EAEAG,GAAAC,EAAApb,UAGAmb,GAAAH,CAGA,IAAAj2B,GAAAiuB,CAEApxB,GAAAoF,OAAAm0B,IACAp2B,EAAAo2B,EACAnI,OAEAjuB,EAAAo2B,EAAA,GACAnI,EAAAmI,EAAA/lB,MAAA,GAAAuB,IAAA,SAAA/V,GAAA,OAAAA,KAGAoyB,EAAAxxB,OAAA,GACA,WAAAuD,GACAiuB,EAAA/vB,KAAAm3B,EAAA/3B,UAGA+3B,EAAAa,WAAAC,EAAAn2B,GAAAf,MAAA,KAAAgvB,IAEAoH,EAAAa,WAAAC,EAAAn2B,GAMA,GACAu2B,GADApL,EAAAkK,EAAAa,UAmBA,IAfAK,EADA,IAAAlB,EAAA/3B,SACA,GAEAw3B,EAAAkB,GAAAX,EAAA/3B,SAGA+3B,EAAAz3B,WACA24B,EAAAlB,EAAAx3B,UAGA,EAAA04B,EACAA,EAAA,EACAA,EAAA,IACAA,EAAA,GAGA,MAAAlB,EAAAhiB,MAAA,CAEA,GAAAmjB,GAAAnB,EAAAO,cACAa,EAAApB,EAAA5c,SACAU,EAAAhc,EAAAsb,QACAge,IAAAd,IACAe,EAAAF,EAAAld,EAAAmd,EAAAnd,KACAH,EAAAG,EAAAqd,EAAAH,EAAAld,EAAAmd,EAAAnd,EAAAid,EAAApL,IAGAuL,EAAAF,EAAAjd,EAAAkd,EAAAld,KACAJ,EAAAI,EAAAod,EAAAH,EAAAjd,EAAAkd,EAAAld,EAAAgd,EAAApL,IAIA,IAAA2K,GAAAT,EAAAS,SACAc,EAAAvB,EAAAvb,IACAA,EAAA3c,EAAA2c,IACA+c,EAAA,MAAAD,GAAA3B,CACA4B,KACAH,EAAAZ,EAAAxc,EAAAsd,EAAAtd,KACAQ,EAAAR,EAAAqd,EAAAb,EAAAxc,EAAAsd,EAAAtd,EAAAid,EAAApL,IAGAuL,EAAAZ,EAAAvc,EAAAqd,EAAArd,KACAO,EAAAP,EAAAod,EAAAb,EAAAvc,EAAAqd,EAAArd,EAAAgd,EAAApL,IAGA3vB,EAAA6Y,QAAA,OAGA,IAAA0hB,GAAAV,EAAAU,UACAe,EAAAzB,EAAAxb,KACAkd,EAAA,MAAAD,GAAA7B,CACA8B,KACAL,EAAAX,EAAAe,KACA35B,EAAA0c,KAAA8c,EAAAZ,EAAAe,EAAAP,EAAApL,IAGA3vB,EAAA6Y,QAAA,UAGAwiB,GAAAE,IACAv7B,EAAA6Y,QAAA,WAGA,IAAAtF,GAAAsmB,EAAA93B,KACA,IAAAwR,GAAA4mB,EAEA,IAAA,GAAAv5B,GAAA,EAAAA,EAAA2S,EAAAtS,OAAAL,IAAA,CACA,GAAA2D,GAAAgP,EAAA3S,GACA4D,EAAAD,EAAAC,KACAmB,EAAApB,EAEAmB,EAAAm0B,EAAAn1B,WAAAF,GACAg3B,EAAAL,EAAAz1B,EAAAC,EAAAo1B,EAAApL,EAEA5tB,GAAA05B,eAAAz7B,EAAAwE,EAAAg3B,IAaA,MANAn6B,GAAAoB,GAAAo3B,EAAAhK,OACAgK,EAAAhK,KAAApsB,MAAAzD,GAAAs5B,IAGAO,EAAAx3B,SAAA04B,EAEAA,EAGA,QAAAG,GAAAx1B,EAAAC,GACA,MAAA,OAAAD,GAAA,MAAAC,GACA,EAGAtE,EAAA0Q,OAAArM,IAAArE,EAAA0Q,OAAApM,IACA,EACA,GAAA,GACA,GAGA,EAIA,QAAA+1B,GAAAC,EAAAC,EAAAx7B,GACA,GAAAy7B,GAAA,EAAAz7B,EACA07B,EAAA17B,EAAAA,CAEA,OAAA,GAAAy7B,EAAAA,EAAAz7B,EAAAu7B,EAAA,EAAAE,EAAAC,EAAAF,EAAAE,EAAA17B,EAGA,QAAA27B,GAAAJ,EAAAC,GACA,MAAA,UAAAl2B,EAAAC,EAAAo1B,GACA,MAAAr1B,IAAAC,EAAAD,GAAAg2B,EAAAC,EAAAC,EAAAb,IAyJA,QAAAI,GAAAa,EAAAC,EAAAlB,EAAAmB,GACA,EAAAnB,EACAA,EAAA,EACAA,EAAA,IACAA,EAAA,EAGA,IAAAr1B,GAAAC,CAcA,IAXAD,EADA,MAAAs2B,EAAAnc,SAAA,MAAAmc,EAAAvc,MACA,MAAAuc,EAAAnc,QAAAmc,EAAAnc,QAAAmc,EAAAvc,MAEAuc,EAIAr2B,EADA,MAAAs2B,EAAApc,SAAA,MAAAoc,EAAAxc,MACA,MAAAwc,EAAApc,QAAAoc,EAAApc,QAAAoc,EAAAxc,MAEAwc,EAGA56B,EAAA0Q,OAAArM,IAAArE,EAAA0Q,OAAApM,GACA,MAAAu2B,GAAAx2B,EAAAC,EAAAo1B,EAEA,IAAA15B,EAAAitB,MAAA5oB,IAAArE,EAAAitB,MAAA3oB,GAAA,CAGA,IAAA,GAFAw2B,MAEAv7B,EAAA,EAAAA,EAAA+E,EAAA1E,OAAAL,IAAA,CACA,GAAAw7B,GAAA12B,EAAA9E,GACAy7B,EAAA12B,EAAA/E,EAEA,IAAA,MAAAw7B,GAAA,MAAAC,EAAA,CACA,GAAAje,GAAA8d,EAAAE,EAAAC,EAAAtB,EAEAiB,GAAAM,aAAAle,EAAA1O,KAAA6sB,MAAAne,IAEA+d,EAAAz5B,KAAA0b,OCzjBA+d,GAAAz5B,KAAA25B,GAIA,MAAAF,GAGA,MAAAp4B,QDwCA,GAAAV,GAAApD,IAIA,IAFAoD,EAAAzB,SAAAs3B,mBAAA,EAEA71B,EAAAgd,eAAA,CAcA+Y,GAkUA,IAAAoD,GAAA,WACA,QAAAC,GAAAC,GACA,OAAAA,EAAAC,QAAAD,EAAA5e,EAAA4e,EAAAE,SAAAF,EAAArxB,EAGA,QAAAwxB,GAAAC,EAAAC,EAAAC,GACA,GAAAN,IACA5e,EAAAgf,EAAAhf,EAAAkf,EAAAC,GAAAF,EACA1xB,EAAAyxB,EAAAzxB,EAAA2xB,EAAAE,GAAAH,EACAJ,QAAAG,EAAAH,QACAC,SAAAE,EAAAF,SAGA,QAAAK,GAAAP,EAAArxB,EAAA6xB,GAAAT,EAAAC,IAGA,QAAAS,GAAAT,EAAAK,GACA,GAAAr8B,IACAu8B,GAAAP,EAAArxB,EACA6xB,GAAAT,EAAAC,IAEAr4B,EAAAw4B,EAAAH,EAAA,GAAAK,EAAAr8B,GACA08B,EAAAP,EAAAH,EAAA,GAAAK,EAAA14B,GACAoG,EAAAoyB,EAAAH,EAAAK,EAAAK,GACAC,EAAA,EAAA,GAAA38B,EAAAu8B,GAAA,GAAA54B,EAAA44B,GAAAG,EAAAH,IAAAxyB,EAAAwyB,IACAK,EAAA,EAAA,GAAA58B,EAAAw8B,GAAA,GAAA74B,EAAA64B,GAAAE,EAAAF,IAAAzyB,EAAAyyB,GAKA,OAHAR,GAAA5e,EAAA4e,EAAA5e,EAAAuf,EAAAN,EACAL,EAAArxB,EAAAqxB,EAAArxB,EAAAiyB,EAAAP,EAEAL,EAGA,MAAA,SAAAa,GAAAZ,EAAAC,EAAA96B,GAEA,GAUA07B,GAAAT,EAAAU,EAVAC,GACA5f,EAAA,GACAzS,EAAA,EACAsxB,QAAA,KACAC,SAAA,MAEA/0B,GAAA,GACA81B,EAAA,EACAC,EAAA,KACAC,EAAA,IAsBA,KAnBAlB,EAAAmB,WAAAnB,IAAA,IACAC,EAAAkB,WAAAlB,IAAA,GACA96B,EAAAA,GAAA,KAEA47B,EAAAf,QAAAA,EACAe,EAAAd,SAAAA,EAEAY,EAAA,OAAA17B,EAGA07B,GAEAG,EAAAJ,EAAAZ,EAAAC,GAEAG,EAAAY,EAAA77B,EAAA+7B,GAEAd,EAAAc,IAUA,GALAJ,EAAAN,EAAAM,GAAAC,EAAAX,GAEAl1B,EAAAnF,KAAA,EAAA+6B,EAAA3f,GACA6f,GAAA,KAEAjuB,KAAAquB,IAAAN,EAAA3f,GAAA8f,GAAAluB,KAAAquB,IAAAN,EAAApyB,GAAAuyB,GACA,KAMA,OAAAJ,GAAA,SAAAQ,GAAA,MAAAn2B,GAAAm2B,GAAAn2B,EAAA5G,OAAA,GAAA,IAAA08B,MAIAhD,GACAsD,OAAA,SAAAv4B,EAAAC,EAAAo1B,GACA,MAAAr1B,IAAAC,EAAAD,GAAAq1B,GAIAI,KAAAY,EAAA,IAAA,GAAA,IAAA,GACAmC,UAAAnC,EAAA,IAAA,EAAA,EAAA,GACAoC,WAAApC,EAAA,EAAA,EAAA,IAAA,GACAqC,cAAArC,EAAA,IAAA,EAAA,IAAA,GAGAsC,eAAAtC,EAAA,IAAA,EAAA,KAAA,MACAuC,gBAAAvC,EAAA,IAAA,KAAA,KAAA,GACAwC,mBAAAxC,EAAA,KAAA,IAAA,IAAA,KAGAyC,eAAAzC,EAAA,IAAA,KAAA,IAAA,KACA0C,gBAAA1C,EAAA,IAAA,IAAA,IAAA,KACA2C,mBAAA3C,EAAA,KAAA,IAAA,KAAA,MAGA4C,gBAAA5C,EAAA,IAAA,KAAA,KAAA,KACA6C,iBAAA7C,EAAA,KAAA,IAAA,KAAA,GACA8C,oBAAA9C,EAAA,KAAA,KAAA,KAAA,GAGA+C,gBAAA/C,EAAA,KAAA,IAAA,KAAA,KACAgD,iBAAAhD,EAAA,KAAA,IAAA,IAAA,GACAiD,oBAAAjD,EAAA,IAAA,EAAA,KAAA,GAGAkD,gBAAAlD,EAAA,KAAA,IAAA,KAAA,KACAmD,iBAAAnD,EAAA,IAAA,EAAA,IAAA,GACAoD,oBAAApD,EAAA,IAAA,EAAA,IAAA,GAGAqD,eAAArD,EAAA,IAAA,IAAA,KAAA,MACAsD,gBAAAtD,EAAA,IAAA,EAAA,IAAA,GACAuD,mBAAAvD,EAAA,EAAA,EAAA,EAAA,GAGAwD,eAAAxD,EAAA,GAAA,IAAA,IAAA,MACAyD,gBAAAzD,EAAA,KAAA,IAAA,KAAA,GACA0D,mBAAA1D,EAAA,KAAA,KAAA,IAAA,KAKA2D,OAAA,SAAA/C,EAAAC,EAAA96B,GACA,GAAA49B,GAAAlD,EAAAG,EAAAC,EAAA96B,EAEA,OAAA,UAAA4D,EAAAC,EAAAo1B,GACA,MAAAr1B,IAAAC,EAAAD,GAAAg6B,EAAA3E,KAIA4E,eAAA,SAAAzgB,EAAAE,EAAAD,EAAAE,GACA,MAAA0c,GAAA7c,EAAAE,EAAAD,EAAAE,OCngBA3f,GAAAD,QAAAs4B,I/BytMGhgB,YAAY,GAAGkN,QAAQ,GAAGxL,UAAU,KAAKmmB,IAAI,SAASz+B,EAAQzB,EAAOD,GgCvuMxE,YAEA,IAAAE,GAAAwB,EAAA,aAEA42B,GACA9R,GAAAtmB,EAAAsmB,KACAC,IAAAvmB,EAAAsmB,IAAAE,qBAAA,IACAC,KAAAzmB,EAAAsmB,IAAAI,2BAAA,IACAC,IAAA3mB,EAAA2mB,MACAzN,QAAAlZ,EAAAkZ,UAGAlZ,GAAA8mB,eAAAsR,GAEAr4B,EAAAD,QAAAs4B,IAEAhgB,YAAA,KAAA8nB,IAAA,SAAA1+B,EAAAzB,EAAAD,GACA,YAEA,IAAAs4B,IAEA+H,IAAA,SAAAv6B,GACA,GAAAkb,GAAAxgB,KAAA2B,SAAA6e,QAGA,OAFAlb,GAAAA,MAEAkb,EAAAqf,IAAAv6B,ICxBAw6B,IAAA,SAAAx6B,GACA,GAAAkb,GAAAxgB,KAAA2B,SAAA6e,QAKA,OAJAlb,GAAAA,MAEAA,EAAAy6B,GAAAz6B,EAAAy6B,IAAA,OAEAvf,EAAAsf,IAAAx6B,IAKAwyB,GAAAkI,KAAAlI,EAAAgI,IAEArgC,EAAAD,QAAAs4B,OAEAmI,IAAA,SAAA/+B,EAAAzB,EAAAD,GACA,YAEA,IAAAK,GAAAqB,EAAA,aACAC,EAAAD,EAAA,WACA2oB,EAAA3oB,EAAA,iBACAE,EAAAF,EAAA,SACAG,EAAAH,EAAA,cACAxB,EAAAwB,EAAA,aAEAg/B,EAAA,SAAA1+B,GACA,KAAAxB,eAAAkgC,IACA,MAAA,IAAAA,GAAA1+B,EAEA,IAAA4B,GAAApD,IAEAwB,GAAAL,EAAAS,UAAAJ,EAEA,IAAA2+B,GAAA3+B,EAAA2+B,SAIAA,KAAA/+B,EAAAg/B,YAAAD,IAAA/+B,EAAAg/B,YAAAD,EAAA,MACAA,EAAAA,EAAA,GAGA,IAAAE,GAAAF,EAAAA,EAAAG,OAAA,IACAD,GAAAA,MAEAA,GAAAA,EAAAj9B,KACAi9B,EAAAj9B,GAAAm9B,UAEAF,KAGA,IAAAG,GAAAH,EAAAG,QAAAH,EAAAG,WAEAL,KAAAA,EAAAG,OAAAD,GACAA,EAAAj9B,GAAAA,CAEA,IAAAq9B,GAAA38B,SAAAjE,GAAAiE,SAAAq8B,IAAA3+B,EAAAk/B,SACAp7B,EAAA9D,CACA8D,GAAA8pB,OAAAjuB,EAAAS,QAAA2C,KAAAk8B,EAAA,OAAA,QAAAn7B,EAAA8pB,QACA9pB,EAAAkb,SAAArf,EAAAS;AAAA2C,KAAAk8B,EAAA,SAAA,QAAAn7B,EAAAkb,SAEA,IAAAmgB,GAAA,SAAAC,EAAAziB,EAAA0iB,GACA,MAAA/8B,UAAAqa,EACAA,EACAra,SAAA+8B,EACAA,EAEAD,GAIAl/B,EAAA1B,KAAA2B,UACAw+B,UAAAA,EACArQ,OAAA,EACAgR,YAAA,EACAx7B,QAAAA,EACAyV,YACAgmB,YACAzb,aACA0b,aACAjI,QAAAlP,EAAA7pB,MACA6b,WACAuT,OAAA,KACA5O,SAAA,KACAygB,sBAAA,EACAC,QAAA,MACAC,QAAA,KACAC,eAAAT,GAAA,EAAAr7B,EAAA87B,gBACAC,mBAAAV,GAAA,EAAAr7B,EAAA+7B,oBACAC,eAAAX,GAAA,EAAAr7B,EAAAg8B,gBACAC,mBAAAZ,GAAA,EAAAr7B,EAAAi8B,oBACAC,oBAAAb,GAAA,EAAAr7B,EAAAk8B,qBACAtO,SAAAyN,GAAA,EAAAr7B,EAAA4tB,SAAA5tB,EAAAm8B,eACAtO,cAAAwN,GAAA,EAAAr7B,EAAA6tB,cAAA7tB,EAAAo8B,oBACAtO,gBAAAuN,GAAA,EAAAr7B,EAAA8tB,iBACAhT,aAAAtc,SAAAwB,EAAA8a,aAAAqgB,EAAAn7B,EAAA8a,aACAhC,KAAAhd,EAAA0Q,OAAAxM,EAAA8Y,MAAA9Y,EAAA8Y,KAAA,EACAC,KACAR,EAAAzc,EAAAwL,YAAAtH,EAAA+Y,MAAAjd,EAAA0Q,OAAAxM,EAAA+Y,IAAAR,GAAAvY,EAAA+Y,IAAAR,EAAA,EACAC,EAAA1c,EAAAwL,YAAAtH,EAAA+Y,MAAAjd,EAAA0Q,OAAAxM,EAAA+Y,IAAAP,GAAAxY,EAAA+Y,IAAAP,EAAA,GAEA9a,WACAE,WACAD,UAEAyb,kBAAA,EACAijB,sBAIAC,EAAAt8B,EAAAu8B,aACA/9B,UAAA89B,GAAA,aAAAA,GAAA,WAAAA,EAGAlgC,EAAAmgC,cAAA,SAEAngC,EAAAmgC,cAAAD,EAIAxgC,EAAA0Q,OAAAxM,EAAA47B,UAAA9/B,EAAA0Q,OAAAxM,EAAA67B,UAAA77B,EAAA47B,QAAA57B,EAAA67B,SACAz/B,EAAAw/B,QAAA57B,EAAA47B,QACAx/B,EAAAy/B,QAAA77B,EAAA67B,SACA//B,EAAA0Q,OAAAxM,EAAA47B,UAAAp9B,SAAAwB,EAAA67B,QACAz/B,EAAAw/B,QAAA57B,EAAA47B,QACA9/B,EAAA0Q,OAAAxM,EAAA67B,UAAAr9B,SAAAwB,EAAA47B,UACAx/B,EAAAy/B,QAAA77B,EAAA67B,QAGA,IAAAW,GAAA,SAAA/uB,GAGA,IAAA,GAFAgvB,IAAA,EAEAphC,EAAA,EAAAA,EAAAqhC,EAAAhhC,OAAAL,IAAA,CACA,GAAAshC,GAAAD,EAAArhC,EAEA,IAAAS,EAAAuD,QAAAs9B,GAAA,CACAF,GAAA,CACA,QAIA,MAAAA,GACA1gC,EAAA6gC,IAAAF,GAAAG,KAAApvB,OAEAA,GAAAivB,GAKA5+B,GAAAg/B,aAAAjhC,EAAAS,QACAygC,oBAAA/8B,EAAA+8B,oBACAC,qBAAAh9B,EAAAg9B,qBACAC,kBAAAj9B,EAAAi9B,kBACAC,iBAAAphC,EAAA0Q,OAAAxM,EAAAk9B,mBAAAl9B,EAAAk9B,iBAAA,EAAAl9B,EAAAk9B,iBAAA,EACAC,WAAA3+B,SAAAwB,EAAAm9B,YAAA,EAAAn9B,EAAAm9B,WACAC,kBAAA5+B,SAAAwB,EAAAo9B,kBAAA,IAAAp9B,EAAAo9B,kBACAC,WAAAvhC,EAAA0Q,OAAAxM,EAAAq9B,aAAAr9B,EAAAq9B,WAAA,EAAAr9B,EAAAq9B,WAAA7+B,OACA8+B,oBAAA9+B,SAAAwB,EAAAs9B,oBAAA,EAAAt9B,EAAAs9B,oBACAC,kBAAA/+B,SAAAwB,EAAAu9B,kBAAA,EAAAv9B,EAAAu9B,mBACAv9B,EAAAkb,UAEA,IAAAwhB,IAAA18B,EAAAxD,MAAAwD,EAAAyV,SACA+mB,GAAA,SAAAgB,GACA,GAAAC,GAAAD,EAAA,GACAE,EAAAF,EAAA,EAGAphC,GAAA0e,cACAhd,EAAA6/B,SAAAF,GAIAz9B,EAAAw7B,aACA19B,EAAA4iB,GAAA,aAAA1gB,EAAAw7B,YACA19B,EAAA4iB,GAAA,aAAA,WACAtkB,EAAAo/B,YAAA,KAKA19B,EAAAg1B,KAAA4K,EAAA,WACA5/B,EAAA81B,qBACAx3B,EAAAouB,OAAA,EAGA1uB,EAAAoB,GAAA8C,EAAAwqB,QACA1sB,EAAA4iB,GAAA,QAAA1gB,EAAAwqB,MAIA,KAAA,GAAAnvB,GAAA,EAAAA,EAAA6/B,EAAAx/B,OAAAL,IAAA,CACA,GAAA6B,GAAAg+B,EAAA7/B,EACAyC,GAAA4iB,GAAA,QAAAxjB,GAEA69B,IAAAA,EAAAG,YAEAp9B,EAAAwV,QAAA,UACAtT,EAAA49B,SAKApL,EAAAoI,EAAAv9B,SAEAxB,GAAAS,OAAAk2B,GACAl1B,eAAA,WACA,MAAA,QAGAugC,QAAA,WACA,MAAAnjC,MAAA2B,SAAAmuB,OAGAA,MAAA,SAAAttB,GAOA,MANAxC,MAAAmjC,UACAnjC,KAAA4Y,QAAA,WAAApW,GAEAxC,KAAAgmB,GAAA,QAAAxjB,GAGAxC,MAGA8gC,WAAA,WACA,MAAA9gC,MAAA2B,SAAAm/B,YAGAP,QAAA,WACA,GAAAn9B,GAAApD,IAEAoD,GAAA41B,oBAEA51B,EAAAmjB,QAAA3hB,KAAA,WAEA,IAAAw+B,GAAAhgC,EAAA+8B,WACA,IAAAiD,EAGA,IAFAA,EAAA9C,OAAA,KAEA8C,EAAAC,WAAAriC,OAAA,GACAoiC,EAAAE,YAAAF,EAAAC,WAAA,GAIA,OAAAjgC,IAGAyC,eAAA,SAAAmB,GACA,GAAAiH,GAAAjO,KAAA2B,SAAAo/B,SAAA/5B,EACA,OAAAlD,UAAAmK,EACAjO,KAAA2B,SAAAoZ,SAAA9M,GAIA4b,EAAA7pB,OAGA6hC,cAAA,WACA,MAAA7hC,MAAA2B,SAAAkgC,eAGAnjB,iBAAA,WACA,MAAA1e,MAAA2B,SAAA+c,kBAGA0B,aAAA,WACA,MAAApgB,MAAA2B,SAAAye,cAGAgL,UAAA,SAAA7lB,GAIA,IAAA,GAHAwV,GAAA/a,KAAA2B,SAAAoZ,SACAgmB,EAAA/gC,KAAA2B,SAAAo/B,SAEApgC,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,GAEAqG,EAAAiB,EAAAtG,SAAAuG,KAAAlB,GACAiH,EAAA8yB,EAAA/5B,GACAu8B,EAAAz/B,SAAAmK,CAEAs1B,KACAt1B,EAAA8M,EAAA/Z,OACA+Z,EAAAtY,KAAAwF,GACA84B,EAAA/5B,GAAAiH,EACAhG,EAAAtG,SAAAsM,MAAAA,GAIA,MAAAjO,OAGAmsB,eAAA,SAAA5mB,GAIA,IAAA,GAHAwV,GAAA/a,KAAA2B,SAAAoZ,SACAgmB,EAAA/gC,KAAA2B,SAAAo/B,SAEApgC,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,GAEAqG,EAAAiB,EAAAtG,SAAAuG,KAAAlB,GACAiH,EAAA8yB,EAAA/5B,GACAw8B,EAAA1/B,SAAAmK,CAEA,IAAAu1B,EAAA,CACAxjC,KAAA2B,SAAAo/B,SAAA/5B,GAAAlD,OACAiX,EAAAjT,OAAAmG,EAAA,EAGA,KAAA,GAAAhB,GAAAgB,EAAAhB,EAAA8N,EAAA/Z,OAAAiM,IAAA,CACA,GAAAw2B,GAAA1oB,EAAA9N,GAAAtL,SAAAuG,KAAAlB,EACA+5B,GAAA0C,KACA1oB,EAAA9N,GAAAtL,SAAAsM,YAMAkyB,UAAA,WACA,MAAAngC,MAAA2B,SAAAw+B,WAGA76B,QAAA,WACA,MAAAnE,GAAAuX,KAAA1Y,KAAA2B,SAAA2D,UAGA0kB,KAAA,SAAAC,GACA,GAAA7mB,GAAApD,KACA0B,EAAA0B,EAAAzB,QAEA,IAAAP,EAAAwL,YAAAqd,GAAA,CAIA,GAFA7mB,EAAA8mB,aAEAD,EAAAlP,SAAA,CACA,GAAA2oB,MAEAC,EAAA,SAAAlZ,EAAAmZ,GACA,IAAA,GAAAjjC,GAAA,EAAAA,EAAA8pB,EAAAzpB,OAAAL,IAAA,CACA,GAAAqpB,GAAAS,EAAA9pB,GACAqG,EAAAgjB,EAAA9hB,KAAAlB,GACAiB,EAAA7E,EAAAyC,eAAAmB,EAEA08B,GAAA18B,IAAA,EAEA,IAAAiB,EAAAjH,OACAiH,EAAA+hB,KAAAA,GAEA4Z,EACAxgC,EAAAoL,IAAArN,EAAAS,QAAAmf,MAAA6iB,GAAA5Z,IAEA5mB,EAAAoL,IAAAwb,IAMA,IAAA5oB,EAAAitB,MAAApE,EAAAlP,UACA4oB,EAAA1Z,EAAAlP,cAIA,KAAA,GADAkd,IAAA,QAAA,SACAt3B,EAAA,EAAAA,EAAAs3B,EAAAj3B,OAAAL,IAAA,CACA,GAAAijC,GAAA3L,EAAAt3B,GACAoa,EAAAkP,EAAAlP,SAAA6oB,EAEAxiC,GAAAitB,MAAAtT,IACA4oB,EAAA5oB,EAAA6oB,GAMAxgC,EAAA2X,WAAA3T,UAAA,SAAAa,GACA,OAAAy7B,EAAAz7B,EAAAjB,QACA6f,SAGAoD,EAAAnoB,OACAsB,EAAAtB,MAAAmoB,EAAAnoB,OAGA,MAAAmoB,EAAA7L,MAAA6L,EAAA7L,OAAA1c,EAAA0c,MACAhb,EAAAgb,KAAA6L,EAAA7L,MAGA6L,EAAA5L,MACA4L,EAAA5L,IAAAR,IAAAnc,EAAA2c,IAAAR,GAAAoM,EAAA5L,IAAAP,IAAApc,EAAA2c,IAAAP,IACA1a,EAAAib,IAAA4L,EAAA5L,IAWA,KAAA,GAPA0M,IACA,UAAA,UAAA,iBAAA,qBACA,iBAAA,qBACA,sBACA,WAAA,gBAAA,mBAGApqB,EAAA,EAAAA,EAAAoqB,EAAA/pB,OAAAL,IAAA,CACA,GAAApB,GAAAwrB,EAAApqB,EAEA,OAAAspB,EAAA1qB,IACA6D,EAAA7D,GAAA0qB,EAAA1qB,IAMA,MAFA6D,GAAAmnB,WAEAvqB,KACA,GAAA8D,SAAAmmB,EAAA,CACA,GAAAD,KAiCA,OA/BAA,GAAAjP,YACA3X,EAAA2X,WAAAqT,KAAA,SAAAztB,EAAAsH,GACA,GAAA8Y,GAAA9Y,EAAA8Y,OAEAiJ,GAAAjP,SAAAgG,KACAiJ,EAAAjP,SAAAgG,OAGAiJ,EAAAjP,SAAAgG,GAAAte,KAAAwF,EAAA+hB,UAGAhqB,KAAA2B,SAAAye,eACA4J,EAAAloB,MAAAsB,EAAAtB,QAAAkoB,QAGAA,EAAAoX,eAAAh+B,EAAAzB,SAAAy/B,eACApX,EAAAqX,mBAAAj+B,EAAAzB,SAAA0/B,mBACArX,EAAA5L,KAAAhb,EAAAzB,SAAAyc,KACA4L,EAAAkX,QAAA99B,EAAAzB,SAAAu/B,QACAlX,EAAAmX,QAAA/9B,EAAAzB,SAAAw/B,QACAnX,EAAAsX,eAAAl+B,EAAAzB,SAAA2/B,eACAtX,EAAAuX,mBAAAn+B,EAAAzB,SAAA4/B,mBACAvX,EAAA3L,IAAAld,EAAAuX,KAAAtV,EAAAzB,SAAA0c,KACA2L,EAAAwX,oBAAAp+B,EAAAzB,SAAA6/B,oBACAxX,EAAAxJ,SAAArf,EAAAuX,KAAAtV,EAAAzB,SAAA2D,QAAAkb,UACAwJ,EAAAqY,oBAAAj/B,EAAAzB,SAAA2D,QAAA+8B,oBACArY,EAAAsY,qBAAAl/B,EAAAzB,SAAA2D,QAAAg9B,qBACAtY,EAAAuY,kBAAAn/B,EAAAzB,SAAA2D,QAAAi9B,kBACAvY,EAAAwY,iBAAAp/B,EAAAzB,SAAA2D,QAAAk9B,iBACAxY,EAAAyY,WAAAr/B,EAAAzB,SAAA2D,QAAAm9B,WAEAzY,IAIAnO,QAAAnc,EAAAwI,MACA+S,MAAA,UACAC,aAAA,UACAC,cAAA,EACAC,cAAA,EACAC,aAAA,UACAC,sBAAA,EACAC,cAAA,UACAC,cAAA,IAGAM,cAAApc,EAAAgc,YACAT,MAAA,UACAU,MAAA,UACAJ,cAAA,UACAK,cAAA,OC5cA1a,EAAA,gBACAA,EAAA,eACAA,EAAA,YACAA,EAAA,YACAA,EAAA,YACAA,EAAA,kBACAA,EAAA,cACAA,EAAA,YACAA,EAAA,WACAA,EAAA,eACAoK,QAAA,SAAAgI,GACAnS,EAAAS,OAAAk2B,EAAAxkB,KAGA7T,EAAAD,QAAA0gC,IAEAxH,gBAAA,GAAA5gB,YAAA,GAAAkN,QAAA,GAAA6e,aAAA,GAAArqB,UAAA,GAAAqf,YAAA,IAAAiL,eAAA,GAAA7W,cAAA,GAAAQ,WAAA,GAAAsW,WAAA,GAAAjW,WAAA,GAAAkW,iBAAA,GAAAC,aAAA,GAAAC,WAAA,GAAAnW,UAAA,GAAAoW,aAAA,KAAAC,IAAA,SAAAljC,EAAAzB,EAAAD,GACA,YAEA,IAAA2B,GAAAD,EAAA,WACAE,EAAAF,EAAA,SAEA42B,GAEA1I,OAAA,SAAA9iB,GACA,GAAA8iB,GAAApvB,KAAA2B,SAAA0iC,WAAA,MAAA/3B,EAAAtM,KAAA2B,SAAA0iC,WAAArkC,KAAA+vB,WAAAzjB,EAIA,OAFA8iB,GAAAkV,MAEAtkC,MAGA+vB,WAAA,SAAAzqB,GACA,GAAAlC,GAAApD,IAEA,IAAA,MAAAsF,EAEA,WADAnE,GAAAiI,MAAA,oDAIA,IAAA,MAAA9D,EAAAf,KAEA,WADApD,GAAAiI,MAAA,8CAIA,IAAA7E,GAAAe,EAAAf,KACAggC,EAAAnhC,EAAAohC,UAAA,SAAAjgC,EAEA,IAAA,MAAAggC,EAEA,WADApjC,GAAAiI,MAAA,yCAAA7E,EAAA,wCAIA,IAAAgB,EAEAA,GADAnE,EAAAoF,OAAAlB,EAAAC,MACAnC,EAAAmI,EAAAjG,EAAAC,MlCutN6B,MAAhBD,EAAQC,KAAeD,EAAQC,KAAOnC,EAAGmI,GmC5wNtD,IAAA6jB,GAAA,GAAAmV,GAAApjC,EAAAS,UAAA0D,GACAlC,GAAAA,EACAmC,KAAAA,IAGA,OAAA6pB,IAKA0I,GAAA9H,aAAA8H,EAAA/H,WAEAtwB,EAAAD,QAAAs4B,IAEA9S,QAAA,GAAAxL,UAAA,KAAAirB,IAAA,SAAAvjC,EAAAzB,EAAAD,GACA,YAEA,IAAAs4B,IACAvR,OAAA,SAAAja,GACA,GAAA5K,GAAA1B,KAAA2B,QAEA,IAAAD,EAAAgjC,eAAA,CACA,GAAAvU,GAAAzuB,EAAAijC,gBACAC,EAAAljC,EAAAmjC,gBAUA,OARAv4B,GAAAmB,YACA0iB,EAAAxI,MAAArb,EAAAmB,iBAGAm3B,EAAA9d,IAAAxa,EAAA1H,OACAggC,EAAAniC,KAAA6J,EAAA1H,OAMA,GAAAlD,EAAAu/B,qBAAA,CAEA,GAAAzgB,GAAAxgB,KAAAwgB,UAEAA,GAAA+F,OAAAja,KAGAisB,cAAA,SAAAluB,GACA,GAAAtG,GAAA/D,KAAA2B,QAEA,OAAAmC,UAAAuG,EACAtG,EAAAk9B,0BAEAl9B,EAAAk9B,qBAAA52B,GAAA,GAAA,IAIAy6B,gBAAA,SAAAzoB,GACArc,KAAAu4B,eAAA,GACAlc,IACArc,KAAAu4B,eAAA,IAGArO,WAAA,WACA,GAAAxoB,GAAA1B,KAAA2B,QAiBA,OAfA,OAAAD,EAAAqjC,aACArjC,EAAAqjC,WAAA,GAGA,IAAArjC,EAAAqjC,aACArjC,EAAAwuB,cAAAxuB,EAAAgjC,gBAAA,EACAhjC,EAAA0uB,eAAApwB,KAAAyN,aACA/L,EAAAijC,gBAAA3kC,KAAAyN,aACA/L,EAAAmjC,oBAEAnjC,EAAAmjC,iBAAA/d,QAGAplB,EAAAqjC,aAEA/kC,MAGAuqB,SAAA,WACA,GAAA7oB,GAAA1B,KAAA2B,QAiBA,OAfAD,GAAAqjC,aAEA,IAAArjC,EAAAqjC,aAEArjC,EAAAwuB,eAAA,EACAxuB,EAAA0uB,eAAAzX,cAGAjX,EAAAgjC,gBAAA,EACA1kC,KAAAumB,QACA3hB,KAAAlD,EAAAmjC,iBACAp3B,WAAA/L,EAAAijC,mBAIA3kC,MAGAglC,MAAA,SAAA3oB,GAKA,MAJArc,MAAAkqB,aACA7N,IACArc,KAAAuqB,WAEAvqB,MC5GAilC,UAAA,SAAA9uB,GACA,GAAA/S,GAAApD,IAEA,OAAAA,MAAAglC,MAAA,WACA,IAAA,GAAAh+B,KAAAmP,GAAA,CACA,GAAAjO,GAAAiO,EAAAnP,GACAiB,EAAA7E,EAAAyC,eAAAmB,EAEAiB,GAAAC,KAAAA,OAMAzI,GAAAD,QAAAs4B,OAEAoN,IAAA,SAAAhkC,EAAAzB,EAAAD,GACA,YAEA,IAAA2B,GAAAD,EAAA,WAEA42B,GAEAqN,SAAA,SAAAC,EAAAhnB,EAAAC,EAAAgnB,GACA,GAAAhlC,GAAAL,KAAA2B,SAAA6e,QAGA,OADAngB,GAAA8kC,SAAAC,EAAAhnB,EAAAC,EAAAgnB,GACArlC,MAGAwgB,SAAA,WACA,MAAAxgB,MAAA2B,SAAA6e,UAGA8kB,YAAA,WAKA,MAJAtlC,MAAAumB,QACA3hB,KAAA,SAGA5E,MAGAulC,OAAA,WAOA,MANAvlC,MAAAumB,QACA3hB,KAAA,WAGA5E,KAAA4Y,QAAA,UAEA5Y,MAGAoiC,aAAA,SAAA98B,GACA,GAAAlC,GAAApD,KAEAwlC,EAAApiC,EAAAohC,UAAA,WAAAl/B,EAAAf,KACA,IAAA,MAAAihC,EAEA,WADArkC,GAAAiI,MAAA,gFAAA9D,EAAAf,KAIA,IAAAkhC,GAAAtkC,EAAAS,UAAA0D,GACAlC,GAAAA,IAEAod,EAAApd,EAAAzB,SAAA6e,SAAA,GAAAglB,GAAAC,EAEAjlB,GAAAklB,KAAAD,IAIAE,gBAAA,WAGA,IAAA,GAFAC,GAAA5lC,KAAA2B,SAAAq/B,UAEArgC,EAAA,EAAAA,EAAAilC,EAAA5kC,OAAAL,IAAA,CACA,GAAAg5B,GAAAiM,EAAAjlC,EAEAg5B,KAGA,MAAA35B,OAGA6lC,SAAA,SAAAlM,GAGA,MAFA35B,MAAA2B,SAAAq/B,UAAAv+B,KAAAk3B,GAEA35B,MAGA8lC,UAAA,SAAAtjC,GACA,GAAAojC,GAAA5lC,KAAA2B,SAAAq/B,SAEA,IAAA,MAAAx+B,EAEA,MADAxC,MAAA2B,SAAAq/B,aACAhhC,IAGA,KAAA,GAAAW,GAAA,EAAAA,EAAAilC,EAAA5kC,OAAAL,IAAA,CpCg4NM,GAAIg5B,GAAKiM,EAAIjlC,EqC/9NnB,IAAA6B,IAAAm3B,EAAA,CACAiM,EAAA99B,OAAAnH,EAAA,EACA,QAIA,MAAAX,OAKA83B,GAAAiO,qBAAAjO,EAAAyN,OAEA9lC,EAAAD,QAAAs4B,IAEAte,UAAA,KAAAwsB,IAAA,SAAA9kC,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,SACA2oB,EAAA3oB,EAAA,iBAEA42B,GAMArqB,WAAA,SAAAlI,EAAA/D,GAEA,MAAAJ,GAAAoF,OAAAjB,GACAvF,KAAAuL,EAAAhG,GAEAnE,EAAA+B,oBAAAoC,GACAA,EAAAkI,aAEArM,EAAAitB,MAAA9oB,GACAskB,EAAA7pB,KAAAuF,EAAA/D,GAGAqoB,EAAA7pB,OAGAsH,MAAA,SAAAqS,GACA,GAAArS,GAAAtH,KAAAuL,EAAA,WACA,MAAAvL,MAAAkN,UAGA,OAAAyM,GACArS,EAAAb,OAAAkT,GAGArS,GAGAH,MAAA,SAAAwS,GACA,GAAAxS,GAAAnH,KAAAuL,EAAA,WACA,MAAAvL,MAAAqhB,UAGA,OAAA1H,GACAxS,EAAAV,OAAAkT,GAGAxS,GrCq+NEoE,EAAG,SAAUoO,GsCriOf,GAAApU,GAAA,GAAAskB,GAAA7pB,KAAAA,KAAA2B,SAAAoZ,SAEA,OAAApB,GACApU,EAAAkB,OAAAkT,GAGApU,GAMAuyB,GAAA/c,SAAA+c,EAAArxB,OAAAqxB,EAAAvsB,EAEA9L,EAAAD,QAAAs4B,IAEAY,gBAAA,GAAA1T,QAAA,KAAAihB,IAAA,SAAA/kC,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,SACAglC,EAAAhlC,EAAA,YAEA42B,GAEAh2B,MAAA,SAAAqkC,GACA,GAAAA,EAAA,CACA,GAAA7lC,GAAAN,KAAAijC,SAAAkD,EAEA7lC,GAAAgf,SAGA,MAAAtf,MAAA2B,SAAAG,OAGAmhC,SAAA,SAAAnhC,GACA,GAAAJ,GAAA1B,KAAA2B,QCzBA,OD2BAP,GAAAglC,WAAAtkC,GACAJ,EAAAI,MAAAA,EAAAukC,cAAArmC,MCtCAoB,EAAAitB,MAAAvsB,GACAJ,EAAAI,MAAAokC,EAAAI,SAAAtmC,KAAA8B,GAEAV,EAAAoF,OAAA1E,GACAJ,EAAAI,MAAAokC,EAAAK,WAAAvmC,KAAA8B,GAGAJ,EAAAI,MAAAokC,EAAAlmC,MAGA0B,EAAAI,OAIArC,GAAAD,QAAAs4B,IAEA9S,QAAA,GAAAwhB,WAAA,KAAAC,IAAA,SAAAvlC,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,SAEA42B,GAEA5E,SAAA,SAAA7oB,GACA,MAAAvG,UAAAuG,EAGArK,KAAA2B,SAAAuxB,UAFAlzB,KAAA2B,SAAAuxB,SAAA7oB,GAAA,GAAA,EAKArK,OAGAmzB,cAAA,SAAA9oB,GACA,MAAAvG,UAAAuG,EAGArK,KAAA2B,SAAAwxB,eAFAnzB,KAAA2B,SAAAwxB,cAAA9oB,GAAA,GAAA,EAKArK,OAGAozB,gBAAA,SAAA/oB,GACA,MAAAvG,UAAAuG,EAGArK,KAAA2B,SAAAyxB,iBAFApzB,KAAA2B,SAAAyxB,gBAAA/oB,GAAA,GAAA,EAKArK,OAGAshC,eAAA,SAAAj3B,GACA,MAAAvG,UAAAuG,EAGArK,KAAA2B,SAAA2/B,gBAFAthC,KAAA2B,SAAA2/B,eAAAj3B,GAAA,GAAA,EAKArK,OAGAuhC,mBAAA,SAAAl3B,GACA,MAAAvG,UAAAuG,EAGArK,KAAA2B,SAAA4/B,oBAFAvhC,KAAA2B,SAAA4/B,mBAAAl3B,GAAA,GAAA,EAKArK,OAGAohC,eAAA,SAAA/2B,GACA,MAAAvG,UAAAuG,EAGArK,KAAA2B,SAAAy/B,gBAFAphC,KAAA2B,SAAAy/B,eAAA/2B,GAAA,GAAA,EAKArK,OAGAqhC,mBAAA,SAAAh3B,GACA,MAAAvG,UAAAuG,EAGArK,KAAA2B,SAAA0/B,oBAFArhC,KAAA2B,SAAA0/B,mBAAAh3B,GAAA,GAAA,EAKArK,OAGAwhC,oBAAA,SAAAn3B,GACA,MAAAvG,UAAAuG,EAGArK,KAAA2B,SAAA6/B,qBAFAxhC,KAAA2B,SAAA6/B,oBAAAn3B,GAAA,GAAA,EAKArK,OAGAqe,IAAA,WACA,GAEAH,GAAAC,EAAAuoB,EAAA7oB,EAAAC,EAFA0U,EAAA1lB,UACAuR,EAAAre,KAAA2B,SAAA0c,GAGA,QAAAmU,EAAAxxB,QACA,IAAA,GACA,MAAAqd,EAEA,KAAA,GAEA,GAAAjd,EAAAoF,OAAAgsB,EAAA,IAEA,MADAtU,GAAAsU,EAAA,GACAnU,EAAAH,EAEA,IAAA9c,EAAAwL,YAAA4lB,EAAA,IAAA,CACA,IAAAxyB,KAAA2B,SAAA2/B,eACA,MAAAthC,KAGA0mC,GAAAlU,EAAA,GACA3U,EAAA6oB,EAAA7oB,EACAC,EAAA4oB,EAAA5oB,EAEA1c,EAAA0Q,OAAA+L,KACAQ,EAAAR,EAAAA,GAGAzc,EAAA0Q,OAAAgM,KACAO,EAAAP,EAAAA,GAGA9d,KAAA4Y,QAAA,gBAEA,KAEA,KAAA,GACA,IAAA5Y,KAAA2B,SAAA2/B,eACA,MAAAthC,KAGAke,GAAAsU,EAAA,GACArU,EAAAqU,EAAA,GAEA,MAAAtU,GAAA,MAAAA,IAAA9c,EAAA0Q,OAAAqM,KACAE,EAAAH,GAAAC,GAGAne,KAAA4Y,QAAA,gBAWA,MAJA5Y,MAAAumB,QACA3hB,KAAA,aAGA5E,MAGA2mC,MAAA,SAAAr6B,GACA,GAEA4R,GAAAC,EAAAuoB,EAAA7oB,EAAAC,EAFA0U,EAAA1lB,UACAuR,EAAAre,KAAA2B,SAAA0c,GAGA,KAAAre,KAAA2B,SAAA2/B,eACA,MAAAthC,KAGA,QAAAwyB,EAAAxxB,QACA,IAAA,GAEAI,EAAAwL,YAAA4lB,EAAA,MACAkU,EAAAlU,EAAA,GACA3U,EAAA6oB,EAAA7oB,EACAC,EAAA4oB,EAAA5oB,EAEA1c,EAAA0Q,OAAA+L,KACAQ,EAAAR,GAAAA,GAGAzc,EAAA0Q,OAAAgM,KACAO,EAAAP,GAAAA,GAGA9d,KAAA4Y,QAAA,gBAEA,MAEA,KAAA,GACAsF,EAAAsU,EAAA,GACArU,EAAAqU,EAAA,GAEA,MAAAtU,GAAA,MAAAA,IAAA9c,EAAA0Q,OAAAqM,KACAE,EAAAH,IAAAC,GAGAne,KAAA4Y,QAAA,gBAWA,MAJA5Y,MAAAumB,QACA3hB,KAAA,aAGA5E,MAGA6vB,IAAA,SAAA9U,EAAA2E,GACA,GAAAknB,GAAA5mC,KAAA6mC,eAAA9rB,EAAA2E,EAEA,IAAAknB,EAAA,CACA,GAAAllC,GAAA1B,KAAA2B,QACAD,GAAA0c,KAAAwoB,EAAAxoB,KACA1c,EAAA2c,IAAAuoB,EAAAvoB,IAEAre,KAAA4Y,QAAA,qBAEA5Y,KAAAumB,QACA3hB,KAAA,aAIA,MAAA5E,OAGA6mC,eAAA,SAAA9rB,EAAA2E,GAMA,GALAte,EAAA0Q,OAAAiJ,IAAAjX,SAAA4b,IACAA,EAAA3E,EACAA,EAAAjX,QAGA9D,KAAA2B,SAAA2/B,gBAAAthC,KAAA2B,SAAAy/B,eAAA,CAIA,GAAAriB,EAEA,IAAA3d,EAAAoF,OAAAuU,GAAA,CACA,GAAA+rB,GAAA/rB,CACAA,GAAA/a,KAAAuL,EAAAu7B,OAEA,IAAA1lC,EAAA4d,YAAAjE,GAAA,CACA,GAAAgsB,GAAAhsB,CACAgE,IACAE,GAAA8nB,EAAA9nB,GACAE,GAAA4nB,EAAA5nB,GACAD,GAAA6nB,EAAA7nB,GACAE,GAAA2nB,EAAA3nB,IAGAL,EAAA3W,EAAA2W,EAAAG,GAAAH,EAAAE,GACAF,EAAAM,EAAAN,EAAAK,GAAAL,EAAAI,OAEA/d,GAAA+B,oBAAA4X,KACAA,EAAA/a,KAAA+a,WAGAgE,GAAAA,GAAAhE,EAAAiE,aAEA,IAEAZ,GAFAhW,EAAApI,KAAAgnC,QACA3nB,EAAArf,KAAAinC,QAIA,IAFAvnB,EAAAte,EAAA0Q,OAAA4N,GAAAA,EAAA,GAEAwnB,MAAA9+B,KAAA8+B,MAAA7nB,IAAAjX,EAAA,GAAAiX,EAAA,IAAA6nB,MAAAnoB,EAAA3W,KAAA8+B,MAAAnoB,EAAAM,IAAAN,EAAA3W,EAAA,GAAA2W,EAAAM,EAAA,EAAA,CACAjB,EAAA3O,KAAAkN,KAAAvU,EAAA,EAAAsX,GAAAX,EAAA3W,GAAAiX,EAAA,EAAAK,GAAAX,EAAAM,GAGAjB,EAAAA,EAAApe,KAAA2B,SAAAw/B,QAAAnhC,KAAA2B,SAAAw/B,QAAA/iB,EACAA,EAAAA,EAAApe,KAAA2B,SAAAu/B,QAAAlhC,KAAA2B,SAAAu/B,QAAA9iB,CAEA,IAAAC,IACAR,GAAAzV,EAAAgW,GAAAW,EAAAE,GAAAF,EAAAG,KAAA,EACApB,GAAAuB,EAAAjB,GAAAW,EAAAI,GAAAJ,EAAAK,KAAA,EAGA,QACAhB,KAAAA,EACAC,IAAAA,MAOA6iB,QAAA,SAAA9iB,GACA,MAAAta,UAAAsa,EACApe,KAAA2B,SAAAu/B,SACA9/B,EAAA0Q,OAAAsM,KACApe,KAAA2B,SAAAu/B,QAAA9iB,GAGApe,OAGAmhC,QAAA,SAAA/iB,GACA,MAAAta,UAAAsa,EACApe,KAAA2B,SAAAw/B,SACA//B,EAAA0Q,OAAAsM,KACApe,KAAA2B,SAAAw/B,QAAA/iB,GAGApe,OAGAoe,KAAA,SAAA9R,GACA,GAAAoR,GACAU,CAEA,IAAAta,SAAAwI,EACA,MAAAtM,MAAA2B,SAAAyc,IAEA,IAAAhd,EAAA0Q,OAAAxF,GACA8R,EAAA9R,MAEA,IAAAlL,EAAAwL,YAAAN,GAAA,CAGA,GAFA8R,EAAA9R,EAAA66B,MAEA76B,EAAA0Q,SAAA,CACA,GAAAjZ,GAAAuI,EAAA0Q,SACAqB,EAAAre,KAAA2B,SAAA0c,IACA+oB,EAAApnC,KAAA2B,SAAAyc,IAEAV,IACAG,EAAA9Z,EAAA8Z,EAAAupB,EAAA/oB,EAAAR,EACAC,EAAA/Z,EAAA+Z,EAAAspB,EAAA/oB,EAAAP,OAEAxR,GAAA2R,mBACAP,EAAApR,EAAA2R,iBAGA,IAAAP,IAAA1d,KAAA2B,SAAA2/B,eACA,MAAAthC,MAIA,IAAAA,KAAA2B,SAAAy/B,eACA,MAAAphC,KAGA,KAAAoB,EAAA0Q,OAAAsM,IAAAV,KAAAtc,EAAA0Q,OAAA4L,EAAAG,KAAAzc,EAAA0Q,OAAA4L,EAAAI,IACA,MAAA9d,KAOA,IAHAoe,EAAAA,EAAApe,KAAA2B,SAAAw/B,QAAAnhC,KAAA2B,SAAAw/B,QAAA/iB,EACAA,EAAAA,EAAApe,KAAA2B,SAAAu/B,QAAAlhC,KAAA2B,SAAAu/B,QAAA9iB,EAEAV,EAAA,CACA,GAAA2pB,GAAArnC,KAAA2B,SAAA0c,IACAipB,EAAAtnC,KAAA2B,SAAAyc,KACAmpB,EAAAnpB,EAEAopB,GACA3pB,GAAA0pB,EAAAD,GAAA5pB,EAAAG,EAAAwpB,EAAAxpB,GAAAH,EAAAG,EACAC,GAAAypB,EAAAD,GAAA5pB,EAAAI,EAAAupB,EAAAvpB,GAAAJ,EAAAI,EAGA9d,MAAA2B,SAAAyc,KAAAA,EACApe,KAAA2B,SAAA0c,IAAAmpB,CAEA,IAAAC,GAAAJ,EAAAxpB,IAAA2pB,EAAA3pB,GAAAwpB,EAAAvpB,IAAA0pB,EAAA1pB,CACA9d,MAAA4Y,QAAA,UAAA6uB,EAAA,QAAA,IAAA,kBAGAznC,MAAA2B,SAAAyc,KAAAA,EACApe,KAAA4Y,QAAA,gBAOA,OAJA5Y,MAAAumB,QACA3hB,KAAA,aAGA5E,MAGA0nC,SAAA,SAAAlmC,GACA,GAAAE,GAAA1B,KAAA2B,SACAgmC,GAAA,EACAC,GAAA,EACAC,KACAC,GAAA,EACAC,GAAA,CAEA,KAAAvmC,EAAA,MAAAxB,KAGA,IAFAoB,EAAA0Q,OAAAtQ,EAAA4c,QAAAupB,GAAA,GACAvmC,EAAAwL,YAAApL,EAAA6c,OAAAupB,GAAA,IACAD,IAAAC,EAAA,MAAA5nC,KAEA,IAAA2nC,EAAA,CACA,GAAAP,GAAA5lC,EAAA4c,IAEAgpB,GAAA1lC,EAAAw/B,SAAAkG,EAAA1lC,EAAAy/B,UAAAz/B,EAAA0/B,eACA0G,GAAA,GAGApmC,EAAA0c,KAAAgpB,EAEAS,EAAAplC,KAAA,SAIA,GAAAmlC,KAAAE,IAAAtmC,EAAAwmC,qBAAAtmC,EAAA4/B,eAAA,CACA,GAAAv9B,GAAAvC,EAAA6c,GAEAjd,GAAA0Q,OAAA/N,EAAA8Z,KACAnc,EAAA2c,IAAAR,EAAA9Z,EAAA8Z,EACAkqB,GAAA,GAGA3mC,EAAA0Q,OAAA/N,EAAA+Z,KACApc,EAAA2c,IAAAP,EAAA/Z,EAAA+Z,EACAiqB,GAAA,GAGAA,GACAF,EAAAplC,KAAA,OAaA,MATAolC,GAAA7mC,OAAA,IACA6mC,EAAAplC,KAAA,YACAzC,KAAA4Y,QAAAivB,EAAArd,KAAA,MAEAxqB,KAAAumB,QACA3hB,KAAA,cAIA5E,MAGAioC,OAAA,SAAAltB,GACA,GAAAsD,GAAAre,KAAAkoC,aAAAntB,EAYA,OAVAsD,KACAre,KAAA2B,SAAA0c,IAAAA,EAEAre,KAAA4Y,QAAA,gBAEA5Y,KAAAumB,QACA3hB,KAAA,cAIA5E,MAGAkoC,aAAA,SAAAntB,EAAAqD,GACA,GAAApe,KAAA2B,SAAA2/B,eAAA,CAIA,GAAAlgC,EAAAoF,OAAAuU,GAAA,CACA,GAAApB,GAAAoB,CACAA,GAAA/a,KAAA+a,SAAApB,OACAvY,GAAA+B,oBAAA4X,KACAA,EAAA/a,KAAA+a,WAGA,IAAAgE,GAAAhE,EAAAiE,cACA5W,EAAApI,KAAAgnC,QACA3nB,EAAArf,KAAAinC,QACA7oB,GAAAta,SAAAsa,EAAApe,KAAA2B,SAAAyc,KAAAA,CAEA,IAAAC,IACAR,GAAAzV,EAAAgW,GAAAW,EAAAE,GAAAF,EAAAG,KAAA,EACApB,GAAAuB,EAAAjB,GAAAW,EAAAI,GAAAJ,EAAAK,KAAA,EAGA,OAAAf,KAGA8pB,MAAA,WACA,MAAAnoC,MAAA2B,SAAA2/B,gBAAAthC,KAAA2B,SAAAy/B,gBAIAphC,KAAA0nC,UACArpB,KAAAR,EAAA,EAAAC,EAAA,GACAM,KAAA,IAGApe,MARAA,MAWAgnC,MAAA,WACA,GAAA7G,GAAAngC,KAAA2B,SAAAw+B,SAEA,OAAAA,GACAA,EAAAiI,YAGA,GAGAnB,OAAA,WACA,GAAA9G,GAAAngC,KAAA2B,SAAAw+B,SAEA,OAAAA,GACAA,EAAAkI,aAGA,GAGAC,OAAA,WACA,GAAAjqB,GAAAre,KAAA2B,SAAA0c,IACAD,EAAApe,KAAA2B,SAAAyc,KACAmqB,EAAAvoC,KAAAwoC,iBAEApkC,GACA6a,IAAAspB,EAAAtpB,GAAAZ,EAAAR,GAAAO,EACAc,IAAAqpB,EAAArpB,GAAAb,EAAAR,GAAAO,EACAe,IAAAopB,EAAAppB,GAAAd,EAAAP,GAAAM,EACAgB,IAAAmpB,EAAAnpB,GAAAf,EAAAP,GAAAM,EAMA,OAHAha,GAAAgE,EAAAhE,EAAA8a,GAAA9a,EAAA6a,GACA7a,EAAAib,EAAAjb,EAAAgb,GAAAhb,EAAA+a,GAEA/a,GAGAokC,eAAA,WACA,GAAAxB,GAAAhnC,KAAAgnC,QACAC,EAAAjnC,KAAAinC,QAEA,QACAhoB,GAAA,EACAE,GAAA,EvC+kOMD,GAAI8nB,EwC1mPV5nB,GAAA6nB,EACA7+B,EAAA4+B,EACA3nB,EAAA4nB,IAMAnP,GAAA2Q,OAAA3Q,EAAAmQ,OAGAnQ,EAAA2J,cAAA3J,EAAA5E,SACA4E,EAAA4J,mBAAA5J,EAAA3E,cAEA1zB,EAAAD,QAAAs4B,IAEA9S,QAAA,KAAA0jB,IAAA,SAAAxnC,EAAAzB,EAAAD,GACA,YAQA,IAAA2B,GAAAD,EAAA,UACAE,EAAAF,EAAA,QACAwlB,EAAAxlB,EAAA,cACAG,EAAAH,EAAA,aACAynC,EAAAznC,EAAA,WACAI,EAAAJ,EAAA,eAEAxB,GAGAwI,KAAA,SAAAoE,GACA,GAAA+nB,IACApZ,MAAA,OACAC,aAAA,OACAC,cAAA,EACAC,cAAA,EACAI,cAAA,EACAH,aAAA,OACAC,sBAAA,EACAC,cAAA,UACAE,iBACA9C,aAAA,EACAuE,MAAA,SAAAnd,KACAud,OAAA,SAAAvd,GAAA,OAAA,GAIA,OAFAuM,GAAAnL,EAAAS,UAAAyyB,EAAA/nB,GAEA,SAAA/H,EAAAib,GACA,GAAAzb,GAAAuI,EACAvM,EAAAC,KACA4oC,EAAA9kC,SAAA/D,EAAAiB,OACAkhC,EAAA0G,EAAA7oC,GAAAA,GACAslB,EAAAujB,EAAA7oC,EAAA,GAAAA,CAGA,IAAAqB,EAAAoF,OAAAjC,GAAA,CAGA,GAAAR,EAAAyX,cAAA1X,SAAA0b,EAAA,CAEA,GAAA3T,EAIA,OAHAwZ,KACAxZ,EAAAwZ,EAAA1jB,SAAAoC,EAAAkX,OAAA1W,IAEAsH,EAGA,GAAA9H,EAAAqX,cAAAtX,SAAA0b,EAAA,CACA,GAAAyb,IAAAl3B,EAAA0X,cAAAlX,EACA,IAAA02B,EAAA,CACA,IAAA,GAAAt6B,GAAA,EAAAG,EAAAohC,EAAAlhC,OAAAF,EAAAH,EAAAA,IACAoD,EAAAuZ,OAAA4kB,EAAAvhC,MACAuhC,EAAAvhC,GAAAgB,SAAAoC,EAAAkX,OAAA1W,GAAAib,EAKAzb,GAAA4U,aAAA5Y,EAAA4Y,cAGA5U,EAAAmZ,MAAAnd,GAEAgE,EAAAuX,sBACAvb,EAAAgE,EAAAwX,eAAAxX,EAAAsX,oBAMA,IAAAtX,EAAAqX,cAAAha,EAAAwL,YAAArI,GAAA,CACA,GACAiO,GAAApH,EADA6e,EAAA1lB,CAGA,KAAAiO,IAAAyX,GAAA,CACA7e,EAAA6e,EAAAzX,EAEA,IAAAyoB,IAAAl3B,EAAA0X,cAAAjJ,EACA,IAAAyoB,EACA,IAAA,GAAAt6B,GAAA,EAAAG,EAAAohC,EAAAlhC,OAAAF,EAAAH,EAAAA,IACAoD,EAAAuZ,OAAA4kB,EAAAvhC,MACAuhC,EAAAvhC,GAAAgB,SAAAoC,EAAAkX,OAAAzI,GAAApH,GAOArH,EAAA4U,aAAA5Y,EAAA4Y,cAGA5U,EAAAmZ,MAAAnd,GAEAgE,EAAAuX,sBACAvb,EAAAgE,EAAAwX,eAAAxX,EAAAsX,kBAIA,IAAAtX,EAAAoX,cAAA/Z,EAAAoB,GAAA+B,GAAA,CACA,GAAA/B,GAAA+B,CACAxE,GAAA4yB,KAAA5uB,EAAAmX,aAAA1Y,OAGA,IAAAuB,EAAAyX,cAAA1X,SAAAS,EAAA,CACA,GAAAsH,EAIA,OAHAwZ,KACAxZ,EAAAwZ,EAAA1jB,SAAAoC,EAAAkX,QAEApP,EAGA,MAAA9L,KAKA2b,WAAA,SAAApP,GACA,GAAA+nB,IACApZ,MAAA,OACAU,MAAA,OACAJ,cAAA,UACAK,cAAA,EACAH,iBAIA,OAFAnP,GAAAnL,EAAAS,UAAAyyB,EAAA/nB,GAEA,SAAA0kB,GACA,GAAAjtB,GAAAuI,EACAvM,EAAAC,KACA4oC,EAAA9kC,SAAA/D,EAAAiB,OACAkhC,EAAA0G,EAAA7oC,GAAAA,EAGA,IAAAqB,EAAAoF,OAAAwqB,GAAA,CAIA,IAAA,GAHA6X,GAAA7X,EAAAnL,MAAA,OACA/kB,EAAA+nC,EAAA7nC,OAEAL,EAAA,EAAAG,EAAAH,EAAAA,IAAA,CACA,GAAAiL,GAAAi9B,EAAAloC,EACA,KAAAS,EAAA0pB,YAAAlf,GAAA,CAEA,GAAAqvB,IAAAl3B,EAAA0X,cAAA7P,EACA,IAAAqvB,EACA,IAAA,GAAA6N,GAAA,EAAAC,EAAA7G,EAAAlhC,OAAA+nC,EAAAD,EAAAA,IACA5G,EAAA4G,GAAAnnC,SAAAoC,EAAAkX,OAAArP,GAAA9H,QAKAC,EAAA6X,cACA7b,EAAAgE,EAAAwX,eAAAxX,EAAA4X,WAIA,IAAA7X,SAAAktB,EAAA,CAEA,IAAA,GAAA8X,GAAA,EAAAC,EAAA7G,EAAAlhC,OAAA+nC,EAAAD,EAAAA,IAAA,CACA,GAAAE,GAAA9G,EAAA4G,GAAAnnC,SAAAoC,EAAAkX,MAEA,KAAA,GAAArP,KAAAo9B,GAAA,CACA,GAAAC,IAAAllC,EAAA0X,cAAA7P,EAEAq9B,KACAD,EAAAp9B,GAAA9H,SAKAC,EAAA6X,cACA7b,EAAAgE,EAAAwX,eAAAxX,EAAA4X,OAIA,MAAA5b,KAKA4b,OACAutB,MAAA,gBACAC,kBAAA,iBACAC,cAAA,WAAA,OAAA,IAIApjB,GAAA,SAAA1Z,GACA,GAAA+nB,IACAnO,qBAAA,EACAE,2BAAA,EAIA,OAFA9Z,GAAAnL,EAAAS,UAAAyyB,EAAA/nB,GAEA,SAAAu7B,EAAAluB,EAAAzR,EAAAmU,GACA,GAAAtc,GAAAC,KACA4oC,EAAA9kC,SAAA/D,EAAAiB,OACAkhC,EAAA0G,EAAA7oC,GAAAA,GACAspC,EAAAjoC,EAAAoF,OAAAqhC,GACA9jC,EAAAuI,CAmBA,IAjBAlL,EAAAwL,YAAA+M,IACA0C,EAAAnU,EACAA,EAAAyR,EACAA,EAAA7V,SACA1C,EAAAoB,GAAAmX,IAAAA,KAAA,KACA0C,EAAA1C,EACAzR,EAAApE,OACA6V,EAAA7V,SAGA1C,EAAAoB,GAAA0F,IAAAA,KAAA,KACAmU,EAAAnU,EACAA,EAAApE,SAKA1C,EAAAoB,GAAA6Z,IAAAA,KAAA,GAAAgtB,EACA,MAAAtpC,EAGA,IAAAspC,EAAA,CACA,GAAAlzB,KACAA,GAAA0xB,GAAAxrB,EACAwrB,EAAA1xB,EAGA,IAAA,GAAAmzB,KAAAzB,GAMA,GALAxrB,EAAAwrB,EAAAyB,GACAjtB,KAAA,IACAA,EAAA3c,EAAAic,MAAAytB,eAGAhoC,EAAAoB,GAAA6Z,GAAA,CAEAitB,EAAAA,EAAAzjB,MAAA,MACA,KAAA,GAAAllB,GAAA,EAAAA,EAAA2oC,EAAAtoC,OAAAL,IAAA,CACA,GAAA4oC,GAAAD,EAAA3oC,EACA,KAAAS,EAAA0pB,YAAAye,GAAA,CAEA,GAAAtxB,GAAAsxB,EAAAtxB,MAAAvY,EAAAic,MAAAutB,MAEA,IAAAjxB,EAiBA,IAAA,GAhBArT,GAAAqT,EAAA,GACAuxB,EAAAvxB,EAAA,GAAAA,EAAA,GAAAnU,OAEA2lC,GACAptB,SAAAA,EACAnU,KAAAA,EACAwhC,UAAA/vB,GAAA,GAAA,EACAA,SAAAA,EACAgwB,OAAA,GAAAjjB,GAAA/M,GACA/U,KAAAA,EACA4kC,UAAAA,EACAtjB,oBAAAniB,EAAAmiB,oBACAE,0BAAAriB,EAAAqiB,0BACAwjB,QAAA1H,GAGAj1B,EAAA,EAAAA,EAAAi1B,EAAAlhC,OAAAiM,IAAA,CACA,GAAAvL,GAAAwgC,EAAAj1B,GAAAtL,QAEAD,GAAA4jB,UAAA5jB,EAAA4jB,cACA5jB,EAAA4jB,UAAA7iB,KAAAgnC,MAMA,MAAA1pC,KAIAymB,eAAA,SAAAqjB,GACA,GAAA9lC,GAAA8lC,CAEA9lC,GAAA+lC,YAAA/lC,EAAAgmC,OAAAhmC,EAAA4uB,KAAA5uB,EAAAiiB,GACAjiB,EAAAimC,eAAAjmC,EAAAkmC,SAAAlmC,EAAAmmC,OAAAnmC,EAAAsiB,IACAtiB,EAAAomC,KAAApmC,EAAA6U,QAGA7U,EAAAqmC,IAAArmC,EAAAsmC,UAAA,SAAAxC,EAAAluB,GACA,GAAA5Z,GAAAC,KACAwyB,EAAA1f,MAAAnQ,UAAAiS,MAAA7T,KAAA+L,UAAA,EAEA,OAAA,IAAAzL,GAAA,SAAAyD,EAAAC,GACA,GAAAsX,GAAA,SAAAnc,GACAH,EAAAsmB,IAAA7iB,MAAAzD,EAAAuqC,GAEAxlC,EAAA5E,IAGAqqC,EAAA/X,EAAA9X,QAAA2B,IACAiuB,EAAAC,EAAA7vB,UAEA3a,GAAAimB,GAAAxiB,MAAAzD,EAAAwqC,OAKAlkB,IAAA,SAAA/Z,GACA,GAAA+nB,KAIA,OAFA/nB,GAAAnL,EAAAS,UAAAyyB,EAAA/nB,GAEA,SAAAu7B,EAAAluB,EAAA0C,GACA,GAAAtc,GAAAC,KACA4oC,EAAA9kC,SAAA/D,EAAAiB,OACAkhC,EAAA0G,EAAA7oC,GAAAA,GACAspC,EAAAjoC,EAAAoF,OAAAqhC,EAEA,IAAA,IAAA/6B,UAAA9L,OAAA,CAEA,IAAA,GAAAL,GAAA,EAAAA,EAAAuhC,EAAAlhC,OAAAL,IACAuhC,EAAAvhC,GAAAgB,SAAA2jB,YAGA,OAAAvlB,GAQA,IALAqB,EAAAoB,GAAAmX,IAAAA,KAAA,KACA0C,EAAA1C,EACAA,EAAA7V,QAGAulC,EAAA,CACA,GAAAlzB,KACAA,GAAA0xB,GAAAxrB,EACAwrB,EAAA1xB,EAGA,IAAA,GAAAmzB,KAAAzB,GAAA,CACAxrB,EAAAwrB,EAAAyB,GAEAjtB,KAAA,IACAA,EAAA3c,EAAAic,MAAAytB,eAGAE,EAAAA,EAAAzjB,MAAA,MACA,KAAA,GAAAxG,GAAA,EAAAA,EAAAiqB,EAAAtoC,OAAAqe,IAAA,CACA,GAAAkqB,GAAAD,EAAAjqB,EACA,KAAAje,EAAA0pB,YAAAye,GAAA,CAEA,GAAAtxB,GAAAsxB,EAAAtxB,MAAAvY,EAAAic,MAAAwtB,kBACA,IAAAlxB,EAIA,IAAA,GAHArT,GAAAqT,EAAA,GAAAA,EAAA,GAAAnU,OACA0lC,EAAAvxB,EAAA,GAAAA,EAAA,GAAAnU,OAEAnD,EAAA,EAAAA,EAAAuhC,EAAAlhC,OAAAL,IAGA,IAAA,GAFA2kB,GAAA4c,EAAAvhC,GAAAgB,SAAA2jB,UAAA4c,EAAAvhC,GAAAgB,SAAA2jB,cAEArY,EAAA,EAAAA,EAAAqY,EAAAtkB,OAAAiM,IAAA,CACA,GAAAw8B,GAAAnkB,EAAArY,GACAu9B,GAAAhB,GAAAA,IAAAC,EAAAD,UACAiB,GAAA7lC,GAAA6kC,EAAA7kC,OAAAA,EACA8lC,GAAAruB,GAAAA,IAAAotB,EAAAptB,SACAsuB,EAAAH,GAAAC,GAAAC,CAGAC,KACArlB,EAAAxd,OAAAmF,EAAA,GACAA,QASA,MAAAlN,KAIA6Y,QAAA,SAAAtM,GACA,GAAA+nB,KAGA,OAFA/nB,GAAAnL,EAAAS,UAAAyyB,EAAA/nB,GAEA,SAAAu7B,EAAAvhB,EAAAskB,GACA,GAAA7qC,GAAAC,KACA4oC,EAAA9kC,SAAA/D,EAAAiB,OACAkhC,EAAA0G,EAAA7oC,GAAAA,GACAspC,EAAAjoC,EAAAoF,OAAAqhC,GACAgD,EAAAzpC,EAAAwL,YAAAi7B,GACAiD,EAAA1pC,EAAAua,MAAAksB,GACAzkC,EAAApD,KAAA2B,SAAAyB,KAAAhC,EAAAgkB,KAAAplB,MAAAA,KAAA,MACA+qC,EAAA3nC,EAAAA,EAAAsb,oBAAA,CAEA,IAAA2qB,EAAA,CACA,GAAAC,GAAAzB,EAAAhiB,MAAA,MACAgiB,KAEA,KAAA,GAAAlnC,GAAA,EAAAA,EAAA2oC,EAAAtoC,OAAAL,IAAA,CACA,GAAA4oC,GAAAD,EAAA3oC,EACA,KAAAS,EAAA0pB,YAAAye,GAAA,CAEA,GAAAtxB,GAAAsxB,EAAAtxB,MAAAvY,EAAAic,MAAAutB,OACAtkC,EAAAqT,EAAA,GACAuxB,EAAAvxB,EAAA,GAAAA,EAAA,GAAAnU,MAEA+jC,GAAAplC,MACAmC,KAAAA,EACA4kC,UAAAA,UAGA,IAAAqB,EAAA,CACA,GAAAG,GAAAnD,CAEAA,IAAAmD,GAGA1kB,EACAllB,EAAAitB,MAAA/H,KACAA,GAAAA,IAGAA,IAGA,KAAA,GAAA3lB,GAAA,EAAAA,EAAAknC,EAAA7mC,OAAAL,IAGA,IAAA,GAFAsqC,GAAApD,EAAAlnC,GAEAsM,EAAA,EAAAA,EAAAi1B,EAAAlhC,OAAAiM,IAAA,CACA,GAMAs8B,GANA2B,EAAAhJ,EAAAj1B,GACAqY,EAAA4lB,EAAAvpC,SAAA2jB,UAAA4lB,EAAAvpC,SAAA2jB,cACA6lB,EAAA/pC,EAAAulB,QAAAukB,GACAE,EAAAD,GAAA7+B,EAAA8iB,MA8BA,IAzBA0b,GACAvB,EAAA0B,EAEA1B,EAAA8B,SAAA9B,EAAA8B,UAAAH,EACA3B,EAAAnmC,GAAAmmC,EAAAnmC,IAAAA,GAGAmmC,EAAA,GAAAZ,GAAAsC,GACAI,SAAAH,EACA9nC,GAAAA,EACAomC,UAAAyB,EAAAzB,YAKAyB,EAAA7b,SACAma,EAAAna,OAAA6b,EAAA7b,QAIA9iB,EAAA8iB,SACAma,EAAAna,OAAA8b,GAIA3B,EAAA+B,WAAA,CACA,GAAA5tB,GAAA6rB,EAAA+B,WACAltB,EAAAhb,EAAAgb,OACAC,EAAAjb,EAAAib,KAEAkrB,GAAAgC,oBACA1tB,EAAAH,EAAAG,EAAAO,EAAAC,EAAAR,EACAC,EAAAJ,EAAAI,EAAAM,EAAAC,EAAAP,GAIA8sB,IACAtlB,IACAkkB,UAAAD,EAAAC,UACA5kC,KAAA2kC,EAAA3kC,KACAyX,SAAAuuB,IAIA,KAAA,GAAAp4B,GAAA,EAAAA,EAAA8S,EAAAtkB,OAAAwR,IAAA,CACA,GAAAg5B,GAAAlmB,EAAA9S,GACAg4B,GAAAgB,EAAAhC,WAAAgC,EAAAhC,YAAAD,EAAAC,UACAiB,EAAAe,EAAA5mC,OAAA2kC,EAAA3kC,KACA6mC,EAAAD,EAAA9B,UAAAwB,IAAA3B,EAAA8B,UAAAjqC,EAAAulB,QAAA4iB,EAAA8B,WAAAG,EAAA7B,OAAA+B,QAAAnC,EAAA8B,WAAA,EACAV,EAAAH,GAAAC,GAAAgB,CAEA,IAAAd,EAAA,CACA,GAAAnY,IAAA+W,EAcA,IAbA/W,EAAAA,EAAA9X,OAAA4L,GAEAklB,EAAAtjC,KACAqhC,EAAArhC,KAAAsjC,EAAAtjC,KAEAqhC,EAAArhC,KAAApE,QAGA0nC,EAAAtlB,qBAAAslB,EAAAplB,6BACAd,EAAAxd,OAAA0K,EAAA,GACAA,KAGAg5B,EAAAplB,0BAEA,IAAA,GADAwjB,GAAA4B,EAAA5B,QACA9oC,EAAA,EAAAA,EAAA8oC,EAAA5oC,OAAAF,IAAA,CACA,GAAA6qC,GAAA/B,EAAA9oC,EACA,IAAA6qC,GAAAA,IAAAT,EAGA,IAAA,GADAU,GAAAD,EAAAhqC,SAAA2jB,UACAumB,EAAA,EAAAA,EAAAD,EAAA5qC,OAAA6qC,IAAA,CACA,GAAAC,GAAAF,EAAAC,EAEAC,KAAAN,IACAI,EAAA9jC,OAAA+jC,EAAA,GACAA,MAOA,GAAAzG,GAAAoG,EAAA9B,UAAAH,EAAA8B,SAAAH,EACAr/B,EAAA2/B,EAAAnvB,SAAA7Y,MAAA4hC,EAAA5S,IAEA3mB,KAAA,GAAA09B,EAAAwC,0BAEAX,GAAA,EAEAv/B,KAAA,IAEA09B,EAAAyC,kBACAzC,EAAA0C,oBAOA,GAAAb,EAAA,CACA,GAAAnxB,GAAA8wB,EAAAG,EAAAvpC,SAAAsY,OAAA,KACA0E,EAAA,MAAA1E,GAAA,IAAAA,EAAAjZ,MAEA2d,IACA1E,EAAAA,EAAA,GACAA,EAAArB,QAAA2wB,IAEAnmC,EAAAwV,QAAA2wB,IAOA,MAAAxpC,KAIA2X,SAAA,SAAAw0B,GACA,GAAA7X,KAGA,OAFA6X,GAAA/qC,EAAAS,UAAAyyB,EAAA6X,GAEA,WACA,GAAAnsC,GAAAC,KACA4oC,EAAA9kC,SAAA/D,EAAAiB,OACAkhC,EAAA0G,EAAA7oC,GAAAA,GACAqD,EAAApD,KAAA2B,SAAAyB,IAAApD,IAEA,KAAAoD,EAAAgd,eAAA,OAAA,CAEA,IAAAnY,GAAAi6B,EAAA,EAEA,OAAAj6B,GACAA,EAAAtG,SAAAqB,UAAAE,QAAAlC,OAAA,EADA,SAMA2W,WAAA,SAAAu0B,GACA,GAAA7X,KAGA,OAFA6X,GAAA/qC,EAAAS,UAAAyyB,EAAA6X,GAEA,WACA,GAAAnsC,GAAAC,KACA4oC,EAAA9kC,SAAA/D,EAAAiB,OACAkhC,EAAA0G,EAAA7oC,GAAAA,GACAqD,EAAApD,KAAA2B,SAAAyB,IAAApD,IAEA,KAAAoD,EAAAgd,eAAA,MAAApgB,KAEA,KAAA,GAAAW,GAAA,EAAAA,EAAAuhC,EAAAlhC,OAAAL,IAAA,CACA,GAAAsH,GAAAi6B,EAAAvhC,EACAsH,GAAAtG,SAAAqB,UAAAC,SAGA,MAAAjD,QAIA4X,MAAA,SAAAs0B,GACA,GAAA7X,KAGA,OAFA6X,GAAA/qC,EAAAS,UAAAyyB,EAAA6X,GAEA,SAAAroC,EAAAtB,GACA,GAAAa,GAAApD,KAAA2B,SAAAyB,IAAApD,IAEA,OAAAoD,GAAAgd,eAEApgB,KAAAyX,SACAG,MAAA/T,EACAhC,SAAAgC,EACAtB,SAAAA,IALAvC,OAUA6X,eAAA,SAAAq0B,GACA,GAAA7X,KAGA,OAFA6X,GAAA/qC,EAAAS,UAAAyyB,EAAA6X,GAEA,SAAAroC,EAAAtB,GACA,GAAAa,GAAApD,KAAA2B,SAAAyB,IAAApD,IAEA,OAAAoD,GAAAgd,eAEApgB,KAAAgD,WACA4U,MAAA/T,EACAhC,SAAAgC,EACAtB,SAAAA,IALAvC,OAUAgD,UAAA,SAAAkpC,GACA,GAAA7X,KAGA,OAFA6X,GAAA/qC,EAAAS,UAAAyyB,EAAA6X,GAEA,SAAAC,EAAA7/B,GACA,GAAAvM,GAAAC,KACA4oC,EAAA9kC,SAAA/D,EAAAiB,OACAkhC,EAAA0G,EAAA7oC,GAAAA,GACAqD,EAAApD,KAAA2B,SAAAyB,IAAApD,KACAw5B,GAAAoP,EACA1O,GAAAV,CAEA,KAAAp2B,EAAAgd,eAAA,MAAApgB,KAEA,IAAA8B,GAAAsB,EAAAtB,OAQA,QANAqqC,EAAAhrC,EAAAS,UAAAuqC,EAAA7/B,GAEAxI,SAAAqoC,EAAAtqC,WACAsqC,EAAAtqC,SAAA,KAGAsqC,EAAAtqC,UACA,IAAA,OACAsqC,EAAAtqC,SAAA,GACA,MACA,KAAA,OACAsqC,EAAAtqC,SAAA,IAIA,GAAAuqC,IAAA,CACA,IAAAD,EAAA,IAAA,GAAAxrC,KAAAwrC,GAAA,CACAC,GAAA,CACA,OAGA,GAAAA,EACA,MAAA,IAAA9qC,GAAA4gC,EAAA,GAAAiK,EASA,IANAjS,IACAiS,EAAArqC,MAAAA,EAAAuqC,aAAAF,EAAArqC,OAAAqqC,EAAApqC,KAEAoqC,EAAApqC,IAAA+B,QAGAqoC,EAAAluB,kBAAAic,EAAA,CACA,GAAA5b,GAAA6tB,EAAAluB,iBACAI,EAAAjb,EAAAib,MACAD,EAAAhb,EAAAgb,MAEA+tB,GAAAnvB,UACAa,GAAAS,EAAAT,EAAAQ,EAAAR,GAAAO,EACAN,GAAAQ,EAAAR,EAAAO,EAAAP,GAAAM,GAKA,GAAA+tB,EAAAxF,OAAAnN,EAAA,CACA,GAAAmN,GAAAwF,EAAAxF,MACA2F,EAAAlpC,EAAAib,KAEA8tB,GAAA9tB,KACAR,EAAAyuB,EAAAzuB,EAAA8oB,EAAA9oB,EACAC,EAAAwuB,EAAAxuB,EAAA6oB,EAAA7oB,GAKA,GAAAmqB,GAAAkE,EAAAlE,QAAAkE,EAAA1D,MACA,IAAAR,GAAAzO,EAAA,CACA,GAAA+S,GAAAnpC,EAAA8kC,aAAAD,EAAA1iC,KAAA4mC,EAAA/tB,KAEAmuB,KACAJ,EAAA9tB,IAAAkuB,GAKA,GAAAJ,EAAAtc,KAAA2J,EAAA,CACA,GAAA3J,GAAAsc,EAAAtc,IACA2c,EAAAppC,EAAAyjC,eAAAhX,EAAAtqB,MAAAsqB,EAAA7Q,YAAA6Q,EAAAnQ,QAEA8sB,KACAL,EAAA9tB,IAAAmuB,EAAAnuB,IACA8tB,EAAA/tB,KAAAouB,EAAApuB,MAIA,MAAA,IAAA9c,GAAA4gC,EAAA,GAAAiK,KAIA10B,QAAA,SAAAy0B,GACA,GAAA7X,KAGA,OAFA6X,GAAA/qC,EAAAS,UAAAyyB,EAAA6X,GAEA,SAAAC,EAAA7/B,GACA,GAAAvM,GAAAC,KACA4oC,EAAA9kC,SAAA/D,EAAAiB,OACAkhC,EAAA0G,EAAA7oC,GAAAA,GACAqD,EAAApD,KAAA2B,SAAAyB,IAAApD,IAEA,KAAAoD,EAAAgd,eAAA,MAAApgB,KAEAsM,KACA6/B,EAAAhrC,EAAAS,UAAAuqC,EAAA7/B,GAIA,KAAA,GAAA3L,GAAA,EAAAA,EAAAuhC,EAAAlhC,OAAAL,IAAA,CACA,GAAAsH,GAAAi6B,EAAAvhC,GACAsC,EAAAgF,EAAAyP,aAAA5T,SAAAqoC,EAAAlpC,OAAAkpC,EAAAlpC,OAEAusB,EAAAvnB,EAAAjF,UAAAmpC,EAAAlpC,GAAAA,OAAA,GAAAa,OAEA0rB,GAAAlsB,OAGA,MAAAtD,QAIA0D,KAAA,SAAAwoC,GACA,GAAA7X,KAGA,OAFA6X,GAAA/qC,EAAAS,UAAAyyB,EAAA6X,GAEA,SAAAv0B,EAAA80B,GACA,GAAA1sC,GAAAC,KACA4oC,EAAA9kC,SAAA/D,EAAAiB,OACAkhC,EAAA0G,EAAA7oC,GAAAA,GACAqD,EAAApD,KAAA2B,SAAAyB,IAAApD,IAEA,KAAAoD,EAAAgd,eAAA,MAAApgB,KAEA,KAAA,GAAAW,GAAA,EAAAA,EAAAuhC,EAAAlhC,OAAAL,IAAA,CAKA,IAAA,GAJAsH,GAAAi6B,EAAAvhC,GACAe,EAAAuG,EAAAtG,SACA+qC,EAAAhrC,EAAAsB,UAAAE,QAEA+J,EAAA,EAAAA,EAAAy/B,EAAA1rC,OAAAiM,IAAA,CACA,GAAAuiB,GAAAkd,EAAAz/B,GACA2sB,EAAApK,EAAA7tB,QAEA8qC,KAGA7S,EAAA/3B,SAAA,GAKA8V,IACAjW,EAAAsB,UAAAC,UAGAwpC,IACA/qC,EAAAsB,UAAAE,YChyBA,MALAE,GAAAmjB,QACA9Y,WAAAzN,KACA4E,KAAA,SAGA5E,OAMAP,GAAAD,QAAAE,IAEAutB,cAAA,EAAA0f,UAAA,GAAA3nC,OAAA,GAAAC,YAAA,GAAA2nC,aAAA,GAAA1nC,SAAA,KAAA2nC,IAAA,SAAA3rC,EAAAzB,EAAAD,GACA,YA6CA,SAAAstC,KACA,OAAA,EAGA,QAAAC,KACA,OAAA,EA7CA,GAAApE,GAAA,SAAAzd,EAAA5X,GAEA,MAAAtT,gBAAA2oC,IAKAzd,GAAAA,EAAAtmB,MACA5E,KAAAgtC,cAAA9hB,EACAlrB,KAAA4E,KAAAsmB,EAAAtmB,KAIA5E,KAAAitC,mBAAA/hB,EAAA,iBAAA6hB,EAAAD,GAIA9sC,KAAA4E,KAAAsmB,EAIA5X,IAIAtT,KAAA4E,KAAAd,SAAAwP,EAAA1O,KAAA0O,EAAA1O,KAAA5E,KAAA4E,KACA5E,KAAAoD,GAAAkQ,EAAAlQ,GACApD,KAAAqrC,SAAA/3B,EAAA+3B,SACArrC,KAAAsrC,WAAAh4B,EAAAg4B,WACAtrC,KAAAurC,mBAAAj4B,EAAAi4B,mBACAvrC,KAAAwpC,UAAAl2B,EAAAk2B,UACAxpC,KAAAovB,OAAA9b,EAAA8b,OACApvB,KAAAkI,KAAAoL,EAAApL,KACAlI,KAAAktC,QAAA55B,EAAA45B,cAIAltC,KAAAmtC,UAAAjiB,GAAAA,EAAAiiB,WAAAC,KAAA/T,QAlCA,GAAAsP,GAAAzd,EAAA5X,GA8CAq1B,GAAAhmC,WACAC,eAAA,WACA,MAAA,SAGAqpC,eAAA,WACAjsC,KAAAitC,mBAAAF,CAEA,IAAA7sC,GAAAF,KAAAgtC,aACA9sC,IAKAA,EAAA+rC,gBACA/rC,EAAA+rC,kBAIAD,gBAAA,WACAhsC,KAAA+rC,qBAAAgB,CAEA,IAAA7sC,GAAAF,KAAAgtC,aACA9sC,IzC05QSA,EAAE8rC,iB0Cx/QX9rC,EAAA8rC,mBAIAqB,yBAAA,WACArtC,KAAAstC,8BAAAP,EACA/sC,KAAAgsC,mBAGAiB,mBAAAH,EACAf,qBAAAe,EACAQ,8BAAAR,GAGArtC,EAAAD,QAAAmpC,OAEA4E,IAAA,SAAArsC,EAAAzB,EAAAD,GACA,YAeA,SAAAguC,GAAA5oC,EAAAL,EAAAkpC,GAEA,GAAAC,GAAAD,CAEA,IAAA,SAAA7oC,EACAs7B,EAAAv9B,UAAA4B,GAAAkpC,MAEA,IAAA,eAAA7oC,EACAilB,EAAAlnB,UAAA4B,GAAAkpC,MAEA,IAAA,WAAA7oC,EAAA,CAqBA,IAAA,GAlBA2/B,GAAA,SAAAj/B,GACAtF,KAAAsF,QAAAA,EAEAmoC,EAAA1sC,KAAAf,KAAAsF,GAGAlE,EAAAwL,YAAA5M,KAAA2B,YACA3B,KAAA2B,aAGA3B,KAAA2B,SAAAyB,GAAAkC,EAAAlC,GACApD,KAAA2B,SAAA2jB,cAGAqoB,EAAApJ,EAAA5hC,UAAAirC,OAAAC,OAAAJ,EAAA9qC,WAEAmrC,KAEAntC,EAAA,EAAAA,EAAAmtC,EAAA9sC,OAAAL,IAAA,CACA,GAAAotC,GAAAD,EAAAntC,EAEAgtC,GAAAI,GAAAJ,EAAAI,IAAA,WAAA,MAAA/tC,OAIA2tC,EAAAloC,QAAAkoC,EAAArJ,IACAqJ,EAAArJ,IAAA,WAAA,MAAAtkC,MAAAyF,QAAAzF,OACA2tC,EAAAloC,OAAAkoC,EAAArJ,MACAqJ,EAAAloC,MAAA,WAAA,MAAAzF,MAAAskC,MAAAtkC,OAGA2tC,EAAAjqC,OACAiqC,EAAAjqC,KAAA,WACA,GAAAlC,GAAAxB,KAAAsF,OAEA,IAAA9D,GAAAA,EAAAiW,QAEA,IAAA,GADAi1B,GAAA1sC,KAAAqvB,WACA1uB,EAAA,EAAAA,EAAA+rC,EAAA1rC,OAAAL,IACA+rC,EAAA/rC,GAAA+C,MAMA,OAFA1D,MAAA4Y,QAAA,cAEA5Y,OAIA2tC,EAAApN,UACAoN,EAAApN,QAAA,WACA,MAAAvgC,QAIA2tC,EAAA3nB,GAAAtmB,EAAAsmB,IAAAoJ,QAAA,IACAue,EAAA1nB,IAAAvmB,EAAAsmB,IAAAoJ,QAAA,EAAAlJ,qBAAA,IACAynB,EAAAxnB,KAAAzmB,EAAAsmB,IAAAoJ,QAAA,EAAAhJ,2BAAA,IACAunB,EAAAtnB,IAAA3mB,EAAA2mB,KAAA+I,QAAA,IACAue,EAAA/0B,QAAAlZ,EAAAkZ,SAAAwW,QAAA,IAEA1vB,EAAA8mB,eAAAmnB,GAEAD,EAAAnJ,MAEA,IAAA,aAAA3/B,GAAA,SAAAL,GAAA,SAAAA,EAAA,CAGA,GAAAypC,GAAAC,EAAA,WAAA,QAAAtrC,UACAurC,EAAAT,EAAA9qC,SAEA,KAAA,GAAAwrC,KAAAH,GAAA,CACA,GAAAI,GAAAJ,EAAAG,GACAE,EAAA,MAAAH,EAAAC,EAEA,IAAAE,EAEA,WADAltC,GAAAiI,MAAA,8BAAA7E,EAAA,yBAAA4pC,EAAA,qBAIAD,GAAAC,GAAAC,EAGAJ,EAAAM,gBAAAhjC,QAAA,SAAA/G,GACA2pC,EAAA3pC,GAAA2pC,EAAA3pC,IAAA,WACApD,EAAAiI,MAAA,yCAAA7E,EAAA,2BAMA,MAAApD,GAAAotC,QACAp4B,IAAAq4B,EACA3F,MAAAjkC,EAAAL,GACAib,MAAAkuB,IAIA,QAAAO,GAAArpC,EAAAL,GACA,MAAApD,GAAAstC,QACAt4B,IAAAq4B,EACA3F,MAAAjkC,EAAAL,KAIA,QAAAmqC,GAAA9pC,EAAAL,EAAAoqC,EAAAC,EAAAnB,GACA,MAAAtsC,GAAAotC,QACAp4B,IAAA04B,EACAhG,MAAAjkC,EAAAL,EAAAoqC,EAAAC,GACApvB,MAAAiuB,IAIA,QAAAqB,GAAAlqC,EAAAL,EAAAoqC,EAAAC,GACA,MAAAztC,GAAAstC,QACAt4B,IAAA04B,EACAhG,MAAAjkC,EAAAL,EAAAoqC,EAAAC,KA7IA,GAAAztC,GAAAD,EAAA,UACAxB,EAAAwB,EAAA,YACA2oB,EAAA3oB,EAAA,gBACAg/B,EAAAh/B,EAAA,UACA6tC,EAAA7tC,EAAA,gBACAE,EAAAF,EAAA,QAGAstC,KAGAK,KAsIArK,EAAA,WAEA,MAAA,KAAA13B,UAAA9L,OACAitC,EAAAzqC,MAAA,KAAAsJ,WAIA,IAAAA,UAAA9L,OACAwsC,EAAAhqC,MAAA,KAAAsJ,WAIA,IAAAA,UAAA9L,OACA8tC,EAAAtrC,MAAA,KAAAsJ,WAIA,IAAAA,UAAA9L,OACA0tC,EAAAlrC,MAAA,KAAAsJ,e1C6/QI3L,GAAKiI,MAAM,mC2C9qRf82B,GAAAv9B,UAAA6hC,UAAAA,EAGAuK,EAAAzjC,QAAA,SAAAyV,GACAA,EAAAytB,WAAAljC,QAAA,SAAAoiC,GACAF,EAAAzsB,EAAAnc,KAAA8oC,EAAAnpC,KAAAmpC,EAAAsB,U3CwrRAvvC,EAAOD,QAAUglC,I4CjsRjByK,eAAA,GAAAC,SAAA,GAAAC,WAAA,GAAAC,eAAA,GAAApqC,OAAA,GAAAE,SAAA,KAAAmqC,IAAA,SAAAnuC,EAAAzB,EAAAD,GACA,YAEAC,GAAAD,UAEAoF,KAAA,SACA4pC,WAAAttC,EAAA,cAIA0D,KAAA,WACA4pC,WAAAttC,EAAA,kBAIA4sB,WAAA,GAAAmW,aAAA,KAAAqL,IAAA,SAAApuC,EAAAzB,EAAAD,GACA,YAuBA,SAAA+vC,GAAAjqC,GACAtF,KAAAsF,QAAAnE,EAAAS,UAAAyyB,EAAA/uB,GAtBA,GAAAnE,GAAAD,EAAA,cACAsuC,EAAAtuC,EAAA,cACAE,EAAAF,EAAA,YAEAmzB,GACAxE,KAAA,EACA/oB,UAAA,EACA4Y,QAAA,GACA+vB,QAAA,EACAC,cAAA,KACA1wB,YAAAlb,OACA6rC,cAAA,EACAljC,MAAA3I,OACA8rC,mBAAA,EACAn4B,SAAA,EACAgY,kBAAA,IACAE,gBAAA7rB,OACAgsB,MAAAhsB,OACAJ,KAAAI,OAOAyrC,GAAA5sC,UAAA2hC,IAAA,WACA,GAYA73B,GAZAH,EAAAtM,KAAAsF,QACAA,EAAAgH,EAEAlJ,EAAAkJ,EAAAlJ,GACAmC,EAAAD,EAAAC,KACA+B,EAAA/B,EAAA+B,QAAAiG,IAAA,WACAsiC,EAAAtqC,EAEAwZ,EAAAywB,EAAAM,gBAAAxqC,EAAA0Z,YAAA1Z,EAAA0Z,aACAC,GAAA,EAAAE,GAAA,EAAA/W,EAAAhF,EAAA4jC,QAAA3nB,EAAAjc,EAAA6jC,UAIA,IAAA7lC,EAAA+B,oBAAAmC,EAAAmH,OACAA,EAAAnH,EAAAmH,UACA,IAAArL,EAAAitB,MAAA/oB,EAAAmH,OAAA,CAGA,IAAA,GAFAsjC,MAEApvC,EAAA,EAAAA,EAAA2E,EAAAmH,MAAAzL,OAAAL,IAAA,CACA,GAAAqG,GAAA1B,EAAAmH,MAAA9L,GACAsH,EAAA7E,EAAAyC,eAAAmB,EACA+oC,GAAAttC,KAAAwF,GAGAwE,EAAArJ,EAAAqK,WAAAsiC,OACA,IAAA3uC,EAAAoF,OAAAlB,EAAAmH,OACAA,EAAArJ,EAAAmI,EAAAjG,EAAAmH,WAGA,IAAAnH,EAAAwB,SACA2F,EAAAnF,EAAAmF,YACA,CAIA,IAHA,GAAAmqB,MACAoZ,EAAA1oC,EAEA0oC,EAAAhvC,OAAA,GAAA,CACA,GAAAivC,GAAA7sC,EAAAqK,YAEAlI,GAAAgH,KACAE,MAAAujC,EAAA,GACAnjC,MAAA,SAAAlM,EAAAyM,EAAArB,EAAAN,EAAAykC,GACAD,EAAAA,EAAAzhC,IAAAzC,IAEAjF,UAAA,IAGAkpC,EAAAA,EAAAziC,IAAA0iC,GACArZ,EAAAn0B,KAAAwtC,GAGAxjC,EAAArJ,EAAAqK,YACA,KAAA,GAAA9M,GAAA,EAAAA,EAAAi2B,EAAA51B,OAAAL,IAAA,CACA,GAAAwvC,GAAAvZ,EAAAj2B,GACA+Q,EAAAy+B,EAAAz+B,WAAA,GACA0+B,EAAAD,EAAA1pC,OAAA,WACA,MAAAzG,MAAA2R,QAAA,KAAAD,GAGAjF,GAAAA,EAAA+B,IAAA4hC,IAOA,GAAAC,MACAC,KACAtjC,KACAM,KACAD,KACAkoB,IAGAsa,GAAAtjC,KACAE,MAAAA,EACA3F,SAAAxB,EAAAwB,SACA+F,MAAA,SAAAlM,EAAAyM,EAAArB,EAAAN,EAAAykC,GACA,GAAAjoC,GAAAjI,KAAA,GACAgH,EAAAiB,EAAAjB,IAYA,IAVAqpC,EAAAjjC,KACAijC,EAAAjjC,OAGAijC,EAAAjjC,GAAA3K,KAAAwF,GACAqoC,EAAAtpC,IAAA,EACAgG,EAAAhG,GAAAoG,EACAE,EAAAtG,GAAAkpC,EACA7iC,EAAArG,GAAAyE,EAEAykC,EAAA,CACA,GAAAK,GAAAL,EAAAlpC,KACAwpC,EAAAjb,EAAAgb,GAAAhb,EAAAgb,MAEAC,GAAA/tC,KAAAsJ,MAOA,KAAA,GADA0kC,MACA9vC,EAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IAAA,CACA,GAAAsH,GAAAX,EAAA3G,EAEA2vC,GAAAroC,EAAAjB,OAGAypC,EAAAhuC,KAAAwF,GAOA,IAFA,GAAAyoC,GAAA,EAAAD,EAAAzvC,OACA2vC,EAAA,EACA,IAAAF,EAAAzvC,QAAA0vC,EAAAC,GAAA,CAKA,IAAA,GAJA5kC,GAAA0kC,EAAAtjC,QACAwC,EAAA5D,EAAA6D,eAAAtI,QACAspC,GAAA,EAEAjwC,EAAA,EAAAA,EAAAgP,EAAA3O,OAAAL,IAAA,CACA,GAAAyM,GAAAJ,EAAA2C,EAAAhP,GAAAqG,KAEA,IAAAlD,SAAAsJ,EAAA,CACAijC,EAAAjjC,GAAA3K,KAAAsJ,GACA6kC,GAAA,CACA,QAIAA,GACAH,EAAAhuC,KAAAsJ,GAGA4kC,IAIA,KAAA,IAAAF,EAAAzvC,QAAA,CACA,GAAA+K,GAAA0kC,EAAAtjC,QAEAyjC,GAAA,CAYAA,KACA,IAAAP,EAAArvC,QACAqvC,EAAA5tC,SAGA4tC,EAAA,GAAA5tC,KAAAsJ,IAKA,GAAA8kC,GAAA,WACA,IAAA,GAAAlwC,GAAA,EAAAA,EAAA0vC,EAAArvC,OAAAL,IAGA,IAAA,GAFA4E,GAAA8qC,EAAA1vC,GAEAsM,EAAA,EAAAA,EAAA1H,EAAAvE,OAAAiM,IAAA,CACA,GAAAhF,GAAA1C,EAAA0H,EAEAhF,GAAAtG,SAAAka,QAAAi1B,cACA1jC,MAAAzM,EACAsN,MAAAhB,IAKA4jC,IAyBA,KAAA,GAtBAE,GAAA,SAAAhlC,GAOA,IAAA,GADAilC,GALA7pC,EAAA4E,EAAA/D,eAAA,WACA,MAAAhI,MAAAkI,KAAA,YAAA6D,EAAA/E,OAEAiqC,EAAAllC,EAAApK,SAAAka,QAAAi1B,aACAI,EAAA,EAEAvwC,EAAA,EAAAA,EAAAwG,EAAAnG,OAAAL,IAAA,CACA,GAAA8K,GAAAtE,EAAAxG,GACAy1B,EAAA3qB,EAAAlF,SAAA,GACA4qC,EAAA/a,EAAAz0B,SAAAka,QAAAi1B,YAEAG,GAAA7jC,OAAA+jC,EAAA/jC,OAAA8jC,EAAAC,EAAA/jC,QACA8jC,EAAAC,EAAA/jC,MACA4jC,EAAA5a,GAIA,MAAA4a,IAIAI,EAAA,EAAAA,EAAA9rC,EAAAsqC,mBAAAwB,IAAA,CAIA,IAAA,GAFAC,GAAAhB,EAAArvC,OACAswC,KACA3wC,EAAA,EAAA0wC,EAAA1wC,EAAAA,IAIA,IAAA,GAHAyM,GAAAijC,EAAA1vC,GAEA4wC,EAAAnkC,EAAApM,OACAiM,EAAA,EAAAskC,EAAAtkC,EAAAA,IAAA,CACA,GAAAhF,GAAAmF,EAAAH,GACAukC,EAAAvpC,EAAAtG,SAAAka,QAAAi1B,aACAW,EAAAV,EAAA9oC,EAEAwpC,KACAD,EAAAC,OAAAA,EACAH,EAAA7uC,KAAAwF,IAKA,IAAA,GAAAtH,GAAA,EAAAA,EAAA2wC,EAAAtwC,OAAAL,IAAA,CACA,GAAAsH,GAAAqpC,EAAA3wC,GACA6wC,EAAAvpC,EAAAtG,SAAAka,QAAAi1B,aACAW,EAAAD,EAAAC,OACAC,EAAAD,EAAA9vC,SAAAka,QAAAi1B,YAEAT,GAAAmB,EAAApkC,OAAAtF,OAAA0pC,EAAAvjC,MAAA,EAIA,KADA,GAAA0jC,GAAAD,EAAAtkC,MAAA,EACAukC,EAAAtB,EAAArvC,OAAA,GACAqvC,EAAA5tC,QAEA4tC,GAAAsB,GAAAlvC,KAAAwF,GAEAupC,EAAApkC,MAAAukC,EACAH,EAAAvjC,MAAAoiC,EAAAsB,GAAA3wC,OAAA,EAGA6vC,IAIA,GAAAe,GAAA,CACA,IAAAtsC,EAAAqqC,aAAA,CACA,IAAA,GAAAhvC,GAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IAAA,CACA,GAAAP,GAAAkH,EAAA3G,GACAkxC,EAAAzxC,EAAA4e,cACA5W,EAAAypC,EAAAzpC,EACAiX,EAAAwyB,EAAAxyB,CAEAuyB,GAAAniC,KAAA9D,IAAAimC,EAAAxpC,EAAAiX,GAEAuyB,GAAAtsC,EAAAoqC,cAiDA,IAAA,GA7CAoC,MACAC,EAAA,SAAA9pC,GACA,GAAA6pC,EAAA7pC,EAAAjB,MACA,MAAA8qC,GAAA7pC,EAAAjB,KAQA,KAAA,GALAgrC,GAAA/pC,EAAAtG,SAAAka,QAAAi1B,aAAA1jC,MACAuC,EAAA1H,EAAA2H,eAAAtI,QAAAiG,IAAA,WACAutB,EAAA,EACAmX,EAAA,EAEAtxC,EAAA,EAAAA,EAAAgP,EAAA3O,OAAAL,IAAA,CACA,GAAAuxC,GAAAviC,EAAAhP,GACAwxC,EAAAD,EAAAvwC,SAAAka,QAAAi1B,aACA7iC,EAAAkkC,EAAAlkC,MACAb,EAAA+kC,EAAA/kC,MACAmkC,EAAAlB,EAAAjjC,GAAApM,QAEAgxC,EAAA5kC,GAAA,IAAA4kC,KACAlX,GAAA7sB,EAAAsjC,EACAU,KAYA,MARAA,GAAAxiC,KAAA9D,IAAA,EAAAsmC,GACAnX,GAAAmX,EAEA,IAAAA,IACAnX,EAAAh3B,QAGAguC,EAAA7pC,EAAAjB,MAAA8zB,EACAA,GAMApM,EAAA,SAAAjuB,EAAA2D,GACA,GAAAguC,GAAAL,EAAAtxC,GACA4xC,EAAAN,EAAA3tC,EAEA,OAAAguC,GAAAC,GAGAC,EAAA,EAAA,EAAAA,EAAAA,IAAA,CAEA,IAAA,GAAA3xC,GAAA,EAAAA,EAAA0vC,EAAArvC,OAAAL,IACA0vC,EAAA1vC,GAAA0vC,EAAA1vC,GAAAwN,KAAAugB,EAEAmiB,KAKA,IAAA,GADA0B,GAAA,EACA5xC,EAAA,EAAAA,EAAA0vC,EAAArvC,OAAAL,IACA4xC,EAAA9iC,KAAA9D,IAAA0kC,EAAA1vC,GAAAK,OAAAuxC,EAyEA,KAAA,GAtEAtK,KACApqB,EAAAkB,EAAAE,GAAAF,EAAA3W,EAAA,EACA0V,EAAAiB,EAAAE,GAAAF,EAAAM,EAAA,GAGAmzB,GAAA,SAAAvqC,EAAAwqC,GACA,GAAAjB,GAAAvpC,EAAAtG,SAAAka,QAAAi1B,aACA1jC,EAAAokC,EAAApkC,MACAa,EAAAujC,EAAAvjC,MACAykC,EAAArC,EAAAjjC,GAAApM,OAEA2xC,EAAAljC,KAAA9D,IAAAoT,EAAA3W,GAAAsqC,EAAA,GAAAd,GACAgB,EAAAnjC,KAAA9D,IAAAoT,EAAAM,GAAAgxB,EAAArvC,OAAA,GAAA4wC,GACAiB,EAAApjC,KAAAkN,IAAAoC,EAAA3W,EAAA,EAAAioC,EAAArvC,OAAA+d,EAAAM,EAAA,EAAAgxB,EAAArvC,OAGA,IAFA6xC,EAAApjC,KAAA9D,IAAAknC,EAAAjB,GAEAtsC,EAAAmqC,OA4BA,CACA,GAAAnqC,EAAAmqC,OAAA,CACA,GAAAqD,GAAAD,EAAAzlC,EAAAylC,GAAAxC,EAAArvC,OAAA,GAAAqvC,EAAA,GAAArvC,QAAA,EAAA6xC,EAAA,EAAA,GACAzvB,EAAA,EAAA3T,KAAAsjC,GAAA1C,EAAAjjC,GAAApM,OAAAiN,CAMA,OAJA,KAAAb,GAAA,IAAAijC,EAAA,GAAArvC,SACA8xC,EAAA,IAIAj1B,EAAAoqB,GAAApqB,EAAAi1B,EAAArjC,KAAA6T,IAAAF,GACAtF,EAAAmqB,GAAAnqB,EAAAg1B,EAAArjC,KAAA8T,IAAAH,IAIA,OACAvF,EAAAoqB,GAAApqB,GAAA5P,EAAA,GAAAykC,EAAA,GAAA,GAAAC,EACA70B,GAAA1Q,EAAA,GAAAwlC,GA3CA,GAAAI,IACAn1B,EAAAoqB,GAAApqB,GAAA5P,EAAA,GAAAykC,EAAA,GAAA,GAAAC,EACA70B,GAAA1Q,EAAA,GAAAwlC,EAGA,OAAAH,GACAO,EAkBAA,GA2BAt1B,MACA/c,EAAA0vC,EAAArvC,OAAA,EAAAL,GAAA,EAAAA,IChbA,IAAA,GDibAyM,GAAAijC,EAAA1vC,GCjbAsM,EAAA,EAAAA,EAAAG,EAAApM,OAAAiM,IAAA,CACA,GAAAlB,GAAAqB,EAAAH,EAEAyQ,IAAA3R,EAAA/E,MAAAwrC,GAAAzmC,EAAApL,IAAA0vC,EAAArvC,OAAA,GAQA,MAJAsG,GAAA6nB,gBAAAnvB,KAAAsF,EAAA,WACA,MAAAoY,IAAA1d,KAAAgH,QAGAhH,MAGAP,EAAAD,QAAA+vC,IAEAhnC,WAAA,GAAA0qC,aAAA,GAAAhpC,aAAA,KAAAipC,IAAA,SAAAhyC,EAAAzB,EAAAD,GACA,YAuBA,SAAA2zC,GAAA7tC,GACAtF,KAAAsF,QAAAnE,EAAAS,UAAAyyB,EAAA/uB,GAtBA,GAAAnE,GAAAD,EAAA,cACAsuC,EAAAtuC,EAAA,cACAE,EAAAF,EAAA,YAEAmzB,GACAxE,KAAA,EACAnQ,QAAA,GACAV,YAAAlb,OACA6rC,cAAA,EACAmD,OAAAhvC,OACAsvC,WAAA,IAAA3jC,KAAAsjC,GACAM,MAAAvvC,OACAwvC,WAAA,EACAnlC,KAAArK,OACA2T,SAAA,EACAgY,kBAAA,IACAE,gBAAA7rB,OACAgsB,MAAAhsB,OACAJ,KAAAI,OAOAqvC,GAAAxwC,UAAA2hC,IAAA,WACA,GAAAh4B,GAAAtM,KAAAsF,QACAA,EAAAgH,EAEAlJ,EAAAkJ,EAAAlJ,GACAmC,EAAAD,EAAAC,KAEA+tC,EAAAxvC,SAAAwB,EAAAiuC,kBAAAjuC,EAAAiuC,iBAAAjuC,EAAAguC,UAEAhsC,EAAA/B,EAAA+B,QAAAiG,IAAA,UAEAjI,GAAA6I,OACA7G,EAAAA,EAAA6G,KAAA7I,EAAA6I,MAkBA,KAAA,GAHA9N,GAZA0e,EAAAywB,EAAAM,gBAAAxqC,EAAA0Z,YAAA1Z,EAAA0Z,aACAC,GAAA,EAAAE,GAAA,EAAA/W,EAAAhF,EAAA4jC,QAAA3nB,EAAAjc,EAAA6jC,WAGAgB,GACApqB,EAAAkB,EAAAE,GAAAF,EAAA3W,EAAA,EACA0V,EAAAiB,EAAAI,GAAAJ,EAAAM,EAAA,GAGAg0B,EAAAvvC,SAAAwB,EAAA+tC,MAAA,EAAA5jC,KAAAsjC,GAAA,EAAAtjC,KAAAsjC,GAAAzrC,EAAAtG,OAAAsE,EAAA+tC,MAEAG,EAAAH,EAAA5jC,KAAA9D,IAAA,EAAArE,EAAAtG,OAAA,GAGA4wC,EAAA,EACAjxC,EAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IAAA,CACA,GAAAP,GAAAkH,EAAA3G,GACAkxC,EAAAzxC,EAAA4e,cACA5W,EAAAypC,EAAAzpC,EACAiX,EAAAwyB,EAAAxyB,CAEAuyB,GAAAniC,KAAA9D,IAAAimC,EAAAxpC,EAAAiX,GAYA,GARAhf,EADAe,EAAA0Q,OAAAxM,EAAAwtC,QACAxtC,EAAAwtC,OACAxrC,EAAAtG,QAAA,EACA,EAEAyO,KAAAkN,IAAAoC,EAAAM,EAAAN,EAAA3W,GAAA,EAAAwpC,EAIAtqC,EAAAtG,OAAA,GAAAsE,EAAAqqC,aAAA,CACAiC,GAAA,IAEA,IAAA6B,GAAAhkC,KAAA6T,IAAAkwB,GAAA/jC,KAAA6T,IAAA,GACAowB,EAAAjkC,KAAA8T,IAAAiwB,GAAA/jC,KAAA8T,IAAA,GACAowB,EAAAlkC,KAAA+F,KAAAo8B,EAAAA,GAAA6B,EAAAA,EAAAC,EAAAA,GACArzC,GAAAoP,KAAA9D,IAAAgoC,EAAAtzC,GAGA,GAAAuzC,GAAA,SAAAjzC,EAAAsH,GACA,GAAAmb,GAAA9d,EAAA8tC,WAAAzyC,EAAA6yC,GAAAF,EAAA,EAAA,I7CwnSQO,EAAKxzC,EAAIoP,KAAK6T,IAAKF,G8C9tS3B0wB,EAAAzzC,EAAAoP,KAAA8T,IAAAH,GACA1F,GACAG,EAAAoqB,EAAApqB,EAAAg2B,EACA/1B,EAAAmqB,EAAAnqB,EAAAg2B;CAGA,OAAAp2B,GAKA,OAFApW,GAAA6nB,gBAAAnvB,KAAAsF,EAAAsuC,GAEA5zC,MAGAP,EAAAD,QAAA2zC,IAEA5qC,WAAA,GAAA0qC,aAAA,GAAAhpC,aAAA,KAAA8pC,IAAA,SAAA7yC,EAAAzB,EAAAD,GACA,YA8BA,SAAAw0C,GAAA1uC,GACAtF,KAAAsF,QAAAnE,EAAAS,UAAAyyB,EAAA/uB,GA7BA,GAAAnE,GAAAD,EAAA,cACAsuC,EAAAtuC,EAAA,cAEAmzB,GACAxE,KAAA,EACAnQ,QAAA,GACA0zB,WAAA,IAAA3jC,KAAAsjC,GACAM,MAAAvvC,OACAwvC,WAAA,EACAW,aAAA,EACAC,eAAA,GACAl1B,YAAAlb,OACA6rC,cAAA,EACA1I,OAAAnjC,OACAkjC,MAAAljC,OACAqwC,WAAA,SAAApoC,GACA,MAAAA,GAAA4F,UAEAyiC,WAAA,SAAA9sC,GACA,MAAAA,GAAAoK,YAAA,GAEA+F,SAAA,EACAgY,kBAAA,IACAE,gBAAA7rB,OACAgsB,MAAAhsB,OACAJ,KAAAI,OAOAkwC,GAAArxC,UAAA2hC,IAAA,WAwBA,IAAA,GAvBAh4B,GAAAtM,KAAAsF,QACAA,EAAAgH,EAEAgnC,EAAAxvC,SAAAwB,EAAAiuC,kBAAAjuC,EAAAiuC,iBAAAjuC,EAAAguC,UAEAlwC,EAAAkJ,EAAAlJ,GAEAmC,EAAAD,EAAAC,KACA+B,EAAA/B,EAAA+B,QAAAiG,IAAA,WAEAwR,EAAAywB,EAAAM,gBAAAxqC,EAAA0Z,YAAA1Z,EAAA0Z,aACAC,GAAA,EAAAE,GAAA,EAAA/W,EAAAhF,EAAA4jC,QAAA3nB,EAAAjc,EAAA6jC,WAGAgB,GACApqB,EAAAkB,EAAAE,GAAAF,EAAA3W,EAAA,EACA0V,EAAAiB,EAAAI,GAAAJ,EAAAM,EAAA,GAGAg1B,KACAjxB,EAAA9d,EAAA8tC,WACAkB,EAAA,EAEA3zC,EAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IAAA,CACA,GACA6e,GADAzT,EAAAzE,EAAA3G,EAIA6e,GAAAla,EAAA6uC,WAAA3wC,MAAAuI,GAAAA,IACAsoC,EAAA5xC,MACA+c,MAAAA,EACAzT,KAAAA,IAIAA,EAAApK,SAAAka,QAAAs4B,WAAA30B,EAIAlY,EAAAqR,aAGA,KAAA,GAAAhY,GAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IAAA,CACA,GAAAoL,GAAAzE,EAAA3G,GACAkxC,EAAA9lC,EAAAiT,aAEAs1B,GAAA7kC,KAAA9D,IAAA2oC,EAAAzC,EAAAzpC,EAAAypC,EAAAxyB,GAIAg1B,EAAAlmC,KAAA,SAAA1N,EAAA2D,GACA,MAAAA,GAAAob,MAAA/e,EAAA+e,OAQA,KAAA,GALA40B,GAAA9uC,EAAA8uC,WAAA9sC,GAGAitC,OACAC,EAAAD,EAAA,GACA5zC,EAAA,EAAAA,EAAA0zC,EAAArzC,OAAAL,IAAA,CACA,GAAAwd,GAAAk2B,EAAA1zC,EAEA,IAAA6zC,EAAAxzC,OAAA,EAAA,CACA,GAAAqW,GAAA5H,KAAAquB,IAAA0W,EAAA,GAAAh1B,MAAArB,EAAAqB,MAEAnI,IAAA+8B,IACAI,KACAD,EAAA9xC,KAAA+xC,IAIAA,EAAA/xC,KAAA0b,GAKA,GAAAs2B,GAAAH,EAAAhvC,EAAA4uC,cAEA,KAAA5uC,EAAAqqC,aAAA,CACA,GAAA+E,GAAAH,EAAAvzC,OAAA,GAAAuzC,EAAA,GAAAvzC,OAAA,EACA2zC,EAAAllC,KAAAkN,IAAAoC,EAAA3W,EAAA2W,EAAAM,GAAA,EAAAo1B,EACAG,EAAAD,GAAAJ,EAAAvzC,OAAA0zC,EAAA,EAAA,EAEAD,GAAAhlC,KAAAkN,IAAA83B,EAAAG,GAKA,IAAA,GADAv0C,GAAA,EACAM,EAAA,EAAAA,EAAA4zC,EAAAvzC,OAAAL,IAAA,CACA,GAAAwmC,GAAAoN,EAAA5zC,GACA0yC,EAAAvvC,SAAAwB,EAAA+tC,MAAA,EAAA5jC,KAAAsjC,GAAA,EAAAtjC,KAAAsjC,GAAA5L,EAAAnmC,OAAAsE,EAAA+tC,MACAG,EAAArM,EAAAqM,OAAAH,EAAA5jC,KAAA9D,IAAA,EAAAw7B,EAAAnmC,OAAA,EAGA,IAAAmmC,EAAAnmC,OAAA,GAAAsE,EAAAqqC,aAAA,CACA,GAAA8D,GAAAhkC,KAAA6T,IAAAkwB,GAAA/jC,KAAA6T,IAAA,GACAowB,EAAAjkC,KAAA8T,IAAAiwB,GAAA/jC,KAAA8T,IAAA,GACAowB,EAAAlkC,KAAA+F,KAAAi/B,EAAAA,GAAAhB,EAAAA,EAAAC,EAAAA,GAEArzC,GAAAoP,KAAA9D,IAAAgoC,EAAAtzC,GAGA8mC,EAAA9mC,EAAAA,EAEAA,GAAAo0C,EAGA,GAAAnvC,EAAA2uC,YAAA,CAIA,IAAA,GAHAY,GAAA,EACAx0C,EAAA,EAEAM,EAAA,EAAAA,EAAA4zC,EAAAvzC,OAAAL,IAAA,CACA,GAAAwmC,GAAAoN,EAAA5zC,GACAm0C,EAAA3N,EAAA9mC,EAAAA,CAEAw0C,GAAAplC,KAAA9D,IAAAkpC,EAAAC,GAGAz0C,EAAA,CACA,KAAA,GAAAM,GAAA,EAAAA,EAAA4zC,EAAAvzC,OAAAL,IAAA,CACA,GAAAwmC,GAAAoN,EAAA5zC,EAEA,KAAAA,IACAN,EAAA8mC,EAAA9mC,GAGA8mC,EAAA9mC,EAAAA,EAEAA,GAAAw0C,GAMA,IAAA,GADAn3B,MACA/c,EAAA,EAAAA,EAAA4zC,EAAAvzC,OAAAL,IAKA,IAAA,GAJAwmC,GAAAoN,EAAA5zC,GACA6yC,EAAArM,EAAAqM,OACAnzC,EAAA8mC,EAAA9mC,EAEA4M,EAAA,EAAAA,EAAAk6B,EAAAnmC,OAAAiM,IAAA,CACA,GAAAkR,GAAAgpB,EAAAl6B,GACAmW,EAAA9d,EAAA8tC,YAAAE,EAAA,EAAA,IAAAE,EAAAvmC,EAEAlJ,GACA8Z,EAAAoqB,EAAApqB,EAAAxd,EAAAoP,KAAA6T,IAAAF,GACAtF,EAAAmqB,EAAAnqB,EAAAzd,EAAAoP,KAAA8T,IAAAH,GCrMA1F,GAAAS,EAAApS,KAAA/E,MAAAjD,EAWA,MANAuD,GAAA6nB,gBAAAnvB,KAAAsF,EAAA,WACA,GAAA0B,GAAAhH,KAAAgH,IAEA,OAAA0W,GAAA1W,KAGAhH,MAGAP,EAAAD,QAAAw0C,IAEAf,aAAA,GAAAhpC,aAAA,KAAA8qC,IAAA,SAAA7zC,EAAAzB,EAAAD,GACA,YA2FA,SAAAw1C,GAAA1vC,GACAtF,KAAAsF,QAAAnE,EAAAS,UAAAyyB,EAAA/uB,GAEAtF,KAAAsF,QAAA8pB,OAAApvB,KAlFA,GAKAi1C,GALA9zC,EAAAD,EAAA,cACAsuC,EAAAtuC,EAAA,cACAg0C,EAAAh0C,EAAA,gBACAE,EAAAF,EAAA,YAOAmzB,GAEAvE,MAAA,aAGApsB,KAAA,aAGA+T,SAAA,EAIA09B,mBAAA,IAIAC,QAAA,GAGAvlB,KAAA,EAGAnQ,QAAA,GAGAV,YAAAlb,OAGAuxC,iBAAA,IAGAC,cAAA,SAAAvpC,GAAA,MAAA,MAGAwpC,YAAA,GAGAC,gBAAA,SAAA/pC,GAAA,MAAA,KAGAgqC,eAAA,SAAAhqC,GAAA,MAAA,MAGAiqC,cAAA,EAGAC,QAAA,GAGAxgC,QAAA,IAGAygC,YAAA,IAGAC,cAAA,IAGAC,QAAA,EAGAC,iBAAA,EAkBAf,GAAAryC,UAAA2hC,IAAA,WACA,GAAAh/B,GAAAtF,KAAAsF,QACAlC,EAAAkC,EAAAlC,GACAgsB,EAAApvB,KACAg2C,EAAAh2C,KAAAg2C,SAEAA,GAAAA,EAAAzyC,aACAyyC,EAAAh2C,KAAAg2C,OAAAd,GAAAe,UAAA3wC,EAAAywC,mBAGA3mB,EAAA7rB,SAAA,EAEA6rB,EAAAxW,SAAAhU,KAAA,cAAAwqB,OAAAA,IAIA6lB,GADA,IAAA3vC,EAAA4wC,OACA,GAEA,CAIA,IAAAC,GAAAC,EAAAhzC,EAAAgsB,EAAA9pB,EAGA2vC,IACAoB,EAAAF,GAKAG,EAAAH,EAAA/yC,EAGA,IAAAm3B,GAAA6S,KAAA/T,MACAkd,GAAA,EACAnB,EAAA,SAAA3P,GACAA,EAAAA,MAEA8Q,IAIA9Q,EAAA+Q,OAAApJ,KAAA/T,MAAAkB,EAAAj1B,EAAA6vC,qBAIAoB,GAAA,EAEAp1C,EAAAi4B,sBAAA,WACAqd,EAAAN,EAAA/yC,EAAAkC,IAGA,IAAAA,EAAAuqB,KACAzsB,EAAAysB,IAAAvqB,EAAAoa,SAGA62B,GAAA,KAIAP,GAAAhwB,GAAA,UAAA,SAAA9lB,GACA,GAAAw2C,GAAAx2C,EAAAgtC,OAEAiJ,GAAAO,YAAAA,EACAtB,MAGAY,EAAAW,MACAR,WAAAA,EACA7wC,SACAmS,QAAAnS,EAAAmS,QACA29B,QAAA9vC,EAAA8vC,QACAC,iBAAA/vC,EAAA+vC,iBACAE,YAAAjwC,EAAAiwC,YACAG,cAAApwC,EAAAowC,cACAC,QAAArwC,EAAAqwC,QACAxgC,QAAA7P,EAAA6P,QACAygC,YAAAtwC,EAAAswC,YACAC,cAAAvwC,EAAAuwC,cACAC,QAAAxwC,EAAAwwC,WAEAxR,IAAA,SAAAqS,GACA,GAyoBAC,GAzoBAT,EAAAQ,EAAAR,WACA7wC,EAAAqxC,EAAArxC,QACA/B,GAAA,EAQAqsB,EAAA,SAAAumB,EAAA7wC,EAAAsqB,GAOAinB,EAAAV,EAAA7wC,GAEAwxC,EAAAX,EAAA7wC,GAEAyxC,EAAAZ,EAAA7wC,GAEA0xC,EAAAb,EAAA7wC,GAEA2xC,EAAAd,EAAA7wC,IAMAuxC,EAAA,SAAAV,EAAA7wC,GAKA,IAAA,GAAA3E,GAAA,EAAAA,EAAAw1C,EAAAe,SAAAl2C,OAAAL,IASA,IAAA,GARAkvC,GAAAsG,EAAAe,SAAAv2C,GACA+H,EAAAmnC,EAAA7uC,OAOAiM,EAAA,EAAAvE,EAAAuE,EAAAA,IAGA,IAAA,GAFAkqC,GAAAhB,EAAAO,YAAAP,EAAAiB,UAAAvH,EAAA5iC,KAEAuF,EAAAvF,EAAA,EAAAvE,EAAA8J,EAAAA,IAAA,CACA,GAAA6kC,GAAAlB,EAAAO,YAAAP,EAAAiB,UAAAvH,EAAAr9B,IAEA8iC,GAAA6B,EAAAE,EAAAlB,EAAA7wC,KASAgwC,EAAA,SAAA6B,EAAAE,EAAAlB,EAAA7wC,GAGA,GAAAgyC,GAAAH,EAAAI,OACAC,EAAAH,EAAAE,MAEA,IAAAD,IAAAE,GAAArB,EAAAsB,WAAA,CAGA,GAAAC,GAAAL,EAAAM,UAAAR,EAAAQ,UACAC,EAAAP,EAAAQ,UAAAV,EAAAU,SAIA,IAAA,IAAAH,GAAA,IAAAE,EAAA,CAKA,GAAAE,GAAAC,EAAAZ,EAAAE,EAAAK,EAAAE,EAEA,IAAAE,EAAA,EAKA,GAAAtB,GAAAlxC,EAAAiwC,YAAAuC,EAGAnwC,EAAA8H,KAAA+F,KAAAkiC,EAAAA,EAAAE,EAAAA,GAEAI,EAAAxB,EAAAkB,EAAA/vC,EACAswC,EAAAzB,EAAAoB,EAAAjwC,MAQA,IAAAuwC,GAAAC,EAAAhB,EAAAO,EAAAE,GACAQ,EAAAD,EAAAd,EAAA,GAAAK,EAAA,GAAAE,GAGAjF,EAAAyF,EAAAv6B,EAAAq6B,EAAAr6B,EACA+0B,EAAAwF,EAAAt6B,EAAAo6B,EAAAp6B,EACAu6B,EAAA1F,EAAAA,EAAAC,EAAAA,EACAjrC,EAAA8H,KAAA+F,KAAA6iC,GAIA7B,GAAAW,EAAA7B,cAAA+B,EAAA/B,eAAA+C,EACAL,EAAAxB,EAAA7D,EAAAhrC,EACAswC,EAAAzB,EAAA5D,EAAAjrC,CAIAwvC,GAAAmB,WACAnB,EAAAoB,SAAAP,EACAb,EAAAqB,SAAAP,GAGAZ,EAAAiB,WACAjB,EAAAkB,SAAAP,EACAX,EAAAmB,SAAAP,MAaAF,EAAA,SAAAZ,EAAAE,EAAAoB,EAAAC,GAEA,GAAAD,EAAA,EACA,GAAAE,GAAAxB,EAAAyB,KAAAvB,EAAAwB,SAEA,IAAAF,GAAAtB,EAAAuB,KAAAzB,EAAA0B,IAGA,IAAAH,EAAA,EACA,GAAAI,GAAA3B,EAAA4B,KAAA1B,EAAA2B,SAEA,IAAAF,GAAAzB,EAAA0B,KAAA5B,EAAA6B,IAGA,OAAAL,IAAA,GAAAG,GAAA,EACArpC,KAAA+F,KAAAmjC,EAAAA,EAAAG,EAAAA,GAEA,GAQAX,EAAA,SAAApsC,EAAA0sC,EAAAC,GAGA,GAAAO,GAAAltC,EAAA4rC,UACAuB,EAAAntC,EAAA8rC,UACAsB,EAAAptC,EAAAk7B,QAAA,EACAmS,EAAArtC,EAAAi7B,OAAA,EACAqS,EAAAX,EAAAD,EACAa,EAAAH,EAAAC,EAOA3vC,IACA,GAAA,CAEA,GAAA,IAAAgvC,GAAAC,EAAA,EAAA,CACAjvC,EAAAoU,EAAAo7B,EAEAxvC,EAAAqU,EAAAo7B,EAAAC,EAAA,CACA,OAIA,GAAA,IAAAV,GAAA,EAAAC,EAAA,CACAjvC,EAAAoU,EAAAo7B,EACAxvC,EAAAqU,EAAAo7B,EAAAC,EAAA,CAEA,OAIA,GAAAV,EAAA,GACAY,GAAA,GAAAC,GACAA,GAAAD,EAAA,CACA5vC,EAAAoU,EAAAo7B,EAAAG,EAAA,EACA3vC,EAAAqU,EAAAo7B,EAAAE,EAAAV,EAAA,EAAAD,CAEA,OAIA,GAAA,EAAAA,GACAY,GAAA,GAAAC,GACAA,GAAAD,EAAA,CACA5vC,EAAAoU,EAAAo7B,EAAAG,EAAA,EACA3vC,EAAAqU,EAAAo7B,EAAAE,EAAAV,EAAA,EAAAD,CAEA,OAIA,GAAAC,EAAA,IACA,GAAAY,GAAAD,GACAA,GAAAC,GAAA,CACA7vC,EAAAoU,EAAAo7B,EAAAE,EAAAV,EAAA,EAAAC,EACAjvC,EAAAqU,EAAAo7B,EAAAC,EAAA,CAEA,OAIA,GAAA,EAAAT,IACA,GAAAY,GAAAD,GACAA,GAAAC,GAAA,CACA7vC,EAAAoU,EAAAo7B,EAAAE,EAAAV,EAAA,EAAAC,EACAjvC,EAAAqU,EAAAo7B,EAAAC,EAAA,CAEA,eAGA,EAIA,OAAA1vC,IAMAqtC,EAAA,SAAAX,EAAA7wC,GAEA,IAAA,GAAA3E,GAAA,EAAAA,EAAAw1C,EAAAoD,SAAA54C,IAAA,CAEA,GAAA8K,GAAA0qC,EAAAqD,YAAA74C,GACA84C,EAAAtD,EAAAiB,UAAA3rC,EAAAiuC,UACAnzC,EAAA4vC,EAAAO,YAAA+C,GACAE,EAAAxD,EAAAiB,UAAA3rC,EAAAmuC,UACAr4C,EAAA40C,EAAAO,YAAAiD,GAGAjC,EAAAn2C,EAAAo2C,UAAApxC,EAAAoxC,UACAC,EAAAr2C,EAAAs2C,UAAAtxC,EAAAsxC,SAIA,IAAA,IAAAH,GAAA,IAAAE,EACA,MAIA,IAAAM,GAAAC,EAAA5xC,EAAAmxC,EAAAE,GACAQ,EAAAD,EAAA52C,EAAA,GAAAm2C,EAAA,GAAAE,GAGAiC,EAAAzB,EAAAv6B,EAAAq6B,EAAAr6B,EACAi8B,EAAA1B,EAAAt6B,EAAAo6B,EAAAp6B,EACAhd,EAAA2O,KAAA+F,KAAAqkC,EAAAA,EAAAC,EAAAA,GAEAtD,EAAA/mC,KAAA6C,IAAA7G,EAAAsuC,YAAAj5C,EAAA,GAAA2K,EAAAuuC,UAEA,IAAA,IAAAl5C,EACA,GAAAk3C,GAAAxB,EAAAqD,EAAA/4C,EACAm3C,EAAAzB,EAAAsD,EAAAh5C,MAEA,IAAAk3C,GAAA,EACAC,EAAA,CAIA1xC,GAAA+xC,WACA/xC,EAAAgyC,SAAAP,EACAzxC,EAAAiyC,SAAAP,GAGA12C,EAAA+2C,WACA/2C,EAAAg3C,SAAAP,EACAz2C,EAAAi3C,SAAAP,KAYAlB,EAAA,SAAAZ,EAAA7wC,GAKA,IAAA,GAJA20C,GAAA,EAIAt5C,EAAA,EAAAA,EAAAw1C,EAAAe,SAAAl2C,OAAAL,IAAA,CACA,GAAAkvC,GAAAsG,EAAAe,SAAAv2C,GACA+H,EAAAmnC,EAAA7uC,MAMA,IAAA,IAAAL,EACA,GAAAu5C,GAAA/D,EAAA9N,aAAA,EACA8R,EAAAhE,EAAA/N,YAAA,MAGA,IAAAj/B,GAAAgtC,EAAAO,YAAAP,EAAAiB,UAAAvH,EAAA,KACA51B,EAAAk8B,EAAAO,YAAAP,EAAAiB,UAAAjuC,EAAAkiB,WACA6uB,EAAAjgC,EAAA09B,UACAwC,EAAAlgC,EAAA49B,SAMA,KAAA,GAAA5qC,GAAA,EAAAvE,EAAAuE,EAAAA,IAAA,CACA,GAAAlB,GAAAoqC,EAAAO,YAAAP,EAAAiB,UAAAvH,EAAA5iC,IAGA,KAAAlB,EAAAusC,SAAA,CAEA,GAAAtb,GAAAkd,EAAAnuC,EAAA4rC,UACAyC,EAAAD,EAAApuC,EAAA8rC,UACArtC,EAAAiF,KAAA+F,KAAAwnB,EAAAA,EAAAod,EAAAA,EACA,IAAA5vC,EAAAyvC,EAAA,CACA,GAAAI,GAAA/0C,EAAAqwC,QAAA3Y,EAAAxyB,EACA8vC,EAAAh1C,EAAAqwC,QAAAyE,EAAA5vC,CACAuB,GAAAwsC,SAAA8B,EACAtuC,EAAAysC,SAAA8B,OAiBAtD,EAAA,SAAAb,EAAA7wC,GAEA,GAAArC,MACAwC,EAAA,EACAC,EAAA,EASA,KAJAzC,EAAAR,KAAAe,MAAAP,EAAAkzC,EAAAe,SAAA,IACAxxC,GAAAywC,EAAAe,SAAA,GAAAl2C,OAGA0E,GAAAD,GAAA,CAEA,GAAA8R,GAAAtU,EAAAwC,KACA80C,EAAApE,EAAAiB,UAAA7/B,GACAxL,EAAAoqC,EAAAO,YAAA6D,GACA9/B,EAAA1O,EAAA0O,QAGA,IAAA,EAAAA,EAAAzZ,SAAA+K,EAAAusC,SAAA,CASA,IAAA,GARAkC,GAAAzuC,EAAAwsC,QACAkC,EAAA1uC,EAAAysC,QAOA73C,EAAA,EAAAA,EAAA8Z,EAAAzZ,OAAAL,IAAA,CACA,GAAA+5C,GAAAvE,EAAAO,YAAAP,EAAAiB,UAAA38B,EAAA9Z,IAEA+5C,GAAAnC,SAAAiC,EACAE,EAAAlC,SAAAiC,EAEAx3C,IAAAyC,GAAA+U,EAAA9Z,GAIAoL,EAAAwsC,QAAA,EACAxsC,EAAAysC,QAAA,KAUAvB,EAAA,SAAAd,EAAA7wC,GAKA,IAAA,GAAA3E,GAAA,EAAAA,EAAAw1C,EAAAwE,SAAAh6C,IAAA,CACA,GAAAP,GAAA+1C,EAAAO,YAAA/1C,EACA,GAAAP,EAAAqa,SAAAzZ,SAEAZ,EAAAw4C,KAAA90C,OACA1D,EAAAy4C,KAAA/0C,OACA1D,EAAA24C,KAAAj1C,OACA1D,EAAA44C,KAAAl1C,QAIA,IAAA,GAAAnD,GAAA,EAAAA,EAAAw1C,EAAAwE,SAAAh6C,IAAA,CACA,GAAAP,GAAA+1C,EAAAO,YAAA/1C,EACA,MAAA,EAAAP,EAAAqa,SAAAzZ,QAAAZ,EAAAk4C,UAAA,CASA,GAAAsC,GAAAC,EAAAz6C,EAAAm4C,QAAAn4C,EAAAo4C,QAAArC,EAAA2E,YACA16C,GAAAu3C,WAAAiD,EAAA/8B,EACAzd,EAAAy3C,WAAA+C,EAAA98B,EACA1d,EAAAm4C,QAAA,EACAn4C,EAAAo4C,QAAA,EACAp4C,EAAAy4C,KAAAz4C,EAAAu3C,UAAAv3C,EAAA4mC,MACA5mC,EAAAw4C,KAAAx4C,EAAAu3C,UAAAv3C,EAAA4mC,MACA5mC,EAAA44C,KAAA54C,EAAAy3C,UAAAz3C,EAAA6mC,OACA7mC,EAAA24C,KAAA34C,EAAAy3C,UAAAz3C,EAAA6mC,OAKA8T,EAAA36C,EAAA+1C,IAIA,IAAA,GAAAx1C,GAAA,EAAAA,EAAAw1C,EAAAwE,SAAAh6C,IAAA,CACA,GAAAP,GAAA+1C,EAAAO,YAAA/1C,EACA,GAAAP,EAAAqa,SAAAzZ,SAAAZ,EAAAk4C,WACAl4C,EAAAu3C,WAAAv3C,EAAAw4C,KAAAx4C,EAAAy4C,MAAA,EACAz4C,EAAAy3C,WAAAz3C,EAAA24C,KAAA34C,EAAA44C,MAAA,EACA54C,EAAA4mC,MAAA5mC,EAAAw4C,KAAAx4C,EAAAy4C,KACAz4C,EAAA6mC,OAAA7mC,EAAA24C,KAAA34C,EAAA44C,QAcA6B,EAAA,SAAA7C,EAAAC,EAAAtsC,GAEA,GAAA6qC,GAAA/mC,KAAA+F,KAAAwiC,EAAAA,EAAAC,EAAAA,EAEA,IAAAzB,EAAA7qC,EACA,GAAAlC,IACAoU,EAAAlS,EAAAqsC,EAAAxB,EACA14B,EAAAnS,EAAAssC,EAAAzB,OAIA,IAAA/sC,IACAoU,EAAAm6B,EACAl6B,EAAAm6B,EAOA,OAAAxuC,IAOAsxC,EAAA,SAAAhvC,EAAAoqC,GAEA,GAAA9qB,GAAAtf,EAAAsf,QACA,IAAA,MAAAA,EAAA,CAQA,GAAAtnB,GAAAoyC,EAAAO,YAAAP,EAAAiB,UAAA/rB,IACAriB,GAAA,CA+BA,QA5BA,MAAAjF,EAAA60C,MAAA7sC,EAAA6sC,KAAA70C,EAAAi3C,SAAAj3C,EAAA60C,QACA70C,EAAA60C,KAAA7sC,EAAA6sC,KAAA70C,EAAAi3C,SACAhyC,GAAA,IAKA,MAAAjF,EAAA80C,MAAA9sC,EAAA8sC,KAAA90C,EAAAk3C,QAAAl3C,EAAA80C,QACA90C,EAAA80C,KAAA9sC,EAAA8sC,KAAA90C,EAAAk3C,QACAjyC,GAAA,IAKA,MAAAjF,EAAAg1C,MAAAhtC,EAAAgtC,KAAAh1C,EAAAm3C,UAAAn3C,EAAAg1C,QACAh1C,EAAAg1C,KAAAhtC,EAAAgtC,KAAAh1C,EAAAm3C,UACAlyC,GAAA,IAKA,MAAAjF,EAAAi1C,MAAAjtC,EAAAitC,KAAAj1C,EAAAo3C,OAAAp3C,EAAAi1C,QACAj1C,EAAAi1C,KAAAjtC,EAAAitC,KAAAj1C,EAAAo3C,OACAnyC,GAAA,GAKAA,EAEA+xC,EAAAh3C,EAAAoyC,GAFA,SAUAiF,EAAA,SAAAC,EAAA/1C,GAIA,IAAA,GAHAgC,GAAA6uC,EAAAO,YACA9f,KAEAj2B,EAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IAAA,CACA,GAAAoL,GAAAzE,EAAA3G,GACA26C,EAAAvvC,EAAAwrC,OACAvgB,EAAAJ,EAAA0kB,GAAA1kB,EAAA0kB,MAEAtkB,GAAAv0B,KAAAsJ,GAKA,IAAA,GAFAwvC,GAAA,EAEA56C,EAAA,EAAAA,EAAAi2B,EAAA51B,OAAAL,IAAA,CACA,GAAAw8B,GAAAvG,EAAAj2B,EACAw8B,GAAAle,GAAAlW,EAAAA,EACAo0B,EAAAje,KAAAnW,EAAAA,GACAo0B,EAAAhe,GAAApW,EAAAA,EACAo0B,EAAA/d,KAAArW,EAAAA,EAEA,KAAA,GAAAkE,GAAA,EAAAA,EAAAkwB,EAAAn8B,OAAAiM,IAAA,CACA,GAAA7M,GAAA+8B,EAAAlwB,EAEAkwB,GAAAle,GAAAxP,KAAAkN,IAAAwgB,EAAAle,GAAA7e,EAAAu3C,UAAAv3C,EAAA4mC,MAAA,GACA7J,EAAAje,GAAAzP,KAAA9D,IAAAwxB,EAAAje,GAAA9e,EAAAu3C,UAAAv3C,EAAA4mC,MAAA,GACA7J,EAAAhe,GAAA1P,KAAAkN,IAAAwgB,EAAAhe,GAAA/e,EAAAy3C,UAAAz3C,EAAA6mC,OAAA,GACA9J,EAAA/d,GAAA3P,KAAA9D,IAAAwxB,EAAA/d,GAAAhf,EAAAy3C,UAAAz3C,EAAA6mC,OAAA,GAGA9J,EAAA/0B,EAAA+0B,EAAAje,GAAAie,EAAAle,GACAke,EAAA9d,EAAA8d,EAAA/d,GAAA+d,EAAAhe,GAEAo8B,GAAApe,EAAA/0B,EAAA+0B,EAAA9d,EAGAuX,EAAAzoB,KAAA,SAAAqtC,EAAAC,GACA,MAAAA,GAAArzC,EAAAqzC,EAAAp8B,EAAAm8B,EAAApzC,EAAAozC,EAAAn8B,GASA,KAAA,GANAxB,GAAA,EACAC,EAAA,EACA49B,EAAA,EACAC,EAAA,EACAC,EAAAnsC,KAAA+F,KAAA+lC,GAAApF,EAAA/N,YAAA+N,EAAA9N,aAEA1nC,EAAA,EAAAA,EAAAi2B,EAAA51B,OAAAL,IAAA,CAGA,IAAA,GAFAw8B,GAAAvG,EAAAj2B,GAEAsM,EAAA,EAAAA,EAAAkwB,EAAAn8B,OAAAiM,IAAA,CACA,GAAA7M,GAAA+8B,EAAAlwB,EAEA7M,GAAAk4C,WACAl4C,EAAAu3C,WAAA95B,EACAzd,EAAAy3C,WAAA/5B,GAIAD,GAAAsf,EAAA/0B,EAAA9C,EAAA+vC,iBACAqG,GAAAve,EAAA/0B,EAAA9C,EAAA+vC,iBACAsG,EAAAlsC,KAAA9D,IAAAgwC,EAAAxe,EAAA9d,GAEAq8B,EAAAE,IACA99B,GAAA69B,EAAAr2C,EAAA+vC,iBACAx3B,EAAA,EACA69B,EAAA,EACAC,EAAA,KAKAE,EAAA,SAAAl7C,GACA,MAAA4C,IAEA,GAIAqsB,EAAAumB,EAAA7wC,EAAA3E,GAGAw1C,EAAA2E,YAAA3E,EAAA2E,YAAAx1C,EAAAuwC,cAGAM,EAAA2E,YAAAx1C,EAAAwwC,SAEA,GAGA,IAGAn1C,EAAA,CAGA,GAAA,CAGA,IAFA,GAAApB,GAAA,EAEAA,EAAA+F,EAAA8vC,SAAAz0C,EAAA2E,EAAA6P,SAAA,CACA,GAAAyhC,GAAAiF,EAAAl7C,EACA,KAAAi2C,EAAA,KAEAr3C,KACAoB,IAGA2E,EAAAmS,SACAqkC,UAAA3F,EAAAO,mBAGAE,GAAAj2C,EAAA,EAAA2E,EAAA6P,QAIA,OAFAimC,GAAAjF,EAAA7wC,GAEA6wC,IACAhU,KAAA,SAAA4Z,GACA5F,EAAAO,YAAAqF,EAAArF,YAEAV,EAAAtyC,OACAw/B,KAGA,IAAAA,GAAA,WACAkS,GAAAoB,OAAA,IAGApnB,EAAAnJ,IAAA,aAAA3gB,EAAA5B,MACA0rB,EAAAxW,SAAAhU,KAAA,aAAAwqB,OAAAA,IAGA,OAAApvB,OAOAg1C,EAAAryC,UAAAe,KAAA,WASA,MARA1D,MAAAuD,SAAA,EAEAvD,KAAAg2C,QACAh2C,KAAAg2C,OAAAtyC,OAGA1D,KAAA4Y,QAAA,cAEA5Y,MAGAg1C,EAAAryC,UAAA49B,QAAA,WAKA,MAJAvgC,MAAAg2C,QACAh2C,KAAAg2C,OAAAtyC,OAGA1D,KAUA,IAAAo2C,GAAA,SAAAhzC,EAAAgsB,EAAA9pB,GAyBA,IAAA,GAvBA6B,GAAA7B,EAAAC,KAAA4B,QACAG,EAAAhC,EAAAC,KAAA+B,QAEA6uC,GACAsB,WAAAr0C,EAAAsb,mBACAg4B,eACAU,aACAuD,SAAArzC,EAAAgI,OACA4nC,YACA8E,gBACAxC,eACAD,SAAApyC,EAAAmI,OACAwrC,YAAAx1C,EAAAswC,YACAxN,YAAAhlC,EAAA4jC,QACAqB,aAAAjlC,EAAA4jC,QACAhoB,YAAAwwB,EAAAM,gBAAAxqC,EAAA0Z,YAAA1Z,EAAA0Z,aACAC,GAAA,EAAAE,GAAA,EAAA/W,EAAAhF,EAAA4jC,QAAA3nB,EAAAjc,EAAA6jC,YAIArQ,EAAAtxB,EAAAC,KAAAqxB,aACAqlB,KAEAt7C,EAAA,EAAAA,EAAAi2B,EAAA51B,OAAAL,IAGA,IAAA,GAFAq2B,GAAAJ,EAAAj2B,GAEAsM,EAAA,EAAAA,EAAA+pB,EAAAh2B,OAAAiM,IAAA,CACA,GAAAlB,GAAAirB,EAAA/pB,EAEAgvC,GAAAlwC,EAAA/E,MAAArG,EAKA,IAAA,GAAAA,GAAA,EAAAA,EAAAw1C,EAAAwE,SAAAh6C,IAAA,CACA,GAAAP,GAAAkH,EAAA3G,GACAkxC,EAAAzxC,EAAA4e,cAEAk9B,IACAA,GAAA5D,SAAAl4C,EAAAmd,SACA2+B,EAAAl1C,GAAA5G,EAAA8H,KAAA,MACAg0C,EAAA7wB,SAAAjrB,EAAA8H,KAAA,UACAg0C,EAAA3E,OAAA0E,EAAA77C,EAAA4G,MACAk1C,EAAAzhC,YACAyhC,EAAAvE,UAAAv3C,EAAA4c,SAAA,KACAk/B,EAAArE,UAAAz3C,EAAA4c,SAAA,KACAk/B,EAAA3D,QAAA,EACA2D,EAAA1D,QAAA,EACA0D,EAAAjV,OAAA4K,EAAAzpC,EACA8zC,EAAAlV,MAAA6K,EAAAxyB,EACA68B,EAAAtD,KAAAsD,EAAAvE,UAAAuE,EAAAlV,MAAA,EACAkV,EAAArD,KAAAqD,EAAAvE,UAAAuE,EAAAlV,MAAA,EACAkV,EAAAnD,KAAAmD,EAAArE,UAAAqE,EAAAjV,OAAA,EACAiV,EAAAlD,KAAAkD,EAAArE,UAAAqE,EAAAjV,OAAA,EACAiV,EAAAjB,QAAApd,WAAAz9B,EAAA0B,MAAA,iBACAo6C,EAAAlB,SAAAnd,WAAAz9B,EAAA0B,MAAA,kBACAo6C,EAAAf,OAAAtd,WAAAz9B,EAAA0B,MAAA,gBACAo6C,EAAAhB,UAAArd,WAAAz9B,EAAA0B,MAAA,mBAGAo6C,EAAA5G,cAAAl0C,EAAAoB,GAAA8C,EAAAgwC,eAAAhwC,EAAAgwC,cAAAv0C,KAAAX,EAAAA,GAAAkF,EAAAgwC,cAGAa,EAAAO,YAAAj0C,KAAAy5C,GAEA/F,EAAAiB,UAAA8E,EAAAl1C,IAAArG,EAYA,IAAA,GARAsC,MACAwC,EAAA,EACAC,EAAA,GAEAy2C,KAIAx7C,EAAA,EAAAA,EAAAw1C,EAAAwE,SAAAh6C,IAAA,CACA,GAAAP,GAAA+1C,EAAAO,YAAA/1C,GACAy7C,EAAAh8C,EAAAirB,QAEA,OAAA+wB,EAEAjG,EAAAO,YAAAP,EAAAiB,UAAAgF,IAAA3hC,SAAAhY,KAAArC,EAAA4G,KAGA/D,IAAAyC,GAAAtF,EAAA4G,GACAm1C,EAAA15C,KAAArC,EAAA4G,KAQA,IAHAmvC,EAAAe,SAAAz0C,KAAA05C,GAGAz2C,GAAAD,GAAA,CAEA,GAAA42C,GAAAp5C,EAAAwC,KACA62C,EAAAnG,EAAAiB,UAAAiF,GACAtwC,EAAAoqC,EAAAO,YAAA4F,GACA7hC,EAAA1O,EAAA0O,QACA,IAAAA,EAAAzZ,OAAA,EAAA,CAEAm1C,EAAAe,SAAAz0C,KAAAgY,EAEA,KAAA,GAAA9Z,GAAA,EAAAA,EAAA8Z,EAAAzZ,OAAAL,IACAsC,IAAAyC,GAAA+U,EAAA9Z,IAMA,IAAA,GAAAA,GAAA,EAAAA,EAAAw1C,EAAAe,SAAAl2C,OAAAL,IAEA,IAAA,GADAkvC,GAAAsG,EAAAe,SAAAv2C,GACAsM,EAAA,EAAAA,EAAA4iC,EAAA7uC,OAAAiM,IAAA,CACA,GAAAgB,GAAAkoC,EAAAiB,UAAAvH,EAAA5iC,GACAkpC,GAAA6F,aAAA/tC,GAAAtN,EAKA,IAAA,GAAAA,GAAA,EAAAA,EAAAw1C,EAAAoD,SAAA54C,IAAA,CACA,GAAAT,GAAAiH,EAAAxG,GACA47C,IACAA,GAAAv1C,GAAA9G,EAAAgI,KAAA,MACAq0C,EAAA7C,SAAAx5C,EAAAgI,KAAA,UACAq0C,EAAA3C,SAAA15C,EAAAgI,KAAA,SAGA,IAAA6xC,GAAA34C,EAAAoB,GAAA8C,EAAAkwC,iBAAAlwC,EAAAkwC,gBAAAz0C,KAAAb,EAAAA,GAAAoF,EAAAkwC,gBACAwE,EAAA54C,EAAAoB,GAAA8C,EAAAmwC,gBAAAnwC,EAAAmwC,eAAA10C,KAAAb,EAAAA,GAAAoF,EAAAmwC,eAGAgE,EAAAtD,EAAAiB,UAAAmF,EAAA7C,UACAC,EAAAxD,EAAAiB,UAAAmF,EAAA3C,UACA4C,EAAArG,EAAA6F,aAAAvC,GACAgD,EAAAtG,EAAA6F,aAAArC,EAEA,IAAA6C,GAAAC,EAAA,CAUA,IARA,GAAAC,GAAAC,EAAAJ,EAAA7C,SAAA6C,EAAA3C,SAAAzD,GAGAyG,EAAAzG,EAAAe,SAAAwF,GACAtvC,EAAA,EAGA8uC,EAAA/F,EAAAO,YAAA+C,GACA,KAAAmD,EAAAt0C,QAAA4zC,EAAAl1C,KACAk1C,EAAA/F,EAAAO,YAAAP,EAAAiB,UAAA8E,EAAA7wB,WACAje,GAKA,KADA8uC,EAAA/F,EAAAO,YAAAiD,GACA,KAAAiD,EAAAt0C,QAAA4zC,EAAAl1C,KACAk1C,EAAA/F,EAAAO,YAAAP,EAAAiB,UAAA8E,EAAA7wB,WACAje,GAQA2sC,IAAA3sC,EAAA9H,EAAAowC,cAGA6G,EAAAxC,YAAAA,EACAwC,EAAAvC,WAAAA,EAEA7D,EAAAqD,YAAA/2C,KAAA85C,GAIA,MAAApG,IAeAwG,EAAA,SAAAxF,EAAAE,EAAAlB,GAEA,GAAA1sC,GAAAozC,EAAA1F,EAAAE,EAAA,EAAAlB,EACA,OAAA,GAAA1sC,EAAAqzC,MAGA,EAEArzC,EAAAomC,OAmBAgN,EAAA,SAAA1F,EAAAE,EAAA0F,EAAA5G,GACA,GAAAtG,GAAAsG,EAAAe,SAAA6F,EAEA,IAAA,GAAAlN,EAAAvnC,QAAA6uC,IAAA,GAAAtH,EAAAvnC,QAAA+uC,GACA,OAAAyF,MAAA,EAAAjN,MAAAkN,EAKA,KAAA,GADA5f,GAAA,EACAx8B,EAAA,EAAAA,EAAAkvC,EAAA7uC,OAAAL,IAAA,CACA,GAAA4W,GAAAs4B,EAAAlvC,GACAq8C,EAAA7G,EAAAiB,UAAA7/B,GACAkD,EAAA07B,EAAAO,YAAAsG,GAAAviC,QAGA,IAAA,IAAAA,EAAAzZ,OAAA,CAIA,GAAAi8C,GAAA9G,EAAA6F,aAAA7F,EAAAiB,UAAA38B,EAAA,KACAyiC,EAAAL,EAAA1F,EAAAE,EAAA4F,EAAA9G,EACA,IAAA,IAAA+G,EAAAJ,MAAA,CAGA,GAAA,IAAAI,EAAAJ,MASA,MAAAI,EANA,IADA/f,IACA,IAAAA,EAEA,QAQA,OAAA2f,MAAA3f,EAAA0S,MAAAkN,IAQA1G,EAAA,SAAAF,GAGA,GAAAlB,EAAA,CAGAkI,QAAAjH,MAAA,eACA,KAAA,GAAAv1C,GAAA,EAAAA,EAAAw1C,EAAAwE,SAAAh6C,IAAA,CACA,GAAAP,GAAA+1C,EAAAO,YAAA/1C,GACAL,EACA,YAAAK,EACA,SAAAP,EAAA4G,GACA,eAAA5G,EAAAqa,SAAA2iC,WACA,eAAAh9C,EAAAirB,SACA,gBAAAjrB,EAAAu3C,UACA,gBAAAv3C,EAAAy3C,UACA,cAAAz3C,EAAAm4C,QACA,cAAAn4C,EAAAo4C,QACA,cAAAp4C,EAAA66C,QACA,eAAA76C,EAAA46C,SACA,aAAA56C,EAAA+6C,OACA,gBAAA/6C,EAAA86C,SAEAiC,SAAAjH,MAAA51C,GAGA68C,QAAAjH,MAAA,YACA,KAAA,GAAAv1C,KAAAw1C,GAAAiB,UACA+F,QAAAjH,MAAA,OAAAv1C,EAAA,YAAAw1C,EAAAiB,UAAAz2C,GAGAw8C,SAAAjH,MAAA,YAEA,KAAA,GADAmH,GAAAlH,EAAAe,SACAv2C,EAAA,EAAAA,EAAA08C,EAAAr8C,OAAAL,IACAw8C,QAAAjH,MAAA,SAAAv1C,EAAA,KAAA08C,EAAA18C,GAAAy8C,WAIA,KAAA,GADA98C,GAAA,eACAK,EAAA,EAAAA,EAAAw1C,EAAA6F,aAAAh7C,OAAAL,IACAL,GAAA,aAAAK,EAAA,WAAAw1C,EAAA6F,aAAAr7C,EAEAw8C,SAAAjH,MAAA51C,GAEAA,EAAA,cACA,KAAA,GAAAK,GAAA,EAAAA,EAAAw1C,EAAAqD,YAAAx4C,OAAAL,IAAA,CACA,GAAAT,GAAAi2C,EAAAqD,YAAA74C,EACAL,IAAA,iBAAAK,EAAA,QAAAT,EAAA8G,GACA,aAAA9G,EAAAw5C,SAAA,cAAAx5C,EAAA05C,SACA,kBAAA15C,EAAA65C,YAEAoD,QAAAjH,MAAA51C,GAEAA,EAAA,aAAA61C,EAAAwE,SACAr6C,GAAA,eAAA61C,EAAAoD,SACAj5C,GAAA,kBAAA61C,EAAA2E,YACAqC,QAAAjH,MAAA51C,KAUAg2C,EAAA,SAAAH,EAAA/yC,GAIA,IAAA,GAHA4jC,GAAAmP,EAAA/N,YACAnB,EAAAkP,EAAA9N,aAEA1nC,EAAA,EAAAA,EAAAw1C,EAAAwE,SAAAh6C,IAAA,CACA,GAAAP,GAAA+1C,EAAAO,YAAA/1C,EAGA,KAAAP,EAAAqa,SAAAzZ,QAAAZ,EAAAk4C,WACAl4C,EAAAu3C,UAAAloC,KAAAwF,SAAA+xB,EACA5mC,EAAAy3C,UAAApoC,KAAAwF,SAAAgyB,KAYAwP,EAAA,SAAAN,EAAA/yC,EAAAkC,GAIA,GAAA8pB,GAAA9pB,EAAA8pB,OACA9nB,EAAAhC,EAAAC,KAAA+B,QACAyX,EAAAo3B,EAAAn3B,YACAs+B,GAAAr+B,GAAAlW,EAAAA,EAAAmW,KAAAnW,EAAAA,GAAAoW,GAAApW,EAAAA,EAAAqW,KAAArW,EAAAA,GAEAzD,GAAA0Z,cACA1X,EAAAgE,QAAA,SAAAS,GACA,GAAAwxC,GAAApH,EAAAO,YAAAP,EAAAiB,UAAArrC,EAAA7D,KAAA,OAEAo1C,GAAAr+B,GAAAxP,KAAAkN,IAAA2gC,EAAAr+B,GAAAs+B,EAAA5F,WACA2F,EAAAp+B,GAAAzP,KAAA9D,IAAA2xC,EAAAp+B,GAAAq+B,EAAA5F,WAEA2F,EAAAn+B,GAAA1P,KAAAkN,IAAA2gC,EAAAn+B,GAAAo+B,EAAA1F,WACAyF,EAAAl+B,GAAA3P,KAAA9D,IAAA2xC,EAAAl+B,GAAAm+B,EAAA1F,aAGAyF,EAAAl1C,EAAAk1C,EAAAp+B,GAAAo+B,EAAAr+B,GACAq+B,EAAAj+B,EAAAi+B,EAAAl+B,GAAAk+B,EAAAn+B,IAGA7X,EAAAmW,UAAA,SAAA9c,EAAAsH,GACA,GAAAs1C,GAAApH,EAAAO,YAAAP,EAAAiB,UAAAnvC,EAAAC,KAAA,OAKA,IAAA5C,EAAA0Z,YAAA,CACA,GAAAw+B,IAAAD,EAAA5F,UAAA2F,EAAAr+B,IAAAq+B,EAAAl1C,EACAq1C,GAAAF,EAAA1F,UAAAyF,EAAAn+B,IAAAm+B,EAAAj+B,CAEA,QACAxB,EAAAkB,EAAAE,GAAAu+B,EAAAz+B,EAAA3W,EACA0V,EAAAiB,EAAAI,GAAAs+B,EAAA1+B,EAAAM,GAGA,OACAxB,EAAA0/B,EAAA5F,UACA75B,EAAAy/B,EAAA1F,cAMA,IAAA1B,EAAArmB,Q/C06SIqmB,EAAWrmB,OAAQ,EgDjtVvBV,EAAAnJ,IAAA,cAAA3gB,EAAAwqB,OACAV,EAAAxW,SAAAhU,KAAA,cAAAwqB,OAAApvB,QAaAP,GAAAD,QAAAw1C,IAEAzsC,WAAA,GAAA0qC,aAAA,GAAAyK,eAAA,GAAAzzC,aAAA,KAAA0zC,IAAA,SAAAz8C,EAAAzB,EAAAD,GACA,YAuBA,SAAAo+C,GAAAt4C,GACAtF,KAAAsF,QAAAnE,EAAAS,UAAAyyB,EAAA/uB,GAtBA,GAAAnE,GAAAD,EAAA,cACAsuC,EAAAtuC,EAAA,cAEAmzB,GACAxE,KAAA,EACAnQ,QAAA,GACAV,YAAAlb,OACA6rC,cAAA,EACAkO,oBAAA,GACAC,UAAA,EACAC,KAAAj6C,OACAk6C,KAAAl6C,OACAkZ,SAAA,SAAAjR,KACAoC,KAAArK,OACA2T,SAAA,EACAgY,kBAAA,IACAE,gBAAA7rB,OACAgsB,MAAAhsB,OACAJ,KAAAI,OAOA85C,GAAAj7C,UAAA2hC,IAAA,WACA,GAAAh4B,GAAAtM,KAAAsF,QACAA,EAAAgH,EAEAlJ,EAAAkJ,EAAAlJ,GACAmC,EAAAD,EAAAC,KACA+B,EAAA/B,EAAA+B,QAAAiG,IAAA,UAEAjI,GAAA6I,OACA7G,EAAAA,EAAA6G,KAAA7I,EAAA6I,MAGA,IAAA4Q,GAAAywB,EAAAM,gBAAAxqC,EAAA0Z,YAAA1Z,EAAA0Z,aACAC,GAAA,EAAAE,GAAA,EAAA/W,EAAAhF,EAAA4jC,QAAA3nB,EAAAjc,EAAA6jC,UAGA,IAAA,IAAAloB,EAAAM,GAAA,IAAAN,EAAA3W,EACAd,EAAA6nB,gBAAAnvB,KAAAsF,EAAA,WACA,OAAAuY,EAAAkB,EAAAE,GAAAnB,EAAAiB,EAAAI,UAGA,CAGA,GAAA8+B,GAAA32C,EAAAgI,OACA4uC,EAAAzuC,KAAA+F,KAAAyoC,EAAAl/B,EAAAM,EAAAN,EAAA3W,GACA21C,EAAAtuC,KAAA6sB,MAAA4hB,GACAF,EAAAvuC,KAAA6sB,MAAAvd,EAAA3W,EAAA2W,EAAAM,EAAA6+B,GAEAC,EAAA,SAAAhgC,GACA,GAAA,MAAAA,EACA,MAAA1O,MAAAkN,IAAAohC,EAAAC,EAEA,IAAArhC,GAAAlN,KAAAkN,IAAAohC,EAAAC,EACArhC,IAAAohC,EACAA,EAAA5/B,EAEA6/B,EAAA7/B,GAKAigC,EAAA,SAAAjgC,GACA,GAAA,MAAAA,EACA,MAAA1O,MAAA9D,IAAAoyC,EAAAC,EAEA,IAAAryC,GAAA8D,KAAA9D,IAAAoyC,EAAAC,EACAryC,IAAAoyC,EACAA,EAAA5/B,EAEA6/B,EAAA7/B,GAKAkgC,EAAA/4C,EAAAy4C,KACAO,EAAA,MAAAh5C,EAAA04C,KAAA14C,EAAA04C,KAAA14C,EAAAi5C,OAGA,IAAA,MAAAF,GAAA,MAAAC,EACAP,EAAAM,EACAL,EAAAM,MACA,IAAA,MAAAD,GAAA,MAAAC,EACAP,EAAAM,EACAL,EAAAvuC,KAAA2F,KAAA6oC,EAAAF,OACA,IAAA,MAAAM,GAAA,MAAAC,EACAN,EAAAM,EACAP,EAAAtuC,KAAA2F,KAAA6oC,EAAAD,OAMA,IAAAA,EAAAD,EAAAE,EAAA,CACA,GAAAO,GAAAL,IACAM,EAAAL,KAGAI,EAAA,GAAAC,GAAAR,EACAE,EAAAK,EAAA,IACAC,EAAA,GAAAD,GAAAP,GACAG,EAAAK,EAAA,OAKA,MAAAR,EAAAD,EAAAD,GAAA,CACA,GAAAS,GAAAL,IACAM,EAAAL,KAGAK,EAAA,GAAAD,GAAAP,EACAG,EAAAK,EAAA,GAEAN,EAAAK,EAAA,GAKA,GAAAE,GAAA3/B,EAAA3W,EAAA41C,EACAW,EAAA5/B,EAAAM,EAAA0+B,CAOA,IALAz4C,EAAAw4C,WACAY,EAAA,EACAC,EAAA,GAGAr5C,EAAAqqC,aACA,IAAA,GAAAhvC,GAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IAAA,CACA,GAAAoL,GAAAzE,EAAA3G,GACA+c,EAAA3R,EAAApK,SAAAqb,UAEA,MAAAU,EAAAG,GAAA,MAAAH,EAAAI,KACAJ,EAAAG,EAAA,EACAH,EAAAI,EAAA,EAGA,IAAA+zB,GAAA9lC,EAAAiT,cACAjb,EAAAuB,EAAAu4C,oBAEAz1C,EAAAypC,EAAAzpC,EAAArE,EACAsb,EAAAwyB,EAAAxyB,EAAAtb,CAEA26C,GAAAjvC,KAAA9D,IAAA+yC,EAAAt2C,GACAu2C,EAAAlvC,KAAA9D,IAAAgzC,EAAAt/B,GA2BA,IAAA,GAvBAu/B,MAEAC,EAAA,SAAAC,EAAAz3B,GACA,MAAAu3B,GAAA,KAAAE,EAAA,IAAAz3B,IAAA,GAAA,GAGA03B,EAAA,SAAAD,EAAAz3B,GACAu3B,EAAA,KAAAE,EAAA,IAAAz3B,IAAA,GAIAy3B,EAAA,EACAz3B,EAAA,EACA23B,EAAA,WACA33B,IACAA,GAAA22B,IACA32B,EAAA,EACAy3B,MAKAG,KACAt+C,EAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IAAA,CACA,GAAAoL,GAAAzE,EAAA3G,GACAu+C,EAAA55C,EAAA0X,SAAAjR,EAEA,IAAAmzC,IAAAp7C,SAAAo7C,EAAAJ,KAAAh7C,SAAAo7C,EAAA73B,KAAA,CACA,GAAA3J,IACAohC,IAAAI,EAAAJ,IACAz3B,IAAA63B,EAAA73B,IAGA,IAAAvjB,SAAA4Z,EAAA2J,IAGA,IAFA3J,EAAA2J,IAAA,EAEAw3B,EAAAnhC,EAAAohC,IAAAphC,EAAA2J,MACA3J,EAAA2J,UAEA,IAAAvjB,SAAA4Z,EAAAohC,IAGA,IAFAphC,EAAAohC,IAAA,EAEAD,EAAAnhC,EAAAohC,IAAAphC,EAAA2J,MACA3J,EAAAohC,KAIAG,GAAAlzC,EAAA/E,MAAA0W,EACAqhC,EAAArhC,EAAAohC,IAAAphC,EAAA2J,MAIA,GAAAusB,GAAA,SAAAjzC,EAAAgmB,GACA,GAAA9I,GAAAC,CAEA,IAAA6I,EAAApJ,UAAAoJ,EAAAmL,mBACA,OAAA,CAIA,IAAAotB,GAAAD,EAAAt4B,EAAA3f,KACA,IAAAk4C,EACArhC,EAAAqhC,EAAA73B,IAAAq3B,EAAAA,EAAA,EAAA3/B,EAAAE,GACAnB,EAAAohC,EAAAJ,IAAAH,EAAAA,EAAA,EAAA5/B,EAAAI,OAEA,CAEA,KAAA0/B,EAAAC,EAAAz3B,IACA23B,GAGAnhC,GAAAwJ,EAAAq3B,EAAAA,EAAA,EAAA3/B,EAAAE,GACAnB,EAAAghC,EAAAH,EAAAA,EAAA,EAAA5/B,EAAAI,GACA4/B,EAAAD,EAAAz3B,GCrPA23B,IAGA,OAAAnhC,EAAAA,EAAAC,EAAAA,GAIAxW,GAAA6nB,gBAAAnvB,KAAAsF,EAAAsuC,GAGA,MAAA5zC,OCVAP,EAAAD,QAAAo+C,IAEA3K,aAAA,GAAAhpC,aAAA,KAAAk1C,IAAA,SAAAj+C,EAAAzB,EAAAD,GACA,YAEAC,GAAAD,UACA+E,KAAA,eAAAyqC,KAAA9tC,EAAA,oBACAqD,KAAA,SAAAyqC,KAAA9tC,EAAA,cACAqD,KAAA,aAAAyqC,KAAA9tC,EAAA,kBACAqD,KAAA,OAAAyqC,KAAA9tC,EAAA,YACAqD,KAAA,OAAAyqC,KAAA9tC,EAAA,YACAqD,KAAA,OAAAyqC,KAAA9tC,EAAA,YACAqD,KAAA,SAAAyqC,KAAA9tC,EAAA,cACAqD,KAAA,SAAAyqC,KAAA9tC,EAAA,gBAGAk+C,iBAAA,GAAAC,WAAA,GAAAC,eAAA,GAAAC,SAAA,GAAAC,SAAA,GAAAC,SAAA,GAAAC,WAAA,GAAAC,WAAA,KAAAC,IAAA,SAAA1+C,EAAAzB,EAAAD,GACA,YAYA,SAAAqgD,GAAAv6C,GACAtF,KAAAsF,QAAAnE,EAAAS,UAAAyyB,EAAA/uB,GAXA,GAAAnE,GAAAD,EAAA,cAGAmzB,GACAvE,MAAA,aACApsB,KAAA,aAUAm8C,GAAAl9C,UAAA2hC,IAAA,WACA,GAAAh/B,GAAAtF,KAAAsF,QACAC,EAAAD,EAAAC,KACA6pB,EAAApvB,IAGAsF,GAAAlC,EClCA,ODoCAgsB,GAAAxW,QAAA,eAGArT,EAAA+B,QAAAmW,UAAA,WACA,OACAI,EAAA,EACAC,EAAA,KlD49VEsR,EAAOnJ,IAAI,cAAe3gB,EAAQwqB,OmD5gWpCV,EAAAxW,QAAA,eAGAwW,EAAAnJ,IAAA,aAAA3gB,EAAA5B,MACA0rB,EAAAxW,QAAA,cAEA5Y,MAIA6/C,EAAAl9C,UAAAe,KAAA,WACA,MAAA1D,OAGAP,EAAAD,QAAAqgD,IAEA51C,aAAA,KAAA61C,IAAA,SAAA5+C,EAAAzB,EAAAD,GACA,YAkBA,SAAAugD,GAAAz6C,GACAtF,KAAAsF,QAAAnE,EAAAS,UAAAyyB,EAAA/uB,GAjBA,GAAAnE,GAAAD,EAAA,cACAE,EAAAF,EAAA,YAEAmzB,GACA5W,UAAA3Z,OACAsa,KAAAta,OACAua,IAAAva,OACA+rB,KAAA,EACAnQ,QAAA,GACAjI,SAAA,EACAgY,kBAAA,IACAE,gBAAA7rB,OACAgsB,MAAAhsB,OACAJ,KAAAI,OAOAi8C,GAAAp9C,UAAA2hC,IAAA,WAOA,QAAAkO,GAAAzmC,GACA,GAAA,MAAAzG,EAAAmY,UACA,MAAA,KAGA,IAAAuiC,EACA,MAAA16C,GAAAmY,UAAAja,MAAAuI,GAAAA,GAGA,IAAA2R,GAAApY,EAAAmY,UAAA1R,EAAApK,SAAAuG,KAAAlB,GAEA,OAAA,OAAA0W,EACA,KAGAA,EArBA,GAAApY,GAAAtF,KAAAsF,QACAC,EAAAD,EAAAC,KAEA+B,EAAA/B,EAAA+B,QACA04C,EAAA5+C,EAAAoB,GAAA8C,EAAAmY,UCjCA,OAVAnW,GAAA6nB,gBAAAnvB,KAAAsF,EAAA,SAAA3E,EAAAoL,GACA,GAAAiR,GAAAw1B,EAAAzmC,EAEA,OAAAA,GAAAwR,UAAA,MAAAP,GACA,EAGAA,IAGAhd,MAGAP,EAAAD,QAAAugD,IAEAx3C,WAAA,GAAA0B,aAAA,KAAAg2C,IAAA,SAAA/+C,EAAAzB,EAAAD,GACA,YAgBA,SAAA0gD,GAAA56C,GACAtF,KAAAsF,QAAAnE,EAAAS,UAAAyyB,EAAA/uB,GAfA,GAAAnE,GAAAD,EAAA,cACAsuC,EAAAtuC,EAAA,cAEAmzB,GACAxE,KAAA,EACAnQ,QAAA,GACAV,YAAAlb,OACA2T,SAAA,EACAgY,kBAAA,IACAE,gBAAA7rB,OACAgsB,MAAAhsB,OACAJ,KAAAI,OAOAo8C,GAAAv9C,UAAA2hC,IAAA,WACA,GAAAh/B,GAAAtF,KAAAsF,QACAlC,EAAAkC,EAAAlC,GACAmC,EAAAD,EAAAC,KACA+B,EAAA/B,EAAA+B,QAAAiG,IAAA,WAEAwR,EAAAywB,EAAAM,gBAAAxqC,EAAA0Z,YAAA1Z,EAAA0Z,apD6kWIC,GAAI,EAAGE,GAAI,EAAG/W,EAAGhF,EAAG4jC,QAAS3nB,EAAGjc,EAAG6jC,WqDtnWvC2M,EAAA,SAAAjzC,EAAAoL,GACA,OACA8R,EAAAkB,EAAAE,GAAAxP,KAAA6sB,MAAA7sB,KAAAwF,SAAA8J,EAAA3W,GACA0V,EAAAiB,EAAAI,GAAA1P,KAAA6sB,MAAA7sB,KAAAwF,SAAA8J,EAAAM,IAMA,OAFA/X,GAAA6nB,gBAAAnvB,KAAAsF,EAAAsuC,GAEA5zC,MAGAP,EAAAD,QAAA0gD,IAEAjN,aAAA,GAAAhpC,aAAA,KAAAk2C,IAAA,SAAAj/C,EAAAzB,EAAAD,GACA,YAEA,IAAAgwC,GAAAtuC,EAAA,iBACAE,EAAAF,EAAA,eACAC,EAAAD,EAAA,iBAEAk/C,IAEAA,GAAAC,iBAAA,GAEAD,EAAAE,oBAAA,WACA,GAAAC,GAAAvgD,KAAAugD,eACA//B,EAAAxgB,KAcAwgD,EAAA,SAAA3iC,EAAAC,EAAAxO,EAAAmxC,EAAAC,EAAAhhC,GACA,GAAAT,GAAAyhC,EAAA7iC,EAAAvO,EAAA,EAAAoQ,EACAR,EAAAwhC,EAAA7iC,EAAAvO,EAAA,EAAAoQ,EACAP,EAAAuhC,EAAA5iC,EAAAxO,EAAA,EAAAoQ,EACAN,EAAAshC,EAAA5iC,EAAAxO,EAAA,EAAAoQ,EAEAgM,EAAA7N,GAAAoB,GAAAC,GAAArB,GAAAC,GAAAqB,GAAAC,GAAAtB,CAEA,OAAA4N,IAGAi1B,EAAA,SAAA9iC,EAAAC,EAAAxO,EAAAmxC,EAAAC,GACA,GAAAE,GAAA/iC,EAAApO,KAAA6T,IAAAm9B,GAAA3iC,EAAArO,KAAA8T,IAAAk9B,GACAI,EAAAhjC,EAAApO,KAAA8T,IAAAk9B,GAAA3iC,EAAArO,KAAA6T,IAAAm9B,GAEAK,EAAAF,EAAAtxC,EACAyxC,EAAAF,EAAAvxC,EAEA0xC,EAAAF,EAAAJ,EAAA7iC,EACAojC,EAAAF,EAAAL,EAAA5iC,CAEA,QACAD,EAAAmjC,EACAljC,EAAAmjC,IAIAC,EAAA,SAAAp/B,EAAAxS,EAAAmxC,EAAAC,GAGA,IAAA,GAFAS,MAEAxgD,EAAA,EAAAA,EAAAmhB,EAAA9gB,OAAAL,GAAA,EAAA,CACA,GAAAkd,GAAAiE,EAAAnhB,GACAmd,EAAAgE,EAAAnhB,EAAA,EAEAwgD,GAAA1+C,KAAAk+C,EAAA9iC,EAAAC,EAAAxO,EAAAmxC,EAAAC,IAGA,MAAAS,IAGAC,EAAA,SAAAt/B,GAGA,IAAA,GAFAjW,MAEAlL,EAAA,EAAAA,EAAAmhB,EAAA9gB,OAAAL,IAAA,CACA,GAAAoD,GAAA+d,EAAAnhB,EAEAkL,GAAApJ,KAAAsB,EAAA8Z,EAAA9Z,EAAA+Z,GAGA,MAAAjS,IAGAw1C,EAAA,SAAA98C,EAAA+8C,GACAlgD,EAAAoF,OAAA86C,KACAA,EAAAf,EAAAe,IAGAf,EAAAh8C,GAAApD,EAAAS,QACA2C,KAAAA,EAEAogB,SACA,KAAA,GACA,KAAA,GACA,IAAA,IACA,IAAA,IAGA48B,QAAA,SAAA1jC,EAAAC,EAAAxO,EAAAmxC,EAAAC,EAAAhhC,GACA,GAAAiF,GAAAy8B,EAAAF,EAAAlhD,KAAA2kB,OAAArV,EAAA,EAAAoQ,EAAA+gC,EAAAC,IACAh1B,EAAA8jB,EAAAgS,yBAAA3jC,EAAAC,EAAA6G,EAEA,OAAA+G,IAGA+1B,aAAAjB,EAEAkB,KAAA,SAAAtc,EAAA91B,EAAAmxC,EAAAC,GACA,GAAA/7B,GAAAu8B,EAAAlhD,KAAA2kB,OAAArV,EAAAmxC,EAAAC,EAEAlgC,GAAAmhC,eAAA,WAAAvc,EAAAzgB,IAGAi9B,QAAA,SAAAn2C,GACA,MAAA,IAGAo2C,IAAA,SAAAp2C,GACA,MAAA,GAAAA,EAAA9J,SAAAG,MAAA,MAAA8d,UAEA0hC,GAGAD,GAAA,QACAE,QAAApgD,EAAA2gD,QAEAL,aAAAtgD,EAAA2gD,QAEAJ,KAAAvgD,EAAA4gD,KAEAH,QAAAzgD,EAAA6gD,QAEAH,IAAA1gD,EAAA6gD,UAGAX,EAAA,YACA18B,SACA,KAAA,GACA,EAAA,EACA,KAAA,MAIA08B,EAAA,QAAA,YAEAA,EAAA,sBACA18B,OAAA47B,EAAA,SAAA57B,OAEAs9B,cAAA,GAAA,KAEAR,aAAAjB,EAEAkB,KAAA,SAAAtc,EAAA91B,EAAAmxC,EAAAC,GACA,GAAAwB,GAAAhB,EAAAlhD,KAAA2kB,OAAArV,EAAAmxC,EAAAC,GACAyB,EAAAniD,KAAAiiD,aACAG,EAAAzB,EAAAwB,EAAA,GAAAA,EAAA,GAAA7yC,EAAAmxC,EAAAC,EAEAlgC,GAAAmhC,eAAA3hD,KAAAuE,MAAA6gC,EAAA8c,EAAAE,IAGAP,IAAA,SAAAp2C,GACA,MAAAA,GAAA9J,SAAAG,MAAA,MAAA8d,WAKAyhC,EAAA,gBACA18B,SACA,KAAA,GACA,EAAA,EACA,KAAA,IACA,KAAA,IAGA09B,YACA,KAAA,IACA,KAAA,GACA,KAAA,GACA,KAAA,IAGAd,QAAA,SAAA1jC,EAAAC,EAAAxO,EAAAmxC,EAAAC,EAAAhhC,GACA,GAAA4iC,GAAAlB,EAAAF,EAAAlhD,KAAA2kB,OAAArV,EAAA,EAAAoQ,EAAA+gC,EAAAC,IACA6B,EAAAnB,EAAAF,EAAAlhD,KAAAqiD,UAAA/yC,EAAA,EAAAoQ,EAAA+gC,EAAAC,IAEAh1B,EAAA8jB,EAAAgS,yBAAA3jC,EAAAC,EAAAwkC,IAAA9S,EAAAgS,yBAAA3jC,EAAAC,EAAAykC,EAEA,OAAA72B,IAGAg2B,KAAA,SAAAtc,EAAA91B,EAAAmxC,EAAAC,GACA,GAAA4B,GAAApB,EAAAlhD,KAAA2kB,OAAArV,EAAAmxC,EAAAC,GACA6B,EAAArB,EAAAlhD,KAAAqiD,UAAA/yC,EAAAmxC,EAAAC,EAEAlgC,GAAAmhC,eAAA3hD,KAAAuE,MAAA6gC,EAAAkd,EAAAC,MAIAlB,EAAA,OACA18B,SACA,KAAA,GACA,EAAA,EACA,KAAA,GACA,GAAA,KAGAk9B,IAAA,SAAAp2C,GACA,MAAAA,GAAA9J,SAAAG,MAAA,MAAA8d,WAIAyhC,EAAA,0BACA18B,QACA,GAAA,KACA,IAAA,IACA,GAAA,KAGA69B,eAAA,EAEAC,gBAAA,IAGApB,EAAA,UACAvO,OAAA,IAEAyO,QAAA,SAAA1jC,EAAAC,EAAAxO,EAAAmxC,EAAAC,EAAAhhC,GACA,GAAAvf,GAAAugD,EACAh1B,EAAAjc,KAAA6C,IAAAnS,EAAA0d,EAAAA,EAAA,GAAApO,KAAA6C,IAAAnS,EAAA2d,EAAAA,EAAA,IAAArO,KAAA6C,KAAAhD,EAAA,EAAAoQ,GAAA1f,KAAA8yC,OAAA,EAEA,OAAApnB,IAGAg2B,KAAA,SAAAtc,EAAA91B,EAAAmxC,EAAAC,GACAlgC,EAAAmhC,eAAA3hD,KAAAuE,MAAA6gC,EAAAsb,EAAA7iC,EAAA6iC,EAAA5iC,EAAA9d,KAAA8yC,OAAAxjC,IAGAsyC,QAAA,SAAAn2C,GACA,MAAA+U,GAAAkiC,cAAAj3C,EAAA9J,SAAAG,MAAA,MAAA8d,SACA5f,KAAA8yC,UAIAuO,EAAA,aACA18B,SACA,IAAA,GACA,KAAA,GACA,KAAA,GACA,IAAA,GAGAi9B,QAAA,SAAAn2C,GACA,MAAA,IAGAo2C,IAAA,SAAAp2C,GACA,MAAA,MAIA41C,EAAA,MAAA,aAEAA,EAAA,UACA18B,SACA,IAAA,EACA,IAAA,EACA,KAAA,IACA,KAAA,MrD6nWE08B,EAAkB,WsDp5WpB18B,SACA,KAAA,IACA,GAAA,GACA,KAAA,IACA,EAAA,GAGAk9B,IAAA,SAAAp2C,GACA,MAAAA,GAAA9J,SAAAG,MAAA,MAAA8d,YAMAngB,EAAAD,QAAA4gD,IAEAuC,cAAA,GAAAC,gBAAA,GAAAC,gBAAA,KAAAC,IAAA,SAAA5hD,EAAAzB,EAAAD,GACA,YAEA,IAAA4gD,MAEA2C,EAAA,SAAA1iD,GACAA,EAAA2iD,SAAA,MAGAC,EAAA,SAAA5iD,GAQA,MAPAA,GAAA2iD,WACA3iD,EAAA2iD,UACA17C,MAAAjH,EAAA+C,GAAAkE,QACAH,MAAA9G,EAAA+C,GAAA+D,UAIA9G,EAAA2iD,SAGA5C,GAAA8C,kBAAA,WACA,MAAAD,GAAAjjD,OAGAogD,EAAA+C,eAAA,WtDs5WE,MAAOF,GAAajjD,MAAOsH,OuD57W7B84C,EAAAgD,eAAA,WACA,MAAAH,GAAAjjD,MAAAmH,OAGAi5C,EAAAiD,oBAAA,WACA,GAAAhjD,GAAAL,IAIA,OAFA+iD,GAAA1iD,GAEA4iD,EAAA5iD,IAGAZ,EAAAD,QAAA4gD,OAEAkD,IAAA,SAAApiD,EAAAzB,EAAAD,GACA,YAmaA,SAAA+jD,GAAA93C,EAAAqW,GACA,GAAA0hC,GAAA,SAAA9nB,EAAAC,EAAA8nB,EAAAtjD,GAAA,MAAAqvC,GAAAgU,UAAA9nB,EAAAC,EAAA8nB,EAAAtjD,IACAuB,EAAA+J,EAAA9J,SACA+hD,EAAAhiD,EAAAkgB,OAAAG,SAEA2hC,GAAAjhD,MACAob,EAAA2lC,EAAA1hC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAA,KACAhE,EAAA0lC,EAAA1hC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAA,OAGA4hC,EAAAjhD,MACAob,EAAA2lC,EAAA1hC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAA,KACAhE,EAAA0lC,EAAA1hC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAA,OAGA4hC,EAAAjhD,MACAob,EAAA2lC,EAAA1hC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAA,IACAhE,EAAA0lC,EAAA1hC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAA,MAGA4hC,EAAAjhD,MACAob,EAAA2lC,EAAA1hC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAA,IACAhE,EAAA0lC,EAAA1hC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAA,MAGA4hC,EAAAjhD,MACAob,EAAA2lC,EAAA1hC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAA,IACAhE,EAAA0lC,EAAA1hC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAA,MAGA4hC,EAAAjhD,MACAob,EAAA2lC,EAAA1hC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAA,KACAhE,EAAA0lC,EAAA1hC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAA,OAGA4hC,EAAAjhD,MACAob,EAAA2lC,EAAA1hC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAA,KACAhE,EAAA0lC,EAAA1hC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAA,OAtcA,GAAA0tB,GAAAtuC,EAAA,iBACAE,EAAAF,EAAA,eACAitB,EAAAjtB,EAAA,6BAEAk/C,IAGAA,GAAAuD,oBAAA,SAAAC,EAAAC,GACA,GAAAC,GAAA9jD,KAAA+jD,4BACAC,EAAAF,EAAA,GACAG,EAAAH,EAAA,GAEAjmC,EAAA+lC,EAAAI,EACAlmC,EAAA+lC,EAAAI,CAGA,OADApmC,IAAA7d,KAAAoD,GAAAib,MAAAR,EAAAC,GAAA9d,KAAAoD,GAAAib,MAAAP,EAAAD,GAAA7d,KAAAoD,GAAAgb,OAAAN,GAAA9d,KAAAoD,GAAAgb,QACAP,EAAAC,IAGAsiC,EAAA2D,0BAAA,WACA,GAAA5jB,GAAAngC,KAAAmgC,UAEAphB,EAAA/e,KAAAkkD,YAAAlkD,KAAAkkD,aAAA/jB,EAAAgkB,uBAEA,QAAAplC,EAAAe,KAAAf,EAAAY,IAAAZ,EAAAgB,MAAAhB,EAAAe,KAAAf,EAAAc,OAAAd,EAAAY,MAGAygC,EAAAgE,qCAAA,WACApkD,KAAAkkD,YAAA,MAIA9D,EAAAiE,mBAAA,SAAAxmC,EAAAC,EAAAwmC,EAAAC,GAWA,QAAAC,GAAAz4C,GACA,GAAArK,GAAAqK,EAAApK,QAEA,IAAA,OAAAD,EAAAI,MAAA,OAAAogB,SAAA,CAEA,GAAA8kB,GAAAj7B,EAAAkV,aAAA,EAAAwjC,EACAxd,EAAAl7B,EAAAoV,cAAA,EAAAsjC,EACAC,EAAA1d,EAAA,EACA2d,EAAA1d,EAAA,EACAvpB,EAAAhc,EAAAsb,QAEA,IACAU,EAAAG,EAAA6mC,GAAA7mC,GAAAA,GAAAH,EAAAG,EAAA6mC,GAEAhnC,EAAAI,EAAA6mC,GAAA7mC,GAAAA,GAAAJ,EAAAI,EAAA6mC,EACA,CACA,GAAAtzB,IAAAizB,GAAAv4C,EAAAslB,YAAAtlB,EAAA8lB,aAGA,IAAAyyB,IAAAjzB,EACA,MAGA,IAAAuzB,GAAAvkD,EAAAwkD,WAAA9kD,EAAA+kD,aAAA/4C,GAGA64C,GAAAG,WAAAlnC,EAAAC,EAAA,EAAAkpB,EAAAC,EAAAvpB,EAAAG,EAAAH,EAAAI,IAEAknC,EAAAviD,KAAAsJ,KAMA,QAAAk5C,GAAAx5C,GACA,GAAA/J,GAAA+J,EAAA9J,QAEA,IAAA,OAAAD,EAAAI,MAAA,OAAAogB,SAAA,CAEA,GAQAgjC,GAGAC,EAXAC,EAAA1jD,EAAAqa,SACAja,EAAAJ,EAAAI,MACAklC,EAAAllC,EAAA,MAAA8d,QAAA,EAAAylC,EACAC,EAAAte,EAAAA,EACAue,EAAA,EAAAve,EACA9b,EAAAxpB,EAAA6E,OACA4kB,EAAAzpB,EAAAH,OACAikD,GAAA,EAKAC,EAAA,WACA,GAAA3hD,SAAAqhD,EACA,MAAAA,EAGA,KAAAb,EAEA,MADAa,IAAA,GACA,CAGA,IAAA9zB,GAAA5lB,EAAA4lB,YAAA5lB,EAAAomB,aACA,OAAAR,IACA8zB,GAAA,GACA,IAGAA,GAAA,GACA,GAGA,IAAA,aAAAC,EAAAM,UAAA,aAAAN,EAAAM,UAAA,aAAAN,EAAAM,SAGA,IAAA,GAFA5jC,GAAAsjC,EAAAO,OAEAhlD,EAAA,EAAAA,EAAA,EAAAmhB,EAAA9gB,OAAAL,GAAA,GAEA6kD,EAAAhW,EAAAoW,eAAA/nC,EAAAC,EAAAgE,EAAAnhB,GAAAmhB,EAAAnhB,EAAA,GAAAmhB,EAAAnhB,EAAA,GAAAmhB,EAAAnhB,EAAA,GAAA4kD,KACAE,KACAH,GAAAJ,EAAA1V,EAAAqW,uBAAAhoC,EAAAC,EAAAgE,EAAAnhB,GAAAmhB,EAAAnhB,EAAA,GAAAmhB,EAAAnhB,EAAA,GAAAmhB,EAAAnhB,EAAA,MAEAqkD,EAAAviD,KAAAgJ,OAIA,IAAA,WAAA25C,EAAAM,UAAA,gBAAAN,EAAAM,UAAA,SAAAN,EAAAM,UAAA,aAAAN,EAAAM,SAEA,IAAA,GADA5jC,GAAAsjC,EAAAO,OACAhlD,EAAA,EAAAA,EAAA,EAAAykD,EAAAO,OAAA3kD,OAAAL,GAAA,GAEA6kD,EAAAhW,EAAAsW,iBAAAjoC,EAAAC,EAAAgE,EAAAnhB,GAAAmhB,EAAAnhB,EAAA,GAAAmhB,EAAAnhB,EAAA,GAAAmhB,EAAAnhB,EAAA,GAAAmhB,EAAAnhB,EAAA,GAAAmhB,EAAAnhB,EAAA,GAAA4kD,KACAE,KACAH,GAAAJ,EAAA1V,EAAAuW,4BAAAloC,EAAAC,EAAAgE,EAAAnhB,GAAAmhB,EAAAnhB,EAAA,GAAAmhB,EAAAnhB,EAAA,GAAAmhB,EAAAnhB,EAAA,GAAAmhB,EAAAnhB,EAAA,GAAAmhB,EAAAnhB,EAAA,MAEAqkD,EAAAviD,KAAAgJ,EAMA,IAAA+5C,GAAAC,KAAA,IAAAT,EAAAhkD,QAAAgkD,EAAAA,EAAAhkD,OAAA,KAAAyK,EAcA,IAAA,GAbAyf,GAAAA,GAAAxpB,EAAA6E,OACA4kB,EAAAA,GAAAzpB,EAAAH,OAEAykD,EAAAlkD,EAAA,MAAA8d,QACAqmC,EAAAlmD,EAAA2iD,cAAAsD,GAEAE,IACA3hD,KAAA,SAAAsZ,EAAAunC,EAAAe,YAAAroC,EAAAsnC,EAAAgB,YAAA3F,MAAA2E,EAAAiB,gBACA9hD,KAAA,SAAAsZ,EAAAunC,EAAAkB,UAAAxoC,EAAAsnC,EAAAmB,UAAA9F,MAAA2E,EAAAoB,gBACAjiD,KAAA,aAAAsZ,EAAAunC,EAAAqB,KAAA3oC,EAAAsnC,EAAAsB,KAAAjG,MAAA2E,EAAAuB,mBACApiD,KAAA,aAAAsZ,EAAAunC,EAAAqB,KAAA3oC,EAAAsnC,EAAAsB,KAAAjG,MAAA2E,EAAAwB,mBAGAjmD,EAAA,EAAAA,EAAAulD,EAAAllD,OAAAL,IAAA,CACA,GAAAkmD,GAAAX,EAAAvlD,GACAikD,EAAAvkD,EAAAkgD,YAAAz+C,EAAA+kD,EAAAtiD,KAAA,gBAAAib,MAEA,IACAolC,EAAAnD,aAAA5jC,EAAAC,EAAAmoC,EAAAY,EAAApG,OAAA5iC,EAAAgpC,EAAAhpC,EAAAC,EAAA+oC,EAAA/oC,GAAAunC,IAEAT,EAAArD,QAAA1jC,EAAAC,EAAAmoC,EAAAY,EAAApG,OAAA5iC,EAAAgpC,EAAAhpC,EAAAC,EAAA+oC,EAAA/oC,GAAAunC,GACA,CACAL,EAAAviD,KAAAgJ,EACA,QAMAs/B,GAAAia,EAAAhkD,OAAA,GAAAgkD,EAAAA,EAAAhkD,OAAA,KAAAyK,IACA+4C,EAAAt5B,GACAs5B,EAAAr5B,KAIA,QAAA27B,GAAA7+C,GACA,GAAAvG,GAAAuG,EAAAtG,SACAolD,EAAAC,CAEA,IAAA,OAAAtlD,EAAAI,MAAA,eAAAogB,SAGA,GAAA,UAAAxgB,EAAAqf,OAAA,eAAArf,EAAAI,MAAA,sBAAAogB,SAAA,CAEA,GAAAN,GAAAlgB,EAAAkgB,OACAuB,EAAAvB,EAAAa,WAAA,EAAAskC,EACA7jC,EAAAtB,EAAAc,YAAA,EAAAqkC,EACAlN,EAAAj4B,EAAAe,OACAm3B,EAAAl4B,EAAAgB,OAEAQ,EAAA1hB,EAAAqa,SAAAsH,WACAC,EAAA7T,KAAA6T,IAAAF,GACAG,EAAA9T,KAAA8T,IAAAH,GAEAI,EAAA,SAAA3F,EAAAC,GAIA,MAHAD,IAAAg8B,EACA/7B,GAAAg8B,GAGAj8B,EAAAA,EAAAyF,EAAAxF,EAAAyF,EAAAs2B,EACA/7B,EAAAD,EAAA0F,EAAAzF,EAAAwF,EAAAw2B,IAIAh3B,EAAA+2B,EAAA12B,EAAA,EACAJ,EAAA82B,EAAA12B,EAAA,EACAH,EAAA82B,EAAA52B,EAAA,EACAD,EAAA62B,EAAA52B,EAAA,EAEAO,EAAAD,EAAAV,EAAAE,GACAU,EAAAF,EAAAV,EAAAG,GACAU,EAAAH,EAAAT,EAAAC,GACAY,EAAAJ,EAAAT,EAAAE,GAEA0B,GACAlB,EAAA5F,EAAA4F,EAAA3F,EACA6F,EAAA9F,EAAA8F,EAAA7F,EACA8F,EAAA/F,EAAA+F,EAAA9F,EACA4F,EAAA7F,EAAA6F,EAAA5F,EAGA0xB,GAAAgS,yBAAA3jC,EAAAC,EAAA6G,IACAqgC,EAAAviD,KAAAwF,OAGA,CACA,GAAA8W,GAAA9W,EAAA+W,aACAO,eAAA,EACAgB,cAAA,EACAd,cAAA,GAIAV,GAAAE,IAAA8nC,EACAhoC,EAAAI,IAAA4nC,EACAhoC,EAAAG,IAAA6nC,EACAhoC,EAAAK,IAAA2nC,EACAhoC,EAAA3W,EAAA2W,EAAAG,GAAAH,EAAAE,GACAF,EAAAM,EAAAN,EAAAK,GAAAL,EAAAI,GAEAqwB,EAAAyX,cAAAloC,EAAAlB,EAAAC,IACAknC,EAAAviD,KAAAwF,IAMA,IAAA,GAxNAlI,GAAAC,KACAK,EAAAL,KACAuF,EAAAlF,EAAA6mD,uBACAlC,KACA5mC,EAAA/d,EAAA+C,GAAAgb,OACA2sB,EAAA1qC,EAAA+C,GAAAsb,mBACA2mC,GAAAd,EAAA,GAAA,GAAAnmC,EACAqmC,GAAAF,EAAA,EAAA,GAAAnmC,EACA4oC,GAAAzC,EAAA,EAAA,GAAAnmC,EAgNAzd,EAAA4E,EAAAvE,OAAA,EAAAL,GAAA,EAAAA,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,GACAe,EAAAuG,EAAAtG,QAEA,IAAAqjD,EAAAhkD,OAAA,EAAA,KAEA,WAAAU,EAAAqf,MACAyjC,EAAAv8C,GAGAg9C,EAAAh9C,GAGA6+C,EAAA7+C,GAKA,MAAA+8C,GAAAhkD,OAAA,EACAgkD,EAAAA,EAAAhkD,OAAA,GAEA,MAKAo/C,EAAA+G,YAAA,SAAAloC,EAAAE,EAAAD,EAAAE,GACA,GAAA9X,GAAAtH,KAAAmjD,iBACAh8C,EAAAnH,KAAAojD,iBACAgE,KAEAC,EAAA53C,KAAAkN,IAAAsC,EAAAC,GACAooC,EAAA73C,KAAA9D,IAAAsT,EAAAC,GACAqoC,EAAA93C,KAAAkN,IAAAwC,EAAAC,GACAooC,EAAA/3C,KAAA9D,IAAAwT,EAAAC,EAEAH,GAAAooC,EACAnoC,EAAAooC,EACAnoC,EAAAooC,EACAnoC,EAAAooC,CAOA,KAAA,GALAC,GAAAjY,EAAAM,iBACA7wB,GAAAA,EAAAE,GAAAA,EACAD,GAAAA,EAAAE,GAAAA,IAGAze,EAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IAAA,CACA,GAAAoL,GAAAzE,EAAA3G,GACA+mD,EAAA37C,EAAAiT,aACAuB,cAAA,EACAd,cAAA,EACAF,eAAA,GAGAiwB,GAAAmY,uBAAAF,EAAAC,IACAN,EAAA3kD,KAAA6E,EAAA3G,IAIA,IAAA,GAAAT,GAAA,EAAAA,EAAAiH,EAAAnG,OAAAd,IAAA,CACA,GAAAuL,GAAAtE,EAAAjH,GACAwB,EAAA+J,EAAA9J,SACAyjD,EAAA1jD,EAAAqa,QAEA,KAAA,MAAAqpC,EAAAwC,QAAA,MAAAxC,EAAAyC,QAAArY,EAAAyX,cAAAQ,EAAArC,EAAAwC,OAAAxC,EAAAyC,WACA,MAAAzC,EAAA0C,MAAA,MAAA1C,EAAA2C,MAAAvY,EAAAyX,cAAAQ,EAAArC,EAAA0C,KAAA1C,EAAA2C,OAEA,GAAA,WAAA3C,EAAAM,UAAA,gBAAAN,EAAAM,UAAA,SAAAN,EAAAM,UAAA,aAAAN,EAAAM,UAAA,aAAAN,EAAAM,UAAA,aAAAN,EAAAM,SAAA,CAKA,IAAA,GAHA5jC,GAAApgB,EAAAkgB,OAAAG,WAAArgB,EAAAkgB,OAAAI,SAAAtgB,EAAAkgB,OAAAQ,YACA4lC,GAAA,EAEArnD,EAAA,EAAAA,EAAAmhB,EAAA9gB,OAAAL,IACA,IAAA6uC,EAAAyY,mBAAAR,EAAA3lC,EAAAnhB,IAAA,CACAqnD,GAAA,CACA,OAIAA,GACAZ,EAAA3kD,KAAAgJ,QAGA,aAAA25C,EAAAM,UAAA,aAAAN,EAAAM,WACA0B,EAAA3kD,KAAAgJ,GAKA,MAAA27C,IAWAhH,EAAA0E,aAAA,SAAA/4C,GACA,GAAA1L,GAAAL,KACA8B,EAAAiK,EAAApK,SAAAG,MACA8iD,EAAA9iD,EAAA,MAAA0d,KAEA,IAAAzT,EAAA6O,WACA,MAAA,cAAAgqC,GAAA,mBAAAA,EACAA,EAEA,WAIA,IAAA,YAAAA,EAAA,CACA,GAAAjgC,GAAA7iB,EAAA,wBAAA0d,KAEA,OAAAnf,GAAAwkD,WAAAqD,YAAAvjC,GAAApgB,KAGA,MAAAqgD,IAGAxE,EAAA+H,wBAAA,WACAnoD,KAAAknD,sBAAA,IAGA9G,EAAA8G,qBAAA,SAAAkB,GACA,GAAAC,GAAAroD,KAAAsoD,sBACAC,EAAAvoD,KAAAwoD,sBACAlhD,EAAAtH,KAAAmjD,iBACAh8C,EAAAnH,KAAAojD,iBACA79C,IAEA,KAAA6iD,GAAAC,GAAAE,GAAAF,IAAA/gD,GAAAihD,IAAAphD,EAyBA5B,EAAAvF,KAAAyoD,sBAzBA,CAGA,IAAA,GAAA9nD,GAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IAAA,CACA,GAAAP,GAAAkH,EAAA3G,IAEAP,EAAAsX,YAAAtX,EAAAixB,YAAAjxB,EAAAyxB,gBACAtsB,EAAA9C,KAAArC,GAIA,IAAA,GAAAO,GAAA,EAAAA,EAAAwG,EAAAnG,OAAAL,IAAA,CACA,GAAAT,GAAAiH,EAAAxG,IAEAT,EAAAwX,YAAAxX,EAAAmxB,YAAAnxB,EAAA2xB,gBACAtsB,EAAA9C,KAAAvC,GAIAqF,EAAA4I,KAAAggB,GACAnuB,KAAAyoD,kBAAAljD,EAYA,MAHAvF,MAAAsoD,sBAAAhhD,EACAtH,KAAAwoD,sBAAArhD,EAEA5B,GA4CA66C,EAAAsI,aAAA,SAAAj9C,GACA,GAAA/J,GAAA+J,EAAA9J,SACAyjD,EAAA1jD,EAAAqa,SACA4sC,EAAAvD,EAAAM,QAEA,IAAA,gBAAAiD,GAAA,WAAAA,GAAA,SAAAA,GAAA,aAAAA,EAGA,IAAA,GAAAhoD,IAFAe,EAAAkgB,OAAAG,aAEA,GAAAphB,EAAA,EAAAykD,EAAAO,OAAA3kD,OAAAL,GAAA,EACA4iD,EAAA93C,EAAA25C,EAAAO,OAAA/wC,MAAAjU,EAAAA,EAAA,QAEA,IAAA,aAAAgoD,EAGA,IAAA,GAFAC,GAAAlnD,EAAAkgB,OAAAI,WAEArhB,EAAA,EAAAA,EAAA,EAAAykD,EAAAO,OAAA3kD,OAAAL,GAAA,EACAioD,EAAAnmD,MACAob,EAAAunC,EAAAO,OAAAhlD,GACAmd,EAAAsnC,EAAAO,OAAAhlD,EAAA,SAGA,IAAA,aAAAgoD,EAAA,CACA,GAAAxmC,GAAAijC,EAAAhjC,WAEA1gB,GAAAkgB,OAAAQ,cACAvE,EAAAsE,EAAA,GAAArE,EAAAqE,EAAA,KACAtE,EAAAsE,EAAA,GAAArE,EAAAqE,EAAA,OAKAi+B,EAAAyI,cAAAzI,EAAAsI,aAEAtI,EAAA0I,+BAAA,SAAA/8C,GACA,GAAAg9C,GAAAh9C,EAAApK,SAAAG,MAAA,MAAAogB,QACA,IAAA6mC,IAAAA,EAAA9wC,MAAA,SAAA,CAEA,GAAA+wC,GAAAC,EACAC,EAAAn9C,EAAAkV,aACAkoC,EAAAp9C,EAAAoV,cACAioC,EAAAr9C,EAAApK,SAAAqb,SACAqsC,EAAAt9C,EAAApK,SAAAG,MAAA,eAAAogB,SACAonC,EAAAv9C,EAAApK,SAAAG,MAAA,eAAAogB,SACAkjC,EAAAr5C,EAAApK,SAAAoa,SACA6F,EAAA7V,EAAApK,SAAAigB,MAEA,QAAAynC,GACA,IAAA,OACAL,EAAAI,EAAAvrC,EAAAqrC,EAAA,CACA,MAEA,KAAA,QACAF,EAAAI,EAAAvrC,EAAAqrC,EAAA,CACA,MAEA,SACAF,EAAAI,EAAAvrC,EAGA,OAAAyrC,GACA,IAAA,MACAL,EAAAG,EAAAtrC,EAAAqrC,EAAA,CACA,MAEA,KAAA,SACAF,EAAAG,EAAAtrC,EAAAqrC,EAAA,CACA,MAEA,SACAF,EAAAG,EAAAtrC,EAGAsnC,EAAAziC,OAAAqmC,EACA5D,EAAAxiC,OAAAqmC,EACArnC,EAAAe,OAAAqmC,EACApnC,EAAAgB,OAAAqmC,EAEAjpD,KAAAupD,qBAAAx9C,KAGAq0C,EAAAoJ,+BAAA,SAAA/9C,GACA,GAAAs9C,GAAAt9C,EAAA9J,SAAAG,MAAA,MAAAogB,QACA,IAAA6mC,IAAAA,EAAA9wC,MAAA,SAAA,CAEA,GAAA+wC,GAAAC,EACAvnD,EAAA+J,EAAA9J,SACAyjD,EAAA1jD,EAAAqa,SAEA6F,EAAAlgB,EAAAkgB,MAEAonC,GAAA5D,EAAAqB,KACAwC,EAAA7D,EAAAsB,KAGAtB,EAAAziC,OAAAqmC,EACA5D,EAAAxiC,OAAAqmC,EACArnC,EAAAe,OAAAqmC,EACApnC,EAAAgB,OAAAqmC,EAEAjpD,KAAAupD,qBAAA99C,KAGA20C,EAAAmJ,qBAAA,SAAAthD,GACA,GAAAm9C,GAAAn9C,EAAAtG,SAAAoa,SACA6F,EAAA3Z,EAAAtG,SAAAigB,OAEA6nC,EAAAzpD,KAAA0pD,aAAAzhD,GACA0hD,EAAA3pD,KAAA4pD,yBAAA3hD,EAAAwhD,EAEA7nC,GAAAa,WAAAknC,EAAA3iB,MACAoe,EAAA3iC,WAAAknC,EAAA3iB,MAEAplB,EAAAc,YAAAinC,EAAA1iB,OACAme,EAAA1iC,YAAAinC,EAAA1iB,QAGAmZ,EAAAsJ,aAAA,SAAAzhD,GACA,GAAAnG,GAAAmG,EAAAtG,SAAAG,MACA2nD,EAAAxhD,EAAAtG,SAAAG,MAAA,MAAAogB,SACA2nC,EAAA/nD,EAAA,kBAAA0d,MACAzD,EAAA9T,EAAAtG,SAAAoa,QASA,IAPA,QAAA8tC,IACA,aAAAA,EACAJ,EAAAA,EAAAK,cACA,aAAAD,IACAJ,EAAAA,EAAAM,gBAGA,SAAAjoD,EAAA,aAAA0d,MAAA,CAIA,GAAAzD,EAAAiuC,eAAAjuC,EAAAkuC,SAEA,MAAAluC,GAAAmuC,mBAQA,KAAA,GAJAC,GAAAV,EAAA5jC,MAAA,MACAukC,EAAAtoD,EAAA,kBAAA8d,QACAyqC,KAEAvpD,EAAA,EAAAA,EAAAqpD,EAAAnpD,OAAAF,IAAA,CACA,GAAAwpD,GAAAH,EAAArpD,GACAypD,EAAAvqD,KAAA4pD,yBAAA3hD,EAAAqiD,EAAA,QAAAA,GACAE,EAAAD,EAAAvjB,KAEA,IAAAwjB,EAAAJ,EAAA,CAIA,IAAA,GAHAK,GAAAH,EAAAzkC,MAAA,OACA6kC,EAAA,GAEAtiD,EAAA,EAAAA,EAAAqiD,EAAAzpD,OAAAoH,IAAA,CACA,GAAAuiD,GAAAF,EAAAriD,GACAwiD,EAAA,IAAAF,EAAA1pD,OAAA2pD,EAAAD,EAAA,IAAAC,EACAE,EAAA7qD,KAAA4pD,yBAAA3hD,EAAA2iD,EAAA,YAAAA,GACAE,EAAAD,EAAA7jB,KAEAojB,IAAAU,EACAJ,GAAAC,EAAA,KAEAN,EAAA5nD,KAAAioD,GACAA,EAAAC,EAAA,KAKAD,EAAAzyC,MAAA,UACAoyC,EAAA5nD,KAAAioD,OAGAL,GAAA5nD,KAAA6nD,GAIAvuC,EAAAgvC,qBAAAV,EACAtuC,EAAAmuC,oBAAAT,EAAAY,EAAA7/B,KAAA,MACAzO,EAAAiuC,aAAAjuC,EAAAkuC,SAKA,MAAAR,IAGArJ,EAAAwJ,yBAAA,SAAA3hD,EAAAwhD,EAAAuB,GACA,GAAA3qD,GAAAL,KACA8B,EAAAmG,EAAAtG,SAAAG,MACAmpD,EAAAnpD,EAAA,cAAAogB,SACA5S,EAAAxN,EAAA,aAAA8d,QAAA,KACAsrC,EAAAppD,EAAA,eAAAogB,SAEAtb,EAAA9E,EAAA,eAAAogB,SAEAipC,EAAAljD,EAAAtG,SAAAsoD,QAEAe,KACAG,GAAA,MAAAH,EAGA,IAAAI,GAAA/qD,EAAAgrD,gBAAAhrD,EAAAgrD,iBAEA,IAAAD,EAAAD,GACA,MAAAC,GAAAD,EAGA,IAAAG,GAAAtrD,KAAAurD,YAEAD,KACAA,EAAAtrD,KAAAurD,aAAAxzB,SAAAyzB,cAAA,OACAzzB,SAAA0zB,KAAAC,YAAAJ,GAGA,IAAAK,GAAAL,EAAAxpD,KAiCA,OA9BA6pD,GAAAC,WAAAV,EACAS,EAAAE,UAAAZ,EACAU,EAAArpC,SAAAhT,EAEAq8C,EAAAG,WAAAllD,EAGA+kD,EAAA3uC,SAAA,WACA2uC,EAAA7rC,KAAA,UACA6rC,EAAAhsC,IAAA,UACAgsC,EAAAI,OAAA,KACAJ,EAAAK,WAAA,SACAL,EAAAM,cAAA,OACAN,EAAAjsC,QAAA,IACAisC,EAAAO,WAAA,IAEA,SAAApqD,EAAA,aAAA0d,MACAmsC,EAAAQ,WAAA,MAEAR,EAAAQ,WAAA,SAIAb,EAAAc,YAAA3C,EAEA2B,EAAAD,IACAnkB,MAAAskB,EAAAljB,YACAnB,OAAAqkB,EAAAjjB,cAGA+iB,EAAAD,IAGA/K,EAAA3/B,yBAAA,SAAAlb,GAKA,IAAA,GAJA4B,MACAG,KACA+kD,KAEA1rD,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,GACAe,EAAAuG,EAAAtG,SACAG,EAAAJ,EAAAI,MACAsjD,EAAA1jD,EAAAqa,SACA6F,EAAAlgB,EAAAkgB,OACA5a,EAAAtF,EAAAwG,KAAAlB,GACAslD,EAAA,MAAAlH,EAAAmH,gBAAA7qD,EAAA6qD,iBAAAnH,EAAAmH,eACAC,EAAA,MAAApH,EAAA6E,UAAAvoD,EAAAuoD,WAAA7E,EAAA6E,SACAwC,EAAAH,GAAAE,CAEA,IAAA,UAAA9qD,EAAAqf,MAAA,CACA,GAAArD,GAAAhc,EAAAsb,SACA0vC,EAAA,MAAA9qC,EAAA+qC,OAAA,MAAA/qC,EAAAgrC,OAAAlvC,EAAAG,IAAA+D,EAAA+qC,OAAAjvC,EAAAI,IAAA8D,EAAAgrC,MACAC,EAAA,MAAAjrC,EAAAkrC,OAAAlrC,EAAAkrC,QAAAhrD,EAAA,MAAA8d,QACAmtC,EAAA,MAAAnrC,EAAAorC,OAAAprC,EAAAorC,QAAAlrD,EAAA,OAAA8d,OAEA8sC,IAAAD,GAAAI,GAAAE,GACAzlD,EAAA7E,KAAAwF,GAGA2Z,EAAA+qC,MAAAjvC,EAAAG,EACA+D,EAAAgrC,MAAAlvC,EAAAI,EACA8D,EAAAkrC,MAAAhrD,EAAA,MAAA8d,QACAgC,EAAAorC,MAAAlrD,EAAA,OAAA8d,YACA,CAEA,GAAAqtC,GAAAvrD,EAAA6E,OAAA5E,SAAAqb,SACAkwC,EAAAxrD,EAAAH,OAAAI,SAAAqb,SACAmwC,EAAA,MAAAvrC,EAAAwrC,MAAA,MAAAxrC,EAAAyrC,MAAAJ,EAAApvC,IAAA+D,EAAAwrC,MAAAH,EAAAnvC,IAAA8D,EAAAyrC,KACAC,EAAA,MAAA1rC,EAAA2rC,MAAA,MAAA3rC,EAAA4rC,MAAAN,EAAArvC,IAAA+D,EAAA2rC,MAAAL,EAAApvC,IAAA8D,EAAA4rC,KACAC,EAAAN,GAAAG,CAEA,KAAAG,IAAAhB,EACA,GAAA,WAAArH,EAAAM,UAAA,aAAAN,EAAAM,UAAA,SAAAN,EAAAM,UAAA,aAAAN,EAAAM,UACA,IAAA2G,EAAArlD,GAAA,CACAG,EAAA1E,KAAAwF,GACAokD,EAAArlD,IAAA,CAGA,KAAA,GADA0vB,GAAAzuB,EAAAyuB,gBACA/1B,EAAA,EAAAA,EAAA+1B,EAAA11B,OAAAL,IAAA,CACA,GAAA+sD,GAAAh3B,EAAA/1B,GACAgtD,EAAAD,EAAA/rD,SAAAuG,KAAAlB,EAEAqlD,GAAAsB,KACAxmD,EAAA1E,KAAAirD,GACArB,EAAAsB,IAAA,SAMAxmD,GAAA1E,KAAAwF,EAKA2Z,GAAAwrC,KAAAH,EAAApvC,EACA+D,EAAAyrC,KAAAJ,EAAAnvC,EACA8D,EAAA2rC,KAAAL,EAAArvC,EACA+D,EAAA4rC,KAAAN,EAAApvC,EAIAsnC,EAAAmH,eAAA7qD,EAAA6qD,eACAnH,EAAA6E,SAAAvoD,EAAAuoD,SAGAjqD,KAAA4tD,2BAAAzmD,GACAnH,KAAA6tD,4BAAAvmD,EAAAH,IAGAi5C,EAAAyN,4BAAA,SAAAvmD,EAAAH,GACA,IAAA,GAAAxG,GAAA,EAAAA,EAAA2G,EAAAtG,OAAAL,IACAX,KAAA8oD,+BAAAxhD,EAAA3G,GAGA,KAAA,GAAAA,GAAA,EAAAA,EAAAwG,EAAAnG,OAAAL,IACAX,KAAAwpD,+BAAAriD,EAAAxG,KAIAy/C,EAAAwN,2BAAA,SAAAzmD,GACAnH,KAAA8tD,sBAAA3mD,IAKAi5C,EAAA0N,sBAAA,SAAA3mD,GACA,GAAAA,GAAA,IAAAA,EAAAnG,OAAA,CAYA,IAAA,GADA+sD,GATA1tD,EAAAL,KACAoD,EAAA/C,EAAA+C,GACA2nC,EAAA3nC,EAAAsb,mBACAsvC,KACAC,KACAC,KACAC,KAIAxtD,EAAA,EAAAA,EAAAwG,EAAAnG,OAAAL,IAAA,CACA,GAAA8K,GAAAtE,EAAAxG,GACAe,EAAA+J,EAAA9J,SACAuG,EAAAxG,EAAAwG,KACApG,EAAAJ,EAAAI,MACAssD,EAAAtsD,EAAA,eAAA0d,MACA6uC,EAAA,qBAAAD,GAAA,aAAAA,CAIA,IAAA,SAAAtsD,EAAAgf,QAAAtB,MAQA,GAJA,eAAA1d,EAAA,sBAAAogB,UACAisC,EAAA1rD,KAAAgJ,GAGA,aAAA2iD,EAAA,CAKA,GAAA3hC,GAAAvkB,EAAA3B,OACAmmB,EAAAxkB,EAAA3G,MAEAwsD,GAAAthC,EAAAC,EACAA,EAAA,MAAAD,EACAA,EAAA,MAAAC,EAEA2hC,IACAN,EAAA,eAAA7lD,EAAAlB,IAGA,MAAAgnD,EAAAD,KACAC,EAAAD,MACAE,EAAAxrD,KAAAsrD,IAGAC,EAAAD,GAAAtrD,KAAAgJ,GAEA4iD,IACAL,EAAAD,GAAAO,cAAA,OAvBAJ,GAAAzrD,KAAAgJ,GAiCA,IAAA,GANAyf,GAAAC,EAAAojC,EAAAC,EAAAvB,EAAAC,EAAAuB,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EACAC,EACAC,EAIAjrD,EAAA,EAAAA,EAAAkqD,EAAAjtD,OAAA+C,IAAA,CACAgqD,EAAAE,EAAAlqD,EACA,IAAAkrD,GAAAjB,EAAAD,EAeA,IAZAkB,EAAA9gD,KAAA,SAAAomB,EAAAM,GACA,MAAAN,GAAA5yB,SAAAsM,MAAA4mB,EAAAlzB,SAAAsM,QAGAid,EAAA+jC,EAAA,GAAAttD,SAAA4E,OACA4kB,EAAA8jC,EAAA,GAAAttD,SAAAJ,OAEAgtD,EAAArjC,EAAAvpB,SACA6sD,EAAArjC,EAAAxpB,SAIA4sD,EAAArmD,KAAAlB,GAAAwnD,EAAAtmD,KAAAlB,GAAA,CACA,GAAAmC,GAAA+hB,CACAA,GAAAC,EACAA,EAAAhiB,EAkBA,GAfA8jD,EAAAsB,EAAAvxC,SACAkwC,EAAAsB,EAAAxxC,SAEAyxC,EAAAvjC,EAAAjK,aACAytC,EAAAxjC,EAAA/J,cAEAwtC,EAAAxjC,EAAAlK,aACA2tC,EAAAzjC,EAAAhK,cAEA0tC,EAAAxuD,EAAAwkD,WAAA7kD,KAAA8kD,aAAA55B,IACA4jC,EAAAzuD,EAAAwkD,WAAA7kD,KAAA8kD,aAAA35B,IAEA6jC,GAAA,EAGAC,EAAAjuD,OAAA,GAAAkqB,IAAAC,GAAA8jC,EAAAX,aAAA,CAGA,GAAAY,GAAAL,EAAAM,cACAlC,EAAApvC,EACAovC,EAAAnvC,EACA2wC,EACAC,EACAxB,EAAArvC,EACAqvC,EAAApvC,EACA,GAIAsxC,EAAAN,EAAAK,cACAjC,EAAArvC,EACAqvC,EAAApvC,EACA6wC,EACAC,EACA3B,EAAApvC,EACAovC,EAAAnvC,EACA,GAGAuxC,GACApwC,GAAAiwC,EAAA,GACAhwC,GAAAkwC,EAAA,GACAjwC,GAAA+vC,EAAA,GACA9vC,GAAAgwC,EAAA,IAGAhV,EAAAgV,EAAA,GAAAF,EAAA,GACAlyB,EAAAoyB,EAAA,GAAAF,EAAA,GACApuD,EAAA2O,KAAA+F,KAAAwnB,EAAAA,EAAAod,EAAAA,GAEA1jC;AACAmH,EAAAmf,EACAlf,EAAAs8B,GAGAkV,GACAzxC,EAAAnH,EAAAmH,EAAA/c,EACAgd,EAAApH,EAAAoH,EAAAhd,EAEAiuD,IACAlxC,GAAAyxC,EAAAxxC,EACAA,EAAAwxC,EAAAzxC,IAMAixC,EAAA/J,WAAAmK,EAAA,GAAAA,EAAA,GAAA,EAAAP,EAAAC,EAAA1B,EAAArvC,EAAAqvC,EAAApvC,IACA+wC,EAAA9J,WAAAqK,EAAA,GAAAA,EAAA,GAAA,EAAAX,EAAAC,EAAAzB,EAAApvC,EAAAovC,EAAAnvC,MAEAixC,KACAC,GAAA,GASA,IAAA,GAJAvjD,GACA8jD,EACAnK,EAEAzkD,EAAA,EAAAA,EAAAsuD,EAAAjuD,OAAAL,IAAA,CACA8K,EAAAwjD,EAAAtuD,GACA4uD,EAAA9jD,EAAA9J,SACAyjD,EAAAmK,EAAAxzC,QAEA,IAAAyzC,GAAApK,EAAAqK,cACAC,EAAA/uD,EAEAgvD,EAAAvK,EAAAwK,aACAC,EAAAZ,EAAAjuD,OAEA8uD,EAAAP,EAAAztD,MACAA,EAAAguD,EACA1B,EAAA0B,EAAA,eAAAtwC,MACAuwC,EAAAD,EAAA,2BACAE,EAAAF,EAAA,yBACAG,GAAAF,GAAAC,EAAAvgD,KAAAkN,IAAAozC,EAAAvwC,MAAAxe,OAAAgvD,EAAAxwC,MAAAxe,QAAA,EACAkvD,GAAAJ,EAAA,2BAAAlwC,QACAuwC,GAAArsD,SAAAisD,EAAAA,EAAAnwC,QAAA,GAAA9b,OACAssD,GAAAJ,EAAAxwC,MAAA,GACA6uC,EAAA,qBAAAD,GAAA,aAAAA,EAEAiC,GAAAd,EAAAhpD,SAAA2kB,CAEAmlC,KAAAhC,IACA8B,IAAA,GAGA,IAAAG,IAAAlL,EAAAmL,cACAC,GAAAvD,EAAApvC,EACA4yC,GAAArL,EAAAsL,cACAC,GAAA1D,EAAAnvC,EACA8yC,GAAAxL,EAAAyL,cACAC,GAAA5lC,EAAAjK,aACA8vC,GAAA3L,EAAA4L,cACAC,GAAA/lC,EAAA/J,cAEA+vC,GAAA9L,EAAA+L,cACAC,GAAAlE,EAAArvC,EACAwzC,GAAAjM,EAAAkM,cACAC,GAAArE,EAAApvC,EACA0zC,GAAApM,EAAAqM,cACAC,GAAAvmC,EAAAlK,aACA0wC,GAAAvM,EAAAwM,cACAC,GAAA1mC,EAAAhK,cAEA2wC,GAAA1M,EAAA2M,MACAxM,GAAAuK,EAAA,2BAAAlwC,OAQA,IANAovC,EACA5J,EAAA4J,WAAA,EAEA5J,EAAA4J,WAAA,EAGAsB,KAAAE,IAAAC,KAAAE,IAAAC,KAAAE,IAAAC,KAAAE,IACAC,KAAAE,IAAAC,KAAAE,IAAAC,KAAAE,IAAAC,KAAAE,IACAC,KAAAvM,MACAiK,IAAAE,GAAAC,IAAAE,GAAAxB,GAHA,CAqBA,GAdAjJ,EAAAmL,cAAAC,GACApL,EAAAsL,cAAAC,GACAvL,EAAAyL,cAAAC,GACA1L,EAAA4L,cAAAC,GACA7L,EAAA+L,cAAAC,GACAhM,EAAAkM,cAAAC,GACAnM,EAAAqM,cAAAC,GACAtM,EAAAwM,cAAAC,GACAzM,EAAAqK,cAAAC,EACAtK,EAAAwK,aAAAC,EACAzK,EAAA4M,UAAAzM,GAIAr6B,IAAAC,EAAA,CAGAi6B,EAAAM,SAAA,MAEA,IAAAz4C,IAAAtM,EACAsxD,GAAA/B,EAEA7B,KACAphD,GAAA,EACAglD,GAAA9B,IAGA/K,EAAA8M,SACAjF,EAAApvC,EACAovC,EAAAnvC,GAAA,EAAArO,KAAA6C,IAAAo8C,EAAA,MAAA,KAAAuD,IAAAhlD,GAAA,EAAA,GAEAggD,EAAApvC,GAAA,EAAApO,KAAA6C,IAAAm8C,EAAA,MAAA,KAAAwD,IAAAhlD,GAAA,EAAA,GACAggD,EAAAnvC,OAGA,IACAitB,IACA7f,EAAAtQ,YAAAsQ,EAAArQ,WAAAsQ,EAAAvQ,YAAAuQ,EAAAtQ,aACAqQ,EAAAhR,UAAAlM,QAAAmd,IAAAA,EAAAjR,UAAAlM,QAAAkd,IACA,CAGAk6B,EAAAM,SAAA,WAIAN,EAAA4J,WAAA,CAEA,IAAA/hD,IAAAtM,EACAsxD,GAAA/B,EAEA7B,KACAphD,GAAA,EACAglD,GAAA9B,GAGA,IAAAgC,IAAA,GAEAC,IACAv0C,EAAAovC,EAAApvC,EAAA4wC,EAAA,EACA3wC,EAAAmvC,EAAAnvC,EAAA4wC,EAAA,GAGA2D,IACAx0C,EAAAqvC,EAAArvC,EAAA8wC,EAAA,EACA7wC,EAAAovC,EAAApvC,EAAA8wC,EAAA,GAGA0D,IACAz0C,EAAApO,KAAAkN,IAAAy1C,GAAAv0C,EAAAw0C,GAAAx0C,GACAC,EAAArO,KAAAkN,IAAAy1C,GAAAt0C,EAAAu0C,GAAAv0C,IAIAy0C,GAAA,GACAC,GAAA/iD,KAAA9D,IAAA4mD,GAAA9iD,KAAA4F,IAAA,IAAAo5C,IACAgE,GAAAhjD,KAAA9D,IAAA4mD,GAAA9iD,KAAA4F,IAAA,IAAAs5C,GAEAvJ,GAAA8M,SACAI,GAAAz0C,EACAy0C,GAAAx0C,GAAA,EAAArO,KAAA6C,IAAA6/C,GAAA,MAAA,KAAAF,IAAAhlD,GAAA,EAAA,GAAAulD,GAEAF,GAAAz0C,GAAA,EAAApO,KAAA6C,IAAA6/C,GAAA,MAAA,KAAAF,IAAAhlD,GAAA,EAAA,GAAAwlD,GACAH,GAAAx0C,OAGA,IAAA,aAAAswC,EAAA,CAGAhJ,EAAAM,SAAA,WACAN,EAAAsN,SAMA,KAAA,GAJAC,IAAA7C,EAAA,mBAAAlwC,QACAgzC,GAAA9C,EAAA,qBAAAlwC,QACAizC,GAAApjD,KAAAkN,IAAAg2C,GAAA3xD,OAAA4xD,GAAA5xD,QAEAV,GAAA,EAAAuyD,GAAAvyD,GAAAA,KAAA,CACA,GAAA8H,IAAAuqD,GAAAryD,IACAkK,GAAAooD,GAAAtyD,IASAwyD,GAAA,EAAA1qD,GACA2qD,GAAA3qD,GAEA4qD,IACAn1C,EAAAwxC,EAAApwC,GAAA6zC,GAAAzD,EAAAnwC,GAAA6zC,GACAj1C,EAAAuxC,EAAAlwC,GAAA2zC,GAAAzD,EAAAjwC,GAAA2zC,GAGA3N,GAAAsN,OAAAjwD,KACAuwD,GAAAn1C,EAAAkxC,EAAAlxC,EAAArT,GACAwoD,GAAAl1C,EAAAixC,EAAAjxC,EAAAtT,SAKA,IACAykD,EAAAjuD,OAAA,IAAA,GACAL,IAAA8O,KAAAuF,MAAAi6C,EAAAjuD,OAAA,IACAqtD,EAKA,CAGA,GAAA4E,IAAA5E,CAEAjJ,GAAAM,SAAAuN,GAAA,cAAA,SACA7N,EAAA8M,UAEA,KAAA,GAAA9tD,IAAA,EAAA6rD,GAAA7rD,GAAAA,KAAA,CACA,GACA8uD,IADAC,IAAA,GAAAlE,EAAAjuD,OAAA,EAAAL,GAAAuvD,GAEAkD,GAAA5jB,EAAA6jB,OAAAF,GAEAF,MACA9C,GAAAJ,EAAAA,EAAAnwC,QAAAxb,IAAA8rD,GACAE,GAAAJ,EAAAxwC,MAAApb,KAIA8uD,GADA7E,EACA8B,GAEArsD,SAAAqsD,GAAAiD,GAAAjD,GAAArsD,MAGA,IAAAwvD,IAAAxvD,SAAAovD,GAAAA,GAAAC,GAEAL,IAAAzC,IAAAhC,EAAA,EAAA+B,GAAAA,GACA2C,IAAA1C,IAAAhC,EAAA+B,GAAA,EAAAA,GAEA4C,IACAn1C,EAAAwxC,EAAApwC,GAAA6zC,GAAAzD,EAAAnwC,GAAA6zC,GACAj1C,EAAAuxC,EAAAlwC,GAAA2zC,GAAAzD,EAAAjwC,GAAA2zC,GAGA3N,GAAA8M,QAAAzvD,KACAuwD,GAAAn1C,EAAAkxC,EAAAlxC,EAAAy1C,GACAN,GAAAl1C,EAAAixC,EAAAjxC,EAAAw1C,SAtCAlO,GAAAM,SAAA,UA6CA1lD,MAAAuzD,cAAA9nD,EAEA,IAAA+nD,KAAApyD,EAAA0Q,OAAAszC,EAAAwC,UAAAxmD,EAAA0Q,OAAAszC,EAAAyC,QACA4L,IAAAryD,EAAA0Q,OAAAszC,EAAAe,eAAA/kD,EAAA0Q,OAAAszC,EAAAgB,aACAsN,IAAAtyD,EAAA0Q,OAAAszC,EAAA0C,QAAA1mD,EAAA0Q,OAAAszC,EAAA2C,MACA4L,IAAAvyD,EAAA0Q,OAAAszC,EAAAkB,aAAAllD,EAAA0Q,OAAAszC,EAAAmB,WAEAqN,GAAA,EACAC,GAAA7zD,KAAA0iD,cAAAoN,EAAA,MAAAlwC,SAAA5f,KAAAqgD,iBACAyT,GAAAF,GAAAC,EAEA,IAAA,WAAAzO,EAAAM,SAAA,CACA,GAAAqO,IAAAvkB,EAAA7nC,UAAAkW,EAAAunC,EAAA8M,QAAA,GAAAp0C,EAAAsnC,EAAA8M,QAAA,KAAAr0C,EAAAunC,EAAAwC,OAAA9pC,EAAAsnC,EAAAyC,SACAmM,GAAAF,GAAAC,GACAE,GAAAzkB,EAAA7nC,UAAAkW,EAAAunC,EAAA8M,QAAA,GAAAp0C,EAAAsnC,EAAA8M,QAAA,KAAAr0C,EAAAunC,EAAA0C,KAAAhqC,EAAAsnC,EAAA2C,OACAmM,GAAAJ,GAAAG,GAEAE,IAAA,CAEA,IAAAX,IAAAC,IAAAO,GAAA,CACAG,IAAA,CAIA,IAAAC,KACAv2C,EAAAunC,EAAA8M,QAAA,GAAAjF,EAAApvC,EACAC,EAAAsnC,EAAA8M,QAAA,GAAAjF,EAAAnvC,GAEAu2C,GAAA5kD,KAAA+F,KAAA4+C,GAAAv2C,EAAAu2C,GAAAv2C,EAAAu2C,GAAAt2C,EAAAs2C,GAAAt2C,GACAw2C,IACAz2C,EAAAu2C,GAAAv2C,EAAAw2C,GACAv2C,EAAAs2C,GAAAt2C,EAAAu2C,IAEAvhB,GAAArjC,KAAA9D,IAAA8iD,EAAAC,GACA6F,IACA12C,EAAAunC,EAAA8M,QAAA,GAAA,EAAAoC,GAAAz2C,EAAAi1B,GACAh1B,EAAAsnC,EAAA8M,QAAA,GAAA,EAAAoC,GAAAx2C,EAAAg1B,IAGA0hB,GAAA3F,EAAAM,cACAlC,EAAApvC,EACAovC,EAAAnvC,EACA2wC,EACAC,EACA6F,GAAA12C,EACA02C,GAAAz2C,EACA,EAGAk2C,KACA5O,EAAA8M,QAAA,GAAA9M,EAAA8M,QAAA,GAAAoC,GAAAz2C,GAAAi2C,GAAAC,IACA3O,EAAA8M,QAAA,GAAA9M,EAAA8M,QAAA,GAAAoC,GAAAx2C,GAAAg2C,GAAAC,MAEA3O,EAAA8M,QAAA,GAAAsC,GAAA,GAAAF,GAAAz2C,EAAAi2C,GACA1O,EAAA8M,QAAA,GAAAsC,GAAA,GAAAF,GAAAx2C,EAAAg2C,IAIA,GAAAJ,IAAAC,IAAAO,GAAA,CACAC,IAAA,CAIA,IAAAC,KACAv2C,EAAAunC,EAAA8M,QAAA,GAAAhF,EAAArvC,EACAC,EAAAsnC,EAAA8M,QAAA,GAAAhF,EAAApvC,GAEAu2C,GAAA5kD,KAAA+F,KAAA4+C,GAAAv2C,EAAAu2C,GAAAv2C,EAAAu2C,GAAAt2C,EAAAs2C,GAAAt2C,GACAw2C,IACAz2C,EAAAu2C,GAAAv2C,EAAAw2C,GACAv2C,EAAAs2C,GAAAt2C,EAAAu2C,IAEAvhB,GAAArjC,KAAA9D,IAAA8iD,EAAAC,GACA6F,IACA12C,EAAAunC,EAAA8M,QAAA,GAAA,EAAAoC,GAAAz2C,EAAAi1B,GACAh1B,EAAAsnC,EAAA8M,QAAA,GAAA,EAAAoC,GAAAx2C,EAAAg1B,IAGA2hB,GAAA3F,EAAAK,cACAjC,EAAArvC,EACAqvC,EAAApvC,EACA6wC,EACAC,EACA2F,GAAA12C,EACA02C,GAAAz2C,EACA,EAGAo2C,KACA9O,EAAA8M,QAAA,GAAA9M,EAAA8M,QAAA,GAAAoC,GAAAz2C,GAAAi2C,GAAAG,IACA7O,EAAA8M,QAAA,GAAA9M,EAAA8M,QAAA,GAAAoC,GAAAx2C,GAAAg2C,GAAAG,MAEA7O,EAAA8M,QAAA,GAAAuC,GAAA,GAAAH,GAAAz2C,EAAAi2C,GACA1O,EAAA8M,QAAA,GAAAuC,GAAA,GAAAH,GAAAx2C,EAAAg2C,IAKAK,IAEAn0D,KAAAuzD,cAAA9nD,GAKA,GAAA,gBAAA25C,EAAAM,UAAA,WAAAN,EAAAM,UAAA,SAAAN,EAAAM,UAAA,aAAAN,EAAAM,SAAA,CACAN,EAAAO,UAEAP,EAAAO,OAAAljD,KAAA2iD,EAAAwC,OAAAxC,EAAAyC,OAEA,KAAA,GAAAzjD,IAAA,EAAAA,GAAA,EAAAghD,EAAA8M,QAAAlxD,OAAAoD,IAAA,EAEAghD,EAAAO,OAAAljD,KAAA2iD,EAAA8M,QAAA9tD,IAAAghD,EAAA8M,QAAA9tD,GAAA,IAGAA,GAAA,EAAAghD,EAAA8M,QAAAlxD,QACAokD,EAAAO,OAAAljD,MAAA2iD,EAAA8M,QAAA9tD,IAAAghD,EAAA8M,QAAA9tD,GAAA,IAAA,GAAAghD,EAAA8M,QAAA9tD,GAAA,GAAAghD,EAAA8M,QAAA9tD,GAAA,IAAA,EAIAghD,GAAAO,OAAAljD,KAAA2iD,EAAA0C,KAAA1C,EAAA2C,KAEA,IAAAlc,IAAA6oB,EACA,YAAAtP,EAAAM,UACAN,EAAAqB,KAAAjX,EAAAgU,UAAA4B,EAAAe,YAAAf,EAAA8M,QAAA,GAAA9M,EAAAkB,UAAA,IACAlB,EAAAsB,KAAAlX,EAAAgU,UAAA4B,EAAAgB,YAAAhB,EAAA8M,QAAA,GAAA9M,EAAAmB,UAAA,KACAnB,EAAA8M,QAAAlxD,OAAA,EAAA,IAAA,GACA6qC,GAAAuZ,EAAAO,OAAA3kD,OAAA,EAAA,EAEAokD,EAAAqB,KAAArB,EAAAO,OAAA9Z,IACAuZ,EAAAsB,KAAAtB,EAAAO,OAAA9Z,GAAA,KAEAA,GAAAuZ,EAAAO,OAAA3kD,OAAA,EAAA,EACA0zD,GAAA,GAEAtP,EAAAqB,KAAAjX,EAAAgU,UAAA4B,EAAAO,OAAA9Z,IAAAuZ,EAAAO,OAAA9Z,GAAA,GAAAuZ,EAAAO,OAAA9Z,GAAA,GAAA6oB,IACAtP,EAAAsB,KAAAlX,EAAAgU,UAAA4B,EAAAO,OAAA9Z,GAAA,GAAAuZ,EAAAO,OAAA9Z,GAAA,GAAAuZ,EAAAO,OAAA9Z,GAAA,GAAA6oB,SAGA,IAAA,aAAAtP,EAAAM,SAEAN,EAAAO,QAAAP,EAAAwC,OAAAxC,EAAAyC,OAAAzC,EAAA0C,KAAA1C,EAAA2C,MAGA3C,EAAAqB,MAAArB,EAAAe,YAAAf,EAAAkB,WAAA,EACAlB,EAAAsB,MAAAtB,EAAAgB,YAAAhB,EAAAmB,WAAA,MAEA,IAAA,aAAAnB,EAAAM,SAMA,GALAN,EAAAO,UACAP,EAAAO,OAAAljD,KAAA2iD,EAAAwC,OAAAxC,EAAAyC,QACAzC,EAAAO,OAAAljD,KAAAe,MAAA4hD,EAAAO,OAAAP,EAAAsN,QACAtN,EAAAO,OAAAljD,KAAA2iD,EAAA0C,KAAA1C,EAAA2C,MAEA3C,EAAAsN,OAAA1xD,OAAA,IAAA,EAAA,CACA,GAAA2zD,IAAAvP,EAAAsN,OAAA1xD,OAAA,EACA4zD,GAAAD,GAAA,CAEAvP,GAAAqB,MAAArB,EAAAsN,OAAAkC,IAAAxP,EAAAsN,OAAAiC,KAAA,EACAvP,EAAAsB,MAAAtB,EAAAsN,OAAAkC,GAAA,GAAAxP,EAAAsN,OAAAiC,GAAA,IAAA,MACA,CACA,GAAAC,IAAAxP,EAAAsN,OAAA1xD,OAAA,EAAA,CAEAokD,GAAAqB,KAAArB,EAAAsN,OAAAkC,IACAxP,EAAAsB,KAAAtB,EAAAsN,OAAAkC,GAAA,GAMA50D,KAAA0oD,aAAAj9C,GACAzL,KAAA60D,qBAAAppD,GACAzL,KAAAwpD,+BAAA/9C,KAKA,IAAA,GAAA9K,GAAA,EAAAA,EAAAutD,EAAAltD,OAAAL,IAAA,CACA,GAAA8K,GAAAyiD,EAAAvtD,GACAe,EAAA+J,EAAA9J,SACAG,EAAAJ,EAAAI,MACAia,GAAAra,EAAAqa,SACAqpC,EAAArpC,EAEA,KAAAA,GAAA+4C,SAAA,CACA,GAAArU,IAAA,EAAAhxC,KAAAwF,SAAAxF,KAAAsjC,EAEAh3B,IAAAxV,QACAsX,EAAApO,KAAA6T,IAAAm9B,IACA3iC,EAAArO,KAAA8T,IAAAk9B,IAGA,IAAAA,IAAA,EAAAhxC,KAAAwF,SAAAxF,KAAAsjC,EAEAh3B,IAAAxa,QACAsc,EAAApO,KAAA6T,IAAAm9B,IACA3iC,EAAArO,KAAA8T,IAAAk9B,KAKA,GAAAv1B,GAAAxpB,EAAA6E,OACA4kB,EAAAzpB,EAAAH,OACA0rD,EAAA/hC,EAAAvpB,SAAAqb,SACAkwC,EAAA/hC,EAAAxpB,SAAAqb,SACAyxC,EAAAvjC,EAAA8b,QACA2nB,EAAAxjC,EAAA6b,QACA0nB,EAAAxjC,EAAA+b,SACA2nB,EAAAzjC,EAAA8b,SACA6L,GAAAhxC,EAAA,mBAAA0d,MACAu1C,GAAAjiB,GAAA,CAEAsS,GAAAhjC,YAAAgjC,EAAAO,QACAP,EAAA7+C,OAAAsX,EAAA4wC,EAAAsG,GAAA9H,EAAApvC,EACAunC,EAAA7+C,OAAAuX,EAAA4wC,EAAAqG,GAAA9H,EAAAnvC,EACAsnC,EAAA7jD,OAAAsc,EAAA8wC,EAAAoG,GAAA7H,EAAArvC,EACAunC,EAAA7jD,OAAAuc,EAAA8wC,EAAAmG,GAAA7H,EAAApvC,GAGAsnC,EAAAqB,MAAArB,EAAAO,OAAA,GAAAP,EAAAO,OAAA,IAAA,EACAP,EAAAsB,MAAAtB,EAAAO,OAAA,GAAAP,EAAAO,OAAA,IAAA,EAGA5pC,GAAA2pC,SAAA,WACA3pC,GAAA+4C,UAAA,EAEA90D,KAAA0oD,aAAAj9C,GACAzL,KAAA60D,qBAAAppD,GACAzL,KAAAwpD,+BAAA/9C,GAGA,IAAA,GAAA9K,GAAA,EAAAA,EAAAwtD,EAAAntD,OAAAL,IAAA,CACA,GAAA8K,GAAA0iD,EAAAxtD,GACAykD,EAAA35C,EAAA9J,SAAAoa,QAEAqpC,GAAA/hC,WAAA5T,KAAAulD,KAAA5P,EAAA6P,SAAA7P,EAAA8P,UAGA,MAAAlH,IAGA,IAAAmH,GAAA,SAAAC,EAAAC,GACA,MAAA5lD,MAAA6lD,MAAAD,EAAAD,GAAA3lD,KAAAsjC,GAAA,EAGAqN,GAAAyU,qBAAA,SAAAppD,GACA,GAQA2pD,GAAAC,EACAzN,EAAAC,EAAAC,EAAAC,EATA3C,EAAA35C,EAAA9J,SAAAoa,SACAw5C,EAAA,aAAAnQ,EAAAM,SACA8P,EAAA,gBAAApQ,EAAAM,SACA+P,EAAA,aAAArQ,EAAAM,SACAjO,EAAA,aAAA2N,EAAAM,SACAgQ,EAAA,SAAAtQ,EAAAM,SAMAuH,EAAAxhD,EAAAlF,SAAAyW,WACAkwC,EAAAzhD,EAAAlK,SAAAyb,UAEAu4C,IACA3N,EAAAxC,EAAAhjC,YAAA,GACAylC,EAAAzC,EAAAhjC,YAAA,GACA0lC,EAAA1C,EAAAhjC,YAAA,GACA2lC,EAAA3C,EAAAhjC,YAAA,KAEAwlC,EAAAxC,EAAAe,YACA0B,EAAAzC,EAAAgB,YACA0B,EAAA1C,EAAAkB,UACAyB,EAAA3C,EAAAmB,WAMA6O,EAAAnI,EAAApvC,EAAA+pC,EACAyN,EAAApI,EAAAnvC,EAAA+pC,EAEAzC,EAAAiB,cAAA8O,EAAAC,EAAAC,EAKA,IAAA5O,GAAArB,EAAAqB,KACAC,EAAAtB,EAAAsB,IAUA,IARA6O,IACA9O,GAAAmB,EAAAE,GAAA,EACApB,GAAAmB,EAAAE,GAAA,GAGAqN,EAAAtN,EAAAF,EACAyN,EAAAtN,EAAAF,EAEA6N,EACAN,EAAA,GACAC,EAAA,MACA,IAAAI,EAAA,CACA,GAAA3zC,GAAAsjC,EAAAO,MAEA,IAAA7jC,EAAA9gB,OAAA,EAAA,IAAA,EAAA,CACA,GAAA2zD,GAAA7yC,EAAA9gB,OAAA,EACA4zD,EAAAD,EAAA,CAEAS,GAAAtzC,EAAA6yC,GAAA7yC,EAAA8yC,GACAS,EAAAvzC,EAAA6yC,EAAA,GAAA7yC,EAAA8yC,EAAA,OACA,CACA,GAAAD,GAAA7yC,EAAA9gB,OAAA,EAAA,EACA4zD,EAAAD,EAAA,EACAgB,EAAAhB,EAAA,CAEAS,GAAAtzC,EAAA6yC,GAAA7yC,EAAA8yC,GACAS,EAAAvzC,EAAA6yC,EAAA,GAAA7yC,EAAA8yC,EAAA,QAEA,IAAAY,GAAA/d,EAAA,CACA,GAEAme,GAAAC,EACAC,EAAAC,EAHAj0C,EAAAsjC,EAAAO,OACAqQ,EAAA5Q,EAAA8M,OAIA,IAAA8D,EAAAh1D,OAAA,EAAA,IAAA,EAAA,CACA,GAAAi1D,GAAAn0C,EAAA9gB,OAAA,EAAA,EACAk1D,EAAAD,EAAA,EACAv6B,EAAAw6B,EAAA,CAEAN,GAAApmB,EAAAgU,UAAA1hC,EAAAm0C,GAAAn0C,EAAAo0C,GAAAp0C,EAAA4Z,GAAA,GACAm6B,EAAArmB,EAAAgU,UAAA1hC,EAAAm0C,EAAA,GAAAn0C,EAAAo0C,EAAA,GAAAp0C,EAAA4Z,EAAA,GAAA,GAEAo6B,EAAAtmB,EAAAgU,UAAA1hC,EAAAm0C,GAAAn0C,EAAAo0C,GAAAp0C,EAAA4Z,GAAA,MACAq6B,EAAAvmB,EAAAgU,UAAA1hC,EAAAm0C,EAAA,GAAAn0C,EAAAo0C,EAAA,GAAAp0C,EAAA4Z,EAAA,GAAA,UACA,CACA,GAAAw6B,GAAAp0C,EAAA9gB,OAAA,EAAA,EACAi1D,EAAAC,EAAA,EACAx6B,EAAAw6B,EAAA,CAEAN,GAAApmB,EAAAgU,UAAA1hC,EAAAm0C,GAAAn0C,EAAAo0C,GAAAp0C,EAAA4Z,GAAA,OACAm6B,EAAArmB,EAAAgU,UAAA1hC,EAAAm0C,EAAA,GAAAn0C,EAAAo0C,EAAA,GAAAp0C,EAAA4Z,EAAA,GAAA,OAEAo6B,EAAAtmB,EAAAgU,UAAA1hC,EAAAm0C,GAAAn0C,EAAAo0C,GAAAp0C,EAAA4Z,GAAA,IACAq6B,EAAAvmB,EAAAgU,UAAA1hC,EAAAm0C,EAAA,GAAAn0C,EAAAo0C,EAAA,GAAAp0C,EAAA4Z,EAAA,GAAA,IAGA05B,EAAAU,EAAAF,EACAP,EAAAU,EAAAF,EAcA,GAXAzQ,EAAAwB,iBAAAuO,EAAAC,EAAAC,GAEAjQ,EAAA8P,SAAAE,EACAhQ,EAAA6P,SAAAI,EAKAD,GAAA,GACAC,GAAA,GAEAI,EAAA,CACA,GAAA3zC,GAAAsjC,EAAAO,MAEA,IAAA7jC,EAAA9gB,OAAA,EAAA,IAAA,OAEA,CACA,GAAA2zD,GAAA7yC,EAAA9gB,OAAA,EAAA,EACA20D,EAAAhB,EAAA,CAEAS,KAAAtzC,EAAA6zC,GAAA7zC,EAAA6yC,IACAU,IAAAvzC,EAAA6zC,EAAA,GAAA7zC,EAAA6yC,EAAA,KAIAvP,EAAAuB,iBAAAwO,EAAAC,EAAAC,GAKAD,EAAAlI,EAAArvC,EAAAiqC,EACAuN,EAAAnI,EAAApvC,EAAAiqC,EAEA3C,EAAAoB,cAAA2O,EAAAC,EAAAC,IAIAjV,EAAAmT,cAAA,SAAA9nD,GACA,GACAtD,GAsBAuzB,EAAAC,EAvBAt7B,EAAAL,KAGAuG,EAAAkF,EAAAlF,SAAA,GACAhF,EAAAkK,EAAAlK,SAAA,GAEAgtD,EAAAhoD,EAAA5E,SACA6sD,EAAAjtD,EAAAI,SAEAsrD,EAAAsB,EAAAvxC,SACAkwC,EAAAsB,EAAAxxC,SAEAm5C,EAAA1qD,EAAA9J,SAAAG,MAAA,sBAAA0d,MACA42C,EAAA3qD,EAAA9J,SAAAG,MAAA,sBAAA0d,MAEA4lC,EAAA35C,EAAA9J,SAAAoa,SAEA4sC,EAAAvD,EAAAM,SACA2Q,EAAA,WAAA1N,GAAA,gBAAAA,GAAA,SAAAA,GAAA,aAAAA,EACAsK,EAAA,WAAAtK,EACAwB,EAAA,aAAAxB,GAAA,aAAAA,EACA2N,EAAA,aAAA3N,CAIA,IAAA0N,EAAA,CACA,GAAAE,IAAAnR,EAAA8M,QAAA,GAAA9M,EAAA8M,QAAA,IACAsE,EAAAvD,GAAA7N,EAAA8M,QAAA9M,EAAA8M,QAAAlxD,OAAA,GAAAokD,EAAA8M,QAAA9M,EAAA8M,QAAAlxD,OAAA,IAAAu1D,CAEA76B,GAAA86B,EACA76B,EAAA46B,MACA,IAAApM,EAAA,CACA,GAAAsM,GAAAH,EAAAlR,EAAAsN,OAAA99C,MAAA,EAAA,IAAAs4C,EAAArvC,EAAAqvC,EAAApvC,GACA44C,EAAAJ,EAAAlR,EAAAsN,OAAA99C,MAAAwwC,EAAAsN,OAAA1xD,OAAA,IAAAisD,EAAApvC,EAAAovC,EAAAnvC,EAEA4d,GAAAg7B,EACA/6B,EAAA86B,EAGAtuD,EAAA9H,EAAAwkD,WAAA7kD,KAAA8kD,aAAAvjD,IAAA4tD,cACAjC,EAAArvC,EACAqvC,EAAApvC,EACAvc,EAAA0f,aACA1f,EAAA4f,cACAua,EAAA,GACAA,EAAA,GACA,EAGA,IAAAi7B,GAAAnnB,EAAAonB,oBAAAzuD,EAAAuzB,EACAr7B,EAAAkgD,YAAA4V,GAAAvU,QAAAn2C,IACAorD,EAAArnB,EAAAonB,oBAAAzuD,EAAAuzB,EACAr7B,EAAAkgD,YAAA4V,GAAAtU,IAAAp2C,GAEA25C,GAAA0C,KAAA+O,EAAA,GACAzR,EAAA2C,KAAA8O,EAAA,GAEAzR,EAAAkB,UAAAqQ,EAAA,GACAvR,EAAAmB,UAAAoQ,EAAA,GAEAxuD,EAAA9H,EAAAwkD,WAAA7kD,KAAA8kD,aAAAv+C,IAAA4oD,cACAlC,EAAApvC,EACAovC,EAAAnvC,EACAvX,EAAA0a,aACA1a,EAAA4a,cACAwa,EAAA,GACAA,EAAA,GACA,EAGA,IAAAm7B,GAAAtnB,EAAAonB,oBACAzuD,EAAAwzB,EACAt7B,EAAAkgD,YAAA6V,GAAAxU,QAAAn2C,IAEAsrD,EAAAvnB,EAAAonB,oBACAzuD,EAAAwzB,EACAt7B,EAAAkgD,YAAA6V,GAAAvU,IAAAp2C,GAGA25C,GAAAwC,OAAAmP,EAAA,GACA3R,EAAAyC,OAAAkP,EAAA,GAEA3R,EAAAe,YAAA2Q,EAAA,GACA1R,EAAAgB,YAAA0Q,EAAA,GAEA3M,IACA/oD,EAAA0Q,OAAAszC,EAAAwC,SAAAxmD,EAAA0Q,OAAAszC,EAAAyC,SAAAzmD,EAAA0Q,OAAAszC,EAAA0C,OAAA1mD,EAAA0Q,OAAAszC,EAAA2C,MAGA3C,EAAA4R,SAAA,EAFA5R,EAAA4R,SAAA,IC3pDA5W,EAAAsC,cAAAtC,EAAA6W,eAAA,SAAAC,GACA,GAAA9L,GAAAprD,KAAAm3D,gBAAAn3D,KAAAm3D,oBAEAC,EAAAhM,EAAA8L,EACA,OAAAE,GACAA,GAGAA,EAAA3nD,KAAA9D,IAAA8D,KAAA6C,IAAA,MAAA4kD,EAAA,IAAA,IACA9L,EAAA8L,GAAAE,EAEAA,IAGA33D,EAAAD,QAAA4gD,IAEAiX,4BAAA,GAAA1U,cAAA,GAAAC,gBAAA,KAAA0U,IAAA,SAAAp2D,EAAAzB,EAAAD,GACA,YAEA,IAAA4gD,KAEAA,GAAAmX,eAAA,SAAAC,EAAAC,GACA,GAAAp3D,GAAAL,KxDkmaM03D,EAAar3D,EAAEq3D,WAAar3D,EAAEq3D,cyDvnapC,IAAAA,EAAAF,IAAAE,EAAAF,GAAAG,MACA,MAAAD,GAAAF,GAAAG,KAGA,IAAAvM,GAAAsM,EAAAF,GAAAE,EAAAF,OAEAG,EAAAvM,EAAAuM,MAAA,GAAAC,MAIA,OAHAD,GAAAE,iBAAA,OAAAJ,GACAE,EAAAzsC,IAAAssC,EAEAG,GAGAl4D,EAAAD,QAAA4gD,OAEA0X,IAAA,SAAA52D,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,eACAC,EAAAD,EAAA,iBAEA62D,EAAA,aACAC,EAAAD,EACA3X,EAAA4X,EAAAr1D,SAEAy9C,GAAA9R,iBAAA,aAAA,SAAA,WAAA,kBAAA,gBAAA,kBAEA8R,EAAA1a,KAAA,SAAApgC,GACA,GAAAjF,GAAAL,IAEAK,GAAAiF,QAAAA,EAEAjF,EAAA+C,GAAAkC,EAAAlC,GAEA/C,EAAA8/B,UAAA76B,EAAAlC,GAAA+8B,YAEA9/B,EAAA43D,WAAAn0D,OAAAA,OAAAA,OAAAA,OAAA,GAGAzD,EAAA63D,WAAAC,KAAA,KAAA1pC,KAAA,KACA2pC,SAAA,KAAAC,YAAA,KACAC,UAAA,EACAC,YAAA,KAAA,MAAAC,SAAA,GAEAn4D,EAAAo4D,UAAAC,yBAEAr4D,EAAAs4D,WACAlzD,MAAA,KAAA+yD,SAAA,EAGAr+B,eAAA,KAAA,KAAA,KAAA,KAAA,KAAA,MACAy+B,qBAAA,KACAC,kBAAA,EAEAx/B,KAAA,KAAA,KAAA,KAAA,KAAA,KAAA,MACAy/B,SAAA,KAAA,KAAA,KAAA,KAAA,KAAA,OAGAz4D,EAAA04D,QAAA,EACA14D,EAAA24D,QAAA1zD,EAAA0zD,QAEA34D,EAAAgiC,oBAAA/8B,EAAA+8B,oBACAhiC,EAAAiiC,qBAAAh9B,EAAAg9B,qBACAjiC,EAAAkiC,kBAAAj9B,EAAAi9B,kBACAliC,EAAAmiC,iBAAAl9B,EAAAk9B,iBACAniC,EAAA44D,kBAAA3zD,EAAAm9B,WACApiC,EAAA64D,iBAAA5zD,EAAAq9B,WACAtiC,EAAAoiC,YAAA,EACApiC,EAAAqiC,kBAAAp9B,EAAAo9B,kBACAriC,EAAA84D,uBAAA,EAAA94D,EAAAqiC,kBACAriC,EAAA+4D,kBAAA,EACA/4D,EAAAg5D,YAAA,EACAh5D,EAAAi5D,mBAAA,EACAj5D,EAAAk5D,eAAA,EACAl5D,EAAAm5D,wBACAn5D,EAAAuiC,oBAAAt9B,EAAAs9B,oBACAviC,EAAAo5D,qBAAAn0D,EAAAs9B,oBAAAt9B,EAAAs9B,oBACAviC,EAAAwiC,kBAAAv9B,EAAAu9B,kBACAxiC,EAAAq5D,mBAAAp0D,EAAAu9B,kBAAAv9B,EAAAu9B,kBACAxiC,EAAAs5D,gBAAA,IAEAt5D,EAAAu5D,YAEAv5D,EAAAw5D,qBACAx5D,EAAAigD,sBACAjgD,EAAA+3B,QAGAgoB,EAAA75B,OAAA,SAAAja,GACA,GAAAwtD,GACAz5D,EAAAL,IAGA85D,GADA14D,EAAAitB,MAAA/hB,EAAA1H,MACA0H,EAAA1H,MAGA0H,EAAA1H,KAGA,KAAA,GAAAjE,GAAA,EAAAA,EAAAm5D,EAAA94D,OAAAL,IAAA,CACA,GAAAiE,GAAAk1D,EAAAn5D,EAEA,QAAAiE,GACA,IAAA,UAEA,WADAvE,GAAAkgC,SAGA,KAAA,MACA,IAAA,SACA,IAAA,OACAlgC,EAAAgjD,qBACA,MAEA,KAAA,WACAhjD,EAAA05D,WAAA,UAAA,EACA,MAEA,KAAA,QACA15D,EAAA8nD,2BAIA,SAAAvjD,GAAA,WAAAA,KACAvE,EAAA+jD,uCACA/jD,EAAA25D,gBAAA35D,EAAA8/B,YAIA9/B,EAAA05D,WAAA,QAAA,GACA15D,EAAA05D,WAAA,QAAA,GAEA/5D,KAAAi6D,kBAEAj6D,KAAAk6D,UAGA9Z,EAAA7f,QAAA,WACAvgC,KAAAm6D,WAAA,EAEAn6D,KAAAoD,GAAA41B,mBAEA,KAAA,GAAAr4B,GAAA,EAAAA,EAAAX,KAAA45D,SAAA54D,OAAAL,IAAA,CACA,GAAAy5D,GAAAp6D,KAAA45D,SAAAj5D,GACAyD,EAAAg2D,CAEAh2D,GAAA7C,OAAA84D,oBAAAj2D,EAAAuX,MAAAvX,EAAAsuB,QAAAtuB,EAAAk2D,YAOA,GAJAt6D,KAAAu6D,gBACAv6D,KAAAu6D,eAAAC,aAGAx6D,KAAAurD,aACA,IACAxzB,SAAA0zB,KAAAnoB,YAAAtjC,KAAAurD,cACA,MAAArrD,OCzJAgB,EAAA,kBACAA,EAAA,iBACAA,EAAA,oBACAA,EAAA,YACAA,EAAA,oBACAA,EAAA,iBACAA,EAAA,aACAoK,QAAA,SAAAgI,GACAnS,EAAAS,OAAAw+C,EAAA9sC,KAGA7T,EAAAD,QAAAw4D,IAEArV,cAAA,GAAAE,gBAAA,GAAA4X,iBAAA,GAAAC,gBAAA,GAAAC,mBAAA,GAAAC,WAAA,GAAAC,mBAAA,GAAAC,gBAAA,GAAAC,WAAA,KAAAC,IAAA,SAAA95D,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,eACAC,EAAAD,EAAA,iBACAynC,EAAAznC,EAAA,kBACA2oB,EAAA3oB,EAAA,uBAEAk/C,IAEAA,GAAA6a,gBAAA,SAAA15D,EAAAoa,EAAA+W,EAAA4nC,GACAt6D,KAAA45D,SAAAn3D,MACAlB,OAAAA,EACAoa,MAAAA,EACA+W,QAAAA,EACA4nC,WAAAA,IAGA/4D,EAAAs2D,iBAAAl8C,EAAA+W,EAAA4nC,IAGAla,EAAA8a,gBAAA,SAAAnvD,GACA,MAAA,KAAAA,EAAApK,SAAAG,MAAA,QAAA0d,OACA,WAAAzT,EAAApK,SAAAG,MAAA,WAAA0d,OACA,WAAAzT,EAAApK,SAAAG,MAAA,QAAA0d,QACAzT,EAAAwR,UACAxR,EAAA4Z,aAEA,GAGA,GAGAy6B,EAAAhoB,KAAA,WACA,GAAA/3B,GAAAL,KAEAm7D,EAAA,SAAA55D,EAAAyvB,EAAA9wB,EAAAoT,GACA,MAAA/R,IACAA,EAAAlB,EAAA+C,GAGA,KAAA,GAAAzC,GAAA,EAAAA,EAAAqwB,EAAAhwB,OAAAL,IAAA,CACA,GAAA4D,GAAAysB,EAAArwB,GAEAgb,EAAAgtB,EAAAzoC,EAAAiB,EAAAS,QAAAgD,KAAAL,GAAA+O,GACA/R,GAAAqX,QAAA+C,KAIAy/C,EAAA,SAAAl7D,GACA,MAAAA,GAAAm7D,UAAAn7D,EAAAo7D,SAAAp7D,EAAAq7D,SAGAC,EAAA,SAAAh6D,GACA,GAAAi6D,EAEA,IAAAj6D,EAAAk6D,WAAAr7D,EAAA+C,GAAAsb,mBAAA,CACA,IAAAld,EAAAk6D,UAAAC,MAAA,CACAn6D,EAAAk6D,UAAAC,QAEA,KAAA,GAAAh7D,GAAA,EAAAA,EAAAa,EAAAk6D,UAAA16D,OAAAL,IAAA,CACA,GAAAsH,GAAAzG,EAAAk6D,UAAA/6D,EAEAa,GAAAk6D,UAAAC,MAAA1zD,EAAAjB,OAAA,GAIAy0D,EAAAj6D,EAAAk6D,UAAAC,MAGA,MAAAF,QAKAG,EAAA,SAAA7vD,EAAAvK,GACA,GAAAuK,EAAApK,SAAAyB,GAAAsb,qBAIA,MAAAld,EAAAq6D,aAAA,MAAAr6D,EAAAk6D,WAMA,IAAA,GAJAD,GAAAD,EAAAh6D,GAEAs6D,EAAA/vD,EAAA+O,cAEAna,EAAA,EAAAA,EAAAm7D,EAAAxsD,OAAA3O,IAAA,CACA,GAAAo7D,GAAAD,EAAAn7D,GACAe,EAAAq6D,EAAAp6D,QAEAH,GAAAq6D,cACAn6D,EAAAqa,SAAA8/C,aAAA,GAGAr6D,EAAAk6D,YAAAD,EAAAM,EAAA/0D,QACAxF,EAAAk6D,UAAAj5D,KAAAs5D,GACAN,EAAAM,EAAA/0D,OAAA,EAEAtF,EAAAgkB,SAAA,EAIA,KAAA,GADAve,GAAAzF,EAAAyF,MACA8F,EAAA,EAAAzL,EAAAq6D,aAAA5uD,EAAA9F,EAAAnG,OAAAiM,IACA9F,EAAA8F,GAAAtL,SAAAoa,SAAA8/C,aAAA,IAMAG,EAAA,SAAAjwD,EAAAvK,GAEA,GAAAE,GAAAqK,EAAApK,SACA85D,EAAAD,EAAAh6D,EAEAA,GAAAq6D,cACAn6D,EAAAqa,SAAA8/C,aAAA,GAGAr6D,EAAAk6D,YAAAD,EAAA1vD,EAAA/E,QACAxF,EAAAk6D,UAAAj5D,KAAAsJ,GACA0vD,EAAA1vD,EAAA/E,OAAA,EAEAtF,EAAAgkB,SAAA,EAIA,KAAA,GADAve,GAAAzF,EAAAyF,MACAxG,EAAA,EAAAa,EAAAq6D,aAAAl7D,EAAAwG,EAAAnG,OAAAL,IACAwG,EAAAxG,GAAAgB,SAAAoa,SAAA8/C,aAAA,CAGAD,GAAA7vD,EAAAvK,GAGAy6D,EAAAlwD,GACA8vD,YAAAr6D,EAAAq6D,eAIAK,EAAA,SAAAC,GACA,GAAAA,EAEA,IAAA,GAAAx7D,GAAA,EAAAA,EAAAw7D,EAAAn7D,OAAAL,IAAA,CAEA,GAAAy7D,GAAAD,EAAAx7D,GAAAgB,QAEA,IAAA,UAAAy6D,EAAAr7C,MAAA,CACAq7C,EAAArgD,SAAA8/C,aAAA,EACAO,EAAA12C,SAAA,CAGA,KAAA,GADA22C,GAAAD,EAAAj1D,MACA8F,EAAA,EAAAA,EAAAovD,EAAAr7D,OAAAiM,IAAAovD,EAAApvD,GAAAtL,SAAAoa,SAAA8/C,aAAA,CAGAI,GAAAE,EAAAx7D,IAAAk7D,aAAA,QAEA,UAAAO,EAAAr7C,QACAq7C,EAAArgD,SAAA8/C,aAAA,KAQAI,EAAA,SAAAlwD,EAAAvK,GAEA,GAAA,MAAAA,EAAAq6D,aAAA,MAAAr6D,EAAAk6D,UAAA,CAGA,GAAAzhD,GAAAlO,CAEA,IAAAA,EAAApK,SAAAyB,GAAAsb,mBAAA,CAIA,KAAAzE,EAAAA,SAAAE,YACAF,EAAAA,EAAAA,SAAA,EAIA,IAAAA,GAAAlO,EAAA,CAcA,IAAA,GAVAzE,GAAA2S,EAAAa,cACA6M,MAAA1N,GACAiO,QAAAnc,GACAmc,QAAAnc,EAAA+O,eAGA3T,EAAAG,EAAAU,iBAEAyzD,EAAAD,EAAAh6D,GAEAb,EAAA,EAAAA,EAAA2G,EAAAgI,OAAA3O,IACAmD,SAAAtC,EAAAq6D,cACAv0D,EAAA3G,GAAAgB,SAAAoa,SAAA8/C,YAAAr6D,EAAAq6D,aAGAr6D,EAAAk6D,YAAAD,EAAAn0D,EAAA3G,GAAAqG,QACAxF,EAAAk6D,UAAAj5D,KAAA6E,EAAA3G,IACA86D,EAAAn0D,EAAA3G,GAAAqG,OAAA,EAEAM,EAAA3G,GAAAgB,SAAA+jB,SAAA,EAIA,KAAA,GAAAzY,GAAA,EAAAnJ,SAAAtC,EAAAq6D,aAAA5uD,EAAA9F,EAAAnG,OAAAiM,IACA9F,EAAA8F,GAAAtL,SAAAoa,SAAA8/C,YAAAr6D,EAAAq6D,eAIA,oBAAAS,mBACAj8D,EAAAk6D,eAAA,GAAA+B,kBAAA,SAAAC,GACA,IAAA,GAAA57D,GAAA,EAAAA,EAAA47D,EAAAv7D,OAAAL,IAAA,CACA,GAAA67D,GAAAD,EAAA57D,GACA87D,EAAAD,EAAAE,YAEA,IAAAD,EAAA,IAAA,GAAAxvD,GAAA,EAAAA,EAAAwvD,EAAAz7D,OAAAiM,IAAA,CACA,GAAA0vD,GAAAF,EAAAxvD,EAEA,IAAA0vD,IAAAt8D,EAAA8/B,UAAA,CACA9/B,EAAAkgC,SACA,YAMAlgC,EAAA8/B,UAAAy8B,YACAv8D,EAAAk6D,eAAAsC,QAAAx8D,EAAA8/B,UAAAy8B,YAAAE,WAAA,KAGAz8D,EAAA46D,gBAAA56D,EAAA8/B,UAAA,iBAAA,SAAAjgC,GACAG,EAAAkgC,YAOAlgC,EAAA46D,gBAAAp7D,OAAA,SAAAsB,EAAA47D,SAAA,SAAA78D,GACAG,EAAA+jD,uCAEA/jD,EAAA25D,gBAAA35D,EAAA8/B,WACA9/B,EAAA05D,WAAA,QAAA,GACA15D,EAAA65D,UACA,KAUA,KARA,GAAA8C,GAAA,SAAA55B,GACA/iC,EAAA46D,gBAAA73B,EAAA,SAAA,SAAAljC,GACAG,EAAA+jD,0CAIA6Y,EAAA58D,EAAA+C,GAAA+8B,YAIA68B,EAAAC,GAEAA,EAAAL,YACAK,EAAAA,EAAAL,UAQAv8D,GAAA46D,gBAAA56D,EAAA8/B,UAAA,cAAA,SAAAjgC,GACAA,EAAA+rC,kBAGA,IAAAixB,GAAA,WACA,MAAA,KAAA78D,EAAA43D,UAAA,GAIA53D,GAAA46D,gBAAA56D,EAAA8/B,UAAA,YAAA,SAAAjgC,GACAA,EAAA+rC,iBACA5rC,EAAA63D,UAAAM,SAAA,EACAn4D,EAAA63D,UAAAiF,MAAAj9D,EAAAi9D,KAEA,IAAA/5D,GAAA/C,EAAA+C,GACAsa,EAAArd,EAAAsjD,oBAAAzjD,EAAA0jD,QAAA1jD,EAAA2jD,SACAuZ,EAAA/8D,EAAA43D,UACAjT,EAAA3kD,EAAAgkD,mBAAA3mC,EAAA,GAAAA,EAAA,IAAA,GAAA,GACAy+C,EAAA97D,EAAAo4D,SAAAC,oBAEAr4D,GAAA63D,UAAAmF,SAAA3/C,CAEA,IAAA4/C,GAAA,WACAj9D,EAAA63D,UAAAqF,kBAAA,EAEAC,aAAAn9D,EAAA63D,UAAAuF,gBAEAp9D,EAAA63D,UAAAuF,eAAAlkD,WAAA,WAEA,IAAAlZ,EAAA63D,UAAAqF,iBAAA,CAGA,GAAAt1D,GAAA5H,EAAA63D,UAAAC,IAEAlwD,GACAA,EAAA2Q,QAAA+vB,EAAAzoC,GACA0E,KAAA,UACA0mC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,OAGAta,EAAAwV,QAAA+vB,EAAAzoC,GACA0E,KAAA,UACA0mC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,SAKArd,EAAAs5D,iBAIA,IAAA,GAAAz5D,EAAAi9D,MAAA,CAEA98D,EAAA63D,UAAAwF,YAAA,CAEA,IAAAC,GAAAh1B,EAAAzoC,GACA0E,KAAA,cACA0mC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,KAGAsnC,IACAA,EAAA4Y,WACA5Y,EAAApsC,QAAA+kD,GAEAt9D,EAAA63D,UAAAC,KAAAnT,GAEA5hD,EAAAwV,QAAA+kD,GAGAt9D,EAAA63D,UAAAE,UAAA,GAAAhrB,OAAAywB,UACAx9D,EAAA63D,UAAA4F,YAAA,MAGA,IAAA,GAAA59D,EAAAi9D,MAAA,CASA,GAPAnY,GACAA,EAAA4Y,WAMA,MAAA5Y,GAEA3kD,EAAA66D,gBAAAlW,GAAA,CAEA,GAAA+Y,GAAAp1B,EAAAzoC,GACA0E,KAAA,OACA0mC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,KAGA,IAAAsnC,EAAA93C,WAAA83C,EAAAx/B,WAEA22C,EAAA97D,EAAAo4D,SAAAC,wBACAsD,EAAAhX,GAAA0W,UAAAS,IAEAnX,EAAApsC,QAAAmlD,OAEA,IAAA/Y,EAAA93C,UAAA83C,EAAAx/B,WAAA,CACA22C,EAAA97D,EAAAo4D,SAAAC,uBAIA,KAAA,GAFAsF,GAAA56D,EAAAmI,EAAA,WAAA,MAAAvL,MAAAkN,UAAAlN,KAAAwlB,aAEA7kB,EAAA,EAAAA,EAAAq9D,EAAAh9D,OAAAL,IAGAN,EAAA66D,gBAAA8C,EAAAr9D,KACAq7D,EAAAgC,EAAAr9D,IAAA+6D,UAAAS,GAIAnX,GAAApsC,QAAAmlD,GAGA19D,EAAA05D,WAAA,QAAA,GACA15D,EAAA05D,WAAA,QAAA,GAMA15D,EAAA63D,UAAAC,KAAAnT,EACA3kD,EAAA63D,UAAAE,UAAA,GAAAhrB,OAAAywB,UAGA1C,EAAAnW,GAAA,YAAA,WAAA,cAAA9kD,GACAorC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,MAGA,MAAAsnC,GACAoY,EAAA,GAAA,EAEA/8D,EAAA6H,KAAA+1D,mBACApgD,EAAAH,EAAA,GACAI,EAAAJ,EAAA,IAGArd,EAAA05D,WAAA,UAAA,GAEA15D,EAAA65D,UACAlV,EAAA3jC,WACA+7C,EAAA,GAAA,GAGAE,IAKAF,EAAA,GAAAA,EAAA,GAAA1/C,EAAA,GACA0/C,EAAA,GAAAA,EAAA,GAAA1/C,EAAA,KAEA,GAEArd,EAAA46D,gBAAAp7D,OAAA,YAAA,SAAAK,GACA,GAAA+rC,IAAA,EACAusB,EAAAn4D,EAAA63D,UAAAM,OAGA,KAAAA,EAAA,CACA,GAAA0F,GAAA79D,EAAA0jD,2BAEA,MAAA7jD,EAAA0jD,QAAAsa,EAAA,IAAAh+D,EAAA0jD,QAAAsa,EAAA,GAAA79D,EAAA89D,aACAj+D,EAAA2jD,QAAAqa,EAAA,IAAAh+D,EAAA2jD,QAAAqa,EAAA,GAAA79D,EAAA+9D,cAIA,MAQA,KALA,GAAAC,GAAAh+D,EAAA8/B,UACA5+B,EAAArB,EAAAqB,OACA+8D,EAAA/8D,EAAAq7D,WACA2B,GAAA,EAEAD,GAAA,CACA,GAAAA,IAAAD,EAAA,CACAE,GAAA,CACA,OAGAD,EAAAA,EAAA1B,WAGA,IAAA2B,EAAA,OAGA,GAAAn7D,GAAA/C,EAAA+C,GACAgb,EAAAhb,EAAAgb,OACAV,EAAArd,EAAAsjD,oBAAAzjD,EAAA0jD,QAAA1jD,EAAA2jD,SACAuZ,EAAA/8D,EAAA43D,UAEAjT,EAAA,IACA3kD,GAAA63D,UAAAsG,eACAxZ,EAAA3kD,EAAAgkD,mBAAA3mC,EAAA,GAAAA,EAAA,IAAA,GAAA,GAEA,IAAA+Q,GAAApuB,EAAA63D,UAAAzpC,KACA0pC,EAAA93D,EAAA63D,UAAAC,KAEAsG,GAAA/gD,EAAA,GAAA0/C,EAAA,GAAA1/C,EAAA,GAAA0/C,EAAA,IAEAjB,EAAA97D,EAAAo4D,SAAAC,qBAEA17B,EAAAogC,EAAA,GAAAA,EAAA,GACAsB,EAAA1hC,EAAAA,EACAod,EAAAgjB,EAAA,GAAAA,EAAA,GACAuB,EAAAvkB,EAAAA,EACAwkB,EAAAF,EAAAC,EACAE,EAAAD,EAAAxgD,EAAAA,EAEA0gD,EAAA1D,EAAAl7D,EAEAG,GAAA63D,UAAAqF,kBAAA,CAEA,IAAAwB,GAAA,WACA,GAAAC,GAAA3+D,EAAA63D,UAAA8G,UAAA3+D,EAAA63D,UAAA8G,aAEA,KAAAA,EAAAh+D,QACAg+D,EAAAv8D,KAAAg8D,EAAA,IACAO,EAAAv8D,KAAAg8D,EAAA,MAEAO,EAAA,IAAAP,EAAA,GACAO,EAAA,IAAAP,EAAA,IAYA,IAPAxyB,GAAA,EAEAkvB,EAAAnW,GAAA,YAAA,aAAA,WAAA9kD,GACAorC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,MAIA,IAAArd,EAAA63D,UAAAiF,MAAA,CACA,GAAAQ,GAAAh1B,EAAAzoC,GACA0E,KAAA,UACA0mC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,KAGAy6C,GACAA,EAAAv/C,QAAA+kD,GAEAv6D,EAAAwV,QAAA+kD,GAGAt9D,EAAA63D,UAAA4F,YAAA,EAEAz9D,EAAA63D,UAAA+G,SAAAja,IAAA3kD,EAAA63D,UAAA+G,UAEA5+D,EAAA63D,UAAA+G,SACA5+D,EAAA63D,UAAA+G,QAAArmD,QAAA+vB,EAAAzoC,GACA0E,KAAA,aACA0mC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,OAIArd,EAAA63D,UAAA+G,QAAAja,EAEAA,GACAA,EAAApsC,QAAA+vB,EAAAzoC,GACA0E,KAAA,cACA0mC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,YAOA,IAAArd,EAAA63D,UAAAI,SAAA,CAGA,GAFArsB,GAAA,EAEA7oC,EAAAk+B,kBAAAl+B,EAAAm+B,qBAAA,CACA,GAAA29B,EAEA,IAAA7+D,EAAA63D,UAAAiH,eAAA,CACA,GAAAC,GAAA/+D,EAAA63D,UAAAmF,QAEA6B,IACArhD,GAAAH,EAAA,GAAA0hD,EAAA,IAAAhhD,EACAN,GAAAJ,EAAA,GAAA0hD,EAAA,IAAAhhD,GAGA/d,EAAA63D,UAAAiH,gBAAA,MAGAD,IACArhD,EAAA4gD,EAAA,GAAArgD,EACAN,EAAA2gD,EAAA,GAAArgD,EAKAhb,GAAAujC,MAAAu4B,GAEA7+D,EAAA63D,UAAAmH,SAAA,EAIA3hD,EAAArd,EAAAsjD,oBAAAzjD,EAAA0jD,QAAA1jD,EAAA2jD,aAGA,IACA,GAAAuZ,EAAA,IAAA,MAAAjF,IAAAA,EAAA92C,SA0BA,CAoBA,GAnBA82C,GAAAA,EAAA92C,UAAA82C,EAAAvyC,UAAAuyC,EAAAmH,aAEAta,GAAAv2B,IAEAA,GACA0sC,EAAA1sC,GAAA,WAAA,cAAAvuB,GACAorC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,MAIAsnC,GACAmW,EAAAnW,GAAA,YAAA,eAAA9kD,GACAorC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,MAIArd,EAAA63D,UAAAzpC,KAAAu2B,GAGAmT,GAAAA,EAAAjrD,UAAA7M,EAAA66D,gBAAA/C,GAEA,GAAA0G,GAAAx+D,EAAAo5D,qBAAA,CAEA,GAAA8F,IAAAl/D,EAAAo4D,SAAA+G,OAEAD,IACAl/D,EAAA05D,WAAA,QAAA,GAGA15D,EAAAo4D,SAAA+G,SAAA,CAIA,KAAA,GAFAzhD,MAEApd,EAAA,EAAAA,EAAAw7D,EAAAn7D,OAAAL,IAAA,CACA,GAAA8+D,GAAAtD,EAAAx7D,EAQA,IALAN,EAAA63D,UAAAsG,cACAxC,EAAAyD,GAAA5D,aAAA,IAIA4D,EAAAvyD,UAAA7M,EAAA66D,gBAAAuE,IAAAA,EAAA/5C,UAAA,CACA,GAAAg6C,GAAAD,EAAA99D,SAAAqb,QAIA,IAFAe,EAAAtb,KAAAg9D,GAEAr+D,EAAA0Q,OAAA2sD,EAAA,KAAAr9D,EAAA0Q,OAAA2sD,EAAA,IAAA,CACA,GAAAkB,IAAAF,EAAA7kD,UAOA,IALA+kD,IACAD,EAAA7hD,GAAA4gD,EAAA,GACAiB,EAAA5hD,GAAA2gD,EAAA,IAGAc,EAAA,CACA,GAAAP,GAAA3+D,EAAA63D,UAAA8G,SAEAW,IAAAv+D,EAAA0Q,OAAAktD,EAAA,KAAA59D,EAAA0Q,OAAAktD,EAAA,MACAU,EAAA7hD,GAAAmhD,EAAA,GACAU,EAAA5hD,GAAAkhD,EAAA,OAQA3+D,EAAA63D,UAAAsG,cAAA,CAEA,IAAAoB,GAAA/1C,EAAAzmB,EAAA2a,EAEA6hD,GAAAxiD,uBACAwiD,EAAAhnD,QAAA,iBAEAvY,EAAA05D,WAAA,QAAA,GACA15D,EAAA65D,aAGA6E,IAKA9yB,IAAA,MA5GA5rC,GAAA63D,UAAAI,WAAAl1D,EAAAo+B,wBAAAs9B,GAAA17D,EAAAk+B,kBAAAl+B,EAAAm+B,sBAOAlhC,EAAA63D,UAAA2H,WAAAz8D,EAAAk+B,kBAAAl+B,EAAAm+B,uBACAlhC,EAAA63D,UAAAI,UAAA,EACAj4D,EAAA63D,UAAAiH,gBAAA,EACA/B,EAAA,GAAA,EAEA/8D,EAAA6H,KAAA+1D,mBACApgD,EAAAH,EAAA,GACAI,EAAAJ,EAAA,IAGArd,EAAA05D,WAAA,UAAA,GACA15D,EAAA65D,WAjBA75D,EAAA6H,KAAA+1D,kBAAAn6D,OACAzD,EAAA63D,UAAA2H,WAAA,EAEAx/D,EAAA05D,WAAA,UAAA,GACA15D,EAAA65D,UAgBA/B,GAAAA,EAAA92C,UAAA82C,EAAAvyC,UAAAuyC,EAAAmH,YA4FA,OAFAlC,GAAA,GAAA1/C,EAAA,GAAA0/C,EAAA,GAAA1/C,EAAA,GAEAuuB,GACA/rC,EAAA8rC,iBAAA9rC,EAAA8rC,kBACA9rC,EAAA+rC,gBAAA/rC,EAAA+rC,kBACA,GAHA,SAKA,GAEA5rC,EAAA46D,gBAAAp7D,OAAA,UAAA,SAAAK,GACA,GAAAs4D,GAAAn4D,EAAA63D,UAAAM,OACA,IAAAA,EAAA,CACAn4D,EAAA63D,UAAAM,SAAA,CAEA,IAAAp1D,GAAA/C,EAAA+C,GAAAsa,EAAArd,EAAAsjD,oBAAAzjD,EAAA0jD,QAAA1jD,EAAA2jD,SAAAuZ,EAAA/8D,EAAA43D,UACAjT,EAAA3kD,EAAAgkD,mBAAA3mC,EAAA,GAAAA,EAAA,IAAA,GAAA,GACAy+C,EAAA97D,EAAAo4D,SAAAC,qBAAAP,EAAA93D,EAAA63D,UAAAC,KACA2G,EAAA1D,EAAAl7D,EAeA,IAbAG,EAAA6H,KAAA+1D,oBACA59D,EAAA05D,WAAA,UAAA,GACA15D,EAAA65D,UAGA75D,EAAA63D,UAAAqF,kBAAA,EAEAl9D,EAAA6H,KAAA+1D,kBAAAn6D,OAEAq0D,GACAA,EAAAmH,aAGA,IAAAj/D,EAAA63D,UAAAiF,MAAA,CACA,GAAAQ,GAAAh1B,EAAAzoC,GACA0E,KAAA,YACA0mC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,KASA,IANAy6C,EACAA,EAAAv/C,QAAA+kD,GAEAv6D,EAAAwV,QAAA+kD,IAGAt9D,EAAA63D,UAAA4F,WAAA,CACA,GAAAgC,GAAAn3B,EAAAzoC,GACA0E,KAAA,SACA0mC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,KAGAy6C,GACAA,EAAAv/C,QAAAknD,GAEA18D,EAAAwV,QAAAknD,GAIAz/D,EAAA63D,UAAA4F,YAAA,EACAz9D,EAAA63D,UAAAiF,MAAA,SAEA,IAAA,IAAA98D,EAAA63D,UAAAiF,MAAA,CAyDA,GAtDA,MAAAhF,GACA93D,EAAAo4D,SAAA+G,SACAn/D,EAAA63D,UAAA2H,WACAx/D,EAAA63D,UAAAmH,SACAjE,EAAAl7D,KAGAkD,EAAAmI,EAAA,WACA,MAAAvL,MAAAwlB,aACA8N,WAEA6oC,EAAAn7D,OAAA,GACAX,EAAA05D,WAAA,QAAA,GAGA15D,EAAAo4D,SAAAC,qBAAAyD,MAGAhB,EAAAnW,GAAA,UAAA,SAAA,YAAA9kD,GACAorC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,MAIArd,EAAAo4D,SAAA+G,SACAn/D,EAAA63D,UAAAmH,SAEAlE,EAAAnW,GAAA,QAAA,MAAA,UAAA9kD,GACAorC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,MAKAsnC,GAAAmT,GAAA93D,EAAAo4D,SAAA+G,SAAAn/D,EAAA63D,UAAA2H,WACA,MAAA7a,GAAAA,EAAArjD,SAAA8jB,aAEAplB,EAAA63D,UAAAI,WAEA,aAAAl1D,EAAAy+B,iBAAAi9B,EACA9Z,EAAAx/B,WACAw/B,EAAA1xB,WAEA0xB,EAAAoY,SAGA0B,IACA17D,EAAAmI,EAAA,aAAA2c,QAAA88B,GAAA1xB,WACA0xB,EAAAoY,WAIA/8D,EAAA05D,WAAA,QAAA,IAIA15D,EAAA63D,UAAA2H,UAAA,CACA,GAAAE,MACA3Y,EAAA/mD,EAAA8mD,YAAAiW,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAEA/8D,GAAA05D,WAAA,UAAA,GAEA3S,EAAApmD,OAAA,GACAX,EAAA05D,WAAA,QAAA,EAGA,KAAA,GAAAp5D,GAAA,EAAAA,EAAAymD,EAAApmD,OAAAL,IACAymD,EAAAzmD,GAAAgB,SAAA8jB,YACAs6C,EAAAt9D,KAAA2kD,EAAAzmD,GAIA,IAAAq/D,GAAAn2C,EAAAzmB,EAAA28D,EAEA,cAAA38D,EAAAy+B,gBACAm+B,EAAA5C,UAEA0B,GACA17D,EAAAmI,EAAA,aAAA2c,QAAA83C,GAAA1sC,WAGA0sC,EAAA5C,UAIA/8D,EAAA65D,SAKA75D,EAAA63D,UAAAI,WACAj4D,EAAA63D,UAAAI,UAAA,EAEAj4D,EAAA05D,WAAA,UAAA,GACA15D,EAAA05D,WAAA,QAAA,GAEA15D,EAAA65D,UAGAkD,EAAA,KAGA/8D,EAAA05D,WAAA,QAAA,GACA15D,EAAA05D,WAAA,QAAA,GAEAmC,EAAAC,GAEAhE,GAAAA,EAAAv/C,QAAA,SAKAwkD,EAAA,GAAA,EAAA/8D,EAAA63D,UAAAC,KAAA,KAEA93D,EAAA63D,UAAAwF,YAAA,EACAr9D,EAAA63D,UAAAsG,cAAA,EACAn+D,EAAA63D,UAAA2H,WAAA,EACAx/D,EAAAo4D,SAAA+G,SAAA,EACAn/D,EAAA63D,UAAAmH,SAAA,EACAh/D,EAAA63D,UAAA8G,gBAEA,EAEA,IAAAiB,GAAA,SAAA//D,GAGA,IAAAG,EAAA6/D,cAAA,CAEA,GAAA98D,GAAA/C,EAAA+C,GACAsa,EAAArd,EAAAsjD,oBAAAzjD,EAAA0jD,QAAA1jD,EAAA2jD,SACAvlC,GAAAZ,EAAA,GAAAta,EAAAgb,OAAAhb,EAAAib,MAAAR,EACAH,EAAA,GAAAta,EAAAgb,OAAAhb,EAAAib,MAAAP,EAEA,IAAAzd,EAAA63D,UAAAsG,cAAAn+D,EAAA63D,UAAAI,UAAAj4D,EAAA63D,UAAAwF,YAAAR,IAEA,WADAh9D,GAAA+rC,gBAIA,IAAA7oC,EAAAk+B,kBAAAl+B,EAAAm+B,sBAAAn+B,EAAAg+B,kBAAAh+B,EAAAi+B,qBAAA,CACAnhC,EAAA+rC,iBAEA5rC,EAAA6H,KAAAi4D,cAAA,EACA3C,aAAAn9D,EAAA6H,KAAAk4D,cACA//D,EAAA6H,KAAAk4D,aAAA7mD,WAAA,WACAlZ,EAAA6H,KAAAi4D,cAAA,EAEA9/D,EAAA05D,WAAA,QAAA,GACA15D,EAAA65D,UACA,IAEA,IAAA7iD,GAAAnX,EAAAmgE,OAAA,MAAAngE,EAAAogE,YAAA,KAAApgE,EAAAqgE,WAAA,GACAlpD,IAAAhX,EAAAmiC,gBAEA,IAAAg+B,GAAA,IAAAtgE,EAAAugE,SACAD,KACAnpD,GAAA,IAGAjU,EAAAgb,MACA+oB,MAAA/jC,EAAAgb,OAAA3O,KAAA6C,IAAA,GAAA+E,GACA4G,kBAAAJ,EAAAS,EAAA,GAAAR,EAAAQ,EAAA,QAQAje,GAAA46D,gBAAA56D,EAAA8/B,UAAA,QAAA8/B,GAAA,GAOA5/D,EAAA46D,gBAAAp7D,OAAA,SAAA,SAAAK,GACAG,EAAA6/D,eAAA,EAEA1C,aAAAn9D,EAAAqgE,sBACArgE,EAAAqgE,qBAAAnnD,WAAA,WACAlZ,EAAA6/D,eAAA,GACA,OACA,GAIA7/D,EAAA46D,gBAAA56D,EAAA8/B,UAAA,WAAA,SAAAjgC,GACA,GAAAwd,GAAArd,EAAAsjD,oBAAAzjD,EAAA0jD,QAAA1jD,EAAA2jD,QAEAxjD,GAAA+C,GAAAwV,QAAA+vB,EAAAzoC,GACA0E,KAAA,WACA0mC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,SAEA,GAEArd,EAAA46D,gBAAA56D,EAAA8/B,UAAA,YAAA,SAAAjgC,GACA,GAAAwd,GAAArd,EAAAsjD,oBAAAzjD,EAAA0jD,QAAA1jD,EAAA2jD,QAEAxjD,GAAA+C,GAAAwV,QAAA+vB,EAAAzoC,GACA0E,KAAA,YACA0mC,YAAAztB,EAAAH,EAAA,GAAAI,EAAAJ,EAAA,SAEA,EAEA,IAAAijD,GAAAC,EAAAC,EAAAC,EACAC,EAAAC,EACAC,EAAAC,EACAld,EAAAC,EACAkd,EAAAC,EACAC,EAUAC,EARA35D,EAAA,SAAAsX,EAAAE,EAAAD,EAAAE,GACA,MAAA3P,MAAA+F,MAAA0J,EAAAD,IAAAC,EAAAD,IAAAG,EAAAD,IAAAC,EAAAD,KAGAoiD,EAAA,SAAAtiD,EAAAE,EAAAD,EAAAE,GACA,OAAAF,EAAAD,IAAAC,EAAAD,IAAAG,EAAAD,IAAAC,EAAAD,GAIA9e,GAAA46D,gBAAA56D,EAAA8/B,UAAA,aAAAmhC,EAAA,SAAAphE,GACAG,EAAAs4D,UAAAH,SAAA,EACAn4D,EAAA6H,KAAA+1D,kBAAAn6D,MAEA,IAAAV,GAAA/C,EAAA+C,GACAkE,EAAAjH,EAAA8iD,iBACAh8C,EAAA9G,EAAA+iD,iBACA/pB,EAAAh5B,EAAAs4D,UAAAt/B,IACAy/B,EAAAz4D,EAAAs4D,UAAAG,OAEA,IAAA54D,EAAAshE,QAAA,GAAA,CAAA,GAAA9jD,GAAArd,EAAAsjD,oBAAAzjD,EAAAshE,QAAA,GAAA5d,QAAA1jD,EAAAshE,QAAA,GAAA3d,QAAAxqB,GAAA,GAAA3b,EAAA,GAAA2b,EAAA,GAAA3b,EAAA,GACA,GAAAxd,EAAAshE,QAAA,GAAA,CAAA,GAAA9jD,GAAArd,EAAAsjD,oBAAAzjD,EAAAshE,QAAA,GAAA5d,QAAA1jD,EAAAshE,QAAA,GAAA3d,QAAAxqB,GAAA,GAAA3b,EAAA,GAAA2b,EAAA,GAAA3b,EAAA,GACA,GAAAxd,EAAAshE,QAAA,GAAA,CAAA,GAAA9jD,GAAArd,EAAAsjD,oBAAAzjD,EAAAshE,QAAA,GAAA5d,QAAA1jD,EAAAshE,QAAA,GAAA3d,QAAAxqB,GAAA,GAAA3b,EAAA,GAAA2b,EAAA,GAAA3b,EAAA,GAIA,GAAAxd,EAAAshE,QAAA,GAAA,CAGA,GAAAC,GAAA,SAAAl8D,GACA,IAAA,GAAA5E,GAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IACA4E,EAAA5E,GAAAgB,SAAA+jB,SAAA,EACAngB,EAAA5E,GAAAgB,SAAAoa,SAAA8/C,aAAA,EACAt2D,EAAA5E,GAAAilB,UAAArgB,EAAA5E,GAAA2+D,aAGAmC,GAAAn6D,GACAm6D,EAAAt6D,EAEA,IAAA28C,GAAAzjD,EAAA0jD,2BACAC,GAAAF,EAAA,GACAG,EAAAH,EAAA,GACAqd,EAAArd,EAAA,GACAsd,EAAAtd,EAAA,GAEA6c,EAAAzgE,EAAAshE,QAAA,GAAA5d,QAAAI,EACA4c,EAAA1gE,EAAAshE,QAAA,GAAA3d,QAAAI,EAEA4c,EAAA3gE,EAAAshE,QAAA,GAAA5d,QAAAI,EACA8c,EAAA5gE,EAAAshE,QAAA,GAAA3d,QAAAI,EAEAod,EACAV,GAAA,GAAAQ,GAAAR,GACAE,GAAA,GAAAM,GAAAN,GACAD,GAAA,GAAAQ,GAAAR,GACAE,GAAA,GAAAM,GAAAN,CAGA,IAAAziD,GAAAjb,EAAAib,MACAD,EAAAhb,EAAAgb,MAEA2iD,GAAAp5D,EAAAg5D,EAAAC,EAAAC,EAAAC,GACAE,EAAAO,EAAAZ,EAAAC,EAAAC,EAAAC,GACAG,IAAAN,EAAAE,GAAA,GAAAD,EAAAE,GAAA,GACAI,IACAD,EAAA,GAAA5iD,EAAAR,GAAAO,GACA6iD,EAAA,GAAA5iD,EAAAP,GAAAM,EAIA,IAAAsjD,GAAA,IACAC,EAAAD,EAAAA,CACA,IAAAC,EAAAX,IAAA9gE,EAAAshE,QAAA,GAAA,CAEA,GAAAI,GAAAvhE,EAAAgkD,mBAAAhrB,EAAA,GAAAA,EAAA,IAAA,GAAA,GACAwoC,EAAAxhE,EAAAgkD,mBAAAhrB,EAAA,GAAAA,EAAA,IAAA,GAAA,EA8BA,OA5BAuoC,IAAAA,EAAA10D,UACA00D,EAAAhE,WAAAhlD,QAAA+vB,EAAAzoC,GACA0E,KAAA,cACA0mC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,OAEAh5B,EAAAs4D,UAAAlzD,MAAAm8D,GAEAC,GAAAA,EAAA30D,UACA20D,EAAAjE,WAAAhlD,QAAA+vB,EAAAzoC,GACA0E,KAAA,cACA0mC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,OAEAh5B,EAAAs4D,UAAAlzD,MAAAo8D,IAGAz+D,EAAAwV,QAAA+vB,EAAAzoC,GACA0E,KAAA,cACA0mC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,OAEAh5B,EAAAs4D,UAAAlzD,MAAA,MAGApF,EAAAs4D,UAAAlzD,QAAApF,EAAAs4D,UAAAlzD,MAAA9D,SAAA+jB,SAAA,GACArlB,EAAAs4D,UAAAmJ,KAAA,EACAzhE,EAAAs4D,UAAAmF,YAAA,EACAz9D,EAAA6H,KAAA+1D,kBAAAn6D,WAEAzD,GAAA65D,UAOA,GAAAh6D,EAAAshE,QAAA,QAEA,IAAAthE,EAAAshE,QAAA,QAEA,IAAAthE,EAAAshE,QAAA,GAAA,CACA,GAAAxc,GAAA3kD,EAAAgkD,mBAAAhrB,EAAA,GAAAA,EAAA,IAAA,GAAA,EAEA,IAAA,MAAA2rB,IACAA,EAAA4Y,WAEAv9D,EAAAs4D,UAAAlzD,MAAAu/C,EAEAA,EAAA93C,UAAA7M,EAAA66D,gBAAAlW,IAAA,CAEA,GAAA+c,GAAA1hE,EAAAo4D,SAAAuJ,gBAKA,IAHA3hE,EAAA05D,WAAA,QAAA,GACA15D,EAAA05D,WAAA,QAAA,GAEA/U,EAAAx/B,WAOA,IAAA,GAJAw4C,GAAA56D,EAAAmI,EAAA,WACA,MAAAvL,MAAAkN,UAAAlN,KAAAwlB,aAGAhT,EAAA,EAAAA,EAAAwrD,EAAAh9D,OAAAwR,IAAA,CACA,GAAAyvD,GAAAjE,EAAAxrD,EAEAnS,GAAA66D,gBAAA+G,IACAjG,EAAAiG,GAAAvG,UAAAqG,QAIA/F,GAAAhX,GAAA0W,UAAAqG,GAGA/c,GAAApsC,QAAA+vB,EAAAzoC,GACA0E,KAAA,OACA0mC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,OAKA8hC,EAAAnW,GAAA,aAAA,WAAA,cAAA9kD,GACAorC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,MAGA,MAAA2rB,IACA3kD,EAAA6H,KAAA+1D,mBACApgD,EAAAH,EAAA,GACAI,EAAAJ,EAAA,IAGArd,EAAA05D,WAAA,UAAA,GACA15D,EAAA65D,SAOA,KAAA,GAAAv5D,GAAA,EAAAA,EAAA04B,EAAAr4B,OAAAL,IACAm4D,EAAAn4D,GAAA04B,EAAA14B,GACAN,EAAAs4D,UAAAx+B,cAAAx5B,GAAA04B,EAAA14B,EAGAN,GAAAs4D,UAAAE,kBAAA,EACAx4D,EAAAs4D,UAAAC,sBAAA,GAAAxrB,MAEAowB,aAAAn9D,EAAAs4D,UAAA8E,gBACAp9D,EAAAs4D,UAAA8E,eAAAlkD,WAAA,WAEAlZ,EAAAs4D,UAAAE,oBAAA,GACAx4D,EAAA6hE,WAEA/G,EAAA96D,EAAAs4D,UAAAlzD,OAAA,WAAAvF,GACAorC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,MAGAh5B,EAAAs4D,UAAAlzD,OACArC,EAAAmI,EAAA,aAAA+nB,aAIAjzB,EAAAs5D,oBAGA,EAEA,IAAAwI,EACA9hE,GAAA46D,gBAAAp7D,OAAA,YAAAsiE,EAAA,SAAAjiE,GAEA,GAAAk9D,GAAA/8D,EAAA43D,UACAO,EAAAn4D,EAAAs4D,UAAAH,QACAp1D,EAAA/C,EAAA+C,GACAi2B,EAAAh5B,EAAAs4D,UAAAt/B,IAAAy/B,EAAAz4D,EAAAs4D,UAAAG,QACA16C,EAAAhb,EAAAgb,MAEA,IAAAle,EAAAshE,QAAA,GAAA,CAAA,GAAA9jD,GAAArd,EAAAsjD,oBAAAzjD,EAAAshE,QAAA,GAAA5d,QAAA1jD,EAAAshE,QAAA,GAAA3d,QAAAxqB,GAAA,GAAA3b,EAAA,GAAA2b,EAAA,GAAA3b,EAAA,GACA,GAAAxd,EAAAshE,QAAA,GAAA,CAAA,GAAA9jD,GAAArd,EAAAsjD,oBAAAzjD,EAAAshE,QAAA,GAAA5d,QAAA1jD,EAAAshE,QAAA,GAAA3d,QAAAxqB,GAAA,GAAA3b,EAAA,GAAA2b,EAAA,GAAA3b,EAAA,GACA,GAAAxd,EAAAshE,QAAA,GAAA,CAAA,GAAA9jD,GAAArd,EAAAsjD,oBAAAzjD,EAAAshE,QAAA,GAAA5d,QAAA1jD,EAAAshE,QAAA,GAAA3d,QAAAxqB,GAAA,GAAA3b,EAAA,GAAA2b,EAAA,GAAA3b,EAAA,GAEA,IAAA,GAAA+gD,MAAAxxD,EAAA,EAAAA,EAAAosB,EAAAr4B,OAAAiM,IAAAwxD,EAAAxxD,GAAAosB,EAAApsB,GAAA6rD,EAAA7rD,EACA,IAAA8tB,GAAA16B,EAAAs4D,UAAAx+B,cACA6C,EAAA3D,EAAA,GAAA0B,EAAA,GACA2jC,EAAA1hC,EAAAA,EACAod,EAAA/gB,EAAA,GAAA0B,EAAA,GACA4jC,EAAAvkB,EAAAA,EACAwkB,EAAAF,EAAAC,EACAE,EAAAD,EAAAxgD,EAAAA,CAGA,IAAAo6C,GAAAn4D,EAAAs4D,UAAAmJ,IAAA,CACA5hE,EAAA+rC,gBAEA,IAAAm2B,GAAAliE,EAAAshE,QAAA,GAAA5d,QAAAI,EAAAqe,EAAAniE,EAAAshE,QAAA,GAAA3d,QAAAI,EACAqe,EAAApiE,EAAAshE,QAAA,GAAA5d,QAAAI,EAAAue,EAAAriE,EAAAshE,QAAA,GAAA3d,QAAAI,EAEAue,EAAAjB,EAAAa,EAAAC,EAAAC,EAAAC,GACAE,EAAAD,EAAAxB,EAEA/mB,EAAA,IACAyoB,EAAAzoB,EAAAA,EACA0oB,EAAA,IACAC,EAAAD,EAAAA,CAGA,IAAAF,GAAAG,GAAAJ,GAAAE,EAAA,CACAriE,EAAAs4D,UAAAmJ,KAAA,EACAzhE,EAAAs4D,UAAAlzD,QAAApF,EAAAs4D,UAAAlzD,MAAA65D,aAAAj/D,EAAAs4D,UAAAlzD,MAAA,MACApF,EAAA6H,KAAA+1D,kBAAAn6D,OACAzD,EAAA05D,WAAA,UAAA,EAEA,IAAA4D,GAAAh1B,EAAAzoC,GACA0E,KAAA,YACA0mC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,KAEAh5B,GAAAs4D,UAAAlzD,MACApF,EAAAs4D,UAAAlzD,MAAAmT,QAAA+kD,GAEAv6D,EAAAwV,QAAA+kD,IAOA,GAAAnF,GAAAn4D,EAAAs4D,UAAAmJ,IAAA,CACA,GAAAnE,GAAAh1B,EAAAzoC,GACA0E,KAAA,UACA0mC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,KAEAh5B,GAAA6H,KAAA+1D,kBAAAn6D,OACAzD,EAAA05D,WAAA,UAAA,GAEA15D,EAAAs4D,UAAAlzD,MACApF,EAAAs4D,UAAAlzD,MAAAmT,QAAA+kD,GAEAv6D,EAAAwV,QAAA+kD,GAGAt9D,EAAAs4D,UAAAlzD,QAAApF,EAAAs4D,UAAAlzD,MAAA9D,SAAA+jB,SAAA,GACArlB,EAAAs4D,UAAAmF,YAAA,CAEA,IAAA9Y,GAAA3kD,EAAAgkD,mBAAAhrB,EAAA,GAAAA,EAAA,IAAA,GAAA,EAEAh5B,GAAAs4D,UAAAsG,SAAAja,IAAA3kD,EAAAs4D,UAAAsG,UAEA5+D,EAAAs4D,UAAAsG,SACA5+D,EAAAs4D,UAAAsG,QAAArmD,QAAA+vB,EAAAzoC,GACA0E,KAAA,aACA0mC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,OAIAh5B,EAAAs4D,UAAAsG,QAAAja,EAEAA,GACAA,EAAApsC,QAAA+vB,EAAAzoC,GACA0E,KAAA,cACA0mC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,YAQA,IAAAm/B,GAAAt4D,EAAAshE,QAAA,IAAAp+D,EAAAo+B,sBACAthC,EAAA+rC,iBAEA5rC,EAAA6H,KAAA+1D,kBAAAn6D,OAEA9D,KAAA6iE,gBAAA,GAAAz1B,MACA/sC,EAAAs4D,UAAAkH,WAAA,EAEAx/D,EAAA05D,WAAA,UAAA,GAEAqD,GAAA,IAAAA,EAAAp8D,QAAA8C,SAAAs5D,EAAA,IAMAA,EAAA,IAAA/jC,EAAA,GAAAA,EAAA,GAAAA,EAAA,IAAA,EACA+jC,EAAA,IAAA/jC,EAAA,GAAAA,EAAA,GAAAA,EAAA,IAAA,IANA+jC,EAAA,IAAA/jC,EAAA,GAAAA,EAAA,GAAAA,EAAA,IAAA,EACA+jC,EAAA,IAAA/jC,EAAA,GAAAA,EAAA,GAAAA,EAAA,IAAA,EACA+jC,EAAA,IAAA/jC,EAAA,GAAAA,EAAA,GAAAA,EAAA,IAAA,EAAA,EACA+jC,EAAA,IAAA/jC,EAAA,GAAAA,EAAA,GAAAA,EAAA,IAAA,EAAA,GAMA+jC,EAAA,GAAA,EACA/8D,EAAAs4D,UAAAkH,WAAA,EAEAx/D,EAAA65D,aAGA,IAAA1B,GAAAt4D,EAAAshE,QAAA,IAAAp+D,EAAAg+B,kBAAAh+B,EAAAk+B,kBAAAl+B,EAAAi+B,sBAAAj+B,EAAAm+B,qBAAA,CACArhC,EAAA+rC,iBAEA5rC,EAAA6H,KAAA+1D,kBAAAn6D,OACAzD,EAAA05D,WAAA,UAAA,EAEA,IAAAgI,GAAA1hE,EAAAo4D,SAAAuJ,aACA,IAAAD,EAAA,CACA1hE,EAAA05D,WAAA,QAAA,EAEA,KAAA,GAAAp5D,GAAA,EAAAA,EAAAohE,EAAA/gE,OAAAL,IACAohE,EAAAphE,GAAAgB,SAAA+jB,SAAA,EACAq8C,EAAAphE,GAAAgB,SAAAoa,SAAA8/C,aAAA,EAKA,GAAAuG,GAAAliE,EAAAshE,QAAA,GAAA5d,QAAAI,EAAAqe,EAAAniE,EAAAshE,QAAA,GAAA3d,QAAAI,EACAqe,EAAApiE,EAAAshE,QAAA,GAAA5d,QAAAI,EAAAue,EAAAriE,EAAAshE,QAAA,GAAA3d,QAAAI,EAGA6e,EAAAn7D,EAAAy6D,EAAAC,EAAAC,EAAAC,GAGAQ,EAAAD,EAAA/B,CAEA,IAAA,GAAAgC,GAAA1B,EAAA,CAEA,GAAA2B,GAAAZ,EAAAzB,EACAsC,EAAAZ,EAAAzB,EAGAsC,EAAAZ,EAAAzB,EACAsC,GAAAZ,EAAAzB,EAIAsC,IAAAJ,EAAAE,GAAA,EACAG,IAAAJ,EAAAE,IAAA,EAWA77B,GAAAlkC,EAAAgb,OACAmpB,GAAAD,GAAAy7B,EACA17B,GAAAjkC,EAAAib,MAGAilD,GAAApC,EAAA,GAAA55B,GAAAD,GAAAxpB,EACA0lD,GAAArC,EAAA,GAAA55B,GAAAD,GAAAvpB,EAEA0pB,IACA3pB,GAAA0pB,GAAAD,IAAAg8B,GAAAj8B,GAAAxpB,EAAAulD,IAAAE,GACAxlD,GAAAypB,GAAAD,IAAAi8B,GAAAl8B,GAAAvpB,EAAAulD,IAAAE,GAIA,IAAAljE,EAAAs4D,UAAAlzD,MAAA,CACA,GAAAs8D,GAAA1hE,EAAAo4D,SAAAuJ,aAEA,IAAAD,EAAA,IAAA,GAAAphE,GAAA,EAAAA,EAAAohE,EAAA/gE,OAAAL,IAAA,CACA,GAAAy7D,IAAA2F,EAAAphE,GAAAgB,QAEAy6D,IAAA12C,SAAA,EACA02C,GAAArgD,SAAA8/C,aAAA,EAGA,GAAA2H,IAAAnjE,EAAAs4D,UAAAlzD,MAAA9D,QACA6hE,IAAA59C,QAAA,EACA49C,GAAA99C,SAAA,EACA89C,GAAAznD,SAAA8/C,aAAA,EAEAx7D,EAAA05D,WAAA,QAAA,GAEA15D,EAAAs4D,UAAAlzD,MACAmT,QAAA,QACAA,QAAA,cAIAxV,EAAAskC,UACAtpB,KAAAmpB,GACAlpB,IAAAmpB,GACAQ,oBAAA,IAGA+4B,EAAA+B,EACAnC,EAAAyB,EACAxB,EAAAyB,EACAxB,EAAAyB,EACAxB,EAAAyB,EAEAliE,EAAA6hE,UAAA,EAIA,GAAAhiE,EAAAshE,QAAA,GAAA,CAAA,GAAA9jD,GAAArd,EAAAsjD,oBAAAzjD,EAAAshE,QAAA,GAAA5d,QAAA1jD,EAAAshE,QAAA,GAAA3d,QAAAxqB,GAAA,GAAA3b,EAAA,GAAA2b,EAAA,GAAA3b,EAAA,GACA,GAAAxd,EAAAshE,QAAA,GAAA,CAAA,GAAA9jD,GAAArd,EAAAsjD,oBAAAzjD,EAAAshE,QAAA,GAAA5d,QAAA1jD,EAAAshE,QAAA,GAAA3d,QAAAxqB,GAAA,GAAA3b,EAAA,GAAA2b,EAAA,GAAA3b,EAAA,GACA,GAAAxd,EAAAshE,QAAA,GAAA,CAAA,GAAA9jD,GAAArd,EAAAsjD,oBAAAzjD,EAAAshE,QAAA,GAAA5d,QAAA1jD,EAAAshE,QAAA,GAAA3d,QAAAxqB,GAAA,GAAA3b,EAAA,GAAA2b,EAAA,GAAA3b,EAAA,QAEA,IAAAxd,EAAAshE,QAAA,GAAA,CACA,GAAA/7D,IAAApF,EAAAs4D,UAAAlzD,MACAgpB,GAAApuB,EAAAs4D,UAAAlqC,KACAu2B,EAAAA,GAAA3kD,EAAAgkD,mBAAAhrB,EAAA,GAAAA,EAAA,IAAA,GAAA,EAOA,IALA,MAAA5zB,IACAvF,EAAA+rC,iBAIA,MAAAxmC,IAAA,SAAAA,GAAA9D,SAAAof,OAAA1gB,EAAA66D,gBAAAz1D,IAEA,GAAAo5D,GAAAx+D,EAAAq5D,mBAAA,CAIA,IAAA,GAHAqI,GAAA1hE,EAAAo4D,SAAAuJ,cACAzC,IAAAl/D,EAAAo4D,SAAA+G,QAEAhtD,GAAA,EAAAA,GAAAuvD,EAAA/gE,OAAAwR,KAAA,CACA,GAAAixD,IAAA1B,EAAAvvD,GAMA,IAJA+sD,IACAvD,EAAAyH,IAAA5H,aAAA,IAGAx7D,EAAA66D,gBAAAuI,KAAAA,GAAAv2D,UAAAu2D,GAAA/9C,UAAA,CACArlB,EAAAo4D,SAAA+G,SAAA,CACA,IAAAE,IAAA+D,GAAA9hE,SAAAqb,SACA2iD,IAAA8D,GAAA7oD,UAOA,IALA+kD,IAAAv+D,EAAA0Q,OAAA2sD,EAAA,KAAAr9D,EAAA0Q,OAAA2sD,EAAA,MACAiB,GAAA7hD,GAAA4gD,EAAA,GACAiB,GAAA5hD,GAAA2gD,EAAA,IAGAc,GAAA,CACAl/D,EAAA05D,WAAA,QAAA,EAEA,IAAAiF,IAAA3+D,EAAAs4D,UAAAqG,SAEAW,KAAAv+D,EAAA0Q,OAAAktD,GAAA,KAAA59D,EAAA0Q,OAAAktD,GAAA,MACAU,GAAA7hD,GAAAmhD,GAAA,GACAU,GAAA5hD,GAAAkhD,GAAA,MAOA,GAAAY,IAAA/1C,EAAAzmB,EAAA2+D,EAEAnC,IAAAxiD,uBACAwiD,GAAAhnD,QAAA,iBAEAvY,EAAA63D,UAAAsG,cAAA,EAEAn+D,EAAA05D,WAAA,QAAA,GAGA15D,EAAAs4D,UAAAx+B,cAAA,IAAA2+B,EAAA,IACAz4D,EAAAs4D,UAAAx+B,cAAA,IAAA2+B,EAAA,IAGAz4D,EAAA05D,WAAA,QAAA,GAGA15D,EAAA65D,aACA,CACA,GAAA8E,IAAA3+D,EAAAs4D,UAAAqG,UAAA3+D,EAAAs4D,UAAAqG,aAEA,KAAAA,GAAAh+D,QACAg+D,GAAAv8D,KAAAg8D,EAAA,IACAO,GAAAv8D,KAAAg8D,EAAA,MAEAO,GAAA,IAAAP,EAAA,GACAO,GAAA,IAAAP,EAAA,IAOAtD,EAAA11D,IAAAu/C,GAAA,YAAA,UAAA,cAAA9kD,GACAorC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,MAGA2rB,GAAAv2B,KACAA,IAAAA,GAAA7V,QAAA+vB,EAAAzoC,GAAA0E,KAAA,aAAA0mC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,OACA2rB,GAAAA,EAAApsC,QAAA+vB,EAAAzoC,GAAA0E,KAAA,cAAA0mC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,QAGAh5B,EAAAs4D,UAAAlqC,KAAAu2B,CAIA,KAAA,GAAArkD,GAAA,EAAAA,EAAA04B,EAAAr4B,OAAAL,IACA04B,EAAA14B,IACAN,EAAAs4D,UAAAx+B,cAAAx5B,IACAk+D,EAAAx+D,EAAAq5D,qBAEAr5D,EAAAs4D,UAAAE,kBAAA,EAKA,IACAL,IACA,MAAA/yD,IAAAA,GAAA4b,WACAje,EAAAk+B,kBAAAl+B,EAAAm+B,qBACA,CAEArhC,EAAA+rC,iBAEA5rC,EAAAqjE,aACAtgE,EAAAujC,OACA9oB,EAAA4gD,EAAA,GAAArgD,EACAN,EAAA2gD,EAAA,GAAArgD,IAGAygD,GAAAx+D,EAAAq5D,qBACAr5D,EAAAqjE,cAAA,EAEAtgE,EAAAujC,OACA9oB,EAAAmf,EAAA5e,EACAN,EAAAs8B,EAAAh8B,IAGA3Y,KACAA,GAAA65D,aAEAj/D,EAAA6H,KAAA+1D,oBACA59D,EAAA6H,KAAA+1D,mBACApgD,EAAAwb,EAAA,GACAvb,EAAAub,EAAA,KAIAh5B,EAAA05D,WAAA,UAAA,GAEA15D,EAAAs4D,UAAAlzD,MAAA,MAKA,IAAAiY,GAAArd,EAAAsjD,oBAAAzjD,EAAAshE,QAAA,GAAA5d,QAAA1jD,EAAAshE,QAAA,GAAA3d,QACAxqB,GAAA,GAAA3b,EAAA,GAAA2b,EAAA,GAAA3b,EAAA,IAIA,IAAA,GAAAzQ,GAAA,EAAAA,EAAAosB,EAAAr4B,OAAAiM,IAAA6rD,EAAA7rD,GAAAosB,EAAApsB,KAGA,EAEA,IAAA02D,EACAtjE,GAAA46D,gBAAAp7D,OAAA,cAAA8jE,EAAA,SAAAzjE,GACA,GAAAuF,GAAApF,EAAAs4D,UAAAlzD,KAEApF,GAAAs4D,UAAAH,SAAA,EAEA/yD,GACAA,EAAA65D,cAIA,IAAAsE,EAyNA,IAxNAvjE,EAAA46D,gBAAAp7D,OAAA,WAAA+jE,EAAA,SAAA1jE,GACA,GAAAuF,GAAApF,EAAAs4D,UAAAlzD,MAEA+yD,EAAAn4D,EAAAs4D,UAAAH,OAEA,IAAAA,EAAA,CACAn4D,EAAAs4D,UAAAH,SAAA,EAEAt4D,EAAA+rC,gBAKA,IAAAmxB,GAAA/8D,EAAA43D,SAEA53D,GAAAqjE,cAAA,EACArjE,EAAA63D,UAAAsG,cAAA,CAEA,IAAAp7D,GAAA/C,EAAA+C,GACAgb,EAAAhb,EAAAgb,OACAib,EAAAh5B,EAAAs4D,UAAAt/B,IACAy/B,EAAAz4D,EAAAs4D,UAAAG,OAEA,IAAA54D,EAAAshE,QAAA,GAAA,CAAA,GAAA9jD,GAAArd,EAAAsjD,oBAAAzjD,EAAAshE,QAAA,GAAA5d,QAAA1jD,EAAAshE,QAAA,GAAA3d,QAAAxqB,GAAA,GAAA3b,EAAA,GAAA2b,EAAA,GAAA3b,EAAA,GACA,GAAAxd,EAAAshE,QAAA,GAAA,CAAA,GAAA9jD,GAAArd,EAAAsjD,oBAAAzjD,EAAAshE,QAAA,GAAA5d,QAAA1jD,EAAAshE,QAAA,GAAA3d,QAAAxqB,GAAA,GAAA3b,EAAA,GAAA2b,EAAA,GAAA3b,EAAA,GACA,GAAAxd,EAAAshE,QAAA,GAAA,CAAA,GAAA9jD,GAAArd,EAAAsjD,oBAAAzjD,EAAAshE,QAAA,GAAA5d,QAAA1jD,EAAAshE,QAAA,GAAA3d,QAAAxqB,GAAA,GAAA3b,EAAA,GAAA2b,EAAA,GAAA3b,EAAA,GAEAjY,GACAA,EAAA65D,YAGA,IAAAuE,EACA,IAAAxjE,EAAAs4D,UAAAmJ,IAAA,CAYA,GAXA+B,EAAAl7B,EAAAzoC;AACA0E,KAAA,YACA0mC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,MAGA5zB,EACAA,EAAAmT,QAAAirD,GAEAzgE,EAAAwV,QAAAirD,IAGAxjE,EAAAs4D,UAAAmF,WAAA,CACA,GAAAgG,GAAAn7B,EAAAzoC,GACA0E,KAAA,SACA0mC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,KAGA5zB,GACAA,EAAAmT,QAAAkrD,GAEA1gE,EAAAwV,QAAAkrD,GAUA,MALAzjE,GAAAs4D,UAAAlzD,QAAApF,EAAAs4D,UAAAlzD,MAAA9D,SAAA+jB,SAAA,GACArlB,EAAAs4D,UAAAmJ,KAAA,EACAzhE,EAAAs4D,UAAAlzD,MAAA,SAEApF,GAAA65D,SAKA,IAAAh6D,EAAAshE,QAAA,IAAAp+D,EAAAo+B,uBAAAnhC,EAAAs4D,UAAAkH,UAAA,CACAx/D,EAAAs4D,UAAAkH,WAAA,CAEA,IAAAE,MACA3Y,EAAA/mD,EAAA8mD,YAAAiW,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAEAA,GAAA,GAAAt5D,OACAs5D,EAAA,GAAAt5D,OACAs5D,EAAA,GAAAt5D,OACAs5D,EAAA,GAAAt5D,OACAs5D,EAAA,GAAA,EAEA/8D,EAAA05D,WAAA,UAAA,EAEA,KAAA,GAAAp5D,GAAA,EAAAA,EAAAymD,EAAApmD,OAAAL,IACAymD,EAAAzmD,GAAAgB,SAAA8jB,YACAs6C,EAAAt9D,KAAA2kD,EAAAzmD,GAIA,IAAAq/D,GAAAn2C,EAAAzmB,EAAA28D,EAEAC,GAAA5C,SAEA4C,EAAAh/D,OAAA,EACAX,EAAA05D,WAAA,QAAA,GAEA15D,EAAA65D,SAIA,GAAA6J,IAAA,CAQA,IANA,MAAAt+D,IACAA,EAAA9D,SAAAikB,QAAA,EACAm+C,GAAA,EACAt+D,EAAA65D,cAGAp/D,EAAAshE,QAAA,GACAnhE,EAAA6H,KAAA+1D,kBAAAn6D,OACAzD,EAAA05D,WAAA,UAAA,OACA,IAAA75D,EAAAshE,QAAA,QAEA,IAAAthE,EAAAshE,QAAA,QAGA,KAAAthE,EAAAshE,QAAA,GAAA,CAEAnhE,EAAA6H,KAAA+1D,kBAAAn6D,OACAzD,EAAA05D,WAAA,UAAA,EAEA,IAAAgI,GAAA1hE,EAAAo4D,SAAAuJ,aAEA,IAAA,MAAAv8D,EAAA,CAEA,GAAAu+D,GAAAv+D,EAAA9D,SAAA+jB,OAEAw2C,GAAA6F,GAEA1hE,EAAA05D,WAAA,QAAA,GACA15D,EAAA05D,WAAA,QAAA,GAEAiK,GACAv+D,EAAAmT,QAAA,QAGAuiD,EAAA11D,GAAA,WAAA,SAAA,YAAAvF,GACAorC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,MAGA5zB,EAAA65D,aAEAj/D,EAAAs4D,UAAAlzD,MAAA,SAEA,CACA,GAAAu/C,GAAA3kD,EAAAgkD,mBAAAhrB,EAAA,GAAAA,EAAA,IAAA,GAAA,EAEA8hC,GAAAnW,GAAA,WAAA,SAAA,YAAA9kD,GACAorC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,MAKA,GAAA2D,GAAA38B,EAAAs4D,UAAAx+B,cAAA,GAAAd,EAAA,GACAqlC,EAAA1hC,EAAAA,EACAod,EAAA/5C,EAAAs4D,UAAAx+B,cAAA,GAAAd,EAAA,GACAslC,EAAAvkB,EAAAA,EACAwkB,EAAAF,EAAAC,EACAE,EAAAD,EAAAxgD,EAAAA,CAGA,OAAA3Y,IACApF,EAAAo4D,SAAA+G,SACA/5D,EAAA9D,SAAA8jB,YACAo5C,EAAAx+D,EAAAq5D,qBACAr5D,EAAA6hE,WAGA,WAAA9+D,EAAAy+B,iBACAz+B,EAAAmI,EAAA,aAAA2c,QAAAziB,GAAA6tB,WACA7tB,EAAA23D,UAEA33D,EAAA+f,WACA/f,EAAA6tB,WAEA7tB,EAAA23D,SAIA2G,GAAA,EAGA1jE,EAAA05D,WAAA,QAAA,IAIA15D,EAAAs4D,UAAAE,kBACAsC,EAAA11D,GAAA,MAAA,UAAAvF,GACAorC,YAAAztB,EAAAwb,EAAA,GAAAvb,EAAAub,EAAA,MAIAh5B,EAAAs4D,UAAAE,kBAAA,EAGA,IAAA,GAAA5rD,GAAA,EAAAA,EAAAosB,EAAAr4B,OAAAiM,IAAA6rD,EAAA7rD,GAAAosB,EAAApsB,EAEA5M,GAAAo4D,SAAA+G,SAAA,EAEA,IAAAt/D,EAAAshE,QAAAxgE,SACAX,EAAAs4D,UAAAqG,cAGA+E,GAAAt+D,GACAA,EAAAkT,aAAA,GAGAzY,EAAAshE,QAAAxgE,OAAA,IACAX,EAAA6hE,UAAA,EACA7hE,EAAA05D,WAAA,QAAA,GACA15D,EAAA65D,aAKA,GAGA,mBAAA+J,YAAA,CAEA,GAAAC,MAEAC,EAAA,SAAAjkE,GACA,OACA0jD,QAAA1jD,EAAA0jD,QACAC,QAAA3jD,EAAA2jD,QACArN,MAAA,EACA4tB,WAAAlkE,EAAAmkE,UACAC,MAAApkE,EAAAokE,MACAC,MAAArkE,EAAAqkE,MACAC,QAAAtkE,EAAA8mC,MAAA,EACAy9B,QAAAvkE,EAAA+mC,OAAA,EACAy9B,QAAAxkE,EAAAwkE,QACAC,QAAAzkE,EAAAykE,QACApjE,OAAArB,EAAAqB,SAIAqjE,EAAA,SAAA1kE,GACA,OACAyb,MAAAzb,EACA2kE,MAAAV,EAAAjkE,KAIA4kE,EAAA,SAAA5kE,GACAgkE,EAAAzhE,KAAAmiE,EAAA1kE,KAGA6kE,EAAA,SAAA7kE,GACA,IAAA,GAAAS,GAAA,EAAAA,EAAAujE,EAAAljE,OAAAL,IAAA,CACA,GAAAoD,GAAAmgE,EAAAvjE,EAEA,IAAAoD,EAAA4X,MAAA0oD,YAAAnkE,EAAAmkE,UAEA,WADAH,GAAAp8D,OAAAnH,EAAA,KAMAqkE,EAAA,SAAA9kE,GACA,GAAA6D,GAAAmgE,EAAAz9D,OAAA,SAAA1C,GACA,MAAAA,GAAA4X,MAAA0oD,YAAAnkE,EAAAmkE,YACA,EAEAtgE,GAAA4X,MAAAzb,EACA6D,EAAA8gE,MAAAV,EAAAjkE,IAGA+kE,EAAA,SAAA/kE,GACAA,EAAAshE,QAAA0C,EAAA/tD,IAAA,SAAApS,GACA,MAAAA,GAAA8gE,SAIAK,EAAA,SAAAhlE,GACA,MAAA,UAAAA,EAAAilE,aAAA,IAAAjlE,EAAAilE,YAGA9kE,GAAA46D,gBAAA56D,EAAA8/B,UAAA,cAAA,SAAAjgC,GACAglE,EAAAhlE,KAEAA,EAAA+rC,iBAEA64B,EAAA5kE,GAEA+kE,EAAA/kE,GACAohE,EAAAphE,MAGAG,EAAA46D,gBAAA56D,EAAA8/B,UAAA,YAAA,SAAAjgC,GACAglE,EAAAhlE,KAEA6kE,EAAA7kE,GAEA+kE,EAAA/kE,GACA0jE,EAAA1jE,MAGAG,EAAA46D,gBAAA56D,EAAA8/B,UAAA,gBAAA,SAAAjgC,GACAglE,EAAAhlE,KAEA6kE,EAAA7kE,GAEA+kE,EAAA/kE,GACAyjE,EAAAzjE,MCl1DAG,EAAA46D,gBAAA56D,EAAA8/B,UAAA,cAAA,SAAAjgC,GACAglE,EAAAhlE,KAEAA,EAAA+rC,iBAEA+4B,EAAA9kE,GAEA+kE,EAAA/kE,GACAiiE,EAAAjiE,QAMAT,EAAAD,QAAA4gD,IAEAglB,sBAAA,GAAAC,iBAAA,GAAA1iB,cAAA,GAAAE,gBAAA,KAAAyiB,IAAA,SAAApkE,EAAAzB,EAAAD,GACA,YAEA,IAAAgwC,GAAAtuC,EAAA,iBAEAk/C,IAEAA,GAAAyZ,mBAAA,WAgCA,QAAA0L,GAAAhhE,EAAAogB,GACA,MAAAkgC,GAAAtgD,IACAA,KAAAA,EAEAogB,OAAAA,EAEA+8B,KAAA,SAAAtc,EAAA8U,EAAAC,EAAAnT,EAAAC,GACAzmB,EAAAglD,cAAA,WAAApgC,EAAA8U,EAAAC,EAAAnT,EAAAC,EAAAjnC,KAAA2kB,SAGAwqC,cAAA,SAAAxC,EAAAC,EAAA5lB,EAAAC,EAAAppB,EAAAC,EAAA4B,GACA,MAAA8vB,GAAAi2B,qBACA5nD,EAAAC,EACA9d,KAAA2kB,OACAgoC,EACAC,EACA5lB,EAAA,EAAAC,EAAA,EACAvnB,IAIAqlC,WAAA,SAAAlnC,EAAAC,EAAA4B,EAAAsnB,EAAAC,EAAAiT,EAAAC,GACA,MAAA3K,GAAAk2B,mBAAA7nD,EAAAC,EAAA+mC,EAAAtgD,GAAAogB,OACAu1B,EAAAC,EAAAnT,EAAAC,GAAA,EAAA,IAAAvnB,KAtDA,GAAAmlC,GAAA7kD,KAAA6kD,cACArkC,EAAAxgB,IAEA6kD,GAAA,SACAtgD,KAAA,UAEAm9C,KAAA,SAAAtc,EAAA8U,EAAAC,EAAAnT,EAAAC,GACAzmB,EAAAglD,cAAAxlE,KAAAuE,MAAA6gC,EAAA8U,EAAAC,EAAAnT,EAAAC,IAGAkoB,cAAA,SAAAxC,EAAAC,EAAA5lB,EAAAC,EAAAppB,EAAAC,EAAA4B,GACA,MAAA8vB,GAAAm2B,qBACA9nD,EAAAC,EACA6uC,EACAC,EACA5lB,EAAA,EAAAtnB,EACAunB,EAAA,EAAAvnB,IAIAqlC,WAAA,SAAAlnC,EAAAC,EAAA4B,EAAAsnB,EAAAC,EAAAiT,EAAAC,GAOA,MANAt8B,IAAAq8B,EACAp8B,GAAAq8B,EAEAt8B,GAAAmpB,EAAA,EAAAtnB,EACA5B,GAAAmpB,EAAA,EAAAvnB,EAEA,GAAA7B,EAAAA,EAAAC,EAAAA,IAiCAynD,EAAA,WAAA/1B,EAAAo2B,kCAAA,EAAA,IAEAL,EAAA,SAAA/1B,EAAAo2B,kCAAA,EAAA,IACA/gB,EAAA,UAAAA,EAAA,OAEAA,EAAA,gBACAtgD,KAAA,iBAEAogB,OAAA6qB,EAAAo2B,kCAAA,EAAA,GAEAlkB,KAAA,SAAAtc,EAAA8U,EAAAC,EAAAnT,EAAAC,GACAzmB,EAAAglD,cAAAxlE,KAAAuE,MAAA6gC,EAAA8U,EAAAC,EAAAnT,EAAAC,IAGAkoB,cAAA,SAAAxC,EAAAC,EAAA5lB,EAAAC,EAAAppB,EAAAC,EAAA4B,GACA,MAAA8vB,GAAAq2B,4BACAhoD,EAAAC,EACA6uC,EACAC,EACA5lB,EAAAC,EACAvnB,IAKAqlC,WAAA,SACAlnC,EAAAC,EAAA4B,EAAAsnB,EAAAC,EAAAiT,EAAAC,GAEA,GAAA2rB,GAAAt2B,EAAAu2B,wBAAA/+B,EAAAC,EAGA,IAAAuI,EAAAk2B,mBAAA7nD,EAAAC,EAAA9d,KAAA2kB,OACAu1B,EAAAC,EAAAnT,EAAAC,EAAA,EAAA6+B,GAAA,EAAA,IAAApmD,GACA,OAAA,CAIA,IAAA8vB,EAAAk2B,mBAAA7nD,EAAAC,EAAA9d,KAAA2kB,OACAu1B,EAAAC,EAAAnT,EAAA,EAAA8+B,EAAA7+B,GAAA,EAAA,IAAAvnB,GACA,OAAA,CAGA,IAAAsmD,GAAA,SAAAnoD,EAAAC,EAAAo8B,EAAAC,EAAAnT,EAAAC,EAAAvnB,GAOA,MANA7B,IAAAq8B,EACAp8B,GAAAq8B,EAEAt8B,GAAAmpB,EAAA,EAAAtnB,EACA5B,GAAAmpB,EAAA,EAAAvnB,EAEA,GAAA7B,EAAAA,EAAAC,EAAAA,EAKA,OAAAkoD,GAAAnoD,EAAAC,EACAo8B,EAAAlT,EAAA,EAAA8+B,EACA3rB,EAAAlT,EAAA,EAAA6+B,EACA,EAAAA,EAAA,EAAAA,EAAApmD,IAEA,EAIAsmD,EAAAnoD,EAAAC,EACAo8B,EAAAlT,EAAA,EAAA8+B,EACA3rB,EAAAlT,EAAA,EAAA6+B,EACA,EAAAA,EAAA,EAAAA,EAAApmD,IAEA,EAIAsmD,EAAAnoD,EAAAC,EACAo8B,EAAAlT,EAAA,EAAA8+B,EACA3rB,EAAAlT,EAAA,EAAA6+B,EACA,EAAAA,EAAA,EAAAA,EAAApmD,IAEA,EAIAsmD,EAAAnoD,EAAAC,EACAo8B,EAAAlT,EAAA,EAAA8+B,EACA3rB,EAAAlT,EAAA,EAAA6+B,EACA,EAAAA,EAAA,EAAAA,EAAApmD,IAEA,GAGA,IAIA6lD,EAAA,WACA,EAAA,EACA,EAAA,EACA,EAAA,GACA,GAAA,IAGAA,EAAA,WAAA/1B,EAAAo2B,kCAAA,EAAA,IAEAL,EAAA,UAAA/1B,EAAAo2B,kCAAA,EAAA,IAEAL,EAAA,WAAA/1B,EAAAo2B,kCAAA,EAAA,IAEAL,EAAA,UAAA/1B,EAAAo2B,kCAAA,EAAA,GAEA,IAAAK,GAAA,GAAAnzD,OAAA,IAEAozD,EAAA12B,EAAA22B,uBAAA,EAAA,GACAC,EAAA52B,EAAA22B,uBAAA,EAAA12D,KAAAsjC,GAAA,GAGAszB,EAAA,IAAA,EAAA52D,KAAA+F,KAAA,GACA6wD,IAAA,IAEA,KAAA,GAAA1lE,GAAA,EAAAA,EAAAylE,EAAAplE,OAAA,EAAAL,IACAylE,EAAA,EAAAzlE,IAAA0lE,EACAD,EAAA,EAAAzlE,EAAA,IAAA0lE,CAGA,KAAA,GAAA1lE,GAAA,EAAA,EAAAA,EAAAA,IACAslE,EAAA,EAAAtlE,GAAAulE,EAAA,EAAAvlE,GACAslE,EAAA,EAAAtlE,EAAA,GAAAulE,EAAA,EAAAvlE,EAAA,GAEAslE,EAAA,EAAAtlE,EAAA,GAAAylE,EAAA,EAAAzlE,GACAslE,EAAA,EAAAtlE,EAAA,GAAAylE,EAAA,EAAAzlE,EAAA,EAIAslE,GAAAz2B,EAAA82B,mBAAAL,GAEAV,EAAA,OAAAU,GAEAV,EAAA,OACA,GAAA,GACA,GAAA,KACA,EAAA,GACA,EAAA,IAGAA,EAAA,YACA,GAAA,GACA,KAAA,GACA,EAAA,GACA,KAAA,IAGA1gB,EAAAqD,YAAA,SAAAvjC,GCzOA,GAEAigC,GAFAh5C,EAAA+Y,EAAA6F,KAAA,KACAjmB,EAAA,WAAAqH,CAGA,QAAAg5C,EAAAC,EAAAtgD,IACAqgD,EAIA2gB,EAAAhhE,EAAAogB,KAKAllB,EAAAD,QAAA4gD,IAEAwC,gBAAA,KAAA2jB,IAAA,SAAArlE,EAAAzB,EAAAD,GACA,YAEA,IAAA2B,GAAAD,EAAA,iBAEAk/C,IAEAA,GAAAomB,aAAA,WACA,MAAAxmE,MAAAymE,gBAAAzmE,KAAA0mE,YAGA,IAAAC,GAAA,IAAA,GACAC,EAAA,GAEAxmB,GAAA8Z,OAAA,SAAA50D,GACAA,EAAAA,GAAAnE,EAAAmf,mBAEA,IAAAjgB,GAAAL,KACA6mE,EAAAvhE,EAAAuhE,aAEA/iE,UAAAzD,EAAAymE,oBAAAzmE,EAAAymE,kBAAA,GACAhjE,SAAAzD,EAAA0mE,iBAAA1mE,EAAA0mE,eAAA,EAEA,IAAAC,GAAA3mE,EAAA0mE,cACAC,GAAAL,EAAAK,EAAAL,EAAAK,EACAA,EAAAJ,EAAAI,EAAAA,EAAAJ,EAEA9iE,SAAAzD,EAAA4mE,eAAA5mE,EAAA4mE,aAAA,EAEA,IAAAC,GAAA95B,KAAA/T,MACA8tC,EAAAD,EAAA7mE,EAAA4mE,aACAG,EAAAD,GAAAH,CAEA,OAAAH,IACAO,IAAA/mE,EAAAgnE,kBAMAhnE,EAAAinE,gBAAA,EACAjnE,EAAAgnE,kBAAA,OACAhnE,EAAAknE,cAAAjiE,SAPAjF,EAAAmnE,WAAA,IAUApnB,EAAA6Z,gBAAA,WACA,GAAA55D,GAAAL,KAEAynE,EAAA,WACA,IAAApnE,EAAA85D,UAAA,CAEA,GAAA95D,EAAAinE,iBAAAjnE,EAAAmnE,UAAA,CACA,GAAAjtC,GAAAp5B,EAAAumE,gBAEArnE,GAAAsnE,OAAAtnE,EAAAknE,cAEA,IAAAK,GAAAvnE,EAAA0mE,eAAA5lE,EAAAumE,gBAEA5jE,UAAAzD,EAAAymE,oBACAzmE,EAAAymE,kBAAAc,EAAArtC,GAGAz2B,SAAAzD,EAAAqmE,cACArmE,EAAAqmE,YAAA,GAGArmE,EAAAqmE,cAEA5iE,SAAAzD,EAAAomE,kBACApmE,EAAAomE,gBAAA,EAGA,IAAA5kE,GAAA+lE,EAAArtC,CAEAl6B,GAAAomE,iBAAA5kE,EACAxB,EAAA0mE,eAAAllE,EC3FAxB,EAAAymE,kBAAAzmE,EAAAymE,kBAAA,EAAAjlE,EAAA,EAEAxB,EAAAinE,gBAAA,EAGAjnE,EAAAmnE,WAAA,EAEArmE,EAAAi4B,sBAAAquC,IAGAtmE,GAAAi4B,sBAAAquC,IAIAhoE,EAAAD,QAAA4gD,IAEAyC,gBAAA,KAAAglB,IAAA,SAAA3mE,EAAAzB,EAAAD,GACA,YAEA,IAEAwvC,GAFA84B,IAIAA,GAAAnmB,eAAA,SAAAp9C,GACA,OAAAyqC,IAAAA,GACA+4B,QAAA,SAAA3iC,EAAAzgB,GACA,IAAA,GAAAhkB,GAAA,EAAAA,EAAAgkB,EAAA3jB,OAAAL,IAAA,CACA,GAAAshB,GAAA0C,EAAAhkB,EAEAykC,GAAA4iC,OAAA/lD,EAAApE,EAAAoE,EAAAnE,KAIAmqD,qBAAA,SAAA7iC,EAAAzgB,EAAAs9B,GAGA,IAAA,GAFAimB,GAEAvnE,EAAA,EAAAA,EAAAgkB,EAAA3jB,OAAAL,IAAA,CACA,GAAAshB,GAAA0C,EAAAhkB,EAEA,KAAAA,IACAunE,EAAAjmD,GAGAmjB,EAAA4iC,OAAA/lD,EAAApE,EAAAoE,EAAAnE,GAGAsnB,EAAA+iC,iBAAAlmB,EAAApkC,EAAAokC,EAAAnkC,EAAAoqD,EAAArqD,EAAAqqD,EAAApqD,IAGAsqD,eAAA,SAAAhjC,EAAAijC,EAAAC,GAEA,IAAA,GADAhmB,GAAA+lB,EACA1nE,EAAA,EAAAA,EAAA2hD,EAAAthD,OAAAL,IAAA,CACA,GAAAshB,GAAAqgC,EAAA3hD,EAEAykC,GAAA4iC,OAAA/lD,EAAApE,EAAAoE,EAAAnE,GAGA,GAAAykC,GAAA+lB,EACAC,EAAAD,EAAA,E7D07eMljC,GAAQojC,OAAQD,EAAW1qD,EAAG0qD,EAAWzqD,E8Dn/e/C,KAAA,GAAAnd,GAAA,EAAAA,EAAA4hD,EAAAvhD,OAAAL,IAAA,CACA,GAAAshB,GAAAsgC,EAAA5hD,EAEAykC,GAAA4iC,OAAA/lD,EAAApE,EAAAoE,EAAAnE,KAIA2xB,OAAA,SAAArK,EAAAyO,EAAAC,EAAAzzC,GACA+kC,EAAAqjC,IAAA50B,EAAAC,EAAAzzC,EAAA,EAAA,EAAAoP,KAAAsjC,IAAA,OAEAxuC,IAGA9E,EAAAD,QAAAsoE,OAEAY,IAAA,SAAAxnE,EAAAzB,EAAAD,GACA,YAEA,IAAAsoE,KAEAA,GAAAa,SAAA,SAAAvjC,EAAA35B,EAAAm9D,GACA,GAAAxjB,GAAA35C,EAAA9J,SAAAoa,SACA8sD,EAAA7oE,KAAA6oE,UAGA,MAAAzjB,EAAA4J,WAAA5J,EAAA4R,SAAA9vB,MAAAke,EAAAO,OAAA,KAAA,CAIA,GAAA7jD,GAAA2J,EAAA9J,SAAAG,KAGA,MAAAA,EAAA,MAAA8d,SAAA,GAAA,CAIA,GAAAkpD,GAAAhnE,EAAA,mBAAA8d,QACAmpD,EAAAjnE,EAAA,mBAAA0d,MACAwpD,EAAAlnE,EAAA,iBAAA0d,KAGA,IAAAopD,EAAA,CAEA,GAAA,IAAAG,EACA,MAGA/oE,MAAAipE,YAAA7jC,EAAA4jC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAD,GACA3jC,EAAA8jC,QAAA,QAEA,QAAA9jB,EAAAM,UAAAmjB,IACAzjC,EAAA8jC,QAAA,YAGA,CACA,GAAAC,GAAArnE,EAAA,cAAA0d,KAEAxf,MAAAipE,YAAA7jC,EAAA+jC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAArnE,EAAA8vB,QAAApS,OAEA4lB,EAAA8jC,QAAA,OAGA,GAAAhS,GAAAp1D,EAAA,MAAA8d,SAAAgpD,EAAA,EAAAE,EAAA,GACAM,EAAAR,EAAA,QAAA9mE,EAAA,cAAA0d,KACA4lB,GAAAikC,UAAAnS,CAEA,IAAAoS,GAAAxnE,EAAA,eAAA8d,QACA2pD,EAAAznE,EAAA,kBAAA0d,MACAgqD,EAAA1nE,EAAA,gBAAA0d,MACAiqD,EAAA3nE,EAAA,mBAAA8d,QACA8pD,EAAA5nE,EAAA,mBAAA8d,OAEA5f,MAAA2pE,YAAAvkC,EAAAokC,EAAAZ,EAAA,EAAAW,EAAAD,EAAAG,EAAAC,GAEA1pE,KAAA4pE,aACAn+D,EACA25B,EACAggB,EAAAO,OACAyjB,EACAlS,GAGAl3D,KAAA6pE,eAAAzkC,EAAA35B,EAAAm9D,GAEA5oE,KAAA2pE,YAAAvkC,EAAA,cAAA,MAKA0iC,EAAA8B,aAAA,SAAAn+D,EAAA25B,EAAAtjB,EAAAld,EAAAoiC,GACA,GAEAp/B,GAFAw9C,EAAA35C,EAAA9J,SAAAoa,SACA+tD,EAAA1kC,EAEA2kC,GAAA,EACAlB,EAAA7oE,KAAA6oE,UAEA,IAAAA,EAAA,CACA,GAAAmB,GAAAloD,EAAA0I,KAAA,KACAy/C,EAAA7kB,EAAA4kB,cAAA5kB,EAAA4kB,eAAAA,CAEAC,IACAriE,EAAAw9B,EAAAggB,EAAA8kB,UACAH,GAAA,IAEAniE,EAAAw9B,EAAA,GAAA+kC,QACA/kB,EAAA4kB,aAAAA,EACA5kB,EAAA8kB,UAAAtiE,GAIA,GAAAkiE,EAAAM,YACA,OAAAxlE,GACA,IAAA,SACAklE,EAAAM,aAAA,EAAA,GACA,MAEA,KAAA,SACAN,EAAAM,aAAA,EAAA,GACA,MAEA,KAAA,QACAN,EAAAM,gBAKA,IAAAL,EAIA,OAHA3kC,EAAAilC,WAAAjlC,EAAAilC,YACAjlC,EAAAojC,OAAA1mD,EAAA,GAAAA,EAAA,IAEAsjC,EAAAM,UACA,IAAA,SACA,IAAA,OACA,IAAA,WACA,IAAA,cACA,IAAAN,EAAA4J,UACA,IAAA,GAAAruD,GAAA,EAAAA,EAAA,EAAAmhB,EAAA9gB,OAAAL,GAAA,EACAykC,EAAA+iC,iBAAArmD,EAAAnhB,GAAAmhB,EAAAnhB,EAAA,GAAAmhB,EAAAnhB,EAAA,GAAAmhB,EAAAnhB,EAAA,GAGA,MAEA,KAAA,WACA,IAAA,WACA,IAAA,WACA,IAAAykD,EAAA4R,QACA,IAAA,GAAAr2D,GAAA,EAAAA,EAAA,EAAAmhB,EAAA9gB,OAAAL,GAAA,EACAykC,EAAA4iC,OAAAlmD,EAAAnhB,GAAAmhB,EAAAnhB,EAAA,IAOAykC,EAAA0kC,EACAjB,EACAzjC,EAAAklC,OAAA1iE,GAEAw9B,EAAAklC,SAIAllC,EAAAglC,aACAhlC,EAAAglC,iBAKAtC,EAAA+B,eAAA,SAAAzkC,EAAA35B,EAAAm9D,GACA,IAAAA,EAAA,CAEA,GAAAxjB,GAAA35C,EAAA9J,SAAAoa,SACAw5C,EAAA,aAAAnQ,EAAAM,QAEA6P,IACAv1D,KAAAuqE,cAAAnlC,EAAA35B,EAAA,SAAA25C,EAAAe,YAAAf,EAAAgB,YAAAhB,EAAAiB,eAGArmD,KAAAuqE,cAAAnlC,EAAA35B,EAAA,aAAA25C,EAAAqB,KAAArB,EAAAsB,KAAAtB,EAAAwB,kBAEA5mD,KAAAuqE,cAAAnlC,EAAA35B,EAAA,aAAA25C,EAAAqB,KAAArB,EAAAsB,KAAAtB,EAAAuB,kBAEA4O,GACAv1D,KAAAuqE,cAAAnlC,EAAA35B,EAAA,SAAA25C,EAAAkB,UAAAlB,EAAAmB,UAAAnB,EAAAoB,iBAIAshB,EAAAyC,cAAA,SAAAnlC,EAAA35B,EAAAie,EAAA7L,EAAAC,EAAA2iC,GACA,KAAAvZ,MAAArpB,IAAA,MAAAA,GAAAqpB,MAAAppB,IAAA,MAAAA,GAAAopB,MAAAuZ,IAAA,MAAAA,GAAA,CAEA,GAAA1gD,GAAAC,KACA8B,EAAA2J,EAAA9J,SAAAG,MACA0oE,EAAA1oE,EAAA4nB,EAAA,gBAAAlK,KAEA,IAAA,SAAAgrD,EAAA,CAIA,GAAAC,GAAArlC,EAAAslC,yBAEAC,EAAA,WAAA7oE,EAAA4nB,EAAA,eAAAlK,MAAA,OAAA,SACAorD,EAAA9oE,EAAA4nB,EAAA,eAAAlK,KAEA,4BAAAgrD,IACAI,EAAA,SACAD,EAAA,WAGA,IAAA7oE,EAAA8vB,QAAApS,OAAA,WAAAorD,KACAxlC,EAAAslC,yBAAA,kBAEA3qE,EAAA8qE,UAAAzlC,EAAA,IAAA,IAAA,IAAA,GACArlC,EAAAkpE,YAAA7jC,EAAA,IAAA,IAAA,IAAA,GAEArlC,EAAA+qE,eAAAr/D,EAAAie,EAAA0b,EACAulC,EAAA7oE,EAAA,MAAA8d,QAAA9d,EAAA4nB,EAAA,gBAAAlK,MACA3B,EAAAC,EAAA2iC,GAGArb,EAAAslC,yBAAAD,EAGA,IAAAM,GAAAjpE,EAAA4nB,EAAA,gBAAAlK,KACAzf,GAAA8qE,UAAAzlC,EAAA2lC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAjpE,EAAA8vB,QAAApS,OACAzf,EAAAkpE,YAAA7jC,EAAA2lC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAjpE,EAAA8vB,QAAApS,OAEAzf,EAAA+qE,eAAAr/D,EAAAie,EAAA0b,EACAwlC,EAAA9oE,EAAA,MAAA8d,QAAA9d,EAAA4nB,EAAA,gBAAAlK,MACA3B,EAAAC,EAAA2iC,MAIAqnB,EAAAgD,eAAA,SAAAr/D,EAAAu/D,EAAA5lC,EAAA6lC,EAAA/T,EAAAtS,EAAA/mC,EAAAC,EAAA2iC,GACA,GAIA74C,GAJAvH,EAAAL,KACA6oE,EAAA7oE,KAAA6oE,WACAzjB,EAAA35C,EAAA9J,SAAAoa,SACAguD,GAAA,EAEAmB,EAAA9lC,EACAsb,GAAA7iC,EAAAA,EAAAC,EAAAA,GACAxO,EAAAtP,KAAA0iD,cAAAwU,GACAiU,EAAA9qE,EAAAkgD,YAAAqE,EAEA,IAAAikB,EAAA,CACA,GAAAmB,GAAA16D,EAAA,IAAAs1C,EAAA,IAAAnE,EAAA,IAAA5iC,EAAA,IAAAC,CACAsnC,GAAAgmB,kBAAAhmB,EAAAgmB,sBACAhmB,EAAAimB,eAAAjmB,EAAAimB,kBAEA,IAAAC,GAAAlmB,EAAAgmB,kBAAAJ,KAAAhB,CACAsB,IACA1jE,EAAAw9B,EAAAggB,EAAAimB,eAAAL,GACAjB,GAAA,IAEAniE,EAAAw9B,EAAA,GAAA+kC,QACA/kB,EAAAgmB,kBAAAJ,GAAAhB,EACA5kB,EAAAimB,eAAAL,GAAApjE,GAIAw9B,EAAAilC,WAAAjlC,EAAAilC,YAEAN,GACAoB,EAAAzpB,KAAAtc,EAAA91B,EAAAmxC,EAAAC,IAGAyqB,EAAA3oB,eAAApd,EAAAmmC,WACAnmC,EAAAmmC,YAGAnmC,EAAA8lC,GAEA,WAAAD,GAAA,SAAAA,KACApC,EACAzjC,EAAA6lC,KAAArjE,GAEAw9B,EAAA6lC,SCnRA,WAAAA,GAAA,SAAAA,KACA7lC,EAAAikC,UAAA8B,EAAA1oB,eAAAyU,EAAA,EACA9xB,EAAAomC,SAAA,QAEA3C,EACAzjC,EAAAklC,OAAA1iE,GAEAw9B,EAAAklC,WAMA7qE,EAAAD,QAAAsoE,OAEA2D,IAAA,SAAAvqE,EAAAzB,EAAAD,GACA,YAEA,IAAAsoE,KAEAA,GAAA4D,cAAA,SAAAtmC,EAAAumC,EAAAC,EAAAC,EAAAC,EAAAC,EAAAluD,EAAAC,EAAA1V,EAAAiX,GACA,GAAAhf,GAAAL,IAEA,KACAolC,EAAA4mC,UAAAL,EAAAC,EAAAC,EAAAC,EAAAC,EAAAluD,EAAAC,EAAA1V,EAAAiX,GACA,MAAAnf,GACAG,EAAA6H,KAAA+jE,kBAAA5rE,EAAA6rE,OAAA,EACA7rE,EAAA6H,KAAA+jE,kBAAA5rE,EAAA8rE,OAAA,EAEA9rE,EAAA+rE,cAAA,EAEA/rE,EAAA65D,WAIA4N,EAAAuE,mBAAA,SAAAjnC,EAAAumC,EAAA5/D,GACA,GAAA1L,GAAAL,KACA2sD,EAAA5gD,EAAApK,SAAAqb,SAAAa,EACA+uC,EAAA7gD,EAAApK,SAAAqb,SAAAc,EACAhc,EAAAiK,EAAApK,SAAAG,MACA+tB,EAAA/tB,EAAA,kBAAA0d,MACA8sD,EAAAxqE,EAAA,yBACAyqE,EAAAzqE,EAAA,yBACA0qE,EAAA1qE,EAAA,qBAAA0d,MACAstC,EAAA/gD,EAAAi7B,QACAgmB,EAAAjhD,EAAAk7B,SACAme,EAAAr5C,EAAApK,SAAAoa,SACA0wD,EAAA3qE,EAAA,mBAAA0d,MACAktD,EAAA,SAAAD,EACAE,EAAA7qE,EAAA,4BAAA0d,MAEAotD,EAAAjB,EAAA3kC,OAAA2kC,EAAAkB,QACAC,EAAAnB,EAAA1kC,QAAA0kC,EAAAoB,SAGA,MAAAH,GAAA,MAAAE,KACA/0C,SAAA0zB,KAAAC,YAAAigB,GAEAiB,EAAAjB,EAAAkB,QAAAlB,EAAA3kC,OAAA2kC,EAAAqB,YACAF,EAAAnB,EAAAoB,QAAApB,EAAA1kC,QAAA0kC,EAAAsB,aAEAl1C,SAAA0zB,KAAAnoB,YAAAqoC,GAGA,IAAAvjE,GAAAwkE,EACAvtD,EAAAytD,EAEAI,EAAAprE,EAAA,mBACA,UAAAorE,EAAA1tD,QAEApX,EADA,MAAA8kE,EAAAC,MACAD,EAAA1tD,MAAA,IAAAstC,EAEAogB,EAAAttD,QAIA,IAAAwtD,GAAAtrE,EAAA,oBASA,IARA,SAAAsrE,EAAA5tD,QAEAH,EADA,MAAA+tD,EAAAD,MACAC,EAAA5tD,MAAA,IAAAwtC,EAEAogB,EAAAxtD,SAIA,IAAAxX,GAAA,IAAAiX,EAAA,CAIA,GAAA,YAAAwQ,EAAA,CACA,GAAAw9C,GAAA59D,KAAAkN,IAAAmwC,EAAA1kD,EAAA4kD,EAAA3tC,EAEAjX,IAAAilE,EACAhuD,GAAAguD,MAEA,IAAA,UAAAx9C,EAAA,CACA,GAAAw9C,GAAA59D,KAAA9D,IAAAmhD,EAAA1kD,EAAA4kD,EAAA3tC,EAEAjX,IAAAilE,EACAhuD,GAAAguD,EAGA,GAAAxvD,GAAA8uC,EAAAG,EAAA,CAEAjvC,IADA,MAAAyuD,EAAAa,OACArgB,EAAA1kD,GAAAkkE,EAAA9sD,MAAA,IAEA8sD,EAAA1sD,OAGA,IAAA9B,GAAA8uC,EAAAI,EAAA,CAEAlvC,IADA,MAAAyuD,EAAAY,OACAngB,EAAA3tC,GAAAktD,EAAA/sD,MAAA,IAEA+sD,EAAA3sD,QAGAwlC,EAAA8kB,YACArsD,GAAA8uC,EACA7uC,GAAA8uC,EAEAD,EAAA,EACAC,EAAA,EAGA,IAAA0gB,GAAAloC,EAAAmoC,WAIA,IAFAnoC,EAAAmoC,YAAAZ,EAEA,cAAAH,EAEAE,IACAtnC,EAAAooC,OAEApoB,EAAA8kB,UACA9kC,EAAAqnC,KAAArnB,EAAA8kB,YAEA7pE,EAAAwkD,WAAAxkD,EAAAykD,aAAA/4C,IAAA21C,KACAtc,EACAunB,EAAAC,EACAE,EAAAE,GAEA5nB,EAAAqnC,SAIApsE,EAAAqrE,cAAAtmC,EAAAumC,EAAA,EAAA,EAAAiB,EAAAE,EAAAjvD,EAAAC,EAAA1V,EAAAiX,GAEAqtD,GACAtnC,EAAAjgB,cAEA,CACA,GAAAsoD,GAAAroC,EAAAsoC,cAAA/B,EAAAa,EACApnC,GAAAylC,UAAA4C,ECzJAptE,EAAAwkD,WAAAxkD,EAAAykD,aAAA/4C,IAAA21C,KACAtc,EACAunB,EAAAC,EACAE,EAAAE,GAEA5nB,EAAAuoC,UAAA9vD,EAAAC,GACAsnB,EAAA6lC,OACA7lC,EAAAuoC,WAAA9vD,GAAAC,GAGAsnB,EAAAmoC,YAAAD,IAIA7tE,EAAAD,QAAAsoE,OAEA8F,IAAA,SAAA1sE,EAAAzB,EAAAD,GACA,YAwKA,SAAAquE,GAAAC,EAAAjwD,EAAAC,EAAAkpB,EAAAC,EAAA6L,GACA,GAAAA,GAAAA,GAAA,CACAg7B,GAAAzD,YACAyD,EAAAtF,OAAA3qD,EAAAi1B,EAAAh1B,GACAgwD,EAAA9F,OAAAnqD,EAAAmpB,EAAA8L,EAAAh1B,GACAgwD,EAAA3F,iBAAAtqD,EAAAmpB,EAAAlpB,EAAAD,EAAAmpB,EAAAlpB,EAAAg1B,GACAg7B,EAAA9F,OAAAnqD,EAAAmpB,EAAAlpB,EAAAmpB,EAAA6L,GACAg7B,EAAA3F,iBAAAtqD,EAAAmpB,EAAAlpB,EAAAmpB,EAAAppB,EAAAmpB,EAAA8L,EAAAh1B,EAAAmpB,GACA6mC,EAAA9F,OAAAnqD,EAAAi1B,EAAAh1B,EAAAmpB,GACA6mC,EAAA3F,iBAAAtqD,EAAAC,EAAAmpB,EAAAppB,EAAAC,EAAAmpB,EAAA6L,GACAg7B,EAAA9F,OAAAnqD,EAAAC,EAAAg1B,GACAg7B,EAAA3F,iBAAAtqD,EAAAC,EAAAD,EAAAi1B,EAAAh1B,GACAgwD,EAAAvC,YACAuC,EAAA7C,OAnLA,GAAA7pE,GAAAF,EAAA,eAEA4mE,IAGAA,GAAAiG,aAAA,SAAA3oC,EAAA35B,GACA,GAAAg+C,GAAAh+C,EAAA9J,SAAAG,MAAA,MAAAogB,QAEA,IAAAunC,IAAAA,EAAAxxC,MAAA,YAIAjY,KAAAqiC,uBAAAriC,KAAAy4D,SAAA+G,SAAAx/D,KAAAkiE,UAAAliE,KAAAk4D,UAAAI,UAAAt4D,KAAAkI,KAAA8lE,OAAAhuE,KAAA0jE,eAAA,CAEA,GAAAuK,GAAAxiE,EAAA9J,SAAAG,MAAA,aAAA8d,QAAAnU,EAAArI,KAAAgb,OACA8vD,EAAAziE,EAAA9J,SAAAG,MAAA,wBAAA8d,OAEA,MAAAsuD,EAAAD,GAAA,CAMA7oC,EAAA+oC,UAAA,SACA/oC,EAAAgpC,aAAA,QAEA,IAAAhpB,GAAA35C,EAAA9J,SAAAoa,QACA,IAAA3a,EAAA0Q,OAAAszC,EAAAziC,SAAAvhB,EAAA0Q,OAAAszC,EAAAxiC,QAAA,CAEA,GAEAQ,GAFAthB,EAAA2J,EAAA9J,SAAAG,MACA+gB,EAAA,eAAA/gB,EAAA,sBAAAogB,QAGAW,IACAO,EAAAgiC,EAAA/hC,WAEA+hB,EAAAuoC,UAAAvoB,EAAAziC,OAAAyiC,EAAAxiC,QACAwiB,EAAA5hB,OAAAJ,GAEApjB,KAAAquE,SAAAjpC,EAAA35B,EAAA,EAAA,GAEA25B,EAAA5hB,QAAAJ,GACAgiB,EAAAuoC,WAAAvoB,EAAAziC,QAAAyiC,EAAAxiC,SAEA5iB,KAAAquE,SAAAjpC,EAAA35B,EAAA25C,EAAAziC,OAAAyiC,EAAAxiC,YAMAklD,EAAAwG,aAAA,SAAAlpC,EAAAr5B,GACA,GAAA09C,GAAA19C,EAAApK,SAAAG,MAAA,MAAAogB,QAEA,IAAAunC,IAAAA,EAAAxxC,MAAA,SAAA,CAIA,GAAAg2D,GAAAliE,EAAApK,SAAAG,MAAA,aAAA8d,QAAA7T,EAAA3I,KAAAgb,OACA8vD,EAAAniE,EAAApK,SAAAG,MAAA,wBAAA8d,OAEA,MAAAsuD,EAAAD,GAAA,CAMA,GAAA5kB,GAAAt9C,EAAApK,SAAAG,MAAA,eAAAogB,SACAonC,EAAAv9C,EAAApK,SAAAG,MAAA,eAAAogB,SACAkjC,EAAAr5C,EAAApK,SAAAoa,QACA,IAAA3a,EAAA0Q,OAAAszC,EAAAziC,SAAAvhB,EAAA0Q,OAAAszC,EAAAxiC,QAAA,CAEA,OAAAymC,GACA,IAAA,OACAjkB,EAAA+oC,UAAA,OACA,MAEA,KAAA,QACA/oC,EAAA+oC,UAAA,MACA,MAEA,SACA/oC,EAAA+oC,UAAA,SAGA,OAAA7kB,GACA,IAAA,MACAlkB,EAAAgpC,aAAA,QACA,MAEA,KAAA,SACAhpC,EAAAgpC,aAAA,KACA,MAEA,SACAhpC,EAAAgpC,aAAA,SAGApuE,KAAAquE,SAAAjpC,EAAAr5B,EAAAq5C,EAAAziC,OAAAyiC,EAAAxiC,YAGAklD,EAAAyG,aAAA,SAAAnpC,GACA,GAAAgmB,EAEAprD,MAAAwuE,WAAAxuE,KAAAwuE,cAEA,KAAA,GAAA7tE,GAAA,EAAAA,EAAAX,KAAAwuE,WAAAxtE,OAAAL,IAGA,GAFAyqD,EAAAprD,KAAAwuE,WAAA7tE,GAEAyqD,EAAAhmB,UAAAA,EACA,MAAAgmB,EASA,OALAA,IACAhmB,QAAAA,GAEAplC,KAAAwuE,WAAA/rE,KAAA2oD,GAEAA,GAKA0c,EAAA2G,eAAA,SAAArpC,EAAAze,GAEA,GAAAgL,GAAAhL,EAAA+K,mBACA5vB,EAAA6kB,EAAAhlB,SAAAG,MACA4sE,EAAA5sE,EAAA,cAAAogB,SACAysD,EAAA7sE,EAAA,aAAA8d,QAAA,KACAgvD,EAAA9sE,EAAA,eAAAogB,SACA2sD,EAAA/sE,EAAA,eAAAogB,SACA0P,EAAA9vB,EAAA,gBAAA0d,MAAA1d,EAAA,QAAA0d,MAAAmS,EACAm9C,EAAAhtE,EAAA,wBAAA0d,MAAAoS,EACAm5C,EAAAjpE,EAAA,MAAA0d,MACAuvD,EAAAjtE,EAAA,sBAAA0d,MACA8pD,EAAAxnE,EAAA,oBAAA8d,QACA2pD,EAAAznE,EAAA,uBAAA0d,MACAgqD,EAAA1nE,EAAA,qBAAA0d,MACAiqD,EAAA3nE,EAAA,wBAAA8d,QACA8pD,EAAA5nE,EAAA,wBAAA8d,QAEAovD,EAAAroD,EAAAhlB,SAAAstE,QACA7jB,EAAAprD,KAAAuuE,aAAAnpC,EAEAgmB,GAAAx/C,MAAAojE,IACA5pC,EAAA8pC,KAAAR,EAAA,IAAAG,EAAA,IAAAF,EAAA,IAAAC,EAEAxjB,EAAAx/C,IAAAojE,EAGA,IAAAvlB,GAAAzpD,KAAA0pD,aAAA/iC,EAaA,OARAye,GAAAomC,SAAA,QAEAxrE,KAAA6qE,UAAAzlC,EAAA2lC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAn5C,GAEA5xB,KAAAipE,YAAA7jC,EAAA2pC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAD,GAEA9uE,KAAA2pE,YAAAvkC,EAAAokC,EAAAD,EAAAD,EAAAG,EAAAC,GAEAjgB,GAoBAqe,EAAAuG,SAAA,SAAAjpC,EAAAze,EAAAqiC,EAAAC,GACA,GAAAvnD,GAAAilB,EAAAhlB,SACAG,EAAAJ,EAAAI,MACA8f,EAAAlgB,EAAAkgB,OACA7F,EAAAra,EAAAqa,SACA4V,EAAAhL,EAAA+K,kBACA,IAAA,IAAAC,GAAA,IAAA7vB,EAAA,gBAAA0d,MAAA,CAEA,GAAAiqC,GAAAzpD,KAAAyuE,eAAArpC,EAAAze,GACApE,EAAAzgB,EAAA,eAAA0d,MACAgD,EAAA1gB,EAAA,eAAA0d,KAOA,IALAmH,EAAAtF,WACAkB,EAAA,SACAC,EAAA,UAGAmE,EAAAzZ,SAAA,CACA,GAAAiiE,GAAArtE,EAAA,gBAAA8d,QACAwvD,EAAAttE,EAAA,iBAAA8d,QACAyvD,EAAAvtE,EAAA,eAAA8d,QACA0vD,EAAAxtE,EAAA,kBAAA8d,OAEAopC,IAAAmmB,EAAA,EACAnmB,GAAAomB,EAAA,EAEAnmB,GAAAomB,EAAA,EACApmB,GAAAqmB,EAAA,EAGA,GAAA,MAAA7lB,IAAAviB,MAAA8hB,KAAA9hB,MAAA+hB,GAAA,CACA,GAAAsmB,GAAAztE,EAAA,2BAAA0d,MACAgwD,EAAA1tE,EAAA,uBAAA0d,MACAiwD,EAAA3tE,EAAA,qBAAA8d,OAEA,IAAA2vD,EAAA,GAAAE,EAAA,GAAAD,EAAA,EAAA,CACA,GAAAE,GAAA,EAAAD,EAAA,CAEA9oD,GAAAzZ,WAEA,QAAAsV,EACAymC,GAAAymB,EACA,WAAAltD,IACAymC,GAAAymB,GAEA,SAAAntD,EACAymC,GAAA0mB,EACA,UAAAntD,IACAymC,GAAA0mB,GAIA,IAAAC,GAAA/tD,EAAAa,WACAmtD,EAAAhuD,EAAAc,YACAmtD,EAAA7mB,CAEAzmC,KACA,UAAAA,EACAstD,GAAAF,EAAA,EACA,QAAAptD,IACAstD,GAAAF,GAIA,IAAAG,GAAA7mB,CAyBA,IAvBAtiC,EAAAzZ,SACA,OAAAsV,EACAstD,GAAAF,EACA,UAAAptD,IACAstD,GAAAF,EAAA,GAGAE,GAAAF,EAAA,EAGA,eAAA9tE,EAAA,sBAAAogB,UACA+mC,EAAA,EACA0mB,GAAA,EACAE,EAAA7mB,EAAA2mB,EAAA,EACAG,EAAA7mB,EAAA2mB,EAAA,IAGAC,GAAAH,EACAI,GAAAJ,EACAE,GAAA,EAAAF,EACAC,GAAA,EAAAD,GAGAH,EAAA,EAAA,CACA,GAAAQ,GAAA3qC,EAAAylC,UACAmF,EAAAluE,EAAA,yBAAA0d,KAEA4lB,GAAAylC,UAAA,QAAAmF,EAAA,GAAA,IAAAA,EAAA,GAAA,IAAAA,EAAA,GAAA,IAAAT,EAAA59C,EAAA,GACA,IAAAs+C,GAAAnuE,EAAA,yBAAAogB,QACA,mBAAA+tD,EACApC,EAAAzoC,EAAAyqC,EAAAC,EAAAH,EAAAC,EAAA,GAEAxqC,EAAA8qC,SAAAL,EAAAC,EAAAH,EAAAC,GAEAxqC,EAAAylC,UAAAkF,EAGA,GAAAN,EAAA,GAAAD,EAAA,EAAA,CACA,GAAAW,GAAA/qC,EAAA6jC,YACAmH,EAAAhrC,EAAAikC,UACAgH,EAAAvuE,EAAA,qBAAA0d,MACA8wD,EAAAxuE,EAAA,qBAAA0d,KAKA,IAHA4lB,EAAA6jC,YAAA,QAAAoH,EAAA,GAAA,IAAAA,EAAA,GAAA,IAAAA,EAAA,GAAA,IAAAb,EAAA79C,EAAA,IACAyT,EAAAikC,UAAAoG,EAEArqC,EAAAglC,YACA,OAAAkG,GACA,IAAA,SACAlrC,EAAAglC,aAAA,EAAA,GACA,MACA,KAAA,SACAhlC,EAAAglC,aAAA,EAAA,GACA,MACA,KAAA,SACAhlC,EAAAikC,UAAAoG,EAAA,EACArqC,EAAAglC,eACA,MACA,KAAA,QACAhlC,EAAAglC,gBAOA,GAFAhlC,EAAAmrC,WAAAV,EAAAC,EAAAH,EAAAC,GAEA,WAAAU,EAAA,CACA,GAAAE,GAAAf,EAAA,CAEArqC,GAAAmrC,WAAAV,EAAAW,EAAAV,EAAAU,EAAAb,EAAA,EAAAa,EAAAZ,EAAA,EAAAY,GAGAprC,EAAAglC,aACAhlC,EAAAglC,gBAEAhlC,EAAAikC,UAAA+G,EACAhrC,EAAA6jC,YAAAkH,GAKA,GAAA9G,GAAA,EAAAvnE,EAAA,sBAAA8d,OAMA,IAJAypD,EAAA,IACAjkC,EAAAikC,UAAAA,GAGA,SAAAvnE,EAAA,aAAA0d,MAAA,CACA,GAAA2qC,GAAApuC,EAAAgvC,qBACAmB,EAAAtqC,EAAAc,YAAAynC,EAAAnpD,MAEA,QAAAwhB,GACA,IAAA,MACAymC,IAAAkB,EAAAnpD,OAAA,GAAAkrD,CACA,MAEA,KAAA,SAEA,KAEA,SACA,IAAA,SACAjD,IAAAkB,EAAAnpD,OAAA,GAAAkrD,EAAA,EAGA,IAAA,GAAAprD,GAAA,EAAAA,EAAAqpD,EAAAnpD,OAAAF,IACAuoE,EAAA,GACAjkC,EAAAqrC,WAAAtmB,EAAArpD,GAAAkoD,EAAAC,GAGA7jB,EAAAsrC,SAAAvmB,EAAArpD,GAAAkoD,EAAAC,GAEAA,GAAAiD,MC3XAmd,GAAA,GACAjkC,EAAAqrC,WAAAhnB,EAAAT,EAAAC,GAGA7jB,EAAAsrC,SAAAjnB,EAAAT,EAAAC,EAIAjpD,MAAA2pE,YAAAvkC,EAAA,cAAA,MAKA3lC,EAAAD,QAAAsoE,IAEAnlB,cAAA,KAAAguB,IAAA,SAAAzvE,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,eAEA4mE,IAGAA,GAAA8I,SAAA,SAAAxrC,EAAAr5B,EAAA68D,GAEA,GACA1f,GAAAC,EADA9oD,EAAAL,KAEA8B,EAAAiK,EAAApK,SAAAG,MACAsjD,EAAAr5C,EAAApK,SAAAoa,SACAra,EAAAqK,EAAApK,SACA+b,EAAAhc,EAAAsb,QAEA,IAAA5b,EAAA0Q,OAAA4L,EAAAG,IAAAzc,EAAA0Q,OAAA4L,EAAAI,GAAA,CAIA,GAEAlW,GAFAihE,EAAA7oE,KAAA6oE,WACAqC,EAAA9lC,EAEA2kC,GAAA,EAEAjB,EAAAhnE,EAAA,mBAAA8d,QACAmpD,EAAAjnE,EAAA,mBAAA0d,MACAwpD,EAAAlnE,EAAA,iBAAA0d,KAEA,KAAAopD,GAAA,IAAAG,EAAA,CAIA,GAAAp3C,GAAA5lB,EAAA2lB,kBACA,IAAA,IAAAC,EAOA,GALAu3B,EAAAn9C,EAAAi7B,QAAAllC,EAAA,gBAAA8d,QAAA9d,EAAA,iBAAA8d,QACAupC,EAAAp9C,EAAAk7B,SAAAnlC,EAAA,eAAA8d,QAAA9d,EAAA,kBAAA8d,QAEAwlB,EAAAikC,UAAAvnE,EAAA,gBAAA8d,QAEA9b,SAAA8kE,GAAAA,EAiMAG,EAAA,IACA/oE,KAAA6qE,UAAAzlC,EAAA4jC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAD,GAEA1oE,EAAAwkD,WAAA,eAAAnD,KACAtc,EACAr5B,EAAApK,SAAAqb,SAAAa,EACA9R,EAAApK,SAAAqb,SAAAc,EACAorC,EAAA,EAAA4f,EACA3f,EAAA,EAAA2f,GAGA1jC,EAAA6lC,YA5MA,CAEA,GAEAtT,GAFAH,EAAA11D,EAAA,oBAAA0d,MAAA,IACA1d,EAAA,oBAAA0d,MAAA,EAGA,IAAA1b,SAAA0zD,EAAA,CAGAG,EAAA33D,KAAAu3D,eAAAC,EAAA,WACAn3D,EAAA6H,KAAA+jE,kBAAA5rE,EAAA6rE,OAAA,EACA7rE,EAAA6H,KAAA+jE,kBAAA5rE,EAAA8rE,OAAA,EAEA9rE,EAAA+rE,cAAA,EAEA/rE,EAAA65D,UAGA,IAAA2W,GAAAnvE,EAAAuwB,aACAvwB,GAAAuwB,eAAA0lC,EAAAp1D,SAEAsuE,IAAAnvE,EAAAuwB,eACAlmB,EAAA4M,aAAA,GAMA,GAAAm4D,GAAAhvE,EAAA,oBAAA0d,MACAuxD,EAAAjvE,EAAA,gBAAA0d,MACAwxD,EAAAlvE,EAAA,gBAAA0d,KAEAxf,MAAA6qE,UAAAzlC,EAAA0rC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAhvE,EAAA,sBAAA0d,MAAAmS,GAEA3xB,KAAAipE,YAAA7jC,EAAA2rC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAjvE,EAAA,kBAAA0d,MAAAmS,EAEA,IAAA23C,GAAAxnE,EAAA,eAAA8d,QACA2pD,EAAAznE,EAAA,kBAAA0d,MACAgqD,EAAA1nE,EAAA,gBAAA0d,MACAiqD,EAAA3nE,EAAA,mBAAA8d,QACA8pD,EAAA5nE,EAAA,mBAAA8d,OAMA,IAJA5f,KAAA2pE,YAAAvkC,EAAAokC,EAAAD,EAAAD,EAAAG,EAAAC,GAEAtkC,EAAAomC,SAAA,QAEApmC,EAAAglC,YACA,OAAA4G,GACA,IAAA,SACA5rC,EAAAglC,aAAA,EAAA,GACA,MAEA,KAAA,SACAhlC,EAAAglC,aAAA,EAAA,GACA,MAEA,KAAA,QACA,IAAA,SACAhlC,EAAAglC,gBAMA,GAAA6F,GAAAnuE,EAAA,MAAAogB,QAEA,IAAA2mD,EAAA,CACA,GAAAmB,GAAAiG,EAAA,IAAA/mB,EAAA,IAAAC,CAEA/jB,GAAAuoC,UAAAjwD,EAAAG,EAAAH,EAAAI,GAEAsnC,EAAA4kB,eAAAA,GACApiE,EAAAw9B,EAAAggB,EAAA8kB,UACAH,GAAA,IAEAniE,EAAAw9B,EAAA,GAAA+kC,QACA/kB,EAAA4kB,aAAAA,EACA5kB,EAAA8kB,UAAAtiE,GAIA,IAAAmiE,EAAA,CAEA,GAAAkH,GAAAvzD,CAEAmrD,KACAoI,GACApzD,EAAA,EACAC,EAAA,IAIAzd,EAAAwkD,WAAA7kD,KAAA8kD,aAAA/4C,IAAA21C,KACAtc,EACA6rC,EAAApzD,EACAozD,EAAAnzD,EACAorC,EACAC,GAGA/jB,EAAA8lC,EAEArC,EACAzjC,EAAA6lC,KAAArjE,GAEAw9B,EAAA6lC,OAGAjrE,KAAA2pE,YAAAvkC,EAAA,cAAA,GAEAthC,SAAA0zD,GACAG,EAAAp1D,UACAvC,KAAAqsE,mBAAAjnC,EAAAuyB,EAAA5rD,EAIA,IAAAmlE,GAAApvE,EAAA,sBAAA0d,MACA2xD,EAAArvE,EAAA,gBAAA8d,OAuCA,IArCA5f,KAAAoxE,OAAArlE,KACA/L,KAAAqxE,QAAAjsC,EAAAr5B,EAAA4lB,IAGA,IAAAu/C,GAAA,IAAAC,KAEAtI,GACAxoE,EAAAwkD,WAAA7kD,KAAA8kD,aAAA/4C,IAAA21C,KACAtc,EACA1nB,EAAAG,EACAH,EAAAI,EACAorC,EACAC,KAKA+nB,EAAA,GACAlxE,KAAA6qE,UAAAzlC,EAAA,EAAA,EAAA,EAAA8rC,GAEArI,EACAzjC,EAAA6lC,KAAArjE,GAEAw9B,EAAA6lC,QAGA,EAAAiG,IACAlxE,KAAA6qE,UAAAzlC,EAAA,IAAA,IAAA,KAAA8rC,GAEArI,EACAzjC,EAAA6lC,KAAArjE,GAEAw9B,EAAA6lC,QAKAkG,EAAA,IAEAtI,EACAzjC,EAAAklC,OAAA1iE,GAEAw9B,EAAAklC,SAGA,WAAA0G,GAAA,CACA5rC,EAAAikC,UAAAvnE,EAAA,gBAAA8d,QAAA,CAEA,IAAA6qD,GAAArlC,EAAAslC,wBACAtlC,GAAAslC,yBAAA,kBAEA7B,EACAzjC,EAAAklC,OAAA1iE,GAEAw9B,EAAAklC,SAGAllC,EAAAslC,yBAAAD,EAKA5B,GACAzjC,EAAAuoC,WAAAjwD,EAAAG,GAAAH,EAAAI,GAIAsnB,EAAAglC,aACAhlC,EAAAglC,oBAwBAtC,EAAAsJ,OAAA,SAAArlE,GAGA,MAFAA,GAAAA,EAAA,GAEAA,EAAApK,SAAAyvE,QAGAtJ,EAAAuJ,QAAA,SAAAjsC,EAAAr5B,EAAAulE,GACAvlE,EAAAA,EAAA,EAEA,IAAArK,GAAAqK,EAAApK,SACA4vE,EAAAxlE,EAAA3I,KAAAtB,QACAA,EAAAJ,EAAAI,MACA0vE,EAAA1vE,EAAA,YACAgrD,EAAA/gD,EAAAi7B,QACAgmB,EAAAjhD,EAAAk7B,SACAppB,EAAAnc,EAAAsb,SAAAa,EACAC,EAAApc,EAAAsb,SAAAc,EACAg1B,EAAArjC,KAAAkN,IAAAmwC,EAAAE,GAAA,EACAykB,EAAA,EACA5I,EAAA7oE,KAAA6oE,UAEAA,KACAhrD,EAAA,EACAC,EAAA,GAGA,MAAA0zD,EAAArE,MACAr6B,EAAAA,EAAA0+B,EAAAhyD,MAAA,IACA1b,SAAA0tE,EAAA5xD,UACAkzB,EAAA0+B,EAAA5xD,QAAA,EAGA,KAAA,GAAAjf,GAAA,EAAAA,GAAA4wE,EAAAG,eAAA/wE,IAAA,CACA,GAAA2O,GAAAxN,EAAA,OAAAnB,EAAA,oBAAA6e,MACAurD,EAAAjpE,EAAA,OAAAnB,EAAA,qBAAA6e,MACAoS,EAAA9vB,EAAA,OAAAnB,EAAA,uBAAA6e,MAAA8xD,EACAx2C,EAAAxrB,EAAA,GAGAwrB,GAAA22C,EAAA,IACA32C,EAAA,EAAA22C,EAGA,IAAAE,GAAA,IAAAliE,KAAAsjC,GAAA,EAAAtjC,KAAAsjC,GAAA0+B,EACAG,EAAA,EAAAniE,KAAAsjC,GAAAjY,EACA+2C,EAAAF,EAAAC,CAMA,KAAAtiE,GAAAmiE,GAAA,GAAAA,EAAA32C,EAAA,IjE0ygBIsK,EAAQilC,YkE1mhBZjlC,EAAAojC,OAAA3qD,EAAAC,GACAsnB,EAAAqjC,IAAA5qD,EAAAC,EAAAg1B,EAAA6+B,EAAAE,GACAzsC,EAAAmmC,YAEAvrE,KAAA6qE,UAAAzlC,EAAA2lC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAn5C,GAEAwT,EAAA6lC,OAEAwG,GAAA32C,KAMAr7B,EAAAD,QAAAsoE,IAEAnlB,cAAA,KAAAmvB,IAAA,SAAA5wE,EAAAzB,EAAAD,GACA,YAEA,IAAAsoE,MAEA3mE,EAAAD,EAAA,iBACAsuC,EAAAtuC,EAAA,iBAEA6wE,EAAA,GAIAjK,GAAAkK,cAAA,WACA,GAAA5sC,GAAAplC,KAAAkI,KAAA+pE,SAAA,EAEA,IAAA,MAAAjyE,KAAAk5D,iBACA,MAAAl5D,MAAAk5D,gBAGA,IAAAgZ,GAAA9sC,EAAA+sC,wBACA/sC,EAAAgtC,8BACAhtC,EAAAitC,2BACAjtC,EAAAktC,0BACAltC,EAAAmtC,yBACAntC,EAAA+sC,wBAAA,CAEA,QAAAtyE,OAAA2yE,kBAAA,GAAAN,GAGApK,EAAA2K,WAAA,SAAArtC,GAKA,IAAA,GAFAgmB,GAFAsnB,EAAA1yE,KAAA2yE,YAAA3yE,KAAA2yE,gBACAC,GAAA,EAGAjyE,EAAA,EAAAA,EAAA+xE,EAAA1xE,OAAAL,IAGA,GAFAyqD,EAAAsnB,EAAA/xE,GAEAyqD,EAAAhmB,UAAAA,EAAA,CACAwtC,GAAA,CACA,OAWA,MAPAA,KACAxnB,GACAhmB,QAAAA,GAEAstC,EAAAjwE,KAAA2oD,IAGAA,GAGA0c,EAAA+C,UAAA,SAAAzlC,EAAA/kC,EAAAT,EAAAwE,EAAA3D,GACA2kC,EAAAylC,UAAA,QAAAxqE,EAAA,IAAAT,EAAA,IAAAwE,EAAA,IAAA3D,EAAA,KAaAqnE,EAAAmB,YAAA,SAAA7jC,EAAA/kC,EAAAT,EAAAwE,EAAA3D,GACA2kC,EAAA6jC,YAAA,QAAA5oE,EAAA,IAAAT,EAAA,IAAAwE,EAAA,IAAA3D,EAAA,KAaAqnE,EAAA6B,YAAA,SAAAvkC,EAAA2lC,EAAAn5C,EAAAihD,EAAAt6B,EAAAC,GACA,GAAAp6B,GAAApe,KAAAoD,GAAAgb,OAEAgtC,EAAAprD,KAAAyyE,WAAArtC,IAGA,IAAAgmB,EAAAme,eAAA,IAAA33C,KAIAw5B,EAAAme,cAAA33C,EAEAA,EAAA,GACAwT,EAAAkkC,WAAAuJ,EAAAz0D,EACAgnB,EAAAokC,YAAA,QAAAuB,EAAA,GAAA,IAAAA,EAAA,GAAA,IAAAA,EAAA,GAAA,IAAAn5C,EAAA,IACAwT,EAAAqkC,cAAAlxB,EAAAn6B,EACAgnB,EAAAskC,cAAAlxB,EAAAp6B,IAEAgnB,EAAAkkC,WAAA,EACAlkC,EAAAokC,YAAA,iBAKA1B,EAAA9N,gBAAA,SAAA75B,GACA,GAAA9/B,GAAAL,KACAkI,EAAA7H,EAAA6H,KACA8+B,EAAA7G,EAAAiI,YACAnB,EAAA9G,EAAAkI,aACA1F,EAAAtiC,EAAA2xE,gBACAc,EAAAzyE,EAAA+4D,mBAGAj5B,IAAA9/B,EAAA6H,KAAA6qE,eAAA1yE,EAAA2yE,yBACA7yC,IAAA9/B,EAAA6H,KAAA6qE,eAAA1yE,EAAA4yE,2BAEAtwC,EAAAmwC,EAGA,IAEAI,GAFA/U,EAAAn3B,EAAArE,EACAy7B,EAAAn3B,EAAAtE,CAGA,IAAAw7B,IAAA99D,EAAA89D,aAAAC,IAAA/9D,EAAA+9D,aAAA,CAIA/9D,EAAAmuE,WAAA,IAEA,IAAA2E,GAAAjrE,EAAAirE,eACAA,GAAArxE,MAAAklC,MAAAA,EAAA,KACAmsC,EAAArxE,MAAAmlC,OAAAA,EAAA,IAEA,KAAA,GAAAtmC,GAAA,EAAAA,EAAAN,EAAA+yE,cAAAzyE,IAEAuyE,EAAAhrE,EAAAmrE,SAAA1yE,IAEAuyE,EAAAlsC,QAAAm3B,GAAA+U,EAAAjsC,SAAAm3B,KAEA8U,EAAAlsC,MAAAm3B,EACA+U,EAAAjsC,OAAAm3B,EAEA8U,EAAApxE,MAAAklC,MAAAA,EAAA,KACAksC,EAAApxE,MAAAmlC,OAAAA,EAAA,KAIA,KAAA,GAAAtmC,GAAA,EAAAA,EAAAN,EAAAizE,aAAA3yE,IAEAuyE,EAAAhrE,EAAA6qE,eAAApyE,IAEAuyE,EAAAlsC,QAAAm3B,GAAA+U,EAAAjsC,SAAAm3B,KAEA8U,EAAAlsC,MAAAm3B,EACA+U,EAAAjsC,OAAAm3B,EAEA8U,EAAApxE,MAAAklC,MAAAA,EAAA,KACAksC,EAAApxE,MAAAmlC,OAAAA,EAAA,KAIA5mC,GAAAkzE,YAAA,EACA,GAAA5wC,IACAuwC,EAAAhrE,EAAA6qE,eAAA1yE,EAAAmzE,gBAEAnzE,EAAAkzE,YAAA,EACAL,EAAAlsC,MAAAm3B,EAAA99D,EAAAkzE,YACAL,EAAAjsC,OAAAm3B,EAAA/9D,EAAAkzE,aAGAlzE,EAAA89D,YAAAA,EACA99D,EAAA+9D,aAAAA,IAIA0J,EAAA3iC,SAAA,SAAA28B,EAAA1jD,EAAAC,EAAAgnB,GACArlC,KAAA2nE,QACAd,cAAA/E,EACA2R,WAAAr1D,EACAs1D,UAAAr1D,EACAs1D,eAAA,EACAC,cAAAvuC,KAIAyiC,EAAAH,OAAA,SAAAriE,GAyGA,QAAAuuE,GAAAzuC,EAAAvnB,EAAAC,EAAA1V,EAAAiX,GACA,GAAAorD,GAAArlC,EAAAslC,wBAEAtlC,GAAAslC,yBAAA,kBACArqE,EAAAwqE,UAAAzlC,EAAA,IAAA,IAAA,IAAA/kC,EAAA84D,wBACA/zB,EAAA8qC,SAAAryD,EAAAC,EAAA1V,EAAAiX,GAEA+lB,EAAAslC,yBAAAD,EAGA,QAAAqJ,GAAA1uC,EAAA2uC,GACA,GAAAC,GAAAC,EAAA7rE,EAAAiX,CAEAhf,GAAA6zE,oBAAA9uC,IAAAl9B,EAAAisE,eAAA9zE,EAAA2yE,yBAAA5tC,IAAAl9B,EAAAisE,eAAA9zE,EAAA4yE,yBAWAe,EAAAI,EACAH,EAAAI,EAEAjsE,EAAA/H,EAAA89D,YACA9+C,EAAAhf,EAAA+9D,eAdA4V,GACAn2D,EAAAQ,EAAAR,EAAAi1D,EACAh1D,EAAAO,EAAAP,EAAAg1D,GAGAmB,EAAA71D,EAAA00D,EAEA1qE,EAAA/H,EAAA89D,YAAA2U,EACAzzD,EAAAhf,EAAA+9D,aAAA0U,GASA1tC,EAAAkvC,aAAA,EAAA,EAAA,EAAA,EAAA,EAAA,GAEA,eAAAP,EACAF,EAAAzuC,EAAA,EAAA,EAAAh9B,EAAAiX,GACAwnD,GAAA/iE,SAAAiwE,IAAAA,GACA3uC,EAAAmvC,UAAA,EAAA,EAAAnsE,EAAAiX,GAGAs0D,IACAvuC,EAAAuoC,UAAAqG,EAAAn2D,EAAAm2D,EAAAl2D,GACAsnB,EAAAioC,MAAA4G,EAAAA,IAEAP,GACAtuC,EAAAuoC,UAAA+F,EAAA71D,EAAA61D,EAAA51D,GAEA21D,GACAruC,EAAAioC,MAAAoG,EAAAA,GA8GA,QAAAe,GAAAC,EAAArvC,GAGA,IAAA,GAFA7/B,GAAAkvE,EAAAlvE,KAEA5E,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,EAEAsH,GAAAiF,UACA7M,EAAAuwE,SAAAxrC,EAAAn9B,GAEAysE,GACAr0E,EAAAiuE,aAAAlpC,EAAAn9B,GAGA5H,EAAAuwE,SAAAxrC,EAAAn9B,GAAA,IACA0sE,IACAt0E,EAAAsoE,SAAAvjC,EAAAn9B,GAEAysE,GACAr0E,EAAA0tE,aAAA3oC,EAAAn9B,GAGA5H,EAAAsoE,SAAAvjC,EAAAn9B,GAAA,KA1RA3C,EAAAA,GAAAnE,EAAAmf,mBAEA,IAAAumD,GAAAvhE,EAAAuhE,cACA8M,EAAAruE,EAAAquE,cACAiB,EAAAtvE,EAAAsvE,kBACAnB,EAAAnuE,EAAAmuE,WACAC,EAAApuE,EAAAouE,UACArzE,EAAAL,KACA2iC,EAAA7+B,SAAAwB,EAAAsuE,cAAA5zE,KAAAgyE,gBAAA1sE,EAAAsuE,cACAxwE,EAAA/C,EAAA+C,GAAA8E,EAAA7H,EAAA6H,KACA2sE,EAAA3sE,EAAA+jE,kBACA6I,EAAAz0E,EAAAkiC,oBAAAskC,IAAAxmE,EAAA6hE,UAAA7hE,EAAA63D,UAAAI,UAAAj4D,EAAAqjE,cAAArjE,EAAA6H,KAAAi4D,cACA19B,EAAA3+B,SAAAwB,EAAAm9B,WAAAn9B,EAAAm9B,WAAApiC,EAAAoiC,WACAqwC,EAAAzyE,EAAA+4D,kBACA16C,EAAAtb,EAAAsb,mBACAq2D,EAAA10E,EAAA63D,UAAAsG,aACAtB,EAAA78D,EAAA63D,UAAA2H,WAAAx/D,EAAAs4D,UAAAkH,WAAA,GAAA,CACAp9B,GAAAA,IAAAokC,GAAAxmE,EAAA44D,oBAAAiE,CACA,IAAA8X,GAAAvyC,GAEAokC,GAAAxmE,EAAA40E,mBACAzX,aAAAn9D,EAAA40E,mBAGAxyC,IACA,MAAApiC,EAAA60E,WACA70E,EAAA60E,SAAA,GAGA70E,EAAA+rE,cACA/rE,EAAA60E,WAGA70E,EAAA60E,SAAA,IACAF,GAAA,GAIA30E,EAAA60E,SAAA70E,EAAAi5D,qBAEAj5D,EAAA+4D,kBAAA/4D,EAAAg5D,cAIAh5D,EAAA6zE,qBACA7zE,EAAA+4D,kBAAA,GAKA/4D,EAAA80E,uBAAAL,IACAD,EAAAx0E,EAAA6rE,OAAA,EACA2I,EAAAx0E,EAAA+0E,aAAA,EAGA,IAAAjuE,GAAA9G,EAAA+iD,iBACAiyB,EAAAjyE,EAAAtB,QAAAH,SAAA0zE,UAEAj3D,EAAAhb,EAAAgb,OACAi2D,EAAAvwE,SAAA2vE,EAAAA,EAAAr1D,EACAC,EAAAjb,EAAAib,MACA+1D,GACAv2D,EAAAQ,EAAAR,EACAC,EAAAO,EAAAP,GAGAw3D,GACAl3D,KAAAA,EACAC,KACAR,EAAAQ,EAAAR,EACAC,EAAAO,EAAAP,IAGAy3D,EAAAl1E,EAAAm1E,aACAC,EAAA3xE,SAAAyxE,GAAAD,EAAAl3D,OAAAm3D,EAAAn3D,MAAAk3D,EAAAj3D,IAAAR,IAAA03D,EAAAl3D,IAAAR,GAAAy3D,EAAAj3D,IAAAP,IAAAy3D,EAAAl3D,IAAAP,CAGA23D,IAAAV,IAAAr2D,IACAre,EAAA+4D,kBAAA,GAGAsa,IACAU,EAAAV,GAKAW,GAAA1xC,EACAyxC,EAAAv2D,GAAA8kB,EACAyxC,EAAAt2D,GAAA6kB,CAEA,IAAAp9B,IACAmwE,MACApuE,SACAH,SACA5B,SAEAowE,SACAruE,SACAH,SACA5B,SA2DA,IAJAuvE,IACAz0E,EAAA80E,sBAAA,GAGAL,EAAA,CACAz0E,EAAA80E,sBAAA,CAEA,IAAAp2D,EAEA,KAAA1e,EAAAu1E,aAAA,CACAv1E,EAAAu1E,gBAEA72D,EAAA1e,EAAAu1E,aAAA72D,GAAA3b,EAAA2X,WAAAiE,cAEA3e,EAAAu1E,aAAAC,QAAAx1E,EAAA6H,KAAA6qE,eAAA1yE,EAAAmzE,eAEA,IAAA1R,GAAAzhE,EAAA6H,KAAAisE,eAAA9zE,EAAAmzE,eAEA1R,GAAAwS,aAAA,EAAA,EAAA,EAAA,EAAA,EAAA,GACAxS,EAAAyS,UAAA,EAAA,EAAAl0E,EAAA89D,YAAA99D,EAAAkzE,YAAAlzE,EAAA+9D,aAAA/9D,EAAAkzE,aAEAlzE,EAAAsnE,QACAd,cAAA/E,EACA8S,mBAAA,EACAhB,cAAAjxC,EAAAtiC,EAAAkzE,aAGA,IAAA+B,GAAAj1E,EAAAu1E,aAAAluC,UACAtpB,KAAAhb,EAAAgb,OACAC,IAAAjb,EAAAib,MACA2oB,MAAA3mC,EAAA89D,YACAl3B,OAAA5mC,EAAA+9D,aAGAkX,GAAAQ,MACAj4D,GAAA,EAAAy3D,EAAAj3D,IAAAR,GAAAy3D,EAAAl3D,KACAN,GAAA,EAAAw3D,EAAAj3D,IAAAP,GAAAw3D,EAAAl3D,MAIAy2D,EAAAx0E,EAAA8rE,OAAA,EACA0I,EAAAx0E,EAAA6rE,OAAA,CAEA,IAAA9mC,GAAAl9B,EAAA+pE,SAAA5xE,EAAA6rE,MAEA2J,EAAAx1E,EAAAu1E,aAAAC,QACAP,EAAAj1E,EAAAu1E,aAAAluC,QACA3oB,GAAA1e,EAAAu1E,aAAA72D,GAEAqmB,EAAAkvC,aAAA,EAAA,EAAA,EAAA,EAAA,EAAA,GAEA7xC,EACAoxC,EAAAzuC,EAAA,EAAA,EAAAkwC,EAAAtuC,MAAAsuC,EAAAruC,QAEA7B,EAAAmvC,UAAA,EAAA,EAAAe,EAAAtuC,MAAAsuC,EAAAruC,OAGA,IAAA8uC,GAAAV,EAAA,4BAAA71D,MACAw2D,EAAAX,EAAA,8BAAA71D,KACAnf,GAAAwqE,UAAAzlC,EAAA2wC,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAC,GACA5wC,EAAA8qC,SAAA,EAAA,EAAAoF,EAAAtuC,MAAAsuC,EAAAruC,OAEA,IAAA7oB,GAAAhb,EAAAgb,MAEA01D,GAAA1uC,GAAA,GAEAA,EAAAmvC,UAAAe,EAAAQ,KAAAj4D,EAAAy3D,EAAAQ,KAAAh4D,EAAAw3D,EAAAtuC,MAAAsuC,EAAAl3D,KAAAukB,EAAA2yC,EAAAruC,OAAAquC,EAAAl3D,KAAAukB,GACAyC,EAAA4mC,UAAA6J,EAAAP,EAAAQ,KAAAj4D,EAAAy3D,EAAAQ,KAAAh4D,EAAAw3D,EAAAtuC,MAAAsuC,EAAAl3D,KAAAukB,EAAA2yC,EAAAruC,OAAAquC,EAAAl3D,KAAAukB,OAEAtiC,GAAAkiC,oBAAAskC,IACAxmE,EAAAu1E,aAAA,KAGA,IAAAK,GAAA51E,EAAA6hE,UAAA7hE,EAAA63D,UAAAI,UAAAj4D,EAAAqjE,cAAArjE,EAAA6H,KAAAi4D,cAAA9/D,EAAA63D,UAAAsG,aACAmW,EAAAt0E,EAAAgiC,qBAAA4zC,EACAvB,EAAAr0E,EAAAiiC,sBAAA2zC,CAEA,IAAApB,EAAAx0E,EAAA8rE,OAAA0I,EAAAx0E,EAAA6rE,OAAAyH,GAAAiB,EAAA,CACAD,GAEAt0E,EAAAytD,sBAAA3mD,EAMA,KAAA,GAHA+uE,GAAA71E,EAAA6mD,uBACA5e,EAAAllC,EAAAklC,SAEA3nC,EAAA,EAAAA,EAAAu1E,EAAAl1E,OAAAL,IAAA,CACA,GACA8zE,GADAxsE,EAAAiuE,EAAAv1E,GAEAoe,EAAA8nD,EAAA,KAAA5+D,EAAA+W,cACAm3D,EAAAtP,GAAA,EAAAr3B,EAAAmY,uBAAArf,EAAAvpB,EAEAo3D,KAGA1B,EADAxsE,EAAAtG,SAAAoa,SAAA8/C,YACAt2D,EAAAmwE,KAEAnwE,EAAAowE,QAGAlB,EAAAlvE,KAAA9C,KAAAwF,KAmCA,GAAAmuE,KAQA,IANAA,EAAA/1E,EAAA6rE,OAAA2I,EAAAx0E,EAAA6rE,OAAAzpC,IAAApiC,EAAAm5D,qBAAAn5D,EAAA6rE,OAAA7rE,EAAA6zE,mBACAkC,EAAA/1E,EAAA6rE,QAAA7rE,EAAAm5D,qBAAAn5D,EAAA6rE,OAAA,GAEAkK,EAAA/1E,EAAA8rE,OAAA0I,EAAAx0E,EAAA8rE,OAAA1pC,IAAApiC,EAAAm5D,qBAAAn5D,EAAA8rE,OAAA9rE,EAAA6zE,mBACAkC,EAAA/1E,EAAA8rE,QAAA9rE,EAAAm5D,qBAAAn5D,EAAA8rE,OAAA,GAEA0I,EAAAx0E,EAAA6rE,OAAAyH,GAAAiB,GAAAwB,EAAA/1E,EAAA6rE,MAAA,CACA,GAAAmK,GAAA5zC,IAAA2zC,EAAA/1E,EAAA6rE,OAAA,IAAA4G,EACA1tC,EAAAyhC,IAAAwP,EAAAh2E,EAAA6H,KAAAisE,eAAA9zE,EAAA2yE,wBAAA9qE,EAAA+pE,SAAA5xE,EAAA6rE,OACA6H,EAAAtxC,IAAA4zC,EAAA,aAAAvyE,MAEAgwE,GAAA1uC,EAAA2uC,GACAS,EAAAjvE,EAAAowE,QAAAvwC,GAEAuuC,GAAAlxC,IACAoyC,EAAAx0E,EAAA6rE,OAAA,GAIA,IAAA0I,IAAAC,EAAAx0E,EAAA8rE,OAAAwH,GAAAyC,EAAA/1E,EAAA8rE,OAAA,CACA,GAAAkK,GAAA5zC,IAAA2zC,EAAA/1E,EAAA8rE,OAAA,IAAA2G,EACA1tC,EAAAyhC,IAAAwP,EAAAh2E,EAAA6H,KAAAisE,eAAA9zE,EAAA4yE,wBAAA/qE,EAAA+pE,SAAA5xE,EAAA8rE,MAEA2H,GAAA1uC,EAAA3C,IAAA4zC,EAAA,aAAAvyE,QACA0wE,EAAAjvE,EAAAmwE,KAAAtwC,GAEAuuC,GAAAlxC,IACAoyC,EAAAx0E,EAAA8rE,OAAA,GAIA,GAAA9rE,EAAA24D,UAAA4b,GAAAC,EAAAx0E,EAAA+0E,cAAAzB,EAAA,CACA,GAAAvuC,GAAAyhC,GAAA3+D,EAAA+pE,SAAA5xE,EAAA+0E,WAIA,IAFAtB,EAAA1uC,GAEA,GAAA/kC,EAAA43D,UAAA,KAAA53D,EAAA63D,UAAA2H,WAAAx/D,EAAAs4D,UAAAkH,WAAA,CACA,GAAAzhD,GAAA/d,EAAA+C,GAAAgb,OACA+yD,EAAAkE,EAAA,8BAAA71D,MAAApB,CAEAgnB,GAAAikC,UAAA8H,EACA/rC,EAAAylC,UAAA,QACAwK,EAAA,uBAAA71D,MAAA,GAAA,IACA61D,EAAA,uBAAA71D,MAAA,GAAA,IACA61D,EAAA,uBAAA71D,MAAA,GAAA,IACA61D,EAAA,yBAAA71D,MAAA,IAEA4lB,EAAA8qC,SACA7vE,EAAA43D,UAAA,GACA53D,EAAA43D,UAAA,GACA53D,EAAA43D,UAAA,GAAA53D,EAAA43D,UAAA,GACA53D,EAAA43D,UAAA,GAAA53D,EAAA43D,UAAA,IAEAkZ,EAAA,IACA/rC,EAAA6jC,YAAA,QACAoM,EAAA,8BAAA71D,MAAA,GAAA,IACA61D,EAAA,8BAAA71D,MAAA,GAAA,IACA61D,EAAA,8BAAA71D,MAAA,GAAA,IACA61D,EAAA,yBAAA71D,MAAA,IAEA4lB,EAAAmrC,WACAlwE,EAAA43D,UAAA,GACA53D,EAAA43D,UAAA,GACA53D,EAAA43D,UAAA,GAAA53D,EAAA43D,UAAA,GACA53D,EAAA43D,UAAA,GAAA53D,EAAA43D,UAAA,KAIA,GAAA/vD,EAAA+1D,oBAAA59D,EAAA63D,UAAA2H,UAAA,CACA,GAAAzhD,GAAA/d,EAAA+C,GAAAgb,OACAV,EAAAxV,EAAA+1D,iBAEA74B,GAAAylC,UAAA,QACAwK,EAAA,mBAAA71D,MAAA,GAAA,IACA61D,EAAA,mBAAA71D,MAAA,GAAA,IACA61D,EAAA,mBAAA71D,MAAA,GAAA,IACA61D,EAAA,qBAAA71D,MAAA,IAEA4lB,EAAAilC,YACAjlC,EAAAqjC,IAAA/qD,EAAAG,EAAAH,EAAAI,EAAAu3D,EAAA,kBAAAz1D,QAAAxB,EAAA,EAAA,EAAA3O,KAAAsjC,IACA3N,EAAA6lC,OAGA,GAAAzE,IAAAnmE,EAAA0mE,cACA,IAAA1mE,EAAA24D,SAAAwN,GAAA,CACAA,GAAA/2D,KAAA6sB,MAAAkqC,GACA,IAAA8P,IAAA7mE,KAAA6sB,MAAA,IAAAkqC,GAEAphC,GAAAkvC,aAAA,EAAA,EAAA,EAAA,EAAA,EAAA,GAEAlvC,EAAAylC,UAAA,wBACAzlC,EAAA6jC,YAAA,wBACA7jC,EAAAikC,UAAA,EACAjkC,EAAAsrC,SAAA,aAAAlK,GAAA,SAAA8P,GAAA,OAAA,EAAA,GAEA,IAAAC,IAAA,EACAnxC,GAAAmrC,WAAA,EAAA,GAAA,IAAA,IACAnrC,EAAA8qC,SAAA,EAAA,GAAA,IAAAzgE,KAAAkN,IAAA25D,GAAAC,GAAA,GAAA,IAGA5C,IACAkB,EAAAx0E,EAAA+0E,aAAA,GAKA,GAAA3yC,GAAA,IAAAqwC,EAAA,CACA,GAAA0D,IAAAtuE,EAAA+pE,SAAA5xE,EAAA6rE,MACAuK,GAAAp2E,EAAA6H,KAAA6qE,eAAA1yE,EAAA2yE,wBAEA0D,GAAAxuE,EAAA+pE,SAAA5xE,EAAA8rE,MACAwK,GAAAt2E,EAAA6H,KAAA6qE,eAAA1yE,EAAA4yE,wBAEA2D,GAAA,SAAA9U,EAAA+U,EAAAC,GACAhV,EAAAwS,aAAA,EAAA,EAAA,EAAA,EAAA,EAAA,GAEAwC,IAAA9B,EACAlT,EAAAyS,UAAA,EAAA,EAAAl0E,EAAA89D,YAAA99D,EAAA+9D,cAEAyV,EAAA/R,EAAA,EAAA,EAAAzhE,EAAA89D,YAAA99D,EAAA+9D,aAGA,IAAA2Y,GAAAjE,CAEAhR,GAAAkK,UACA6K,EACA,EAAA,EACAx2E,EAAA89D,YAAA4Y,EAAA12E,EAAA+9D,aAAA2Y,EACA,EAAA,EACA12E,EAAA89D,YAAA99D,EAAA+9D,gBAIAyW,EAAAx0E,EAAA6rE,OAAAkK,EAAA/1E,EAAA6rE,SACA0K,GAAAJ,GAAAC,GAAAL,EAAA/1E,EAAA6rE,OACA2I,EAAAx0E,EAAA6rE,OAAA,IAGA2I,EAAAx0E,EAAA8rE,OAAAiK,EAAA/1E,EAAA8rE,SACAyK,GAAAF,GAAAC,GAAAP,EAAA/1E,EAAA8rE,OACA0I,EAAAx0E,EAAA8rE,OAAA,GAIA9rE,EAAAgnE,kBAAA,EAEAhnE,EAAAm1E,aAAAF,EAEAj1E,EAAA6zE,qBACA7zE,EAAA6zE,oBAAA,EACA7zE,EAAA22E,mBAAA,EACA32E,EAAAoiC,YAAA,GAGAA,IACApiC,EAAA40E,kBAAA17D,WAAA,WACAlZ,EAAA40E,kBAAA,KAEA50E,EAAAm5D,qBAAAn5D,EAAA6rE,OAAA,EACA7rE,EAAAm5D,qBAAAn5D,EAAA8rE,OAAA,EACA9rE,EAAAoiC,YAAA,EACApiC,EAAA6zE,oBAAAY,EACAz0E,EAAA60E,SAAA,EAEAL,EAAAx0E,EAAA6rE,OAAA,EACA2I,EAAAx0E,EAAA8rE,OAAA,EAEA9rE,EAAA65D,UACA6X,ICvpBA1xE,EAAA+rE,cAAA,EAGAvF,GAAAxmE,EAAAygC,aACAzgC,EAAAygC,YAAA,EACA19B,EAAAwV,QAAA,eAGAiuD,GACAzjE,EAAAuiC,mBAKAlmC,EAAAD,QAAAsoE,IAEAllB,gBAAA,GAAAC,gBAAA,KAAAo0B,IAAA,SAAA/1E,EAAAzB,EAAAD,GACA,YAEA,IAAAgwC,GAAAtuC,EAAA,iBAEA4mE,IAGAA,GAAAoP,gBAAA,SACA9xC,EAAAvnB,EAAAC,EAAAkpB,EAAAC,EAAAtiB,GAEA,GAAAzD,GAAA8lB,EAAA,EACA5lB,EAAA6lB,EAAA,CAEA7B,GAAAilC,WAAAjlC,EAAAilC,YAEAjlC,EAAAojC,OAAA3qD,EAAAqD,EAAAyD,EAAA,GAAA7G,EAAAsD,EAAAuD,EAAA,GAEA,KAAA,GAAAhkB,GAAA,EAAAA,EAAAgkB,EAAA3jB,OAAA,EAAAL,IACAykC,EAAA4iC,OAAAnqD,EAAAqD,EAAAyD,EAAA,EAAAhkB,GAAAmd,EAAAsD,EAAAuD,EAAA,EAAAhkB,EAAA,GAGAykC,GAAAmmC,aAIAzD,EAAAqP,uBAAA,SACA/xC,EAAAvnB,EAAAC,EAAAkpB,EAAAC,EAAA6L,GAEA,GAAAskC,GAAApwC,EAAA,EACAqwC,EAAApwC,EAAA,EACA6+B,EAAAt2B,EAAAu2B,wBAAA/+B,EAAAC,EAEA7B,GAAAilC,WAAAjlC,EAAAilC,YAGAjlC,EAAAojC,OAAA3qD,EAAAC,EAAAu5D,GAEAjyC,EAAAkyC,MAAAz5D,EAAAu5D,EAAAt5D,EAAAu5D,EAAAx5D,EAAAu5D,EAAAt5D,EAAAgoD,GAEA1gC,EAAAkyC,MAAAz5D,EAAAu5D,EAAAt5D,EAAAu5D,EAAAx5D,EAAAC,EAAAu5D,EAAAvR,GAEA1gC,EAAAkyC,MAAAz5D,EAAAu5D,EAAAt5D,EAAAu5D,EAAAx5D,EAAAu5D,EAAAt5D,EAAAgoD,GAEA1gC,EAAAkyC,MAAAz5D,EAAAu5D,EAAAt5D,EAAAu5D,EAAAx5D,EAAAC,EAAAu5D,EAAAvR,GAEA1gC,EAAA4iC,OAAAnqD,EAAAC,EAAAu5D,GAGAjyC,EAAAmmC,YAWA,KAAA,GARAgM,GAAA9nE,KAAA8T,IAAA,GACAi0D,EAAA/nE,KAAA6T,IAAA,GAEAC,KACAD,KAEAm0D,EAAAhoE,KAAAsjC,GAAA,GAEApyC,EAAA,EAAA8O,KAAAsjC,GAAApyC,EAAA,EAAA8O,KAAAsjC,GAAApyC,GAAA82E,EACAl0D,EAAA5iB,GAAA8O,KAAA8T,IAAA5iB,GACA2iB,EAAA3iB,GAAA8O,KAAA6T,IAAA3iB,EAGAmnE,GAAA4P,gBAAA,SAAAtyC,EAAA8U,EAAAC,EAAAnT,EAAAC,GAGA,GAFA7B,EAAAilC,WAAAjlC,EAAAilC,YAEAjlC,EAAAuyC,QACAvyC,EAAAuyC,QAAAz9B,EAAAC,EAAAnT,EAAA,EAAAC,EAAA,EAAA,EAAA,EAAA,EAAAx3B,KAAAsjC,QnE0wiBM,KAAK,GmExwiBXu5B,GAAAC,EACAqL,EAAA5wC,EAAA,EACA6wC,EAAA5wC,EAAA,EnEswiBetmC,EAAI,EAAI8O,KAAKsjC,GAAIpyC,EAAI,EAAI8O,KAAKsjC,GAAIpyC,GAAK82E,EoE/1iBtDnL,EAAApyB,EAAA09B,EAAAr0D,EAAA5iB,GAAA42E,EAAAK,EAAAt0D,EAAA3iB,GAAA62E,EACAjL,EAAApyB,EAAA09B,EAAAv0D,EAAA3iB,GAAA42E,EAAAM,EAAAt0D,EAAA5iB,GAAA62E,EAEA,IAAA72E,EACAykC,EAAAojC,OAAA8D,EAAAC,GAEAnnC,EAAA4iC,OAAAsE,EAAAC,EAKAnnC,GAAAmmC,aAGA9rE,EAAAD,QAAAsoE,IAEAllB,gBAAA,KAAAk1B,IAAA,SAAA52E,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,eAEA4mE,IAEAA,GAAAiQ,aAAA,SAAA3vE,EAAAiX,GACA,GAAA24D,GAAAjgD,SAAAyzB,cAAA,SAIA,OAHAwsB,GAAAhxC,MAAA5+B,EACA4vE,EAAA/wC,OAAA5nB,GAEA24D,EAAAA,EAAAC,WAAA,QAGAnQ,EAAAoQ,kBAAA,SAAA5yE,GACA,GAAAlC,GAAApD,KAAAoD,GACA2b,EAAA3b,EAAA2X,WAAAiE,cACAgoB,EAAA1hC,EAAA6yE,KAAA1oE,KAAA2F,KAAA2J,EAAA3W,GAAApI,KAAAmgC,UAAAiI,YACAnB,EAAA3hC,EAAA6yE,KAAA1oE,KAAA2F,KAAA2J,EAAAM,GAAArf,KAAAmgC,UAAAkI,aACAglC,EAAA,CAEA,IAAAvpE,SAAAwB,EAAA+nE,MACArmC,GAAA1hC,EAAA+nE,MACApmC,GAAA3hC,EAAA+nE,MAEAA,EAAA/nE,EAAA+nE,UACA,IAAAjsE,EAAA0Q,OAAAxM,EAAA8yE,WAAAh3E,EAAA0Q,OAAAxM,EAAA+yE,WAAA,CACA,GAAAC,GAAAvvE,EAAAA,EACAwvE,EAAAxvE,EAAAA,CAEA3H,GAAA0Q,OAAAxM,EAAA8yE,YACAE,EAAAjL,EAAA/nE,EAAA8yE,SAAApxC,GAGA5lC,EAAA0Q,OAAAxM,EAAA+yE,aACAE,EAAAlL,EAAA/nE,EAAA+yE,UAAApxC,GAGAomC,EAAA59D,KAAAkN,IAAA27D,EAAAC,GAEAvxC,GAAAqmC,EACApmC,GAAAomC,EAGA,GAAAmL,GAAAzgD,SAAAyzB,cAAA,SAEAgtB,GAAAxxC,MAAAA,EACAwxC,EAAAvxC,OAAAA,EAEAuxC,EAAA12E,MAAAklC,MAAAA,EAAA,KACAwxC,EAAA12E,MAAAmlC,OAAAA,EAAA,IAEA,IAAAwxC,GAAAD,EAAAP,WAAA,KAGA,IAAAjxC,EAAA,GAAAC,EAAA,EAYA,GAVAwxC,EAAAlE,UAAA,EAAA,EAAAvtC,EAAAC,GAEA3hC,EAAAy6B,KACA04C,EAAA5N,UAAAvlE,EAAAy6B,GACA04C,EAAAC,KAAA,EAAA,EAAA1xC,EAAAC,GACAwxC,EAAAxN,QAGAwN,EAAA/N,yBAAA,cAEAplE,EAAA6yE,KACAn4E,KAAA2nE,QACAd,cAAA4R,EACA9E,eAAA,EACAF,WAAApG,EACAqG,WAAA71D,GAAAkB,EAAAE,GAAAouD,EAAAvvD,GAAAiB,EAAAI,GAAAkuD,GACAuG,cAAA,QAEA,CACA,GAAAtnC,GAAAlpC,EAAAib,MACAA,GACAR,EAAAyuB,EAAAzuB,EAAAwvD,EACAvvD,EAAAwuB,EAAAxuB,EAAAuvD,GAEAjvD,EAAAhb,EAAAgb,OAAAivD,CAEArtE,MAAA2nE,QACAd,cAAA4R,EACA9E,eAAA,EACAF,WAAAr1D,EACAs1D,UAAAr1D,EACAu1D,cAAA,ICtGA,MAAA4E,IAGA1Q,EAAAjoC,IAAA,SAAAv6B,GACA,MAAAtF,MAAAk4E,kBAAA5yE,GAAAqzE,UAAA,cAGA7Q,EAAAhoC,IAAA,SAAAx6B,GACA,MAAAtF,MAAAk4E,kBAAA5yE,GAAAqzE,UAAA,eAGAl5E,EAAAD,QAAAsoE,IAEAnlB,cAAA,KAAAi2B,IAAA,SAAA13E,EAAAzB,EAAAD,GAOA,YAoBA,SAAAq5E,GAAAvzE,GACA,GAAAjF,GAAAL,IAEAK,GAAA6H,MACAmrE,SAAA,GAAAvgE,OAAAg1D,EAAAsL,eACAnB,SAAA,GAAAn/D,OAAAg1D,EAAAsL,eACAnH,kBAAA,GAAAn5D,OAAAg1D,EAAAsL,eAEAL,eAAA,GAAAjgE,OAAAg1D,EAAAwL,cACAa,eAAA,GAAArhE,OAAAg1D,EAAAsL,gBAGA/yE,EAAA6H,KAAAirE,gBAAAp7C,SAAAyzB,cAAA,MACA,IAAAstB,GAAAz4E,EAAA6H,KAAAirE,gBAAArxE,KACAzB,GAAA6H,KAAAirE,gBAAA4F,aAAA,QAAA,+CACAD,EAAA97D,SAAA,WACA87D,EAAA/sB,OAAA,IACA+sB,EAAAE,SAAA,QAEA,IAAA74C,GAAA76B,EAAAlC,GAAA+8B,WACAA,GAAAurB,YAAArrD,EAAA6H,KAAAirE,iBACAhzC,EAAA44C,aAAA,SAAA54C,EAAA84C,aAAA,UAAA,IAAA;AAEA,IAAA,GAAAt4E,GAAA,EAAAA,EAAAmnE,EAAAsL,cAAAzyE,IAAA,CACA,GAAAuyE,GAAA7yE,EAAA6H,KAAAmrE,SAAA1yE,GAAAo3B,SAAAyzB,cAAA,SACAnrD,GAAA6H,KAAA+pE,SAAAtxE,GAAAuyE,EAAA+E,WAAA,MACA/E,EAAA6F,aAAA,QAAA,+IAAA33E,EAAA83E,KAAA,gDAAA,KACAhG,EAAApxE,MAAAkb,SAAA,WACAk2D,EAAA6F,aAAA,UAAA,QAAAp4E,GACAuyE,EAAApxE,MAAAiqD,OAAAotB,OAAArR,EAAAsL,cAAAzyE,GACAN,EAAA6H,KAAAirE,gBAAAznB,YAAAwnB,GAEA7yE,EAAA6H,KAAA+jE,kBAAAtrE,IAAA,EAEAN,EAAA6H,KAAAkxE,UAAA/4E,EAAA6H,KAAAmrE,SAAA,GAEAhzE,EAAA6H,KAAAmrE,SAAAvL,EAAAoE,MAAA6M,aAAA,UAAA,QAAAjR,EAAAoE,KAAA,SACA7rE,EAAA6H,KAAAmrE,SAAAvL,EAAAsN,YAAA2D,aAAA,UAAA,QAAAjR,EAAAsN,WAAA,cACA/0E,EAAA6H,KAAAmrE,SAAAvL,EAAAqE,MAAA4M,aAAA,UAAA,QAAAjR,EAAAqE,KAAA,QAEA,KAAA,GAAAxrE,GAAA,EAAAA,EAAAmnE,EAAAwL,aAAA3yE,IACAN,EAAA6H,KAAA6qE,eAAApyE,GAAAo3B,SAAAyzB,cAAA,UACAnrD,EAAA6H,KAAAisE,eAAAxzE,GAAAN,EAAA6H,KAAA6qE,eAAApyE,GAAAs3E,WAAA,MACA53E,EAAA6H,KAAA6qE,eAAApyE,GAAAmB,MAAAkb,SAAA,WACA3c,EAAA6H,KAAA6qE,eAAApyE,GAAAo4E,aAAA,UAAA,SAAAp4E,GACAN,EAAA6H,KAAA6qE,eAAApyE,GAAAmB,MAAAiqD,OAAAotB,QAAAx4E,EAAA,GACAN,EAAA6H,KAAA6qE,eAAApyE,GAAAmB,MAAAkqD,WAAA,QAIA3rD,GAAAg5E,cAAA,EApEA,GAAAl4E,GAAAD,EAAA,iBACAE,EAAAF,EAAA,eAEAo4E,EAAAT,EACA/Q,EAAA+Q,EAAAl2E,SAEAmlE,GAAAsL,cAAA,EAEAtL,EAAAsN,WAAA,EACAtN,EAAAqE,KAAA,EACArE,EAAAoE,KAAA,EAEApE,EAAAwL,aAAA,EAEAxL,EAAA0L,eAAA,EACA1L,EAAAkL,uBAAA,EACAlL,EAAAmL,uBAAA,EAuDAnL,EAAA/N,WAAA,SAAAh5C,EAAA1W,GACA,GAAAhK,GAAAL,IAEA,QAAA+gB,GACA,IAAA,OACA1gB,EAAA6H,KAAA+jE,kBAAAnE,EAAAoE,MAAA7hE,CACA,MACA,KAAA,OACAhK,EAAA6H,KAAA+jE,kBAAAnE,EAAAqE,MAAA9hE,CACA,MACA,KAAA,SACAhK,EAAA6H,KAAA+jE,kBAAAnE,EAAAsN,YAAA/qE,GAMA,IAAAkvE,GAAA,mBAAApP,OAEArC,GAAA0R,cAAA,SAAAxzD,GACA,MAAAliB,UAAAkiB,EACAhmB,KAAAq5E,kBAGAr5E,KAAAq5E,aAAArzD,GAAA,GAAA,IAGA8hD,EAAAe,SAAA,WACA,MAAA0Q,IAAAv5E,KAAAq5E,eC3HAn4E,EAAA,kBACAA,EAAA,mBACAA,EAAA,oBACAA,EAAA,wBACAA,EAAA,mBACAA,EAAA,oBACAA,EAAA,oBACAA,EAAA,kBACAA,EAAA,kBACAoK,QAAA,SAAAgI,GACAnS,EAAAS,OAAAkmE,EAAAx0D,KAGA7T,EAAAD,QAAA85E,IAEA32B,cAAA,GAAAE,gBAAA,GAAA4X,iBAAA,GAAAgf,kBAAA,GAAAC,mBAAA,GAAAC,uBAAA,GAAAC,kBAAA,GAAAC,mBAAA,GAAAC,mBAAA,GAAAC,iBAAA,GAAAjf,gBAAA,KAAAkf,IAAA,SAAA94E,EAAAzB,EAAAD,GACA,YAEA,IAEAwvC,GAFA84B,IAIAA,GAAAtC,cAAA,SAAAjhE,GACA,GAAAxE,GAAAC,ItE4kjBE,QAASgvC,IAASA,GuEpmjBpB2oC,QAAA,SAAAvyC,EAAA8U,EAAAC,EAAAnT,EAAAC,GACAlnC,EAAA23E,gBAAAtyC,EAAA8U,EAAAC,EAAAnT,EAAAC,IAGA8gC,QAAA,SAAA3iC,EAAA8U,EAAAC,EAAAnT,EAAAC,EAAAtiB,GACA5kB,EAAAm3E,gBAAA9xC,EAAA8U,EAAAC,EAAAnT,EAAAC,EAAAtiB,IvEwmjBIs1D,eAAkB,SAAU70C,EAAS8U,EAASC,EAASnT,EAAOC,GwE7mjBlElnC,EAAAo3E,uBAAA/xC,EAAA8U,EAAAC,EAAAnT,EAAAC,EAAA,QAEA1iC,IAGA9E,EAAAD,QAAAsoE,OAEAoS,IAAA,SAAAh5E,EAAAzB,EAAAD,GACA,YAEAC,GAAAD,UACA+E,KAAA,OAAAyqC,KAAA9tC,EAAA,YACAqD,KAAA,OAAAyqC,KAAA9tC,EAAA,YACAqD,KAAA,SAAAyqC,KAAA9tC,EAAA,gBAGAi5E,SAAA,GAAAC,WAAA,GAAA36B,SAAA,KAAA46B,IAAA,SAAAn5E,EAAAzB,EAAAD,GxE+mjBA,YyE9njBA,SAAA86E,GAAAh1E,GACAtF,KAAAsF,QAAAA,EACAtF,KAAAu4B,cAAA,EAGA,GAAAwpB,GAAA,YAEAu4B,GAAA33E,WACA8d,yBAAAshC,EACAx7B,OAAA,WAAAvmB,KAAAu4B,iBACAmN,KAAAqc,GAGAtiD,EAAAD,QAAA86E,OAEAC,IAAA,SAAAr5E,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,QACAC,EAAAD,EAAA,UACAg0C,EAAAh0C,EAAA,YACAG,EAAAH,EAAA,aACAxB,EAAAwB,EAAA,YAEAs5E,EAAA,SAAAC,GACA,KAAAz6E,eAAAw6E,IACA,MAAA,IAAAA,GAAAC,EAGAz6E,MAAA2B,UACAg1C,QAGA,IAAA+jC,GAAA,CAIA,IAFAt5E,EAAA0Q,OAAA2oE,GAEA,mBAAAE,YAAA,MAAAA,UAAAC,oBACAH,EAAAE,UAAAC,wBAEA,KACAH,EAAAv5E,EAAA,MAAA25E,OAAA75E,OACA,MAAA85E,GACAL,EAAAC,EAIA,IAAA,GAAA/5E,GAAA,EAAA85E,EAAA95E,EAAAA,IACAX,KAAAW,GAAA,GAAAu0C,EAGAl1C,MAAAgB,OAAAy5E,GAGAM,EAAAP,EAAA73E,SAEAxB,GAAAS,OAAAm5E,GAEAn4E,eAAA,WAAA,MAAA,UAGAlC,QAAA,SAAA8B,EAAAw4E,GACA,IAAA,GAAAr6E,GAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAq1C,GAAAh2C,KAAAW,EAEAq1C,GAAAt1C,QAAA8B,EAAAw4E,GAGA,MAAAh7E,OAIAiV,OAAA,WACA,GAAAtU,GAAA8O,KAAA6sB,OAAAt8B,KAAAgB,OAAA,GAAAyO,KAAAwF,UACA+gC,EAAAh2C,KAAAW,EAEA,OAAAq1C,IAIA1R,IAAA,SAAA9hC,GACA,GAAAm0C,GAAA32C,KAAA2B,SAAAg1C,KAAAxpC,OAEA,OAAAnN,MAAAiV,SAAA0hC,KAAAA,GAAArS,IAAA9hC,IAIA0qC,QAAA,SAAArB,GACA,MAAA7rC,MAAAiV,SAAAi4B,QAAArB,IAIAiQ,UAAA,SAAAjQ,GACA,IAAA,GAAAlrC,GAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAq1C,GAAAh2C,KAAAW,EAEAq1C,GAAA9I,QAAArB,GAGA,MAAA7rC,OAIA0D,KAAA,WACA,IAAA,GAAA/C,GAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAq1C,GAAAh2C,KAAAW,EAEAq1C,GAAAtyC,OAGA,MAAA1D,OAIA22C,KAAA,SAAAzuC,GACA,GAAAyuC,GAAA32C,KAAA2B,SAAAg1C,IAEA,KAAAv1C,EAAAitB,MAAAnmB,GAGA,KAAA,4CAGA,OALAyuC,GAAAl0C,KAAAyF,GAKAlI,MAGAi7E,WAAA,WACA,GAAAC,GAAAzrE,KAAA2F,KAAApV,KAAA2B,SAAAg1C,KAAA,GAAA31C,OAAAhB,KAAAgB,OAIA,OAFAk6E,GAAAzrE,KAAA9D,IAAA,EAAAuvE,IAMAC,OAAA,SAAA34E,GAOA,IAAA,GANAzC,GAAAC,KACA0B,EAAA3B,EAAA4B,SACAu5E,EAAAn7E,EAAAk7E,aACAtkC,EAAAj1C,EAAAi1C,KAAAxpC,QAAAuN,WACA0gE,KAEAz6E,EAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAq1C,GAAAh2C,KAAAW,GACAiU,EAAA+hC,EAAA7uC,OAAA,EAAAozE,GAEAG,EAAArlC,EAAAW,KAAA/hC,GAAA0vB,IAAA9hC,EAEA44E,GAAA34E,KAAA44E,EAEA,IAAAC,GAAA,IAAA3kC,EAAA31C,MACA,IAAAs6E,EAAA,MAGA,MAAAj6E,GAAA6gC,IAAAk5C,GAAAj5C,KAAA,SAAAW,GAKA,IAAA,GAJAy4C,MACAx3E,EAAA,EAGApD,EAAA,EAAAA,EAAAmiC,EAAA9hC,OAAAL,IAGA,IAAA,GAFAwhC,GAAAW,EAAAniC,GAEAsM,EAAA,EAAAA,EAAAk1B,EAAAnhC,OAAAiM,IAAA,CACA,GAAA9M,GAAAgiC,EAAAl1B,EAEAsuE,GAAAx3E,KAAA5D,EAIA,MAAAo7E,MAKAplE,IAAA,SAAA3T,GACA,GAAAzC,GAAAC,IAIA,OAFAD,GAAAW,QAAA8B,EAAA,eAEAzC,EAAAo7E,OAAA,SAAAt1D,GACA,GAAA21D,MACAC,EAAA32E,OAEAA,SAAA,SAAAqZ,GACAq9D,EAAA/4E,KAAA0b,GAGA,KAAA,GAAAxd,GAAA,EAAAA,EAAAklB,EAAA7kB,OAAAL,IAAA,CACA,GAAA+6E,GAAAF,EAAAx6E,OACA6K,EAAA8vE,YAAA91D,EAAAllB,IACAi7E,EAAAF,IAAAF,EAAAx6E,MAEA46E,IACAJ,EAAA/4E,KAAAoJ,GAMA,MAFA/G,SAAA22E,EAEAD,KAMA/0E,OAAA,SAAAjE,GACA,GAAAd,GAAA1B,KAAA2B,SACAg1C,EAAAj1C,EAAAi1C,KAAA,EAEA,OAAA32C,MAAAmW,IAAA3T,GAAA2/B,KAAA,SAAA9Z,GAGA,IAAA,GAFAxc,MAEAlL,EAAA,EAAAA,EAAAg2C,EAAA31C,OAAAL,IAAA,CACA,GAAAshC,GAAA0U,EAAAh2C,GACAk7E,EAAAxzD,EAAA1nB,EAEAk7E,IACAhwE,EAAApJ,KAAAw/B,GAIA,MAAAp2B,MAKAsC,KAAA,SAAA2tE,GACA,GAAA/7E,GAAAC,KACAgL,EAAAhL,KAAA2B,SAAAg1C,KAAA,GAAA31C,OACAk6E,EAAAl7E,KAAAi7E,YAcA,OAZAa,GAAAA,GAAA,SAAAr7E,EAAA2D,GACA,MAAAA,GAAA3D,EACA,GACAA,EAAA2D,EACA,EAGA,GAGArE,EAAAW,QAAAo7E,EAAA,YAEA/7E,EAAAo7E,OAAA,SAAAt1D,GACA,GAAAk2D,GAAAl2D,EAAA1X,KAAA6tE,SACAl3E,SAAAi3E,KAEA55C,KAAA,SAAA85C,GAwCA,IAAA,GAlCAt0D,GAAA,SAAAhnB,EAAAsM,EAAAtB,GAEAsB,EAAAwC,KAAAkN,IAAA1P,EAAAjC,GACAW,EAAA8D,KAAAkN,IAAAhR,EAAAX,EAQA,KAAA,GALAlK,GAAAH,EACAN,EAAA4M,EAEA0hB,KAEAnc,EAAA1R,EAAA6K,EAAA6G,EAAAA,IAAA,CAEA,GAAA0pE,GAAAD,EAAAt7E,GACAw7E,EAAAF,EAAAhvE,EAEA5M,GAAAM,IAAAsM,GAAAtB,GAAAmwE,EAAAI,EAAAC,IAAA,IACAxtD,EAAAlsB,KAAAy5E,GACAv7E,MAEAguB,EAAAlsB,KAAA05E,GACAlvE,KAMA,IAAA,GAAAuF,GAAA,EAAAA,EAAAmc,EAAA3tB,OAAAwR,IAAA,CACA,GAAAvE,GAAAnN,EAAA0R,CAEAypE,GAAAhuE,GAAA0gB,EAAAnc,KAIA4pE,EAAAlB,EAAAlwE,EAAAoxE,EAAAA,GAAA,EAEA,IAAA,GAAAz7E,GAAA,EAAAqK,EAAArK,EAAAA,GAAA,EAAAy7E,EACAz0D,EAAAhnB,EAAAA,EAAAy7E,EAAAz7E,EAAA,EAAAy7E,EAKA,OAAAH,OAOA,IAAAI,GAAA,SAAA76E,GAGA,MAFAA,GAAAA,MAEA,SAAAgB,EAAA85E,GACA,GAAA3lC,GAAA32C,KAAA2B,SAAAg1C,KAAAxpC,OAEA,OAAAnN,MAAAiV,SAAA0hC,KAAAA,GAAAn1C,EAAA+6E,UAAA/5E,EAAA85E,IAIAn7E,GAAAS,OAAAm5E,GACAyB,UAAAH,GAAAE,SAAA,QAEAE,OAAAJ,GAAAE,SAAA,WAEAG,YAAAL,GAAAE,SAAA,iBzEoojBA,IAAI/5E,GAAKu4E,C0El8jBTv4E,GAAAmC,QAAAnC,EAAA8hC,IACA9hC,EAAAm6E,UAAAn6E,EAAAo6E,KAAAp6E,EAAAkB,KACAlB,EAAA6lB,QAAA7lB,EAAA9B,QAGAS,EAAAS,OAAAm5E,GACA/0D,GAAAtmB,EAAAsmB,KACAC,IAAAvmB,EAAAsmB,IAAAE,qBAAA,IACAG,IAAA3mB,EAAA2mB,MACAzN,QAAAlZ,EAAAkZ,YAGAlZ,EAAA8mB,eAAAu0D,GAEAt7E,EAAAD,QAAAg7E,IAEArrC,WAAA,GAAAnqC,OAAA,GAAAC,YAAA,GAAA43E,WAAA,GAAA33E,SAAA,GAAA43E,GAAAh5E,SAAAi5E,IAAA,SAAA77E,EAAAzB,EAAAD,GACA,cAIA,WACA,GAAA4M,GAAA4wE,EAAAhoE,EAAAioE,EAAAC,EAAAC,EAAAC,EAAAC,EAAAC,EAAA3gE,EAAA4gE,EAAAC,EAAAzuE,EAAA0uE,EAAAC,CAEA1oE,GAAAvF,KAAAuF,MAAA2H,EAAAlN,KAAAkN,IAOAqgE,EAAA,SAAAn/D,EAAAC,GACA,MAAAA,GAAAD,EACA,GAEAA,EAAAC,EACA,EAEA,GAaAw/D,EAAA,SAAA78E,EAAAod,EAAA8/D,EAAAC,EAAA9B,GACA,GAAA+B,EAOA,IANA,MAAAF,IACAA,EAAA,GAEA,MAAA7B,IACAA,EAAAkB,GAEA,EAAAW,EACA,KAAA,IAAA/8E,OAAA,0BAKA,KAHA,MAAAg9E,IACAA,EAAAn9E,EAAAO,QAEA48E,EAAAD,GACAE,EAAA7oE,GAAA2oE,EAAAC,GAAA,GACA9B,EAAAj+D,EAAApd,EAAAo9E,IAAA,EACAD,EAAAC,EAEAF,EAAAE,EAAA,CAGA,UAAA/1E,OAAAtE,MAAA/C,GAAAk9E,EAAAA,EAAAA,GAAAjjE,OAAAmD,IAAAA,GAQAs/D,EAAA,SAAA9uD,EAAAyvD,EAAAhC,GAKA,MAJA,OAAAA,IACAA,EAAAkB,GAEA3uD,EAAA5rB,KAAAq7E,GACAL,EAAApvD,EAAA,EAAAA,EAAArtB,OAAA,EAAA86E,IAQAoB,EAAA,SAAA7uD,EAAAytD,GACA,GAAAiC,GAAAC,CAYA,OAXA,OAAAlC,IACAA,EAAAkB,GAEAe,EAAA1vD,EAAAhjB,MACAgjB,EAAArtB,QACAg9E,EAAA3vD,EAAA,GACAA,EAAA,GAAA0vD,EACAL,EAAArvD,EAAA,EAAAytD,IAEAkC,EAAAD,EAEAC,GAeAX,EAAA,SAAAhvD,EAAAyvD,EAAAhC,GACA,GAAAkC,EAOA,OANA,OAAAlC,IACAA,EAAAkB,GAEAgB,EAAA3vD,EAAA,GACAA,EAAA,GAAAyvD,EACAJ,EAAArvD,EAAA,EAAAytD,GACAkC,GAQAZ,EAAA,SAAA/uD,EAAAyvD,EAAAhC,GACA,GAAAmC,EAQA,OAPA,OAAAnC,IACAA,EAAAkB,GAEA3uD,EAAArtB,QAAA86E,EAAAztD,EAAA,GAAAyvD,GAAA,IACAG,GAAA5vD,EAAA,GAAAyvD,GAAAA,EAAAG,EAAA,GAAA5vD,EAAA,GAAA4vD,EAAA,GACAP,EAAArvD,EAAA,EAAAytD,IAEAgC,GAQAb,EAAA,SAAA5uD,EAAAytD,GACA,GAAAn7E,GAAAu9E,EAAAC,EAAAC,EAAAC,EAAAC,CAUA,KATA,MAAAxC,IACAA,EAAAkB,GAEAoB,EAAA,WACAE,IACA,KAAA,GAAAC,GAAA,EAAAN,EAAAjpE,EAAAqZ,EAAArtB,OAAA,GAAAi9E,GAAA,EAAAA,EAAAM,EAAAA,EAAAN,EAAAA,GAAA,EAAAM,IAAAA,IAAAD,EAAA77E,KAAA87E,EACA,OAAAD,IACA96E,MAAAxD,MAAAkE,UACAm6E,KACAH,EAAA,EAAAC,EAAAC,EAAAp9E,OAAAm9E,EAAAD,EAAAA,IACAv9E,EAAAy9E,EAAAF,GACAG,EAAA57E,KAAAi7E,EAAArvD,EAAA1tB,EAAAm7E,GAEA,OAAAuC,IASAtvE,EAAA,SAAAsf,EAAAyvD,EAAAhC,GACA,GAAAp+D,EAKA,OAJA,OAAAo+D,IACAA,EAAAkB,GAEAt/D,EAAA2Q,EAAA/lB,QAAAw1E,GACA,KAAApgE,GAGA+/D,EAAApvD,EAAA,EAAA3Q,EAAAo+D,GACA4B,EAAArvD,EAAA3Q,EAAAo+D,IAJA,QAYAyB,EAAA,SAAAlvD,EAAAjuB,EAAA07E,GACA,GAAA0C,GAAAthC,EAAAghC,EAAAC,EAAAF,CAKA,IAJA,MAAAnC,IACAA,EAAAkB,GAEA9/B,EAAA7uB,EAAAzZ,MAAA,EAAAxU,IACA88C,EAAAl8C,OACA,MAAAk8C,EAIA,KAFA+/B,EAAA//B,EAAA4+B,GACAmC,EAAA5vD,EAAAzZ,MAAAxU,GACA89E,EAAA,EAAAC,EAAAF,EAAAj9E,OAAAm9E,EAAAD,EAAAA,IACAM,EAAAP,EAAAC,GACAd,EAAAlgC,EAAAshC,EAAA1C,EAEA,OAAA5+B,GAAA/uC,KAAA2tE,GAAA53E,WAQAs5E,EAAA,SAAAnvD,EAAAjuB,EAAA07E,GACA,GAAA0C,GAAA79E,EAAA89E,EAAAvhC,EAAAghC,EAAAK,EAAAJ,EAAAF,EAAAG,EAAAC,CAIA,IAHA,MAAAvC,IACAA,EAAAkB,GAEA,GAAA58E,GAAAiuB,EAAArtB,OAAA,CAEA,GADAk8C,EAAA7uB,EAAAzZ,MAAA,EAAAxU,GAAA+N,KAAA2tE,IACA5+B,EAAAl8C,OACA,MAAAk8C,EAIA,KAFAuhC,EAAAvhC,EAAAA,EAAAl8C,OAAA,GACAi9E,EAAA5vD,EAAAzZ,MAAAxU,GACA89E,EAAA,EAAAC,EAAAF,EAAAj9E,OAAAm9E,EAAAD,EAAAA,IACAM,EAAAP,EAAAC,GACApC,EAAA0C,EAAAC,GAAA,IACAnB,EAAApgC,EAAAshC,EAAA,EAAA,KAAA1C,GACA5+B,EAAA7xC,MACAozE,EAAAvhC,EAAAA,EAAAl8C,OAAA,GAGA,OAAAk8C,GAIA,IAFA+/B,EAAA5uD,EAAAytD,GACAuC,KACA19E,EAAA49E,EAAA,EAAAH,EAAAzhE,EAAAvc,EAAAiuB,EAAArtB,QAAAo9E,GAAA,EAAAA,EAAAG,EAAAA,EAAAH,EAAAz9E,EAAAy9E,GAAA,IAAAG,IAAAA,EACAF,EAAA57E,KAAAy6E,EAAA7uD,EAAAytD,GAEA,OAAAuC,IAGAZ,EAAA,SAAApvD,EAAAqwD,EAAAhhE,EAAAo+D,GACA,GAAA6C,GAAA1kE,EAAA2kE,CAKA,KAJA,MAAA9C,IACAA,EAAAkB,GAEA2B,EAAAtwD,EAAA3Q,GACAA,EAAAghE,IACAE,EAAAlhE,EAAA,GAAA,EACAzD,EAAAoU,EAAAuwD,GACA9C,EAAA6C,EAAA1kE,GAAA,IACAoU,EAAA3Q,GAAAzD,EACAyD,EAAAkhE,CAKA,OAAAvwD,GAAA3Q,GAAAihE,GAGAjB,EAAA,SAAArvD,EAAA3Q,EAAAo+D,GACA,GAAA+C,GAAAC,EAAAH,EAAAI,EAAAL,CAQA,KAPA,MAAA5C,IACAA,EAAAkB,GAEA8B,EAAAzwD,EAAArtB,OACA09E,EAAAhhE,EACAihE,EAAAtwD,EAAA3Q,GACAmhE,EAAA,EAAAnhE,EAAA,EACAohE,EAAAD,GACAE,EAAAF,EAAA,EACAC,EAAAC,KAAAjD,EAAAztD,EAAAwwD,GAAAxwD,EAAA0wD,IAAA,KACAF,EAAAE,GAEA1wD,EAAA3Q,GAAA2Q,EAAAwwD,GACAnhE,EAAAmhE,EACAA,EAAA,EAAAnhE,EAAA,CAGA,OADA2Q,GAAA3Q,GAAAihE,EACAlB,EAAApvD,EAAAqwD,EAAAhhE,EAAAo+D,IAGA1vE,EAAA,WAiBA,QAAAA,GAAA0vE,GACA97E,KAAA87E,IAAA,MAAAA,EAAAA,EAAAkB,EACAh9E,KAAAsH,SAoEA,MAtFA8E,GAAA3J,KAAA06E,EAEA/wE,EAAAf,IAAA6xE,EAEA9wE,EAAA4yE,QAAA3B,EAEAjxE,EAAA6yE,QAAA7B,EAEAhxE,EAAA6wE,QAAAA,EAEA7wE,EAAA2C,WAAAA,EAEA3C,EAAAmxE,SAAAA,EAEAnxE,EAAAoxE,UAAAA,EAOApxE,EAAAzJ,UAAAF,KAAA,SAAAob,GACA,MAAAs/D,GAAAn9E,KAAAsH,MAAAuW,EAAA7d,KAAA87E,MAGA1vE,EAAAzJ,UAAA0I,IAAA,WACA,MAAA6xE,GAAAl9E,KAAAsH,MAAAtH,KAAA87E,MAGA1vE,EAAAzJ,UAAAu8E,KAAA,WACA,MAAAl/E,MAAAsH,MAAA,IAGA8E,EAAAzJ,UAAAw8E,SAAA,SAAAthE,GACA,MAAA,KAAA7d,KAAAsH,MAAAgB,QAAAuV,IAGAzR,EAAAzJ,UAAAq8E,QAAA,SAAAnhE,GACA,MAAAw/D,GAAAr9E,KAAAsH,MAAAuW,EAAA7d,KAAA87E,MAGA1vE,EAAAzJ,UAAAs8E,QAAA,SAAAphE,GACA,MAAAu/D,GAAAp9E,KAAAsH,MAAAuW,EAAA7d,KAAA87E,MAGA1vE,EAAAzJ,UAAAs6E,QAAA,WACA,MAAAA,GAAAj9E,KAAAsH,MAAAtH,KAAA87E,MAGA1vE,EAAAzJ,UAAAoM,WAAA,SAAA8O,GACA,MAAA9O,GAAA/O,KAAAsH,MAAAuW,EAAA7d,KAAA87E,MAGA1vE,EAAAzJ,UAAAoxE,MAAA,WACA,MAAA/zE,MAAAsH,UAGA8E,EAAAzJ,UAAA4X,MAAA,WACA,MAAA,KAAAva,KAAAsH,MAAAtG,QAGAoL,EAAAzJ,UAAA2M,KAAA,WACA,MAAAtP,MAAAsH,MAAAtG,QAGAoL,EAAAzJ,UAAA+nB,MAAA,WACA,GAAA00D,EAGA,OAFAA,GAAA,GAAAhzE,GACAgzE,EAAA93E,MAAAtH,KAAAsH,MAAAsN,MAAA,GACAwqE,GAGAhzE,EAAAzJ,UAAAuL,QAAA,WACA,MAAAlO,MAAAsH,MAAAsN,MAAA,IAGAxI,EAAAzJ,UAAA08E,OAAAjzE,EAAAzJ,UAAAF,KAEA2J,EAAAzJ,UAAAgd,IAAAvT,EAAAzJ,UAAAu8E,KAEA9yE,EAAAzJ,UAAA28E,MAAAlzE,EAAAzJ,UAAAu8E,KAEA9yE,EAAAzJ,UAAA48E,IAAAnzE,EAAAzJ,UAAAw8E,SAEA/yE,EAAAzJ,UAAA+V,KAAAtM,EAAAzJ,UAAA+nB,MAEAte,KC1XA,SAAA9F,EAAAk5E,GACA,MAAA,kBAAA9/E,SAAAA,OAAAC,IACAD,UAAA8/E,GACA,gBAAAhgF,GACAC,EAAAD,QAAAggF,IAEAl5E,EAAA8F,KAAAozE,KAEAx/E,KAAA,WACA,MAAAoM,OAGArL,KAAAf,WAIAy/E,IAAA,SAAAv+E,EAAAzB,EAAAD,GACA,YAEA,IAAAK,GAAAqB,EAAA,YACAE,EAAAF,EAAA,QACAg/B,EAAAh/B,EAAA,UACAsjC,EAAAtjC,EAAA,eACAw+E,EAAAx+E,EAAA,mBACAy+E,EAAAz+E,EAAA,gBACAg0C,EAAAh0C,EAAA,YACAs5E,EAAAt5E,EAAA,YAEAjB,EAAA,SAAAqF,GAOA,MALAxB,UAAAwB,IACAA,MAIAlE,EAAAwL,YAAAtH,GACA,GAAA46B,GAAA56B,GAIAlE,EAAAoF,OAAAlB,GACAk/B,EAAAhhC,MAAAghC,EAAA13B,WADA,OAMA7M,GAAA2/E,QAAA,QC9CA//E,GAAAA,EAAAggF,QACAH,EAAA7/E,EAAAggF,OAAA5/E,GAIAA,EAAAy/E,eAAA,SAAAG,GACAH,EAAAG,EAAA5/E,IAIAA,EAAAmmC,WAAAnmC,EAAA0/E,WAAAA,EACA1/E,EAAA+1C,OAAA/1C,EAAAi1C,OAAAA,EACAj1C,EAAA6/E,OAAA7/E,EAAAu6E,OAAAA,EAEA/6E,EAAAD,QAAAS,IAEAivC,SAAA,GAAA6wC,cAAA,GAAAC,WAAA,GAAAh7E,OAAA,GAAAi7E,kBAAA,GAAAC,eAAA,GAAArD,WAAA,GAAAsD,WAAA,MAAAC,IAAA,SAAAl/E,EAAAzB,EAAAD,GACA,YAEA,IAAAK,GAAAqB,EAAA,YACAy5E,EAAA96E,EAAAA,EAAA86E,UAAA,KAEA0F,EAAA,SACAC,WACAC,EAAA,WACAC,QAAAC,aAEAC,EAAA,SAAAz2D,GACA,MAAAA,IAAAA,EAAArnB,gBAAAxB,EAAAoB,GAAAynB,EAAArnB,gBAAAqnB,EAAArnB,iBAAA,MAGAxB,GACAu/E,QAAA,SAAA12D,GACA,MAAA,OAAAA,GAGAzjB,OAAA,SAAAyjB,GACA,MAAA,OAAAA,SAAAA,IAAAo2D,GAGA79E,GAAA,SAAAynB,GACA,MAAA,OAAAA,SAAAA,KAAAs2D,GAGAlyD,MAAA,SAAApE,GACA,MAAAnX,OAAA8tE,QAAA9tE,MAAA8tE,QAAA32D,GAAA,MAAAA,GAAAA,YAAAnX,QAGAlG,YAAA,SAAAqd,GACA,MAAA,OAAAA,SAAAA,KAAAq2D,IAAAl/E,EAAAitB,MAAApE,IAAAA,EAAA42D,cAAAjzC,QAGAkzC,OAAA,SAAA72D,GACA,MAAA,OAAAA,SAAAA,KAAAq2D,GAGAxuE,OAAA,SAAAmY,GACA,MAAA,OAAAA,GAAA,gBAAAA,KAAAid,MAAAjd,IAGA82D,QAAA,SAAA92D,GACA,MAAA7oB,GAAA0Q,OAAAmY,IAAAxa,KAAAuF,MAAAiV,KAAAA,GAGA5f,KAAA,SAAA4f,GACA,MAAA,OAAAA,SAAAA,WAAA,GAGAmW,YAAA,SAAAnW,GACA,MAAA,cAAAu2D,EACA18E,OAEA,MAAAmmB,GAAAA,YAAAw2D,cAIAt9E,oBAAA,SAAA8mB,GACA,MAAA7oB,GAAAulB,QAAAsD,IAAA7oB,EAAAqM,WAAAwc,IAGAtD,QAAA,SAAAsD,GACA,MAAA,eAAAy2D,EAAAz2D,IAAAA,EAAAtoB,SAAA0jB,QAGA5X,WAAA,SAAAwc,GACA,MAAA,eAAAy2D,EAAAz2D,KAAAA,EAAAtoB,SAAA0jB,QAGAD,KAAA,SAAA6E,GACA,MAAA,SAAAy2D,EAAAz2D,IAGAnoB,MAAA,SAAAmoB,GACA,MAAA,UAAAy2D,EAAAz2D,IAGAmc,WAAA,SAAAnc,GACA,MAAA,eAAAy2D,EAAAz2D,IAGAtO,MAAA,SAAAsO,GACA,MAAA,UAAAy2D,EAAAz2D,IAGA+rB,OAAA,SAAA/rB,GACA,MAAA,WAAAy2D,EAAAz2D,IAGA61D,OAAA,SAAA71D,GACA,MAAA,WAAAy2D,EAAAz2D,IAGAa,YAAA,SAAAb,GACA,MAAAA,GAEA7oB,EAAAoF,OAAAyjB,KACA,KAAAA,GAAAA,EAAAhS,MAAA,WACA,GAIA,GAPA,GAUA+oE,eAAA,SAAA/2D,GACA,MAAAA,IAAA7oB,EAAAoF,OAAAyjB,IAAA,KAAAA,IAAAA,EAAAhS,MAAA,UACA,GAGA,GAGAgpE,WAAA,SAAAh3D,GACA,MAAA,mBAAAw2D,cACA,EAEAx2D,YAAAw2D,cAIAzhE,YAAA,SAAAiL,GACA,MAAA7oB,GAAAwL,YAAAqd,IACA7oB,EAAA0Q,OAAAmY,EAAAhL,KAAA7d,EAAA0Q,OAAAmY,EAAA/K,KACA9d,EAAA0Q,OAAAmY,EAAA9K,KAAA/d,EAAA0Q,OAAAmY,EAAA7K,KAIAza,QAAA,SAAAslB,GACA,MAAA7oB,GAAA0/E,OAAA72D,IAAA7oB,EAAAoB,GAAAynB,EAAAkY,OAGA0iC,MAAA,WACA,MAAAhlE,KAAA,gBAAAA,IAAAA,EAAAqhF,eAAAnpD,mBAAAmpD,iBAGAC,MAAA,WACA,MAAA,mBAAAC,iBAAA,iBAAArpD,UAAAspD,gBAAAv/E,OAGAw/E,OAAA,WACA,MAAA,mBAAAC,YAAA,oBAAAxpD,UAAAspD,gBAAAv/E,OAGA0/E,SAAA,WACA,MAAA,mBAAAC,SAGAC,MAAA,WACA,MAAA/G,IAAAA,EAAAgH,OAAA1pE,MAAA,SAGA2pE,SAAA,WACA,MAAAxgF,GAAAsgF,SAAAtgF,EAAAkgF,UAAAlgF,EAAAogF,YAGAtI,GAAA,WACA,MAAAyB,IAAAA,EAAAkH,UAAA5pE,MAAA,uBAGA6pE,QAAA,WACA,MAAAnH,IAAAA,EAAAoH,WAAA9pE,MAAA,SCnLA+pE,IAAA,WACA,MAAArH,IAAAA,EAAAoH,WAAA9pE,MAAA,SAGAgqE,MAAA,WACA,MAAAtH,IAAAA,EAAAoH,WAAA9pE,MAAA,WAGAiqE,KAAA,WACA,MAAAvH,IAAAA,EAAAoH,WAAA9pE,MAAA,SAIAxY,GAAAD,QAAA4B,IAEA++E,WAAA,MAAAgC,IAAA,SAAAjhF,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,QAEAkhF,EAAA,SAAAC,GACA,GAAA73E,GAAA63E,EAAA,GAAA/hD,OAAA+hD,EAAA,GAAA/hD,UAEA,OAAA91B,IAGAk1E,EAAA,SAAAn0E,EAAAtL,GACAsL,IAEAA,EAAA/I,GAAAvC,YAIAsL,EAAA/I,GAAAvC,UAAA,SAAAuB,GACA,GAAA8gF,GAAA/2E,EAAAvL,KAGA,IAAA,QAAAwB,EACA,MAAA4gF,GAAAE,GAAAl/E,EAIA,IAAAhC,EAAAoB,GAAAhB,GAAA,CAEA,GAAAsuB,GAAAtuB,EACA4B,EAAAg/E,EAAAE,GAAAl/E,EAEA,IAAAA,GAAAA,EAAA+/B,UACA//B,EAAAwV,QAAA,WAAAkX,OAEA,CACA,GAAA5nB,GAAAk6E,EAAAE,GACA9hD,EAAAt4B,EAAAs4B,QAAAt4B,EAAAs4B,WAEAA,GAAA/9B,KAAAqtB,QAMA,IAAA1uB,EAAAwL,YAAApL,GACA,MAAA8gF,GAAAl0D,KAAA,WACA,GAAA9oB,GAAAiG,EAAA3J,UAAAJ,GACA2+B,UAAA50B,EAAAvL,MAAA,I7E2ilBQC,GAAUqF,M8EtmlBlBiG,EAAAtL,UAAAA,EAGA,MAAAsL,EAAA/I,GAAAY,IAAA,MAAAmI,EAAAnI,KACAmI,EAAA/I,GAAAY,GAAAmI,EAAA/I,GAAAvC,UACAsL,EAAAnI,GAAAmI,EAAAtL,aAIAR,GAAAD,QAAAkgF,IAEA16E,OAAA,KAAAu9E,IAAA,SAAArhF,EAAAzB,EAAAD,GACA,YAEA,IAAAgwC,KAEAA,GAAA6jB,OAAA,SAAAx1C,GACA,MAAAA,GAAA,EACA,EACA,EAAAA,EACA,GAEA,GAIA2xB,EAAA7nC,SAAA,SAAA+zB,EAAAC,GACA,MAAAlsB,MAAA+F,KAAAg6B,EAAAgzC,WAAA9mD,EAAAC,KAGA6T,EAAAgzC,WAAA,SAAA9mD,EAAAC,GACA,GAAAqB,GAAArB,EAAA9d,EAAA6d,EAAA7d,EACAu8B,EAAAze,EAAA7d,EAAA4d,EAAA5d,CAEA,OAAAkf,GAAAA,EAAAod,EAAAA,GAIA5K,EAAAgU,UAAA,SAAAyS,EAAAv6B,EAAAC,EAAAx7B,GACA,OAAA,EAAAA,IAAA,EAAAA,GAAA81D,EAAA,GAAA,EAAA91D,GAAAA,EAAAu7B,EAAAv7B,EAAAA,EAAAw7B,GAGA6T,EAAAizC,YAAA,SAAAxsB,EAAAv6B,EAAAC,EAAAx7B,GACA,OACA0d,EAAA2xB,EAAAgU,UAAAyS,EAAAp4C,EAAA6d,EAAA7d,EAAA8d,EAAA9d,EAAA1d,GACA2d,EAAA0xB,EAAAgU,UAAAyS,EAAAn4C,EAAA4d,EAAA5d,EAAA6d,EAAA7d,EAAA3d,KAKAqvC,EAAAM,gBAAA,SAAA/wB,GACA,GAAA,MAAAA,EAAAE,IAAA,MAAAF,EAAAI,GAAA,CACA,GAAA,MAAAJ,EAAAG,IAAA,MAAAH,EAAAK,IAAAL,EAAAG,IAAAH,EAAAE,IAAAF,EAAAK,IAAAL,EAAAI,GACA,OACAF,GAAAF,EAAAE,GACAE,GAAAJ,EAAAI,GACAD,GAAAH,EAAAG,GACAE,GAAAL,EAAAK,GACAhX,EAAA2W,EAAAG,GAAAH,EAAAE,GACAI,EAAAN,EAAAK,GAAAL,EAAAI,GAEA,IAAA,MAAAJ,EAAA3W,GAAA,MAAA2W,EAAAM,GAAAN,EAAA3W,GAAA,GAAA2W,EAAAM,GAAA,EACA,OACAJ,GAAAF,EAAAE,GACAE,GAAAJ,EAAAI,GACAD,GAAAH,EAAAE,GAAAF,EAAA3W,EACAgX,GAAAL,EAAAI,GAAAJ,EAAAM,EACAjX,EAAA2W,EAAA3W,EACAiX,EAAAN,EAAAM,KAMAmwB,EAAAmY,uBAAA,SAAA+6B,EAAAC,GAEA,MAAAD,GAAAzjE,GAAA0jE,EAAAzjE,IAAA,EACAyjE,EAAA1jE,GAAAyjE,EAAAxjE,IAAA,EAGAwjE,EAAAxjE,GAAAyjE,EAAA1jE,IAAA,EACA0jE,EAAAzjE,GAAAwjE,EAAAzjE,IAAA,EAGAyjE,EAAAtjE,GAAAujE,EAAAxjE,IAAA,EACAwjE,EAAAvjE,GAAAsjE,EAAAvjE,IAAA,EAGAujE,EAAAvjE,GAAAwjE,EAAAvjE,IAAA,EACAujE,EAAAxjE,GAAAujE,EAAAtjE,IAAA,GAGA,GAGAowB,EAAAyX,cAAA,SAAAloC,EAAAlB,EAAAC,GACA,MAAAiB,GAAAE,IAAApB,GAAAA,GAAAkB,EAAAG,IAAAH,EAAAI,IAAArB,GAAAA,GAAAiB,EAAAK,IAGAowB,EAAAyY,mBAAA,SAAAlpC,EAAAkD,GACA,MAAAjiB,MAAAinD,cAAAloC,EAAAkD,EAAApE,EAAAoE,EAAAnE,IAGA0xB,EAAAq2B,4BAAA,SACAhoD,EAAAC,EAAA6uC,EAAAC,EAAA5lB,EAAAC,EAAAvnB,GAEA,GAMAkjE,GANA9c,EAAA9lE,KAAA+lE,wBAAA/+B,EAAAC,GAEAmwC,EAAApwC,EAAA,EACAqwC,EAAApwC,EAAA,EAOA47C,EAAAl2B,EAAAyqB,EAAAtR,EAAApmD,EACAojE,EAAAl2B,EAAAyqB,EAAA33D,EACAqjE,EAAAp2B,EAAAyqB,EAAAtR,EAAApmD,EACAsjE,EAAAF,CAKA,IAHAF,EAAA5iF,KAAAijF,qBACAplE,EAAAC,EAAA6uC,EAAAC,EAAAi2B,EAAAC,EAAAC,EAAAC,GAAA,GAEAJ,EAAA5hF,OAAA,EACA,MAAA4hF,EAMA,IAAAM,GAAAv2B,EAAAyqB,EAAA13D,EACAyjE,EAAAv2B,EAAAyqB,EAAAvR,EAAApmD,EACA0jE,EAAAF,EACAG,EAAAz2B,EAAAyqB,EAAAvR,EAAApmD,CAKA,IAHAkjE,EAAA5iF,KAAAijF,qBACAplE,EAAAC,EAAA6uC,EAAAC,EAAAs2B,EAAAC,EAAAC,EAAAC,GAAA,GAEAT,EAAA5hF,OAAA,EACA,MAAA4hF,EAMA,IAAAU,GAAA32B,EAAAyqB,EAAAtR,EAAApmD,EACA6jE,EAAA32B,EAAAyqB,EAAA33D,EACA8jE,EAAA72B,EAAAyqB,EAAAtR,EAAApmD,EACA+jE,EAAAF,CAKA,IAHAX,EAAA5iF,KAAAijF,qBACAplE,EAAAC,EAAA6uC,EAAAC,EAAA02B,EAAAC,EAAAC,EAAAC,GAAA,GAEAb,EAAA5hF,OAAA,EACA,MAAA4hF,EAMA,IAAAc,GAAA/2B,EAAAyqB,EAAA13D,EACAikE,EAAA/2B,EAAAyqB,EAAAvR,EAAApmD,EACAkkE,EAAAF,EACAG,EAAAj3B,EAAAyqB,EAAAvR,EAAApmD,CAKA,IAHAkjE,EAAA5iF,KAAAijF,qBACAplE,EAAAC,EAAA6uC,EAAAC,EAAA82B,EAAAC,EAAAC,EAAAC,GAAA,GAEAjB,EAAA5hF,OAAA,EACA,MAAA4hF,EAKA,IAAAkB,GAIAC,EAAAp3B,EAAAyqB,EAAAtR,EACAke,EAAAp3B,EAAAyqB,EAAAvR,CAMA,IALAge,EAAA9jF,KAAAikF,oBACApmE,EAAAC,EAAA6uC,EAAAC,EACAm3B,EAAAC,EAAAle,EAAApmD,GAGAokE,EAAA9iF,OAAA,GACA8iF,EAAA,IAAAC,GACAD,EAAA,IAAAE,EACA,OAAAF,EAAA,GAAAA,EAAA,GAMA,IAAAI,GAAAv3B,EAAAyqB,EAAAtR,EACAqe,EAAAv3B,EAAAyqB,EAAAvR,CAMA,IALAge,EAAA9jF,KAAAikF,oBACApmE,EAAAC,EAAA6uC,EAAAC,EACAs3B,EAAAC,EAAAre,EAAApmD,GAGAokE,EAAA9iF,OAAA,GACA8iF,EAAA,IAAAI,GACAJ,EAAA,IAAAK,EACA,OAAAL,EAAA,GAAAA,EAAA,GAMA,IAAAM,GAAAz3B,EAAAyqB,EAAAtR,EACAue,EAAAz3B,EAAAyqB,EAAAvR,CAMA,IALAge,EAAA9jF,KAAAikF,oBACApmE,EAAAC,EAAA6uC,EAAAC,EACAw3B,EAAAC,EAAAve,EAAApmD,GAGAokE,EAAA9iF,OAAA,GACA8iF,EAAA,IAAAM,GACAN,EAAA,IAAAO,EACA,OAAAP,EAAA,GAAAA,EAAA,GAMA,IAAAQ,GAAA33B,EAAAyqB,EAAAtR,EACAye,EAAA33B,EAAAyqB,EAAAvR,CAMA,OALAge,GAAA9jF,KAAAikF,oBACApmE,EAAAC,EAAA6uC,EAAAC,EACA03B,EAAAC,EAAAze,EAAApmD,GAGAokE,EAAA9iF,OAAA,GACA8iF,EAAA,IAAAQ,GACAR,EAAA,IAAAS,GACAT,EAAA,GAAAA,EAAA,QAOAt0C,EAAAoW,eAAA,SAAA/nC,EAAAC,EAAAgF,EAAAE,EAAAD,EAAAE,EAAA0a,GACA,GAAAx9B,GAAAw9B,EAEA1e,EAAAxP,KAAAkN,IAAAmG,EAAAC,GACA7D,EAAAzP,KAAA9D,IAAAmX,EAAAC,GACA5D,EAAA1P,KAAAkN,IAAAqG,EAAAC,GACA7D,EAAA3P,KAAA9D,IAAAqX,EAAAC,EAEA,OAAApF,IAAAoB,EAAA9e,GAAA+e,EAAA/e,GAAA0d,GACAC,GAAAqB,EAAAhf,GAAAif,EAAAjf,GAAA2d,GAGA0xB,EAAAsW,iBAAA,SACAjoC,EAAAC,EAAAmB,EAAAE,EAAAD,EAAAE,EAAAolE,EAAAC,EAAA9mD,GAEA,GAAA5e,IACAE,GAAAxP,KAAAkN,IAAAsC,EAAAulE,EAAAtlE,GAAAye,EACAze,GAAAzP,KAAA9D,IAAAsT,EAAAulE,EAAAtlE,GAAAye,EACAxe,GAAA1P,KAAAkN,IAAAwC,EAAAslE,EAAArlE,GAAAue,EACAve,GAAA3P,KAAA9D,IAAAwT,EAAAslE,EAAArlE,GAAAue,EAIA,OAAA9f,GAAAkB,EAAAE,IAAApB,EAAAkB,EAAAG,IAAApB,EAAAiB,EAAAI,IAAArB,EAAAiB,EAAAK,IAEA,GAGA,GAKAowB,EAAAk1C,WAAA,SAAAjkF,EAAA2D,EAAA+4B,EAAA3yB,EAAA0yC,GAQA94C,GAAA3D,EACA08B,GAAA18B,EACA+J,GAAA/J,CAEA,IAAAkkF,GAAA7hF,EAAAzC,EAAAukF,EAAAtkF,EAAAH,EAAA0kF,EAAAC,CAUA,OARAhiF,IAAA,EAAAq6B,EAAA/4B,EAAAA,GAAA,EACA/D,IAAA,GAAAmK,GAAApG,GAAA,EAAA+4B,EAAA,GAAA/4B,EAAAA,IACA/D,GAAA,GAEAskF,EAAA7hF,EAAAA,EAAAA,EAAAzC,EAAAA,EACA68C,EAAA,GAAA,EACA2nC,EAAAzgF,EAAA,EAEAugF,EAAA,GACArkF,EAAAD,EAAAoP,KAAA+F,KAAAmvE,GACArkF,EAAA,EAAAA,GAAAmP,KAAA6C,KAAAhS,EAAA,EAAA,GAAAmP,KAAA6C,IAAAhS,EAAA,EAAA,GACAH,EAAAE,EAAAoP,KAAA+F,KAAAmvE,GACAxkF,EAAA,EAAAA,GAAAsP,KAAA6C,KAAAnS,EAAA,EAAA,GAAAsP,KAAA6C,IAAAnS,EAAA,EAAA,GACA+8C,EAAA,IAAA2nC,EAAAvkF,EAAAH,EACA0kF,IAAAvkF,EAAAH,GAAA,EACA+8C,EAAA,GAAAA,EAAA,IAAA2nC,EACAA,EAAAp1E,KAAA+F,KAAA,KAAArV,EAAAG,GAAA,EACA48C,EAAA,GAAA2nC,OACA3nC,EAAA,IAAA2nC,KAIA3nC,EAAA,GAAAA,EAAA,GAAA,EAEA,IAAAynC,GACAG,EAAA,EAAAzkF,GAAAoP,KAAA6C,KAAAjS,EAAA,EAAA,GAAAoP,KAAA6C,IAAAjS,EAAA,EAAA,GACA68C,EAAA,IAAA2nC,EAAA,EAAAC,OACA5nC,EAAA,GAAAA,EAAA,KAAA4nC,EAAAD,MAIA/hF,GAAAA,EACA8hF,EAAA9hF,EAAAA,EAAAA,EACA8hF,EAAAn1E,KAAAs1E,KAAA1kF,EAAAoP,KAAA+F,KAAAovE,IACAE,EAAA,EAAAr1E,KAAA+F,KAAA1S,GACAo6C,EAAA,IAAA2nC,EAAAC,EAAAr1E,KAAA6T,IAAAshE,EAAA,GACA1nC,EAAA,IAAA2nC,EAAAC,EAAAr1E,KAAA6T,KAAAshE,EAAA,EAAAn1E,KAAAsjC,IAAA,QACAmK,EAAA,IAAA2nC,EAAAC,EAAAr1E,KAAA6T,KAAAshE,EAAA,EAAAn1E,KAAAsjC,IAAA,OAKAvD,EAAAuW,4BAAA,SACAloC,EAAAC,EAAAmB,EAAAE,EAAAD,EAAAE,EAAAolE,EAAAC,GASA,GAAAhkF,GAAA,EAAAwe,EAAAA,EAAA,EAAAA,EAAAC,EAAA,EAAAD,EAAAulE,EAAA,EAAAtlE,EAAAA,EAAA,EAAAA,EAAAslE,EAAAA,EAAAA,EACArlE,EAAAA,EAAA,EAAAA,EAAAC,EAAA,EAAAD,EAAAslE,EAAA,EAAArlE,EAAAA,EAAA,EAAAA,EAAAqlE,EAAAA,EAAAA,EAEArgF,EAAA,EAAA6a,EAAAC,EAAA,EAAAD,EAAAA,EAAA,EAAAA,EAAAulE,EAAA,EAAAtlE,EAAAA,EAAA,EAAAA,EAAAslE,EACA,EAAArlE,EAAAC,EAAA,EAAAD,EAAAA,EAAA,EAAAA,EAAAslE,EAAA,EAAArlE,EAAAA,EAAA,EAAAA,EAAAqlE,EAEAtnD,EAAA,EAAAle,EAAAA,EAAA,EAAAA,EAAAC,EAAAD,EAAAulE,EAAAvlE,EAAApB,EAAA,EAAAqB,EAAAA,EAAA,EAAAA,EAAArB,EAAA2mE,EAAA3mE,EACA,EAAAsB,EAAAA,EAAA,EAAAA,EAAAC,EAAAD,EAAAslE,EAAAtlE,EAAArB,EAAA,EAAAsB,EAAAA,EAAA,EAAAA,EAAAtB,EAAA2mE,EAAA3mE,EAEAtT,EAAA,EAAAyU,EAAAC,EAAAD,EAAAA,EAAAA,EAAApB,EAAAqB,EAAArB,EACAsB,EAAAC,EAAAD,EAAAA,EAAAA,EAAArB,EAAAsB,EAAAtB,EAIArR,IAGAzM,MAAA0kF,WAAAjkF,EAAA2D,EAAA+4B,EAAA3yB,EAAAiC,EAMA,KAAA,GAJAu4E,GAAA,KAEA14E,KAEA2B,EAAA,EAAA,EAAAA,EAAAA,GAAA,EACAwB,KAAAquB,IAAArxB,EAAAwB,EAAA,IAAA+2E,GACAv4E,EAAAwB,IAAA,GACAxB,EAAAwB,IAAA,GACA3B,EAAA7J,KAAAgK,EAAAwB,GAIA3B,GAAA7J,KAAA,GACA6J,EAAA7J,KAAA,EAMA,KAAA,GAHAwiF,GAEAC,EAAAC,EAAAC,EAHAC,EAAA,GAIA1kF,EAAA,EAAAA,EAAA2L,EAAAtL,OAAAL,IACAukF,EAAAz1E,KAAA6C,IAAA,EAAAhG,EAAA3L,GAAA,GAAAse,EACA,GAAA,EAAA3S,EAAA3L,IAAA2L,EAAA3L,GAAAue,EACA5S,EAAA3L,GAAA2L,EAAA3L,GAAA6jF,EAEAW,EAAA11E,KAAA6C,IAAA,EAAAhG,EAAA3L,GAAA,GAAAwe,EACA,GAAA,EAAA7S,EAAA3L,IAAA2L,EAAA3L,GAAAye,EACA9S,EAAA3L,GAAA2L,EAAA3L,GAAA8jF,EAEAW,EAAA31E,KAAA6C,IAAA4yE,EAAArnE,EAAA,GAAApO,KAAA6C,IAAA6yE,EAAArnE,EAAA,GAEAunE,GAAA,EACAA,EAAAD,IACAC,EAAAD,EACAH,EAAA34E,EAAA3L,KAGA0kF,EAAAD,EACAH,EAAA34E,EAAA3L,GAIA,OAAA0kF,IAGA71C,EAAAqW,uBAAA,SAAAhoC,EAAAC,EAAAmB,EAAAE,EAAAD,EAAAE,GACA,GAAAkmE,IAAAznE,EAAAoB,EAAAnB,EAAAqB,GACAmrC,GAAAprC,EAAAD,EAAAG,EAAAD,GAEAomE,EAAAj7B,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAA,EAAA,GACAk7B,EAAAF,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAEAG,EAAAH,EAAA,GAAAh7B,EAAA,GAAAg7B,EAAA,GAAAh7B,EAAA,GACAo7B,EAAAD,EAAAA,EAAAF,CAEA,OAAA,GAAAE,EACAD,EAGAE,EAAAH,GACA1nE,EAAAqB,IAAArB,EAAAqB,IAAApB,EAAAsB,IAAAtB,EAAAsB,GAGAomE,EAAAE,GAGAl2C,EAAAgS,yBAAA,SAAA3jC,EAAAC,EAAA6G,GAOA,IAAA,GANA1F,GAAAE,EAAAD,EAAAE,EACAqlE,EAGAkB,EAAA,EACAxtB,EAAA,EACAx3D,EAAA,EAAAA,EAAAgkB,EAAA3jB,OAAA,EAAAL,IAaA,GAXAse,EAAA0F,EAAA,EAAAhkB,GACAwe,EAAAwF,EAAA,EAAAhkB,EAAA,GAEAA,EAAA,EAAAgkB,EAAA3jB,OAAA,GACAke,EAAAyF,EAAA,GAAAhkB,EAAA,IACAye,EAAAuF,EAAA,GAAAhkB,EAAA,GAAA,KAEAue,EAAAyF,EAAA,GAAAhkB,EAAA,EAAAgkB,EAAA3jB,OAAA,IACAoe,EAAAuF,EAAA,GAAAhkB,EAAA,EAAAgkB,EAAA3jB,OAAA,GAAA,IAGAie,GAAApB,GAAAqB,GAAArB,OAEA,CAAA,KAAAoB,GAAApB,GAAAA,GAAAqB,GACArB,GAAAoB,GAAAC,GAAArB,GAaA,QAXA4mE,IAAA5mE,EAAAoB,IAAAC,EAAAD,IAAAG,EAAAD,GAAAA,EAEAslE,EAAA3mE,GACA6nE,IAGA7nE,EAAA2mE,GACAtsB,IASA,MAAAwtB,GAAA,IAAA,GACA,GAEA,GAIAn2C,EAAAk2B,mBAAA,SACA7nD,EAAAC,EAAA8nE,EAAA1rC,EAAAC,EAAAnT,EAAAC,EAAA4+C,EAAAnmE,GAGA,GAGA+gC,GAHAqlC,EAAA,GAAAhzE,OAAA8yE,EAAA5kF,OAKA,OAAA6kF,EAAA,IACAplC,EAAAhxC,KAAAulD,KAAA6wB,EAAA,GAAAA,EAAA,IAEAA,EAAA,GAAA,EACAplC,GAAAhxC,KAAAsjC,GAAA,EAEA0N,GAAAA,EAAAhxC,KAAAsjC,GAAA,GAGA0N,EAAAolC,CAOA,KAAA,GAJAviE,GAAA7T,KAAA6T,KAAAm9B,GACAl9B,EAAA9T,KAAA8T,KAAAk9B,GAGA9/C,EAAA,EAAAA,EAAAmlF,EAAA9kF,OAAA,EAAAL,IACAmlF,EAAA,EAAAnlF,GACAqmC,EAAA,GAAA4+C,EAAA,EAAAjlF,GAAA2iB,EACAsiE,EAAA,EAAAjlF,EAAA,GAAA4iB,GAEAuiE,EAAA,EAAAnlF,EAAA,GACAsmC,EAAA,GAAA2+C,EAAA,EAAAjlF,EAAA,GAAA2iB,EACAsiE,EAAA,EAAAjlF,GAAA4iB,GAEAuiE,EAAA,EAAAnlF,IAAAu5C,EACA4rC,EAAA,EAAAnlF,EAAA,IAAAw5C,CAGA,IAAAx1B,EAEA,IAAAjF,EAAA,EAAA,CACA,GAAAqmE,GAAA/lF,KAAAgmF,cACAF,GACApmE,EAEAiF,GAAA3kB,KAAAimF,UAAAF,OAEAphE,GAAAmhE,CAGA,OAAAt2C,GAAAgS,yBAAA3jC,EAAAC,EAAA6G,IAGA6qB,EAAAy2C,UAAA,SAAAC,GAOA,IAAA,GAHAC,GAAAC,EAAAC,EAAAC,EACAC,EAAAC,EAAAC,EAAAC,EAHAC,EAAA,GAAA7zE,OAAAozE,EAAAllF,OAAA,GAKAL,EAAA,EAAAA,EAAAulF,EAAAllF,OAAA,EAAAL,IAAA,CACAwlF,EAAAD,EAAA,EAAAvlF,GACAylF,EAAAF,EAAA,EAAAvlF,EAAA,GACA0lF,EAAAH,EAAA,EAAAvlF,EAAA,GACA2lF,EAAAJ,EAAA,EAAAvlF,EAAA,GAEAA,EAAAulF,EAAAllF,OAAA,EAAA,GACAulF,EAAAL,EAAA,GAAAvlF,EAAA,IACA6lF,EAAAN,EAAA,GAAAvlF,EAAA,GAAA,GACA8lF,EAAAP,EAAA,GAAAvlF,EAAA,GAAA,GACA+lF,EAAAR,EAAA,GAAAvlF,EAAA,GAAA,KAEA4lF,EAAAL,EAAA,GACAM,EAAAN,EAAA,GACAO,EAAAP,EAAA,GACAQ,EAAAR,EAAA,GAGA,IAAAl0E,GAAAhS,KAAAijF,qBACAkD,EAAAC,EACAC,EAAAC,EACAC,EAAAC,EACAC,EAAAC,GACA,EAEAC,GAAA,EAAAhmF,GAAAqR,EAAA,GACA20E,EAAA,EAAAhmF,EAAA,GAAAqR,EAAA,GAGA,MAAA20E,IAGAn3C,EAAAw2C,cAAA,SAAArhE,EAAAiiE,GAMA,IAAA,GAFAC,GAAAC,EAAAC,EAAAC,EAFAjB,EAAA,GAAAjzE,OAAA,EAAA6R,EAAA3jB,QAIAL,EAAA,EAAAA,EAAAgkB,EAAA3jB,OAAA,EAAAL,IAAA,CACAkmF,EAAAliE,EAAA,EAAAhkB,GACAmmF,EAAAniE,EAAA,EAAAhkB,EAAA,GAEAA,EAAAgkB,EAAA3jB,OAAA,EAAA,GACA+lF,EAAApiE,EAAA,GAAAhkB,EAAA,IACAqmF,EAAAriE,EAAA,GAAAhkB,EAAA,GAAA,KAEAomF,EAAApiE,EAAA,GACAqiE,EAAAriE,EAAA,GAOA,IAAA4zB,GAAAyuC,EAAAF,EACAtuC,IAAAuuC,EAAAF,GAGAI,EAAAx3E,KAAA+F,KAAA+iC,EAAAA,EAAAC,EAAAA,GACA0uC,EAAA3uC,EAAA0uC,EACAE,EAAA3uC,EAAAyuC,CAEAlB,GAAA,EAAAplF,GAAAkmF,EAAAK,EAAAN,EACAb,EAAA,EAAAplF,EAAA,GAAAmmF,EAAAK,EAAAP,EACAb,EAAA,EAAAplF,EAAA,GAAAomF,EAAAG,EAAAN,EACAb,EAAA,EAAAplF,EAAA,GAAAqmF,EAAAG,EAAAP,EAGA,MAAAb,IAGAv2C,EAAAm2B,qBAAA,SACA9nD,EAAAC,EAAAo8B,EAAAC,EAAAitC,EAAAC,GAEA,GAAAjyB,GAAAlb,EAAAr8B,EACAw3C,EAAAlb,EAAAr8B,CAEAs3C,IAAAgyB,EACA/xB,GAAAgyB,CAEA,IAAAC,GAAA73E,KAAA+F,KAAA4/C,EAAAA,EAAAC,EAAAA,GAEAkyB,EAAAD,EAAA,CAEA,IAAA,EAAAC,EACA,QAGA,IAAAC,GAAAD,EAAAD,CAEA,SAAAptC,EAAAr8B,GAAA2pE,EAAA3pE,GAAAs8B,EAAAr8B,GAAA0pE,EAAA1pE,IAIA0xB,EAAAy0C,oBAAA,SACAhlE,EAAAE,EAAAD,EAAAE,EAAA86B,EAAAC,EAAArH,GAGA,GAAAtoC,IAAA0U,EAAAD,EAAAG,EAAAD,GACAge,GAAA+c,EAAAC,GACA56C,GAAA0f,EAAAi7B,EAAA/6B,EAAAg7B,GAEA15C,EAAA+J,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAA,EAAA,GACApG,EAAA,GAAA7E,EAAA,GAAAiL,EAAA,GAAAjL,EAAA,GAAAiL,EAAA,IACA2yB,EAAA59B,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAuzC,EAAAA,EAEA6xC,EAAAvgF,EAAAA,EAAA,EAAA3D,EAAA08B,CAEA,IAAA,EAAAwnD,EACA,QAGA,IAAA8C,KAAArjF,EAAAqL,KAAA+F,KAAAmvE,KAAA,EAAAlkF,GACAinF,IAAAtjF,EAAAqL,KAAA+F,KAAAmvE,KAAA,EAAAlkF,GAEAknF,EAAAl4E,KAAAkN,IAAA8qE,EAAAC,GACAE,EAAAn4E,KAAA9D,IAAA87E,EAAAC,GACAG,IAUA,IARAF,GAAA,GAAA,GAAAA,GACAE,EAAAplF,KAAAklF,GAGAC,GAAA,GAAA,GAAAA,GACAC,EAAAplF,KAAAmlF,GAGA,IAAAC,EAAA7mF,OACA,QAGA,IAAA8mF,GAAAD,EAAA,GAAAr9E,EAAA,GAAAyU,EACA8oE,EAAAF,EAAA,GAAAr9E,EAAA,GAAA2U,CAEA,IAAA0oE,EAAA7mF,OAAA,EAAA,CAEA,GAAA6mF,EAAA,IAAAA,EAAA,GACA,OAAAC,EAAAC,EAGA,IAAAC,GAAAH,EAAA,GAAAr9E,EAAA,GAAAyU,EACAgpE,EAAAJ,EAAA,GAAAr9E,EAAA,GAAA2U,CAEA,QAAA2oE,EAAAC,EAAAC,EAAAC,GAIA,OAAAH,EAAAC,IAKAv4C,EAAA04C,oBAAA,SAAAhuC,EAAAC,EACArH,EAAAq1C,EAAAC,GAEA,GAAAC,GAAAF,EAAAjuC,EACAouC,EAAAF,EAAAjuC,EACAxyC,EAAA8H,KAAA+F,KAAA6yE,EAAAA,EACAC,EAAAA,GAEAC,EAAAF,EAAA1gF,EACA6gF,EAAAF,EAAA3gF,CAEA,QAAAuyC,EAAAquC,EAAAz1C,EACAqH,EAAAquC,EAAA11C,IAGAtD,EAAAi5C,0BAAA,SAAA9jE,GAIA,IAAA,GAFA69D,GADAkG,EAAA,KAGA/nF,EAAA,EAAAA,EAAAgkB,EAAA3jB,OAAA,EAAAL,IAEA6hF,EAAA79D,EAAA,EAAAhkB,GAAAgkB,EAAA,EAAAhkB,GACAgkB,EAAA,EAAAhkB,EAAA,GAAAgkB,EAAA,EAAAhkB,EAAA,GAEA6hF,EAAAkG,IACAA,EAAAlG,EAIA,OAAAkG,IAGAl5C,EAAAyzC,qBAAA,SACAhkE,EAAAE,EAAAD,EAAAE,EAAAolE,EAAAC,EAAAkE,EAAAC,EAAAC,GAEA,GAAAC,IAAAH,EAAAnE,IAAArlE,EAAAslE,IAAAmE,EAAAnE,IAAAxlE,EAAAulE,GACAuE,GAAA7pE,EAAAD,IAAAE,EAAAslE,IAAArlE,EAAAD,IAAAF,EAAAulE,GACAwE,GAAAJ,EAAAnE,IAAAvlE,EAAAD,IAAA0pE,EAAAnE,IAAAplE,EAAAD,EAEA,IAAA,IAAA6pE,EAAA,CACA,GAAAC,GAAAH,EAAAE,EACAE,EAAAH,EAAAC,CAEA,OAAAC,IAAA,GAAA,GAAAA,GAAAC,GAAA,GAAA,GAAAA,GACAjqE,EAAAgqE,GAAA/pE,EAAAD,GAAAE,EAAA8pE,GAAA7pE,EAAAD,IAGA0pE,GAGA5pE,EAAAgqE,GAAA/pE,EAAAD,GAAAE,EAAA8pE,GAAA7pE,EAAAD,OAIA,MAAA,KAAA2pE,GAAA,IAAAC,GAKA9pE,EAAAC,EAAAypE,GAAAx6E,OAAA,KAAAw6E,GACAA,EAAAC,IAIA3pE,EAAAC,EAAAslE,GAAAr2E,OAAA,KAAAq2E,GACAA,EAAAC,IAIAD,EAAAmE,EAAAzpE,GAAA/Q,OAAA,KAAA+Q,GACAA,EAAAE,UAYAowB,EAAAi2B,qBAAA,SACA5nD,EAAAC,EAAA8nE,EAAA1rC,EAAAC,EAAAnT,EAAAC,EAAAvnB,GAOA,IAAA,GAJA1N,GADAm3E,KAGArD,EAAA,GAAAhzE,OAAA8yE,EAAA5kF,QAEAL,EAAA,EAAAA,EAAAmlF,EAAA9kF,OAAA,EAAAL,IACAmlF,EAAA,EAAAnlF,GAAAilF,EAAA,EAAAjlF,GAAAqmC,EAAAkT,EACA4rC,EAAA,EAAAnlF,EAAA,GAAAilF,EAAA,EAAAjlF,EAAA,GAAAsmC,EAAAkT,CAGA,IAAAx1B,EAEA,IAAAjF,EAAA,EAAA,CACA,GAAAqmE,GAAAv2C,EAAAw2C,cACAF,GACApmE,EAEAiF,GAAA6qB,EAAAy2C,UAAAF,OAEAphE,GAAAmhE,CAMA,KAAA,GAFAsD,GAAAC,EAAAC,EAAAC,EAEA5oF,EAAA,EAAAA,EAAAgkB,EAAA3jB,OAAA,EAAAL,IAEAyoF,EAAAzkE,EAAA,EAAAhkB,GACA0oF,EAAA1kE,EAAA,EAAAhkB,EAAA,GAEAA,EAAAgkB,EAAA3jB,OAAA,EAAA,GACAsoF,EAAA3kE,EAAA,GAAAhkB,EAAA,IACA4oF,EAAA5kE,EAAA,GAAAhkB,EAAA,GAAA,KAEA2oF,EAAA3kE,EAAA,GACA4kE,EAAA5kE,EAAA,IAGA3S,EAAAhS,KAAAijF,qBACAplE,EAAAC,EAAAo8B,EAAAC,EACAivC,EAAAC,EACAC,EAAAC,GAEA,IAAAv3E,EAAAhR,QACAmoF,EAAA1mF,KAAAuP,EAAA,GAAAA,EAAA,GAIA,OAAAm3E,IAGA35C,EAAAonB,oBAAA,SACA5kD,EAAAszE,EAAAkE,GAEA,GAAA/qB,IAAAzsD,EAAA,GAAAszE,EAAA,GAAAtzE,EAAA,GAAAszE,EAAA,IAEAtkF,EAAAyO,KAAA+F,KAAAipD,EAAA,GAAAA,EAAA,GAAAA,EAAA,GAAAA,EAAA,IAEAgrB,GAAAzoF,EAAAwoF,GAAAxoF,CAMA,OAJA,GAAAyoF,IACAA,EAAA,OAGAnE,EAAA,GAAAmE,EAAAhrB,EAAA,GAAA6mB,EAAA,GAAAmE,EAAAhrB,EAAA,KAGAjvB,EAAAo2B,kCAAA,SAAA8jB,EAAAC,GACA,GAAAhlE,GAAA6qB,EAAA22B,uBAAAujB,EAAAC,EAGA,OAFAhlE,GAAA6qB,EAAA82B,mBAAA3hD,IAKA6qB,EAAA82B,mBAAA,SAAA3hD,GAKA,IAAA,GAJA9G,GAAAC,EACA4rE,EAAA/kE,EAAA3jB,OAAA,EACA63C,EAAA9vC,EAAAA,EAAAiwC,EAAAjwC,EAAAA,EAAA6vC,IAAA7vC,EAAAA,GAAAgwC,IAAAhwC,EAAAA,GAEApI,EAAA,EAAA+oF,EAAA/oF,EAAAA,IACAkd,EAAA8G,EAAA,EAAAhkB,GACAmd,EAAA6G,EAAA,EAAAhkB,EAAA,GAEAk4C,EAAAppC,KAAAkN,IAAAk8B,EAAAh7B,GACA+6B,EAAAnpC,KAAA9D,IAAAitC,EAAA/6B,GACAm7B,EAAAvpC,KAAAkN,IAAAq8B,EAAAl7B,GACAi7B,EAAAtpC,KAAA9D,IAAAotC,EAAAj7B,EAOA,KAAA,GAHA8rE,GAAA,GAAAhxC,EAAAC,GACAgxC,EAAA,GAAA9wC,EAAAC,GAEAr4C,EAAA,EAAA+oF,EAAA/oF,EAAAA,IACAkd,EAAA8G,EAAA,EAAAhkB,GAAAgkB,EAAA,EAAAhkB,GAAAipF,EACA9rE,EAAA6G,EAAA,EAAAhkB,EAAA,GAAAgkB,EAAA,EAAAhkB,EAAA,GAAAkpF,EAEAhxC,EAAAppC,KAAAkN,IAAAk8B,EAAAh7B,GACA+6B,EAAAnpC,KAAA9D,IAAAitC,EAAA/6B,GACAm7B,EAAAvpC,KAAAkN,IAAAq8B,EAAAl7B,GACAi7B,EAAAtpC,KAAA9D,IAAAotC,EAAAj7B,EAGA,IAAA,GAAAk7B,EACA,IAAA,GAAAr4C,GAAA,EAAA+oF,EAAA/oF,EAAAA,IACAmd,EAAA6G,EAAA,EAAAhkB,EAAA,GAAAgkB,EAAA,EAAAhkB,EAAA,IAAA,GAAAq4C,EAIA,OAAAr0B,IAGA6qB,EAAA22B,uBAAA,SAAAujB,EAAAC,GAEA,GAAAG,GAAA,EAAAJ,EAAA,EAAAj6E,KAAAsjC,GACAK,EAAAs2C,EAAA,IAAA,EACAj6E,KAAAsjC,GAAA,EAAA+2C,EAAA,EAAAr6E,KAAAsjC,GAAA,CAEAK,IAAAu2C,CAKA,KAAA,GADAI,GAAAlsE,EAAAC,EAFA6G,EAAA,GAAA7R,OAAA,EAAA42E,GAGA/oF,EAAA,EAAA+oF,EAAA/oF,EAAAA,I9E6mlBIopF,EAAeppF,EAAImpF,EAAY12C,E+Eh/mBnCv1B,EAAA8G,EAAA,EAAAhkB,GAAA8O,KAAA6T,IAAAymE,GACAjsE,EAAA6G,EAAA,EAAAhkB,EAAA,GAAA8O,KAAA8T,KAAAwmE,EAGA,OAAAplE,IAGA6qB,EAAAu2B,wBAAA,SAAA/+B,EAAAC,GAGA,MAAAx3B,MAAAkN,IAAAqqB,EAAA,EAAAC,EAAA,EAAA,IAGAxnC,EAAAD,QAAAgwC,OAEAw6C,IAAA,SAAA9oF,EAAAzB,EAAAD,GAIA,YAGA,IAAAyqF,GAAA,EACAC,EAAA,EACAC,EAAA,EAGAC,EAAA,SAAAC,GAEA,MAAArqF,gBAAAoqF,IAIApqF,KAAAgH,GAAA,iBACAhH,KAAAy8B,MAAAwtD,EACAjqF,KAAAsqF,aAAAxmF,OACA9D,KAAAuqF,aAAAzmF,OACA9D,KAAAwqF,eACAxqF,KAAAyqF,cAGAzqF,KAAA0qF,OACAvoD,KAAAniC,KAAAmiC,KAAAxP,KAAA3yB,YAIA,kBAAAqqF,IACAA,EAAAtpF,KAAAf,KAAAA,KAAA2qF,QAAAh4D,KAAA3yB,MAAAA,KAAA+E,OAAA4tB,KAAA3yB,SAjBA,GAAAoqF,GAAAC,GAqBAD,GAAAznF,WAEAgoF,QAAA,SAAAnrE,GAAA,MAAAorE,GAAA5qF,KAAAkqF,EAAA,eAAA1qE,IACAza,OAAA,SAAAya,GAAA,MAAAorE,GAAA5qF,KAAAmqF,EAAA,eAAA3qE,IAGA2iB,KAAA,SAAAqoD,EAAAC,GACA,GAAAI,GAAA7qF,KACA+S,EAAA,GAAAq3E,EAMA,OALAS,GAAAL,YAAA/nF,KACAqoF,EAAAN,EAAAz3E,EAAA,YACA83E,EAAAJ,WAAAhoF,KACAqoF,EAAAL,EAAA13E,EAAA,WACAg4E,EAAAF,GACA93E,EAAA23E,OAKA,IAAAE,GAAA,SAAAC,EAAApuD,EAAAl4B,EAAAib,GAMA,MALAqrE,GAAApuD,QAAAwtD,IACAY,EAAApuD,MAAAA,EACAouD,EAAAtmF,GAAAib,EACAurE,EAAAF,IAEAA,GAIAE,EAAA,SAAAF,GACAA,EAAApuD,QAAAytD,EACAc,EAAAH,EAAA,cAAAA,EAAAP,cACAO,EAAApuD,QAAA0tD,GACAa,EAAAH,EAAA,aAAAA,EAAAN,eAIAS,EAAA,SAAAH,EAAAtmF,EAAAib,GAKA,GAAA,IAAAqrE,EAAAtmF,GAAAvD,OAAA,CAIA,GAAAiqF,GAAAJ,EAAAtmF,EACAsmF,GAAAtmF,KACA,IAAA2mF,GAAA,WACA,IAAA,GAAAvqF,GAAA,EAAAA,EAAAsqF,EAAAjqF,OAAAL,IACAsqF,EAAAtqF,GAAA6e,GAIA,mBAAA2rE,cACAA,aAAAD,GAEA3xE,WAAA2xE,EAAA,KAIAJ,EAAA,SAAAnxD,EAAA5mB,EAAAq4E,GACA,MAAA,UAAA5rE,GACA,GAAA,kBAAAma,GACA5mB,EAAAq4E,GAAArqF,KAAAgS,EAAAyM,OACA,CACA,GAAA09B,EACA,KAAAA,EAAAvjB,EAAAna,GACA,MAAAtf,GAEA,WADA6S,GAAAhO,OAAA7E,GAGA4E,EAAAiO,EAAAmqC,MAMAp4C,EAAA,SAAAH,EAAAkZ,GAEA,GAAAlZ,IAAAkZ,GAAAlZ,EAAA+lF,QAAA7sE,EAEA,WADAlZ,GAAAI,OAAA,GAAAsmF,WAAA,sCAMA,IAAAlpD,EACA,IAAA,gBAAAtkB,IAAA,OAAAA,GAAA,kBAAAA,GACA,IAAAskB,EAAAtkB,EAAAskB,KACA,MAAAjiC,GAEA,WADAyE,GAAAI,OAAA7E,GAOA,GAAA,kBAAAiiC,GA6BAx9B,EAAAgmF,QAAA9sE,OA7BA,CACA,GAAAytE,IAAA,CACA,KAEAnpD,EAAAphC,KAAA8c,EAEA,SAAAC,GACAwtE,IAAAA,GAAA,EACAxtE,IAAAD,EACAlZ,EAAAI,OAAA,GAAAsmF,WAAA,4BAEAvmF,EAAAH,EAAAmZ,KAIA,SAAAzd,GACAirF,IAAAA,GAAA,EACA3mF,EAAAI,OAAA1E,MAIA,MAAAH,GACAorF,GACA3mF,EAAAI,OAAA7E,MAUAmB,EAAA,mBAAAA,GAAA+oF,EAAA/oF,CAGAA,GAAA6gC,IAAA7gC,EAAA6gC,KAAA,SAAAqpD,GACA,MAAA,IAAAlqF,GAAA,SAAAmqF,EAAAC,GAaA,IAAA,GAZAC,GAAA,GAAA54E,OAAAy4E,EAAAvqF,QACA2qF,EAAA,EAEAhB,EAAA,SAAAhqF,EAAAwd,GACAutE,EAAA/qF,GAAAwd,EACAwtE,IAEAA,IAAAJ,EAAAvqF,QACAwqF,EAAAE,IAIA/qF,EAAA,EAAAA,EAAA4qF,EAAAvqF,OAAAL,KACA,SAAAA,GACA,GAAAoD,GAAAwnF,EAAA5qF,GACAirF,EAAA,MAAA7nF,EAAAo+B,IAEA,IAAAypD,E/Em/mBU7nF,EAAEo+B,KAAK,SAAUhkB,GgFhsnB3BwsE,EAAAhqF,EAAAwd,IACA,SAAA28D,GACA2Q,EAAA3Q,SAEA,CACA,GAAA38D,GAAApa,CACA4mF,GAAAhqF,EAAAwd,KAEAxd,MAMAlB,EAAAD,QAAA6B,OAEAwqF,IAAA,SAAA3qF,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,QACAC,EAAAD,EAAA,UAEAwlB,EAAA,SAAAolE,EAAAnyE,GAEA,KAAA3Z,eAAA0mB,IACA,MAAA,IAAAA,GAAAolE,EAAAnyE,EAGA7V,UAAA6V,GAAA7V,SAAAgoF,IACAnyE,EAAAmyE,EACAA,EAAAhoF,OAGA,IAAA/D,GAAAC,IAOA,IALAD,EAAA4B,UACAoqF,aAAA,KACAC,SAAA,IAGAryE,GAAAvY,EAAAoF,OAAAmT,IAAAA,EAAA1B,MAAA,SAEA,MAAA6zE,EAEA/rF,EAAAiB,OAAA,GAEAjB,EAAA,GAAAksF,IACAlsF,EAAA,GAAAghB,MAAA+qE,EACA/rF,EAAAiB,OAAA,OAGA,IAAAI,EAAA+B,oBAAAwW,GAAA,CACA,GAAAlM,GAAAkM,EAAAlM,YAEA1N,GAAA,GAAAksF,IACAlsF,EAAA,GAAA0N,WAAAA,EACA1N,EAAAiB,OAAA,MAEA,IAAAI,EAAAoB,GAAAmX,GACA5Z,EAAA,GAAAksF,IACAlsF,EAAA,GAAA0G,OAAAkT,EACA5Z,EAAAiB,OAAA,MAEA,CAAA,IAAAI,EAAAoF,OAAAmT,GAwWA,WADAxY,GAAAiI,MAAA,mDAAAuQ,EApWA,IAAAuyE,GAAA,KAGAD,EAAA,WACA,OACAj0E,WACAm0E,kBACAjkF,QACA6Y,MAAA,KACA+F,OACAslE,QAGA3+E,WAAA,KACAhH,OAAA,KAIAwT,OAAA,KACAuR,SAAA,KACA6gE,QAAA,KAGAC,MAAA,KACAC,WAAA,OAKAC,GACAC,SAAA,6FACAC,aAAA,kCACAC,OAAA,cACAnmF,OAAA,qBAAA,oBACAsL,OAAA3Q,EAAA+nC,MAAAp3B,OACAs6E,KAAA,4BACAQ,UAAA,YACAL,WAAA,OACAD,MAAA,YACAD,QAAA,MAEAG,GAAAK,SAAA,oBAAAL,EAAAC,SAAA,MACAD,EAAAhtE,MAAAgtE,EAAAhmF,OAAA,IAAAgmF,EAAA16E,OACA06E,EAAAxzE,UAAAwzE,EAAAK,SACAL,EAAAxlF,GAAAwlF,EAAAK,QAYA,KAAA,GARAC,GAAA,SAAAC,GACA,MAAAA,GAAA/N,QAAA,GAAAgO,QAAA,QAAAR,EAAAC,SAAA,IAAA,KAAA,SAAAx0E,EAAAg1E,EAAA3H,EAAA4H,GACA,MAAAD,MAKAE,EAAAX,EAAAE,aAAA7mE,MAAA,KACAllB,EAAA,EAAAA,EAAAwsF,EAAAnsF,OAAAL,IAAA,CACA,GAAAysF,GAAAD,EAAAxsF,EACA6rF,GAAAE,cAAA,KAAAU,EAKA,IAAA,GADAD,GAAAX,EAAAE,aAAA7mE,MAAA,KACAllB,EAAA,EAAAA,EAAAwsF,EAAAnsF,OAAAL,IAAA,CACA,GAAAysF,GAAAD,EAAAxsF,EAEAysF,GAAA9kF,QAAA,MAAA,GACA,MAAA8kF,IAEAZ,EAAAE,cAAA,OAAAU,GAQA,GAAAC,KAEA9oF,KAAA,QACA+oF,OAAA,EACApkD,MAAA,kBACAqkD,SAAA,SAAAxsE,GACA/gB,KAAA+gB,MAAA,KAAAA,EAAAA,EAAAA,EAAA,OAKAxc,KAAA,QACA+oF,OAAA,EAGApkD,MAAA,4RACAqkD,SAAA,SAAA9wD,GACAz8B,KAAAmsF,eAAA1pF,KAAAg6B,MAKAl4B,KAAA,KACA+oF,OAAA,EACApkD,MAAA,OAAAsjD,EAAAxlF,GAAA,IACAumF,SAAA,SAAAvmF,GACAhH,KAAA8mB,IAAArkB,KAAAqqF,EAAA9lF,OAKAzC,KAAA,YACA+oF,OAAA,EACApkD,MAAA,OAAAsjD,EAAAxzE,UAAA,IACAu0E,SAAA,SAAAv0E,GACAhZ,KAAAgY,QAAAvV,KAAAqqF,EAAA9zE,OAKAzU,KAAA,aACA+oF,OAAA,EACApkD,MAAA,WAAAsjD,EAAAK,SAAA,WACAU,SAAA,SAAAV,GACA7sF,KAAAkI,KAAAzF,MACAwY,MAAA6xE,EAAAD,QAMAtoF,KAAA,cACA+oF,OAAA,EACApkD,MAAA,WAAAsjD,EAAAK,SAAA,SAAAL,EAAAE,aAAA,SAAAF,EAAAhtE,MAAA,WACA+tE,SAAA,SAAAV,EAAAH,EAAAltE,GACA,GAAAguE,GAAA,MAAA,GAAAR,QAAA,IAAAR,EAAAhmF,OAAA,KAAAinF,KAAAjuE,EAGAA,GADAguE,EACAhuE,EAAAkuE,UAAA,EAAAluE,EAAAxe,OAAA,GAEA68B,WAAAre,GAGAxf,KAAAkI,KAAAzF,MACAwY,MAAA6xE,EAAAD,GACAc,SAAAjB,EACAltE,MAAAA,OAMAjb,KAAA,WACA+oF,OAAA,EACApkD,MAAA,WAAAsjD,EAAAG,OAAA,SAAAH,EAAAK,SAAA,WACAU,SAAA,SAAAZ,EAAAE,GACA7sF,KAAAkI,KAAAzF,MACAwY,MAAA6xE,EAAAD,GACAc,SAAAhB,OAMApoF,KAAA,cACA+oF,OAAA,EACApkD,MAAA,cAAAsjD,EAAAJ,KAAA,SAAAI,EAAAE,aAAA,SAAAF,EAAA16E,OAAA,cACAy7E,SAAA,SAAAnB,EAAAM,EAAA56E,GACA9R,KAAAosF,KAAA3pF,MACAwY,MAAA6xE,EAAAV,GACAuB,SAAAjB,EACAltE,MAAAqe,WAAA/rB,QAMAvN,KAAA,YACAqoF,WAAA,EACA1jD,MAAAsjD,EAAAI,UACAW,SAAA,WAEAxtF,IAAAY,GAAAsrF,IACAC,EAAA,QAKA3nF,KAAA,QACAqoF,WAAA,EACA1jD,MAAAsjD,EAAAF,MACAiB,SAAA,WAEA,GAAAK,GAAA3B,GACA2B,GAAA3zE,OAAAja,KACA4tF,EAAAvB,QAAAH,EAGAnsF,EAAAY,GAAAitF,KAKArpF,KAAA,aACAqoF,WAAA,EACA1jD,MAAAsjD,EAAAD,WACAgB,SAAA,WAEA,GAAAM,GAAA5B,GACA4B,GAAAriE,SAAAxrB,KACA6tF,EAAAxB,QAAAH,EAGAnsF,EAAAY,GAAAktF,KAKAtpF,KAAA,UACAupF,UAAA,EACA5kD,MAAAsjD,EAAAH,QACAkB,SAAA,WACA,MAAA,OAAArB,GAAAlsF,KAAAqsF,SAAArsF,MACAmB,EAAAiI,MAAA,wCAAAuQ,EAAA,MACA,IAGAuyE,EAAAlsF,UACAA,KAAAqsF,QAAArsF,SAMAD,GAAA4B,SAAAoqF,aAAApyE,CACA,IAAAo0E,GAAAp0E,EACAhZ,EAAA,EAGAqtF,EAAA,SAAAC,GAKA,IAAA,GAJAC,GACAj2E,EACA1T,EAEA0I,EAAA,EAAAA,EAAAogF,EAAArsF,OAAAiM,IAAA,CACA,GAAA/M,GAAAmtF,EAAApgF,GACA7M,EAAAF,EAAAqE,IAGA,KAAAnD,EAAAoB,GAAAyrF,IAAAA,EAAA7tF,EAAAF,GAAA,CAEA,GAAA2rC,GAAAkiD,EAAA91E,MAAA,GAAA+0E,QAAA,IAAA9sF,EAAAgpC,OAEA,IAAA,MAAA2C,EAAA,CACA5zB,EAAA4zB,EACAqiD,EAAAhuF,EACAqE,EAAAnE,CAEA,IAAA+tF,GAAAtiD,EAAA,EACAkiD,GAAAA,EAAAL,UAAAS,EAAAntF,OAEA,SAIA,OACAktF,KAAAA,EACAj2E,MAAAA,EACA1T,KAAAA,IAKA6pF,EAAA,WACA,GAAAn2E,GAAA81E,EAAA91E,MAAA,OAEA,IAAAA,EAAA,CACA,GAAAk2E,GAAAl2E,EAAA,EACA81E,GAAAA,EAAAL,UAAAS,EAAAntF,SAOA,KAHAjB,EAAA,GAAAksF,IAEAmC,MACA,CACA,GAAAC,GAAAL,GAEA,IAAA,MAAAK,EAAAH,KAEA,WADA/sF,GAAAiI,MAAA,iBAAAuQ,EAAA,cAIA,KAAA,GADA6Y,MACAvlB,EAAA,EAAAA,EAAAohF,EAAAp2E,MAAAjX,OAAAiM,IACAulB,EAAA/vB,KAAA4rF,EAAAp2E,MAAAhL,GAIA,IAAApB,GAAAwiF,EAAAH,KAAAX,SAAA/pF,MAAAzD,EAAAY,GAAA6xB,EAEA,IAAA3mB,KAAA,EAAA,MAIA,IAAAkiF,EAAA91E,MAAA,SACA,MAIAlY,EAAAiB,OAAAL,EAAA,CAGA,KAAA,GAAAsM,GAAA,EAAAA,EAAAlN,EAAAiB,OAAAiM,IAAA,CACA,GAAAqgF,GAAAvtF,EAAAkN,EAEA,IAAA,MAAAqgF,EAAAjB,QAAA,CAEA,KACAiB,EAAAjB,SAAAiB,GAEA,GAAA,MAAAA,EAAArzE,OAAA,CACA,GAAAA,GAAAqzE,EAAArzE,OACAqyE,EAAAgB,CAEAhB,GAAAryE,OAAA,KACAA,EAAAqyE,MAAAA,EAEAgB,EAAArzE,MACA,CAAA,GAAA,MAAAqzE,EAAA9hE,SAQA,CACArqB,EAAAiI,MAAA,+CAAAkkF,EAAA,2CACA,OATA,GAAA9hE,GAAA8hE,EAAA9hE,SACA+gE,EAAAe,CAEAf,GAAA/gE,SAAA,KACAA,EAAA+gE,WAAAA,EAEAe,EAAA9hE,EAOAzrB,EAAAkN,GAAAqgF,EAAAjB,SAKA,GAAA,MAAAP,EACA,IAAA,GAAA7+E,GAAA,EAAAA,EAAAlN,EAAAiB,OAAAiM,IAAA,CACA,GAAA,MAAAlN,EAAAkN,GAAA8T,OAAAhhB,EAAAkN,GAAA8T,OAAA+qE,EAEA,WADA3qF,GAAAiI,MAAA,UAAArJ,EAAAkN,GAAA8T,MAAA,oCAAA+qE,EAAA,kBAAAnyE,EAAA,IAIA5Z,GAAAkN,GAAA8T,MAAA+qE,GASA/rF,EAAA4B,SAAAqqF,SAAA,GAIAsC,EAAA5nE,EAAA/jB,SAEA2rF,GAAAh/E,KAAA,WACA,MAAAtP,MAAAgB,QAGAstF,EAAA//D,GAAA,SAAA5tB,GACA,MAAAX,MAAAW,GAGA,IAAA4tF,GAAA,SAAAjB,EAAA3mE,GAEA,GAAA,MAAA2mE,EAAAvsE,OAAA,KAAAusE,EAAAvsE,OAAAusE,EAAAvsE,OAAA4F,EAAAhlB,SAAAof,MACA,OAAA,CAOA,KAAA,GAJA3d,GAAAujB,EAAAvjB,KAGAorF,GAAA,EACAh8E,EAAA,EAAAA,EAAA86E,EAAAnB,eAAAnrF,OAAAwR,IAAA,CACA,GAAAs0B,GAAAwmD,EAAAnB,eAAA35E,EAEA,QAAAs0B,GACA,IAAA,YACA0nD,EAAA7nE,EAAAnB,UACA,MACA,KAAA,cACAgpE,GAAA7nE,EAAAnB,UACA,MACA,KAAA,cACAgpE,EAAA7nE,EAAAlB,YACA,MACA,KAAA,gBACA+oE,GAAA7nE,EAAAlB,YACA,MACA,KAAA,UACA+oE,EAAA7nE,EAAApJ,QACA,MACA,KAAA,YACAixE,GAAA7nE,EAAApJ,QACA,MACA,KAAA,WACAixE,EAAA7nE,EAAA0K,SACA,MACA,KAAA,UACAm9D,GAAA7nE,EAAA0K,SACA,MACA,KAAA,eACAm9D,EAAA7nE,EAAAkL,aACA,MACA,KAAA,WACA28D,EAAA7nE,EAAAjB,SACA,MACA,KAAA,QACA8oE,GAAA7nE,EAAAjB,SACA,MACA,KAAA,WACA8oE,EAAA7nE,EAAApK,SACA,MACA,KAAA,UACAiyE,GAAA7nE,EAAApK,SACA,MACA,KAAA,aACAiyE,EAAA7nE,EAAAhB,WACA,MACA,KAAA,eACA6oE,GAAA7nE,EAAAhB,WACA,MACA,KAAA,YACA6oE,EAAA7nE,EAAAjP,UACA,MACA,KAAA,cACA82E,GAAA7nE,EAAAjP,UACA,MACA,KAAA,UACA82E,EAAA7nE,EAAAzZ,UAAAyZ,EAAAlM,WAAAN,UACA,MACA,KAAA,SACA,IAAA,aACAq0E,EAAA7nE,EAAAzZ,UAAAyZ,EAAA1M,SAAAE,UACA,MACA,KAAA,UACAq0E,EAAA7nE,EAAAzZ,UAAAyZ,EAAA1M,SAAAM,OACA,MACA,KAAA,QACAi0E,EAAA7nE,EAAAtF,UAAAsF,EAAAze,KAAA,YAAAye,EAAAze,KAAA,SACA,MACA,KAAA,UACAsmF,EAAA7nE,EAAAtF,UAAAsF,EAAAze,KAAA,YAAAye,EAAAze,KAAA,SACA,MACA,KAAA,UACAsmF,EAAA7nE,EAAAf,QACA,MACA,KAAA,YACA4oE,GAAA7nE,EAAAf,QACA,MACA,KAAA,SACA4oE,EAAAptF,EAAAyjE,OACA,MACA,KAAA,iBACA2pB,EAAA7nE,EAAAsL,eACA,MACA,KAAA,oBACAu8D,GAAA7nE,EAAAsL,gBAIA,IAAAu8D,EAAA,MAEA,IAAAA,EAAA,OAAA,CAIA,KAAA,GADAC,IAAA,EACAj8E,EAAA,EAAAA,EAAA86E,EAAAxmE,IAAA9lB,OAAAwR,IAAA,CACA,GAAAxL,GAAAsmF,EAAAxmE,IAAAtU,GACAk8E,EAAA/nE,EAAAhlB,SAAAuG,KAAAlB,EAIA,IAFAynF,EAAAA,GAAAznF,GAAA0nF,GAEAD,EAAA,MAEA,IAAAA,EAAA,OAAA,CAIA,KAAA,GADAE,IAAA,EACAn8E,EAAA,EAAAA,EAAA86E,EAAAt1E,QAAAhX,OAAAwR,IAAA,CACA,GAAA4F,GAAAk1E,EAAAt1E,QAAAxF,EAIA,IAFAm8E,EAAAA,GAAAhoE,EAAA5N,SAAAX,IAEAu2E,EAAA,MAEA,IAAAA,EAAA,OAAA,CAGA,IAAAC,GAAA,SAAAtiF,GAEA,IAAA,GADAuiF,IAAA,EACAr8E,EAAA,EAAAA,EAAA86E,EAAAhhF,EAAA/H,MAAAvD,OAAAwR,IAAA,CACA,GAIAk5B,GAJAxjC,EAAAolF,EAAAhhF,EAAA/H,MAAAiO,GACAm7E,EAAAzlF,EAAAylF,SACAnuE,EAAAtX,EAAAsX,MACAvE,EAAA/S,EAAA+S,KAGA,IAAA,MAAA0yE,GAAA,MAAAnuE,EAAA,CAEA,GAAAsvE,GAAAxiF,EAAAyiF,WAAA9zE,GACA+zE,EAAA5tF,EAAAoF,OAAAsoF,IAAA1tF,EAAA0Q,OAAAg9E,GAAA,GAAAA,EAAA,GACAG,EAAA,GAAAzvE,EAEA0vE,GAAA,CACAvB,GAAArlF,QAAA,MAAA,IACA0mF,EAAAA,EAAAjlC,cACAklC,EAAAA,EAAAllC,cAEA4jC,EAAAA,EAAA3O,QAAA,IAAA,IACAkQ,GAAA,EAGA,IAAAC,IAAA,EACAC,GAAA,CAaA,QAZAzB,EAAArlF,QAAA,MAAA,IACAqlF,EAAAA,EAAA3O,QAAA,IAAA,IACAmQ,GAAA,GAKAD,IACA1vE,EAAAyvE,EAAAllC,cACA+kC,EAAAE,EAAAjlC,eAGA4jC,GACA,IAAA,KACAjiD,EAAAsjD,EAAAK,OAAAJ,IAAA,CACA,MACA,KAAA,KACAvjD,EAAA,MAAA,GAAAshD,QAAAiC,EAAA,KAAAxB,KAAAuB,EACA,MACA,KAAA,KACAtjD,EAAA,MAAA,GAAAshD,QAAA,IAAAiC,GAAAxB,KAAAuB,EACA,MACA,KAAA,IACAtjD,EAAAojD,IAAAtvE,CACA,MACA,KAAA,KACAksB,EAAAojD,IAAAtvE,CACA,MACA,KAAA,IACAksB,EAAAyjD,EAAA3vE,GAAAsvE,EAAAA,EAAAtvE,EACA4vE,GAAA,CACA,MACA,KAAA,KACA1jD,EAAAyjD,EAAA3vE,EAAAsvE,EAAAA,GAAAtvE,EACA4vE,GAAA,CACA,MACA,KAAA,IACA1jD,EAAAyjD,EAAAL,GAAAtvE,EAAAA,EAAAsvE,EACAM,GAAA,CACA,MACA,KAAA,KACA1jD,EAAAyjD,EAAAL,EAAAtvE,EAAAA,GAAAsvE,EACAM,GAAA,CACA,MACA,SACA1jD,GAAA,OAIA,IAAA,MAAAiiD,EACA,OAAAA,GACA,IAAA,IACAjiD,EAAAp/B,EAAAgjF,YAAAr0E,EACA,MACA,KAAA,IACAywB,GAAAp/B,EAAAgjF,YAAAr0E,EACA,MACA,KAAA,IACAywB,EAAAp/B,EAAAijF,eAAAt0E,OAIAywB,IAAAp/B,EAAAijF,eAAAt0E,EAQA,IALAk0E,IAAAC,IACA1jD,GAAAA,EACA0jD,GAAA,IAGA1jD,EAAA,CACAmjD,GAAA,CACA,QAIA,MAAAA,IAIAA,EAAAD,GACArqF,KAAA,OACAwqF,WAAA,SAAA9zE,GACA,MAAA0L,GAAAhlB,SAAAuG,KAAA+S,IAEAu0E,SAAA,SAAAv0E,GACA,MAAA,yBAAAA,GAEAs0E,eAAA,SAAAt0E,GACA,MAAAnX,UAAA6iB,EAAAhlB,SAAAuG,KAAA+S,IAEAq0E,YAAA,SAAAr0E,GACA,MAAA0L,GAAAhlB,SAAAuG,KAAA+S,IACA,GAEA,IAIA,KAAA4zE,EACA,OAAA,CAIA,IAAAY,GAAAb,GACArqF,KAAA,OACAwqF,WAAA,SAAA9zE,GACA,MAAA0L,GAAA1L,MAEAu0E,SAAA,SAAAv0E,GACA,MAAA,WAAAA,EAAA,MAEAs0E,eAAA,SAAAt0E,GACA,MAAA,OAAA0L,EAAA1L,MAEAq0E,YAAA,SAAAr0E,GACA,MAAA0L,GAAA1L,MACA,GAEA,IAIA,KAAAw0E,EACA,OAAA,CAIA,IAAA,MAAAnC,EAAA7/E,WAAA,CACA,GAAAiiF,GAAA,MAAApC,EAAA7/E,WAAA9L,SAAAmlB,IAAAH,EAAA3f,KAEA,KAAA0oF,EACA,OAAA,EAKA,GAAA,MAAApC,EAAA7mF,QAAA,IAAAkgB,EAAAlZ,aAAAhH,OAAA6mF,EAAA7mF,QAAA6I,OACA,OAAA,CAKA,IAAAqgF,GAAA,SAAArC,EAAAvyE,GACA,GAAA,MAAAuyE,EAAA,CACA,GAAA5hD,IAAA,CAEA,KAAAtoC,EAAAsb,mBACA,OAAA,CAGA3D,GAAAA,GAGA,KAAA,GAAApa,GAAA,EAAAA,EAAAoa,EAAA/Z,OAAAL,IACA,GAAA4tF,EAAAjB,EAAAvyE,EAAApa,IAAA,CACA+qC,GAAA,CACA,OAIA,MAAAA,GAEA,OAAA,EAIA,OAAAikD,GAAArC,EAAArzE,OAAA,WACA,MAAA0M,GAAA1M,YAGA01E,EAAArC,EAAA9hE,SAAA,WACA,MAAA7E,GAAAzM,aAGAy1E,EAAArC,EAAAhB,MAAA,WACA,MAAA3lE,GAAAlM,cAGAk1E,EAAArC,EAAAf,WAAA,WACA,MAAA5lE,GAAA7L,iBAIA,GAfA,EAmBAwzE,GAAA7nF,OAAA,SAAAgH,GACA,GAAA1N,GAAAC,KACAoD,EAAAqK,EAAArK,IAGA,IAAArD,EAAA4B,SAAAqqF,QACA,MAAA5oF,GAAAqK,YAGA,IAAAmiF,GAAA,SAAAjvF,EAAAgmB,GACA,IAAA,GAAA1Z,GAAA,EAAAA,EAAAlN,EAAAiB,OAAAiM,IAAA,CACA,GAAAqgF,GAAAvtF,EAAAkN,EAEA,IAAAshF,EAAAjB,EAAA3mE,GACA,OAAA,EAIA,OAAA,EAGA,OAAA5mB,EAAA4B,SAAAoqF,eACA6D,EAAA,WAAA,OAAA,GAGA,IAAAC,GAAApiF,EAAAhH,OAAAmpF,EAEA,OAAAC,IAIAvB,EAAA5iD,QAAA,SAAAzjC,GACA,GAAAlI,GAAAC,IAGA,IAAAD,EAAA4B,SAAAqqF,QACA,OAAA,CAGA,KAAA,GAAA/+E,GAAA,EAAAA,EAAAlN,EAAAiB,OAAAiM,IAAA,CACA,GAAAqgF,GAAAvtF,EAAAkN,EAEA,IAAAshF,EAAAjB,EAAArlF,GACA,OAAA,EAIA,OAAA,GAIAqmF,EAAAlxC,SAAAkxC,EAAA30E,SAAA,WC9zBA,IAAA,GDg0BAozE,GAAA,GAEA+C,EAAA,SAAA7lE,EAAA8lE,GACA,MAAA3uF,GAAAoF,OAAAyjB,GACA8lE,EAAA,IAAA9lE,EAAA,IAAAA,EAEA,IAGA+lE,EAAA,SAAA1C,GACA,GAAAP,GAAA,EAEAO,GAAAjB,UAAAiB,IACAP,GAAA,IAGA,IAAAhsE,GAAA+uE,EAAAxC,EAAAvsE,MACAgsE,IAAAhsE,EAAA2sE,UAAA,EAAA3sE,EAAA/f,OAAA,EAEA,KAAA,GAAAiM,GAAA,EAAAA,EAAAqgF,EAAAplF,KAAAlH,OAAAiM,IAAA,CACA,GAAA/E,GAAAolF,EAAAplF,KAAA+E,EAGA8/E,IADA7kF,EAAAsX,MACA,IAAAtX,EAAA+S,MAAA60E,EAAA5nF,EAAAylF,UAAAmC,EAAA5nF,EAAAsX,OAAA,GAAA,IAEA,IAAAswE,EAAA5nF,EAAAylF,UAAAzlF,EAAA+S,MAAA,IAIA,IAAA,GAAAhO,GAAA,EAAAA,EAAAqgF,EAAAlB,KAAAprF,OAAAiM,IAAA,CACA,GAAAm/E,GAAAkB,EAAAlB,KAAAn/E,EACA8/E,IAAA,KAAAX,EAAAnxE,MAAA60E,EAAA1D,EAAAuB,UAAAmC,EAAA1D,EAAA5sE,OAAA,GAAA,KAGA,IAAA,GAAAvS,GAAA,EAAAA,EAAAqgF,EAAAnB,eAAAnrF,OAAAiM,IAAA,CACA,GAAA65B,GAAAwmD,EAAAnB,eAAAxrF,EACAosF,IAAAjmD,EAGA,IAAA,GAAA75B,GAAA,EAAAA,EAAAqgF,EAAAxmE,IAAA9lB,OAAAiM,IAAA,CACA,GAAA65B,GAAA,IAAAwmD,EAAAxmE,IAAAnmB,EACAosF,IAAAjmD,EAGA,IAAA,GAAA75B,GAAA,EAAAA,EAAAqgF,EAAAt1E,QAAAhX,OAAAiM,IAAA,CACA,GAAA65B,GAAA,IAAAwmD,EAAAt1E,QAAA/K,EACA8/E,IAAAjmD,EAmBA,MAhBA,OAAAwmD,EAAArzE,SACA8yE,EAAAiD,EAAA1C,EAAArzE,QAAA,MAAA8yE,GAGA,MAAAO,EAAA9hE,WACAuhE,EAAAiD,EAAA1C,EAAA9hE,UAAA,IAAAuhE,GAGA,MAAAO,EAAAhB,QACAS,GAAA,MAAAiD,EAAA1C,EAAAhB,QAGA,MAAAgB,EAAAf,aACAQ,GAAA,IAAAiD,EAAA1C,EAAAf,aAGAQ,GCj4BApsF,EAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAA2sF,GAAAttF,KAAAW,EAEAosF,IAAAiD,EAAA1C,GAEAttF,KAAAgB,OAAA,GAAAL,EAAAX,KAAAgB,OAAA,IACA+rF,GAAA,MAIA,MAAAA,IAGAttF,EAAAD,QAAAknB,IAEA1hB,OAAA,GAAAE,SAAA,KAAA+qF,IAAA,SAAA/uF,EAAAzB,EAAAD,GACA,YAEA,IAAA2B,GAAAD,EAAA,WACAE,EAAAF,EAAA,SAEAgvF,IAMAA,GAAA1sF,MAAA,SAAA+B,GACA,GAAAxF,GAAAC,IAEAD,GAAA4B,SAAAwkC,WACAnmC,KAAA2B,SAAAwuF,iBACAnwF,KAAA2B,SAAAyuF,aAGA,KAAA,GAAAC,GAAA,EAAAA,EAAA9qF,EAAAvE,OAAAqvF,IAAA,CACA,GAAApoF,GAAA1C,EAAA8qF,GACAC,EAAAvwF,EAAAwwF,eAAAtoF,GACAuoF,EAAAzwF,EAAA0wF,gBAAAH,GACAI,EAAA3wF,EAAA4wF,kBAAAL,EAAAE,EAAAvoF;AAEAlI,EAAA6wB,kBAAA3oB,EAAAyoF,EAAAE,WACA7wF,EAAA8wF,iBAAA5oF,GAIAlI,EAAA4B,SAAAwkC,UAAA,GAGA+pD,EAAAY,kBAAA,SAAAC,EAAAC,GACA,GAAAjxF,GAAAC,KACAorD,EAAArrD,EAAA4B,SAAAyuF,UAAArwF,EAAA4B,SAAAyuF,cACAa,EAAAF,EAAA,IAAAC,EACA55B,EAAAhM,EAAA6lC,EAEA,IAAA75B,EACA,MAAAA,EAMA,KAAA,GAHAw5B,MACAM,KAEAvwF,EAAA,EAAAA,EAAAZ,EAAAiB,OAAAL,IAAA,CACA,GAAAmhE,GAAA/hE,EAAAY,GACAwwF,EAAA,MAAAJ,EAAApwF,GACAywF,EAAA,MAAAJ,EAAArwF,GACA0wF,EAAAF,IAAAC,EACAE,EAAAxvB,EAAAyvB,iBAAAvwF,OAAA,CAEA,IAAAqwF,GAAAC,EAAA,CACA,GAAAh+E,EAEA+9E,IAAAC,EACAh+E,EAAAwuD,EAAA31B,WACAklD,EACA/9E,EAAAwuD,EAAA31B,WACAmlD,IACAh+E,EAAAwuD,EAAAyvB,iBAGA,KAAA,GAAAtkF,GAAA,EAAAA,EAAAqG,EAAAtS,OAAAiM,IAAA,CAQA,IAAA,GAPA3I,GAAAgP,EAAArG,GACA1I,EAAAD,EAAAC,KAKAitF,GAAA,EACAh/E,EAAA7R,EAAA,EAAA6R,EAAAzS,EAAAiB,OAAAwR,IAAA,CACA,GAAAi/E,GAAA1xF,EAAAyS,GACAk/E,EAAA,MAAAV,EAAAx+E,EAEA,IAAAk/E,IAEAF,EAAA,MAAAC,EAAAtlD,WAAA7nC,EAAAC,OAEA,MAGA2sF,EAAA3sF,IAAAitF,IACAN,EAAA3sF,IAAA,EACAqsF,EAAAnuF,KAAA8B,MAQA,MADA6mD,GAAA6lC,GAAAL,EACAA,GAGAV,EAAAK,eAAA,SAAAtoF,GACA,GAEA2oF,GAFA7wF,EAAAC,KACA2xF,EAAA,GAEAC,EAAA3pF,EAAAtG,SAAAkwF,aAAA,EAEA9xF,GAAA4B,SAAAwkC,WACAyrD,EAAA,GAIA,KAAA,GAAAjxF,GAAA,EAAAA,EAAAZ,EAAAiB,OAAAL,IAAA,CACA,GAAAykC,GAAArlC,EAAAY,GACAmxF,EAAA1sD,EAAAzrB,UAAAyrB,EAAAzrB,SAAA+xB,QAAAzjC,EAGA0pF,IADAG,EACA,IAEA,IAQA,MAJAlB,GAAA7wF,EAAA+wF,kBAAAc,EAAAD,GAEA1pF,EAAAtG,SAAAkwF,YAAAF,GAGA/lF,IAAA+lF,EACAI,cAAAnB,IAKAV,EAAAO,gBAAA,SAAAH,GACA,GAAAqB,GAAArB,EAAA1kF,IACA7L,EAAAC,KACAgyF,EAAAhyF,KAAA2B,SAAAwuF,cAAAnwF,KAAA2B,SAAAwuF,iBAGA,IAAA6B,EAAAL,GAAA,MAAAK,GAAAL,EAQA,KAAA,GANA7vF,IACAH,UACAiK,IAAA+lF,IAIAhxF,EAAA,EAAAA,EAAAZ,EAAAiB,OAAAL,IAAA,CACA,GAAAmhE,GAAA/hE,EAAAY,GACAsxF,EAAA,MAAAN,EAAAhxF,EAEA,IAAAsxF,EAEA,IAAA,GAAAhlF,GAAA,EAAAA,EAAA60D,EAAA31B,WAAAnrC,OAAAiM,IAAA,CACA,GAAA3I,GAAAw9D,EAAA31B,WAAAl/B,GACAilF,EAAApwF,EAAAwC,EAAAC,MAAAD,CAEA4tF,GAAA9sD,QAAA08B,GAKA,MADAkwB,GAAAL,GAAA7vF,EACAA,GAGAouF,EAAAS,kBAAA,SAAAL,EAAAE,EAAAvoF,GAKA,IAAA,GAJAlI,GAAAC,KACA4wF,EAAAN,EAAAyB,cACAI,KAEAxxF,EAAA,EAAAA,EAAAiwF,EAAA5vF,OAAAL,IAAA,CACA,GAAAyxF,GAAAxB,EAAAjwF,GACA0xF,EAAA7B,EAAA4B,GACAE,EAAArqF,EAAAtG,SAAAG,MAAAswF,EAGA,IAAAC,GAAAC,IAAAD,EAAA,CAEA,GAAAE,GAAAJ,EAAAC,IACAzjF,KAAA2jF,EAGAvyF,GAAAyyF,oBAAAvqF,EAAAoqF,GAEAE,EAAAx/E,KAAA9K,EAAAtG,SAAAG,MAAAswF,GAEAG,EAAAx/E,MAAAw/E,EAAAx/E,KAAAmf,SACAqgE,EAAAx/E,KAAAw/E,EAAAx/E,KAAA0/E,WAIA,OACA7B,UAAAuB,IAIAjC,EAAAW,iBAAA,SAAA5oF,GACA,GAAAvG,GAAAuG,EAAAtG,SACA5B,EAAAC,KACA8B,EAAAJ,EAAAI,KAEA,KAAAmG,EAAAsU,UAAA,CAGA,GAAA60D,IAAA,CACA,IAAA,UAAA1vE,EAAAqf,OAAAhhB,EAAA4B,SAAAyvE,OACA,IAAA,GAAAzwE,GAAA,EAAAA,GAAAZ,EAAA2xE,eAAA/wE,IAAA,CACA,GAAA2O,GAAA5N,EAAAI,MAAA,OAAAnB,EAAA,oBAAA6e,KAEA,IAAAlQ,EAAA,EAAA,CACA8hE,GAAA,CACA,QAKA1vE,EAAA0vE,OAAAA,CAEA,IAAAzwB,GAAA7+C,EAAA,kBAAAogB,SACA6mC,EAAAjnD,EAAA,MAAAogB,SACA+oC,EAAAnpD,EAAA,cAAAogB,SACA5S,EAAAxN,EAAA,aAAA8d,QAAA,KACAsrC,EAAAppD,EAAA,eAAAogB,SAEAtb,EAAA9E,EAAA,eAAAogB,SACAM,EAAA1gB,EAAA,eAAAogB,SACAK,EAAAzgB,EAAA,eAAAogB,SACAwwE,EAAA5wF,EAAA,sBAAA8d,QACA+yE,EAAA7wF,EAAA,aAAAogB,SACA0wE,EAAA9wF,EAAA,kBAAA8d,OACAle,GAAAuoD,SAAAgB,EAAA,IAAA37C,EAAA,IAAA47C,EAAA,IAAAtkD,EAAA,IAAAmiD,EAAA,IAAApI,EAAA,IAAAn+B,EAAA,IAAAD,EAAA,IAAAmwE,EAAA,IAAAC,EAAA,IAAAC,EACAlxF,EAAAutE,QAAAhkB,EAAA,IAAArkD,EAAA,IAAA0I,EAAA,IAAA47C,CAEA,IAAAlkB,GAAAllC,EAAA,MAAA8d,QACAqnB,EAAAnlC,EAAA,OAAA8d,QACAizE,EAAA/wF,EAAA,gBAAA8d,OAGA,IAFAle,EAAA6qD,eAAAvlB,EAAA,IAAAC,EAAA,IAAA4rD,EAEA,UAAA5qF,EAAAtG,SAAAof,MAAA,CACA,GAAA+xE,GAAAhxF,EAAA,2BAAA8d,QACAmzE,EAAAjxF,EAAA,2BAAAA,EAAA,2BAAA8d,QAAA4K,KAAA,KAAA1mB,OACAkvF,EAAAlxF,EAAA,yBAAA0d,MAAAgL,KAAA,KACAyoE,EAAAnxF,EAAA,eAAAogB,SACAgxE,EAAApxF,EAAA,qBAAAA,EAAA,qBAAA8d,QAAA4K,KAAA,KAAA1mB,OACAqvF,EAAArxF,EAAA,mBAAA0d,MAAAgL,KAAA,IAEA9oB,GAAA6qD,gBAAA,IAAAumC,EAAA,IAAAC,EAAA,IAAAC,EAAA,IAAAE,EAAA,IAAAC,EAAA,IAAAF,EAGAvxF,EAAA0xF,SAAAhmD,KAAA/T,QAmBA62D,EAAAsC,oBAAA,SAAAvqF,EAAAorF,GACA,GAGAvE,GAAAwE,EAHAvzF,EAAAC,KACAsE,EAAA+uF,EACAvxF,EAAAmG,EAAAtG,SAAAG,MAEAg4D,EAAA/5D,EAAA+5D,MACAl1D,EAAA7E,EAAAosC,WAAA7nC,EAAAC,MAAAK,KACA2uF,EAAAjvF,EAAA4tB,OACAshE,EAAA1xF,EAAAwC,EAAAC,MACAkvF,EAAAD,GAAAA,EAAAthE,OACAxwB,EAAAuG,EAAAtG,QAGA,KAAA,WAAA0xF,EAAA9uF,MAAA,UAAA8uF,EAAA9uF,OAAA0D,EAAAiF,SAAA,CACA,GAAA,SAAAmmF,EAAA7zE,QAAAvX,EAAA2S,WACA,OAAA,CACA,UAAAy4E,EAAA7zE,OAAAvX,EAAA2S,aACAtW,EAAA+uF,EAAArzF,KAAA66B,MAAAw4D,EAAA9uF,KAAA,OAAAgvF,IAKA,GAAAA,GAAAjvF,EAAAovF,aAAA,CACA,GAAAC,GAAA7xF,EAAAwC,EAAAC,KAGA,OAAAovF,GAEAA,EAAAzhE,QAAAyhE,EAAAlB,UAGA3wF,EAAAwC,EAAAC,MAAAovF,EAAAlB,UACA,IAGA,GARA,EAYA,GAAAmB,GAAA,WACAzyF,EAAAiI,MAAA,4EAAAnB,EAAAjB,KAAA,mBAAA1C,EAAAC,KAAA,sBAAAD,EAAA2W,MAAA,eAAA3W,EAAA2W,MAAA,gDAAA3W,EAAA2W,MAAA,aAIA,QAAA3W,EAAAk3E,QACA,IAAA1hB,GAAA+5B,QACA,IAAA/5B,GAAAg6B,cACA,IAAAh6B,GAAAi6B,WAEA,GAKAjF,GALAkF,EAAA1vF,EAAAk3E,SAAA1hB,EAAAg6B,cACAG,EAAA3vF,EAAAk3E,SAAA1hB,EAAAi6B,WAGAhpE,EAAAzmB,EAAA2W,MAAA4K,MAAA,IAIAipE,GADAmF,GAAAD,EACAtyF,EAAAma,QAEAna,EAAAwG,IAGA,KAAA,GAAAvH,GAAA,EAAAA,EAAAoqB,EAAA/pB,QAAA8tF,EAAAnuF,IAAA,CACA,GAAAsa,GAAA8P,EAAApqB,EACAmuF,GAAAA,EAAA7zE,GAGA,GAAA6f,EAcA,IAVAA,EAHA15B,EAAA0Q,OAAAg9E,IAGAA,EAAAxqF,EAAA4vF,WAAA5vF,EAAA6vF,SAAA7vF,EAAA4vF,UAFA,EAMA,EAAAp5D,EACAA,EAAA,EACAA,EAAA,IACAA,EAAA,GAGAl2B,EAAAmmE,MAAA,CACA,GAAAqpB,GAAA9vF,EAAA+vF,SAAA,GACAC,EAAAhwF,EAAAiwF,SAAA,GACAC,EAAAlwF,EAAA+vF,SAAA,GACAI,EAAAnwF,EAAAiwF,SAAA,GACAG,EAAApwF,EAAA+vF,SAAA,GACAM,EAAArwF,EAAAiwF,SAAA,GACAK,EAAA,MAAAtwF,EAAA+vF,SAAA,GAAA,EAAA/vF,EAAA+vF,SAAA,GACAQ,EAAA,MAAAvwF,EAAAiwF,SAAA,GAAA,EAAAjwF,EAAAiwF,SAAA,GAEAO,GACArlF,KAAA6sB,MAAA83D,GAAAE,EAAAF,GAAAt5D,GACArrB,KAAA6sB,MAAAk4D,GAAAC,EAAAD,GAAA15D,GACArrB,KAAA6sB,MAAAo4D,GAAAC,EAAAD,GAAA55D,GACArrB,KAAA6sB,MAAAs4D,GAAAC,EAAAD,GAAA95D,GAGAw4D,IACAphE,OAAA5tB,EAAA4tB,OACA3tB,KAAAD,EAAAC,KACAib,MAAAs1E,EACA5yE,SAAA,OAAA4yE,EAAA,GAAA,KAAAA,EAAA,GAAA,KAAAA,EAAA,GAAA,SAGA,CAAA,IAAAlwF,EAAAkN,OAKA,OAAA,CAJA,IAAAijF,GAAAzwF,EAAA+vF,UAAA/vF,EAAAiwF,SAAAjwF,EAAA+vF,UAAAv5D,CACAw4D,GAAAtzF,KAAA66B,MAAAv2B,EAAAC,KAAAwwF,EAAAzwF,EAAA4tB,QAAA,GAMAohE,IACAA,EAAAtzF,KAAA66B,MAAAv2B,EAAAC,KAAAivF,EAAAtxE,SAAA5d,EAAA4tB,QAAA,IAGAohE,GAAAM,IACAN,EAAA0B,QAAA1wF,EACAA,EAAAgvF,CAEA,MAGA,KAAAx5B,GAAA5xD,KACA,IAAA4xD,GAAAm7B,WACA,IAAAn7B,GAAAj+C,QACA,GAKAizE,GALAkF,EAAA1vF,EAAAk3E,SAAA1hB,EAAAm7B,WACAhB,EAAA3vF,EAAAk3E,SAAA1hB,EAAAj+C,QAGAkP,EAAAzmB,EAAA2W,MAAA4K,MAAA,IASA,IALAipE,EADAmF,GAAAD,EACAtyF,EAAAma,QAEAna,EAAAwG,KAGA,IAAA,GAAAvH,GAAA,EAAAA,EAAAoqB,EAAA/pB,OAAAL,IAAA,CACA,GAAAsa,GAAA8P,EAAApqB,EACAmuF,GAAAA,EAAA7zE,GAKA,GAFAq4E,EAAAtzF,KAAA66B,MAAAv2B,EAAAC,KAAAuqF,EAAAxqF,EAAA4tB,QAAA,IAEAohE,EAAA,CACA,GAAA4B,GAAA1B,EAAAA,EAAAtxE,SAAA,EAEAoxE,GAAAtzF,KAAA66B,MAAAv2B,EAAAC,KAAA2wF,EAAA5wF,EAAA4tB,QAAA,GAGAohE,GAAAM,IACAN,EAAA0B,QAAA1wF,EACAA,EAAAgvF,CAEA,MAEA,KAAAx5B,GAAAt3D,GACA,GAAAA,GAAA8B,EAAAkb,MACA21E,EAAA3yF,EAAAyF,EAEAqrF,GAAAtzF,KAAA66B,MAAAv2B,EAAAC,KAAA4wF,EAAA7wF,EAAA4tB,QAAA,GACAohE,EAAA0B,QAAA1wF,EACAA,EAAAgvF,CAEA,MAEA,KAAAxvF,QACA,KAEA,SACA,OAAA,EAqBA,MAjBAyvF,IACAE,EACAnvF,EAAAmuF,SAAAe,EAAAf,SAEAnuF,EAAAmuF,SAAAe,EAGA1xF,EAAAwC,EAAAC,MAAAD,GAGAmvF,EACAD,EAAAf,SAAAnuF,EAEAxC,EAAAwC,EAAAC,MAAAD,GAIA,GAIA4rF,EAAA5wE,OAAA,WACA,GAAAlc,GAAApD,KAAA2B,SAAAyB,GACAmC,EAAAnC,EAAA2X,UAEAxV,GAAAoT,eAKAu3E,EAAA3/D,cAAA,SAAAhrB,GAGA,IAAA,GAFAxF,GAAAC,KAEAW,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CAIA,IAAA,GAHAsH,GAAA1C,EAAA5E,GACAmB,EAAAmG,EAAAtG,SAAAG,MAEAmL,EAAA,EAAAA,EAAAlN,EAAAosC,WAAAnrC,OAAAiM,IAAA,CACA,GAAA3I,GAAAvE,EAAAosC,WAAAl/B,GACAmoF,EAAAtzF,EAAAwC,EAAAC,KAEA,IAAA6wF,GAAAA,EAAAJ,QAAA,CACA,GAAAA,GAAAI,EAAAJ,OACAh1F,MAAAwyF,oBAAAvqF,EAAA+sF,IAIAh1F,KAAA6wF,iBAAA5oF,KAKAioF,EAAAt/D,kBAAA,SAAA3oB,EAAA2oF,EAAAyE,GACA,GAAAt1F,GAAAC,KACA0B,EAAAuG,EAAAtG,SACAG,EAAAJ,EAAAI,MACAwR,EAAAxR,EAAA,uBAAA0d,MACA3d,EAAAC,EAAA,uBAAA8d,QACAhI,EAAA9V,EAAA,oBAAA8d,QACA7d,IAEA,IAAAuR,EAAAtS,OAAA,GAAAa,EAAA,EAAA,CAIA,IAAA,GADAyzF,IAAA,EACA30F,EAAA,EAAAA,EAAA2S,EAAAtS,OAAAL,IAAA,CACA,GAAA2D,GAAAgP,EAAA3S,GACAuxF,EAAApwF,EAAAwC,GACAixF,EAAA3E,EAAAtsF,EAEA,IAAAixF,EAAA,CAEA,GAIAC,GAJAC,EAAAF,EAAA5mF,KACA+mF,EAAAD,EACAE,EAAA,MAAAJ,EAAAxiF,KAAAwiF,EAAAxiF,KAAAm/E,EACA76E,GAAA,EAEAu+E,EAAA,IAEAF,KAGAt0F,EAAA0Q,OAAA4jF,EAAA91E,UAAAxe,EAAA0Q,OAAA6jF,EAAA/1E,UACAvI,EAAAs+E,EAAA/1E,QAAA81E,EAAA91E,QACA41E,EAAAE,EAAA91E,QAAAg2E,EAAAv+E,GAGAjW,EAAA0Q,OAAA4jF,EAAAl2E,QAAApe,EAAA0Q,OAAA6jF,EAAAn2E,QACAnI,EAAAs+E,EAAAn2E,MAAAk2E,EAAAl2E,MACAg2E,EAAAE,EAAAl2E,MAAAo2E,EAAAv+E,GAGAjW,EAAAitB,MAAAqnE,EAAAl2E,QAAApe,EAAAitB,MAAAsnE,EAAAn2E,SACAnI,EAAAq+E,EAAAl2E,MAAA,KAAAm2E,EAAAn2E,MAAA,IACAk2E,EAAAl2E,MAAA,KAAAm2E,EAAAn2E,MAAA,IACAk2E,EAAAl2E,MAAA,KAAAm2E,EAAAn2E,MAAA,GAGAg2E,EAAAE,EAAAxzE,UAIA7K,IACAtV,EAAAuC,GAAAqxF,EAAAzzE,SACAliB,KAAA8lB,YAAA7d,EAAA3D,EAAAkxF,GACAF,GAAA,KAMA,IAAAA,EAAA,MAEA5zF,GAAAm0F,eAAA,EAEA5tF,EAAAvE,OAEAkU,EAAA,GACA3P,EAAA2P,MAAAA,GAGA3P,EAAAwP,SACA1V,IAAAA,IAEAF,SAAAA,EACA6tB,OAAA5tB,EAAA,8BAAA0d,MACAvc,OAAA,EACAV,SAAA,WACA8yF,GACAt1F,EAAAmxB,eAAAjpB,EAAAqL,GC1kBA5R,EAAAm0F,eAAA,SAIAn0F,GAAAm0F,gBACA5tF,EAAAvE,OAEA1D,KAAAkxB,eAAAjpB,EAAAqL,GAEA5R,EAAAm0F,eAAA,IAIAp2F,EAAAD,QAAA0wF,IAEAlrE,QAAA,GAAAxL,UAAA,KAAAs8E,IAAA,SAAA50F,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,SACAC,EAAAD,EAAA,WAEAgvF,IAIAA,GAAApqE,YAAA,SAAAvgB,EAAAhB,EAAAib,EAAAoR,GACA,GAAA7wB,GAAAC,KACAsT,KACA+hF,GAAA,CAGA,IAAA,MAAA9wF,GAAA,OAAAA,GAEA,GAAAT,SAAA0b,EACA,IAAA,GAAA7e,GAAA,EAAAA,EAAAZ,EAAAosC,WAAAnrC,OAAAL,IAAA,CACA,GAAA2D,GAAAvE,EAAAosC,WAAAxrC,GACA4D,EAAAD,EAAAC,KAEA8uF,EAAArzF,KAAA66B,MAAAt2B,EAAAib,GAAA,EAEA6zE,IACA//E,EAAA7Q,KAAA4wF,QAKA,IAAAjyF,EAAAoF,OAAAjC,GAAA,CACA,GAAA8uF,GAAArzF,KAAA66B,MAAAt2B,EAAAib,GAAA,EAEA6zE,IACA//E,EAAA7Q,KAAA4wF,OAEA,CAAA,IAAAjyF,EAAAwL,YAAArI,GAsBA,OAAA,CArBA,IAAAwxF,GAAAxxF,CACAqsB,GAAApR,CAEA,KAAA,GAAA7e,GAAA,EAAAA,EAAAZ,EAAAosC,WAAAnrC,OAAAL,IAAA,CACA,GAAA2D,GAAAvE,EAAAosC,WAAAxrC,GACA4D,EAAAD,EAAAC,KACAib,EAAAu2E,EAAAxxF,EAMA,IAJAT,SAAA0b,IACAA,EAAAu2E,EAAA50F,EAAAuD,WAAAH,KAGAT,SAAA0b,EAAA,CACA,GAAA6zE,GAAArzF,KAAA66B,MAAAt2B,EAAAib,GAAA,EAEA6zE,IACA//E,EAAA7Q,KAAA4wF,KASA,GAAA,IAAA//E,EAAAtS,OAAA,OAAA,CAIA,KAAA,GADA6K,IAAA,EACAlL,EAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CAMA,IAAA,GAFA40F,GAHAttF,EAAA1C,EAAA5E,GACAmB,EAAAmG,EAAAtG,SAAAG,MACA8uF,KAGA3jF,EAAA,EAAAA,EAAAqG,EAAAtS,OAAAiM,IAAA,CACA,GAAA3I,GAAAgP,EAAArG,EAEA,IAAA2jB,EAAA,CACA,GAAA6kE,GAAA3zF,EAAAwC,EAAAC,KACAgxF,GAAA3E,EAAAtsF,EAAAC,OAAAoK,KAAA8mF,GAGA5pF,EAAA7L,KAAAwyF,oBAAAvqF,EAAA3D,IAAAuH,EAEA+kB,IACA2kE,EAAAxiF,KAAAjR,EAAAwC,EAAAC,OAKAsH,GACA7L,KAAA6wF,iBAAA5oF,GAGA2oB,GACA5wB,KAAA4wB,kBAAA3oB,EAAA2oF,EAAAyE,GAIA,MAAAxpF,IAIAqkF,EAAA10D,eAAA,SAAAj2B,EAAAhB,EAAAib,GACAjb,EAAApD,EAAA60F,WAAAzxF,EAEA,KAAA,GAAA5D,GAAA,EAAAA,EAAA4E,EAAAvE,OAAAL,IAAA,CACA,GAAAsH,GAAA1C,EAAA5E,GACA2D,EAAA2D,EAAAtG,SAAAG,MAAAyC,GACAK,EAAA5E,KAAAmsC,WAAA5nC,GAAAK,KACAqxF,EAAArxF,EAAAmmE,MACAmrB,EAAAtxF,EAAAuxF,OAEA7xF,GAAA4tB,QAKA5tB,EAAAkb,MAAAA,EAEA,MAAAlb,EAAAsb,UACAtb,EAAAsb,QAAAJ,GAGAy2E,EACA3xF,EAAA4d,SAAA,OAAA1C,EAAAgL,KAAA,KAAA,IACA0rE,EACA5xF,EAAA4d,SAAA1C,EAAAgL,KAAA,KAEAlmB,EAAA4d,SAAA,GAAA1C,GAfAxf,KAAA8lB,YAAA7d,EAAA1D,EAAAib,KAoBA0wE,EAAAj/D,kBAAA,SAAA1rB,EAAAqrB,GACA,MAAA5wB,MAAAkxB,eAAA3rB,EAAAvF,KAAAo2F,cAAAxlE,IAGAs/D,EAAAh/D,eAAA,SAAA3rB,EAAA+N,EAAAsd,GAGA,IAAA,GAFAykE,IAAA,EAEApoF,EAAA,EAAAA,EAAA1H,EAAAvE,OAAAiM,IAAA,CAKA,IAAA,GAJAhF,GAAA1C,EAAA0H,GACA2jF,KACA9uF,EAAAmG,EAAAtG,SAAAG,MAEAnB,EAAA,EAAAA,EAAA2S,EAAAtS,OAAAL,IAAA,CACA,GAAA4D,GAAA+O,EAAA3S,GACA2D,EAAAtE,KAAAmsC,WAAA5nC,GACAib,EAAA,GACA6zE,EAAArzF,KAAA66B,MAAAt2B,EAAAib,GAAA,GACAi2E,EAAA3zF,EAAAwC,EAAAC,MlFmpqBUgxF,EAAW3E,EAAWtsF,EAAKC,OAAWoK,KAAM8mF,EmFxzqBtDz1F,MAAAwyF,oBAAAvqF,EAAAorF,GAEAkC,EAAAxiF,KAAAjR,EAAAwC,EAAAC,MAGAvE,KAAA6wF,iBAAA5oF,GAEA2oB,GACA5wB,KAAA4wB,kBAAA3oB,EAAA2oF,EAAAyE,KAKA51F,EAAAD,QAAA0wF,IAEAlrE,QAAA,GAAAxL,UAAA,KAAA68E,IAAA,SAAAn1F,EAAAzB,EAAAD,GACA,YAEA,IAAAK,GAAAqB,EAAA,aAEAgvF,IAGAA,GAAAoG,kBAAA,WACA,GAAAC,GAAAv2F,KAAAw2F,aAAA,YAEA,OAAA,OAAAD,EACA14D,WAAA04D,GC5BA,GAKArG,EAAAsG,aAAA,SAAAC,GACA,GAAArzF,GAAApD,KAAA2B,SAAAyB,GACA69E,EAAA79E,EAAA+8B,WAEA,OAAAtgC,IAAAohF,GAAAphF,EAAA62F,iBACA72F,EAAA62F,iBAAAzV,GAAA0V,iBAAAF,GADA,QAKAh3F,EAAAD,QAAA0wF,IAEAr3D,YAAA,MAAA+9D,IAAA,SAAA11F,EAAAzB,EAAAD,GACA,YAEA,IAAA2B,GAAAD,EAAA,WACAE,EAAAF,EAAA,SAEAgvF,IAGAA,GAAAv/D,iBAAA,SAAA1oB,GACA,MAAAjI,MAAA8wB,YAAA7oB,GAAA,IAIAioF,EAAAp/D,YAAA,SAAA7oB,EAAA4uF,GACA,GAAA92F,GAAAC,KACAiI,EAAAA,EAAA,EAEA,IAAAA,EAAA,CAGA,IAAA,GAFA2Z,MAEAjhB,EAAA,EAAAA,EAAAZ,EAAAosC,WAAAnrC,OAAAL,IAAA,CACA,GAAA2D,GAAAvE,EAAAosC,WAAAxrC,GACAwd,EAAApe,EAAA8wB,sBAAA5oB,EAAA3D,EAAAC,KAAAsyF,EAEA14E,KACAyD,EAAAtd,EAAAC,MAAA4Z,EACAyD,EAAAzgB,EAAAuD,WAAAJ,EAAAC,OAAA4Z,GAIA,MAAAyD,KAIAsuE,EAAAr/D,sBAAA,SAAA5oB,EAAAwuF,EAAAI,GACA,GAAA92F,GAAAC,KACAiI,EAAAA,EAAA,EAEA,IAAAA,EAAA,CACA,GAAAnG,GAAAmG,EAAAtG,SAAAG,MACAwC,EAAAvE,EAAAosC,WAAAsqD,GACA7xF,EAAAN,EAAAM,KACAkyF,EAAAh1F,EAAAwC,EAAAC,MACA6Z,EAAAnW,EAAA7E,KAAAgb,MAEA,IAAA04E,EAAA,CACA,GAAA3pB,GAAA2pB,EAAA3pB,MAAAvoE,EAAAmyF,eAAA,KAAA,KACA54E,EAAAgvD,KAAAzyD,OAAAo8E,EAAAl3E,SAAAzJ,IAAA,SAAAyJ,GACA,MAAAA,IAAAi3E,EAAAz4E,EAAA,GAAA+uD,IACA3iD,KAAA,KAAAssE,EAAA50E,QAEA,OAAA/D,MAMA+xE,EAAA91D,cAAA,SAAAnyB,GACA,GAEAnG,GAFA/B,EAAAC,KACA4hB,KAEAo1E,EAAA51F,EAAAulB,QAAA1e,EAQA,IALAnG,EADAk1F,EACA/uF,EAAAtG,SAAAG,MAEAmG,EAIA,IAAA,GAAAtH,GAAA,EAAAA,EAAAZ,EAAAosC,WAAAnrC,OAAAL,IAAA,CACA,GAAA2D,GAAAvE,EAAAosC,WAAAxrC,GACAm2F,EAAAh1F,EAAAwC,EAAAC,OAAAzC,EAAAX,EAAAuD,WAAAJ,EAAAC,MAEAT,UAAAgzF,IAEAA,EADA11F,EAAAwL,YAAAkqF,GACA92F,KAAA66B,MAAAv2B,EAAAC,KAAAuyF,EAAA50E,UAEAliB,KAAA66B,MAAAv2B,EAAAC,KAAAuyF,IAIAA,IACAl1E,EAAAtd,EAAAC,MAAAuyF,EACAl1E,EAAAzgB,EAAAuD,WAAAJ,EAAAC,OAAAuyF,GAKA,MAAAl1E,IAGAsuE,EAAA7jD,aAAA,SAAA4qD,GACA,GAAAl3F,GAAAC,KACA4hB,KACA9f,EAAAm1F,EpFy1qBM3jF,EAAQvT,EAAKosC,UqFx8qBnB,IAAArqC,EACA,IAAA,GAAAyC,KAAAzC,GAAA,CACA,GAAAqc,GAAArc,EAAAyC,GACAD,EAAAgP,EAAA/O,IAAA+O,EAAAnS,EAAA60F,WAAAzxF,IACAuyF,EAAA92F,KAAA66B,MAAAv2B,EAAAC,KAAA4Z,EAEAyD,GAAAnf,KAAAq0F,GAIA,MAAAl1E,IAGAniB,EAAAD,QAAA0wF,IAEAlrE,QAAA,GAAAxL,UAAA,KAAA09E,IAAA,SAAAh2F,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,SACAC,EAAAD,EAAA,WACAwlB,EAAAxlB,EAAA,eAEAglC,EAAA,SAAA9iC,GAEA,MAAApD,gBAAAkmC,GAIA9kC,EAAAgkB,KAAAhiB,IAKApD,KAAA2B,UACAyB,GAAAA,EACAiyE,aACAlvC,UAAA,GAGAnmC,KAAAgB,OAAA,MAEAhB,MAAAm3F,4BAZAh2F,GAAAiI,MAAA,sCAJA,GAAA88B,GAAA9iC,IAmBA8sF,EAAAhqD,EAAAvjC,SAEAutF,GAAAttF,eAAA,WACA,MAAA,SAIAstF,EAAAnc,MAAA,WACA,IAAA,GAAApzE,GAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IACAX,KAAAW,GAAAmD,MAKA,OAHA9D,MAAAgB,OAAA,EACAhB,KAAA2B,SAAAwkC,UAAA,EAEAnmC,MAGAkwF,EAAAkH,eAAA,WAIA,MAHAp3F,MAAA+zE,QACA/zE,KAAAm3F,uBAEAn3F,MAIAkwF,EAAA9qE,KAAA,WACA,MAAAplB,MAAA2B,SAAA0zE,WAIA6a,EAAAv2E,SAAA,SAAA09E,GAEA,GAAA19E,GAAA,SAAA09E,EAAA,KAAA,GAAA3wE,GAAA2wE,GAEA12F,EAAAX,KAAAgB,QAQA,OAPAhB,MAAAW,IACAgZ,SAAAA,EACAwyB,cACAolD,oBACAtjF,MAAAtN,GAGAX,MAIAkwF,EAAAnuF,IAAA,WACA,GAAAhC,GAAAC,KACAwyB,EAAA1lB,SAEA,QAAA0lB,EAAAxxB,QACA,IAAA,GAGA,IAAA,GAFAmV,GAAAqc,EAAA,GAEA7xB,EAAA,EAAAA,EAAAZ,EAAAosC,WAAAnrC,OAAAL,IAAA,CACA,GAAA2D,GAAAvE,EAAAosC,WAAAxrC,GACA22F,EAAAnhF,EAAA7R,EAAAC,KAEAT,UAAAwzF,IACAA,EAAAnhF,EAAAhV,EAAAuD,WAAAJ,EAAAC,QAGAT,SAAAwzF,GACAt3F,KAAAu3F,QAAAjzF,EAAAC,KAAA+yF,GAIA,KAEA,KAAA,GACAt3F,KAAAu3F,QAAA/kE,EAAA,GAAAA,EAAA,IAOA,MAAAxyB,OAEAkwF,EAAApuF,MAAAouF,EAAAnuF,IAGAmuF,EAAAqH,QAAA,SAAAhzF,EAAAib,GAEA,GAAAiR,GAAAzwB,KAAA66B,MAAAt2B,EAAAib,EAGA,IAAAiR,EAAA,CACA,GAAA9vB,GAAAX,KAAAgB,OAAA,CACAhB,MAAAW,GAAAwrC,WAAA1pC,KAAAguB,GACAzwB,KAAAW,GAAAwrC,WAAA1b,EAAAlsB,MAAAksB,EAEAA,EAAAlsB,KAAA0T,MAAA,8BAAAwY,EAAAjR,QACAxf,KAAA2B,SAAAyvE,QAAA,GAGA3gD,EAAA+qD,QACAx7E,KAAAW,GAAA4wF,iBAAA9uF,KAAAguB,EAIA,IAAA+mE,IAAAx3F,KAAAW,GAAAgZ,QACA69E,KACAx3F,KAAA2B,SAAA0zE,UAAA5kD,EAAAlsB,MAAAksB,GAIA,MAAAzwB,OAIAkmC,EAAAI,SAAA,SAAAljC,EAAA4mB,GACA,GAAAloB,GAAA,GAAAokC,GAAA9iC,EAIA,OAFAtB,GAAAwkC,SAAAtc,GAEAloB,GAGAokC,EAAAK,WAAA,SAAAnjC,EAAAoD,GACA,MAAA,IAAA0/B,GAAA9iC,GAAAmjC,WAAA//B,KAIAtF,EAAA,WrF28qBEA,EAAQ,YsFpnrBVA,EAAA,eACAA,EAAA,iBACAA,EAAA,UACAA,EAAA,kBACAA,EAAA,gBACAA,EAAA,YACAoK,QAAA,SAAAgI,GACAnS,EAAAS,OAAAsuF,EAAA58E,KAIA4yB,EAAA4zB,MAAAo2B,EAAAp2B,MACA5zB,EAAAiG,WAAA+jD,EAAA/jD,WAEA1sC,EAAAD,QAAA0mC,IAEAlhB,QAAA,GAAAqE,cAAA,GAAA7P,UAAA,GAAAi+E,UAAA,GAAAC,WAAA,GAAAC,cAAA,GAAAC,gBAAA,GAAAC,SAAA,GAAAC,UAAA,GAAAC,eAAA,GAAAC,iBAAA,KAAAC,IAAA,SAAA/2F,EAAAzB,EAAAD,GACA,YAEA,IAAA0wF,KAEAA,GAAAgI,cAAA,SAAAluE,GAGA,IAAA,GAFAloB,GAAA9B,KAEAW,EAAA,EAAAA,EAAAqpB,EAAAhpB,OAAAL,IAAA,CACA,GAAAykC,GAAApb,EAAArpB,GACAgZ,EAAAyrB,EAAAzrB,SACArG,EAAA8xB,EAAAtjC,OAAAsjC,EAAArjC,GAEAD,GAAA6X,SAAAA,EAEA,KAAA,GAAApV,KAAA+O,GAAA,CACA,GAAAkM,GAAAlM,EAAA/O,EAEAzC,GAAAC,IAAAwC,EAAAib,IAIA,MAAA1d,IAIAouF,EAAA5pD,SAAA,SAAAtc,GACA,GAAAloB,GAAA9B,IAKA,OAHA8B,GAAAs1F,iBACAt1F,EAAAo2F,cAAAluE,GAEAloB,GAIAouF,EAAAlmE,KAAA,WAGA,IAAA,GAFAA,MAEArpB,EAAAX,KAAAm4F,cAAAx3F,EAAAX,KAAAgB,OAAAL,IAAA,CCvDA,IAAA,GDwDAmhE,GAAA9hE,KAAAW,GACAgZ,EAAAmoD,EAAAnoD,SACArG,EAAAwuD,EAAA31B,WACApqC,KC3DAkL,EAAA,EAAAA,EAAAqG,EAAAtS,OAAAiM,IAAA,CACA,GAAA3I,GAAAgP,EAAArG,EACAlL,GAAAuC,EAAAC,MAAAD,EAAA4d,SAGA8H,EAAAvnB,MACAkX,SAAAA,EAAAA,EAAAyjC,WAAA,OACAt7C,MAAAC,IAIA,MAAAioB,IAGAvqB,EAAAD,QAAA0wF,OAEAkI,IAAA,SAAAl3F,EAAAzB,EAAAD,GACA,YAEA,IAAA2B,GAAAD,EAAA,WACAE,EAAAF,EAAA,SAEAgvF,IAGAA,GAAAr1D,MAAA,SAAAt2B,EAAAib,EAAA+zE,EAAA8E,GACA,GAEAxsF,GAFAysF,GAAA/zF,EAAAib,EAAA+zE,EAAA8E,GAAA7tE,KAAA,KACA+tE,EAAAv4F,KAAAu4F,UAAAv4F,KAAAu4F,cAEAvpD,EAAAwpD,EAAA7lE,KAAA3yB,KAaA,QAXA6L,EAAA0sF,EAAAD,MACAzsF,EAAA0sF,EAAAD,GAAAtpD,EAAAzqC,EAAAib,EAAA+zE,EAAA8E,IAIAxsF,EAAA1K,EAAAuX,KAAA7M,GAEAA,IACAA,EAAA2T,MAAAre,EAAAuX,KAAA7M,EAAA2T,QAGA3T,EASA,IAAA2sF,GAAA,SAAAj0F,EAAAib,EAAA+zE,EAAA8E,GACA,GAAAt4F,GAAAC,IAEAuE,GAAApD,EAAA60F,WAAAzxF,EAEA,IAAAksB,GAAA1wB,EAAAosC,WAAA5nC,GACAk0F,EAAAj5E,EACAs6C,EAAA/5D,EAAA+5D,KAEA,KAAArpC,EAAA,MAAA,KACA,IAAA3sB,SAAA0b,GAAA,OAAAA,EAAA,MAAA,KAGAiR,GAAAioE,QACAjoE,EAAAA,EAAAkoE,SACAp0F,EAAAksB,EAAAlsB,KAGA,IAAAipF,GAAApsF,EAAAoF,OAAAgZ,EACAguE,KACAhuE,EAAAA,EAAAo5E,OAGA,IAAAh0F,GAAA6rB,EAAA7rB,IACA,KAAAA,EAAA,MAAA,KAGA,IAAA2uF,IAAA,KAAA/zE,GAAA,OAAAA,GACA,OACAjb,KAAAA,EACAib,MAAAA,EACA0S,QAAA,EACAwhE,cAAA,EAKA,IAAAtyF,EAAAoB,GAAAgd,GACA,OACAjb,KAAAA,EACAib,MAAAA,EACA0C,SAAA,KACAs5D,OAAA1hB,EAAAt3D,GACA0vB,OAAAqhE,EAKA,IAAArrF,GAAA2rF,EAAAoB,EAAAnB,EAAAj4E,EAAAk4E,CACA,KAAAvG,GAAA6K,OAGA,CAAA,IACAnwF,EAAA,GAAA8kF,QAAAlzB,EAAA5xD,KAAAghC,OAAAukD,KAAAjuE,MACAy1E,EAAA,GAAAjI,QAAAlzB,EAAAm7B,WAAA/rD,OAAAukD,KAAAjuE,MACA3D,EAAA,GAAAmxE,QAAAlzB,EAAAj+C,QAAAqtB,OAAAukD,KAAAjuE,IACA,CACA,GAAA+zE,EAAA,OAAA,CAEA,IAAA/X,EAWA,OATAA,GADAtzE,EACA4xD,EAAA5xD,KACA+sF,EACAn7B,EAAAm7B,WAEAn7B,EAAAj+C,QAGA3T,EAAAA,GAAA+sF,GAAAp5E,GAGAtX,KAAAA,EACAib,MAAAtX,EACAga,SAAA,GAAA1C,EACAg8D,OAAAA,EACAvgE,MAAA/S,EAAA,GACAgqB,OAAAqhE,GAGA,IACAM,EAAA,GAAA7G,QAAAlzB,EAAA+5B,QAAA3qD,OAAAukD,KAAAjuE,MACAs0E,EAAA,GAAA9G,QAAAlzB,EAAAg6B,cAAA5qD,OAAAukD,KAAAjuE,MACAu0E,EAAA,GAAA/G,QAAAlzB,EAAAi6B,WAAA7qD,OAAAukD,KAAAjuE,IACA,CACA,GAAA+zE,EAAA,OAAA,CACA,IAAA3uF,EAAAi0F,SAAA,OAAA,CAEA,IAAArd,EAYA,IAVAA,EADAqY,EACA/5B,EAAA+5B,QACAC,EACAh6B,EAAAg6B,cAEAh6B,EAAAi6B,WAGAF,EAAAA,GAAAC,GAAAC,GAGAnvF,EAAAmmE,QAAAnmE,EAAAkN,OAAA,OAAA,CAEA,IAAAuiF,GAAAr0F,KAAA66B,MAAAt2B,EAAAsvF,EAAA,GACA,KAAAQ,GAAAA,EAAA7Y,OAAA,OAAA,CAEA,IAAA+Y,GAAAv0F,KAAA66B,MAAAt2B,EAAAsvF,EAAA,GACA,KAAAU,GAAAA,EAAA/Y,OAAA,OAAA,CAGA,IAAA6Y,EAAA70E,QAAA+0E,EAAA/0E,MACA,OAAA,CAEA,IAAA5a,EAAAmmE,MAAA,CACA,GAAAvvB,GAAA64C,EAAA70E,MACAi8B,EAAA84C,EAAA/0E,MAEAxQ,IAAAwsC,EAAA,KAAAC,EAAA,IACAD,EAAA,KAAAC,EAAA,IACAD,EAAA,KAAAC,EAAA,IAEAD,EAAA,KAAAC,EAAA,KAEA,MAAAD,EAAA,IAAA,IAAAA,EAAA,IAEA,MAAAC,EAAA,IAAA,IAAAA,EAAA,IAKA,IAAAzsC,EAAA,OAAA,EAGA,OACAzK,KAAAA,EACAib,MAAAq0E,EACA3xE,SAAA,GAAA1C,EACAg8D,OAAAA,EACAvgE,MAAA44E,EAAA,GACAK,SAAAr2D,WAAAg2D,EAAA,IACAM,SAAAt2D,WAAAg2D,EAAA,IACAQ,SAAAA,EAAA70E,MACA+0E,SAAAA,EAAA/0E,MACA0S,OAAAqhE,IAIA,GAAA3uF,EAAAi0F,UAAA,aAAAR,EAAA,CACA,GAAA3M,EAUA,IAPAA,EADA8B,EACAhuE,EAAAqG,MAAA,OACAzkB,EAAAitB,MAAA7O,GACAA,GAEAA,GAGA5a,EAAAk0F,cAAApN,EAAA1qF,OAAA,IAAA,EAAA,MAAA,KAEA,IAAA+3F,GAAArN,EAAAv1E,IAAA,SAAA/K,GACA,GAAArH,GAAAhE,EAAA86B,MAAAt2B,EAAA6G,EAAAmoF,EAAA,WAEA,OAAA,OAAAxvF,EAAA6b,QACA7b,EAAA6b,QAEA7b,EAAAyb,OAIA,QACAjb,KAAAA,EACAib,MAAAu5E,EACAn5E,QAAAm5E,EACA72E,SAAA62E,EAAAvuE,KAAA,KACA0H,OAAAqhE,EACApmB,MAAAvoE,EAAAkN,SAAAlN,EAAAo0F,SAAAp0F,EAAAmyF,eAAA,KAAAjzF,QAKA,GAAAm1F,GAAA,WACA,IAAA,GAAAt4F,GAAA,EAAAA,EAAAiE,EAAAs0F,MAAAl4F,OAAAL,IAAA,CACA,GAAAw4F,GAAAv0F,EAAAs0F,MAAAv4F,EAEA,IAAAw4F,IAAA35E,EACA,OACAjb,KAAAA,EACAib,MAAAA,EACA0C,SAAA,GAAA1C,EACA0S,OAAAqhE,GAKA,MAAA,MAIA,IAAA3uF,EAAAkN,OAAA,CACA,GAAAq7D,GACA4pB,EAAA,IAUA,IARAnyF,EAAAuoE,QACAA,EAAAvoE,EAAAuoE,OAGAvoE,EAAAmyF,gBACAA,EAAAnyF,EAAAmyF,gBAGAnyF,EAAAo0F,SACA,GAAAxL,EAAA,CACA,GAAA4L,GAAA,SAAAx0F,EAAAy0F,aAAA,OAAA,GACAlsB,KAAAisB,EAAAjsB,EACA,IAAAl1D,GAAAuH,EAAAvH,MAAA,KAAA9W,EAAA+nC,MAAAp3B,OAAA,KAAAsnF,EAAA,MAEAnhF,KACAuH,EAAAvH,EAAA,GACAk1D,EAAAl1D,EAAA,IAAA8+E,SAGA5pB,GAAAvoE,EAAAmyF,iBACA5pB,EAAA4pB,EAOA,IAHAv3E,EAAAqe,WAAAre,GAGA0nB,MAAA1nB,IAAA1b,SAAAc,EAAAs0F,MACA,MAAA,KAKA,IAAAhyD,MAAA1nB,IAAA1b,SAAAc,EAAAs0F,MAGA,MAFA15E,GAAAi5E,EAEAQ,GAIA,IAAAr0F,EAAAm8E,UAAA3/E,EAAA2/E,QAAAvhE,GACA,MAAA,KAIA,IAAA1b,SAAAc,EAAA+X,KAAA6C,EAAA5a,EAAA+X,KACA7Y,SAAAc,EAAA+G,KAAA6T,EAAA5a,EAAA+G,IAEA,MAAA,KAGA,IAAAE,IACAtH,KAAAA,EACAib,MAAAA,EACA0C,SAAA,GAAA1C,GAAA2tD,EAAAA,EAAA,IACAA,MAAAA,EACAj7C,OAAAqhE,EAoBA,OAhBA3uF,GAAAo0F,UAAA,OAAA7rB,GAAA,OAAAA,EACAthE,EAAA+T,QAAAJ,EAEA3T,EAAA+T,QAAA,OAAAutD,GAAAA,EAAAntE,KAAAs2F,oBAAA92E,EAAA,GAIA,OAAA2tD,GAAA,MAAAA,KACAthE,EAAA+T,QAAA,OAAAutD,EAAA3tD,EAAA,IAAAA,IAIA,QAAA2tD,GAAA,QAAAA,KACAthE,EAAA+T,QAAA,QAAAutD,EAAA3tD,EAAAA,EAAA/P,KAAAsjC,GAAA,KAGAlnC,EAEA,GAAAjH,EAAA00F,SAAA,CAEA,GAAAhmF,MACAimF,EAAA,GAAA/5E,CAEA,IAAA,SAAA+5E,OAGA,CAGA,IAAA,GADAC,GAAAD,EAAA1zE,MAAA,KACAllB,EAAA,EAAAA,EAAA64F,EAAAx4F,OAAAL,IAAA,CACA,GAAA81F,GAAA+C,EAAA74F,GAAAi4F,MAEA74F,GAAAosC,WAAAsqD,IACAnjF,EAAA7Q,KAAAg0F,GAIA,GAAA,IAAAnjF,EAAAtS,OAAA,MAAA,MAGA,OACAuD,KAAAA,EACAib,MAAAlM,EACA4O,SAAA,IAAA5O,EAAAtS,OAAA,OAAAsS,EAAAkX,KAAA,MACA0H,OAAAqhE,GAGA,GAAA3uF,EAAAmmE,MAAA,CACA,GAAA0uB,GAAAt4F,EAAAu4F,YAAAl6E,EAEA,OAAAi6E,IAGAl1F,KAAAA,EACAib,MAAAi6E,EACAv3E,SAAA,GAAA1C,EACA0S,OAAAqhE,EACAl3D,YAAA,GAPA,KAUA,GAAAz3B,EAAAskC,OAAAtkC,EAAA+0F,QAAA,CAGA,GAAA/0F,EAAAs0F,MAAA,CACA,GAAAU,GAAAX,GAEA,IAAAW,EAAA,MAAAA,GAKA,IAAA,GAFAD,GAAA/0F,EAAA+0F,QAAA/0F,EAAA+0F,SAAA/0F,EAAAskC,OAEAvoC,EAAA,EAAAA,EAAAg5F,EAAA34F,OAAAL,IAAA,CACA,GAAAuoC,GAAA,GAAA8jD,QAAA2M,EAAAh5F,IACAkrC,EAAA3C,EAAAukD,KAAAjuE,EAEA,IAAAqsB,EACA,OACAtnC,KAAAA,EACAib,MAAAqsB,EACA3pB,SAAA,GAAA1C,EACA0S,OAAAqhE,GAMA,MAAA,MAEA,MAAA3uF,GAAA4B,QvFqrrBMjC,KAAMA,EwFrksBZib,MAAAA,EACA0C,SAAA,GAAA1C,EACA0S,OAAAqhE,GAGA3uF,EAAAs0F,MACAD,IAGA,KAKAx5F,GAAAD,QAAA0wF,IAEAlrE,QAAA,GAAAxL,UAAA,KAAAqgF,IAAA,SAAA34F,EAAAzB,EAAAD,GACA,YAEA,IAAA2B,GAAAD,EAAA,WAEAgvF,MAEA,WACA,GAAAp+E,GAAA3Q,EAAA+nC,MAAAp3B,OACAgoF,EAAA34F,EAAA+nC,MAAA6wD,eACAC,EAAA74F,EAAA+nC,MAAA+wD,eACAC,EAAA/4F,EAAA+nC,MAAAgxD,KACAC,EAAAh5F,EAAA+nC,MAAAixD,KACAjyF,EAAA,SAAAwhB,GAAA,MAAA,IAAAA,EAAA,kCACAmqE,EAAA,SAAAnqE,GACA,GAAA0wE,GAAAtoF,EAAA,SAAAgoF,EAAA,IAAAE,EAAA,IAAAE,EAAA,IAAAC,CACA,OAAA,IAAAzwE,EAAA,iCAAA5X,EAAA,gBAAAA,EAAA,cAAAsoF,EAAA,gBAAAA,EAAA,QAIAlK,GAAAp2B,OACAj2D,MAAAiO,QAAA,EAAA6K,IAAA,EAAAwwD,MAAA,OAAA4pB,cAAA,MACAj8D,SAAAhpB,QAAA,EAAA6K,IAAA,EAAAhR,IAAA,IAAAwhE,MAAA,IAAA4pB,cAAA,KACAsD,eAAAvoF,QAAA,EAAA6K,IAAA,EAAAhR,IAAA,EAAAqtF,UAAA,GACAsB,eAAAxoF,QAAA,EAAA6K,IAAA,GAAAhR,IAAA,EAAAqtF,UAAA,GACAuB,gBAAAzoF,QAAA,EAAA6K,IAAA,EAAAokE,SAAA,EAAAiY,UAAA,GACAh8E,UAAAk8E,OAAA,SAAA,WACAv+C,UAAA7oC,QAAA,EAAA6K,IAAA,EAAAu8E,OAAA,OAAA,UACApnF,QAAAA,QAAA,EAAAknF,UAAA,GACAwB,SAAA1oF,QAAA,EAAAknF,UAAA,EAAAH,UAAA,GACAvpF,MAAAwC,QAAA,EAAA6K,IAAA,GACA89E,mBAAA3oF,QAAA,GACA4oF,oBAAA5oF,QAAA,EAAA+mF,UAAA,GACA8B,QAAA7oF,QAAA,EAAA6K,IAAA,EAAA08E,cAAA,GACAuB,MAAA9oF,QAAA,EAAA6K,IAAA,EAAA08E,cAAA,EAAAH,OAAA,SACA2B,OAAA/oF,QAAA,EAAAunF,cAAA,GACAyB,UAAA5B,OAAA,SAAA,WAAA,WAAA,cACA6B,OAAA7B,OAAA,OAAA,UAAA,UACA8B,QAAA9B,OAAA,OAAA,SACAnuB,OAAAA,OAAA,GACA1gE,MAAA6uF,OAAA,MAAA,OACA9vB,WAAA8vB,OAAA,QAAA,SAAA,WACAloB,aAAAkoB,OAAA,QAAA,SAAA,SAAA,WACA9qC,YAAA8qC,OAAA,SAAA,mBAAA,WAAA,aACAttC,YAAA1iB,MAAA,4CACA+xD,aAAA/B,OAAA,aAAA,WACArtC,WAAAqtC,OAAA,SAAA,SAAA,YACAptC,YAAAotC,OAAA,SAAA,OAAA,SAAA,UAAA,MAAA,MAAA,MAAA,MAAA,MAAA,MAAA,MAAA,MAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA,MACAgC,gBAAAhC,OAAA,OAAA,YAAA,WAAA,iBACArvC,eAAAqvC,OAAA,OAAA,YAAA,cACAiC,UAAAjC,OAAA,OAAA,SACAkC,qBAAAlC,OAAA,YAAA,mBACAmC,WAAAnC,OAAA,YAAA,iBAAA,UAAA,WAAA,SAAA,WAAA,UAAA,WAAA,UAAA,OAAA,UAAA,MAAA,WAAA,YACAoC,uBAAApC,OAAA,UAAA,YACA1uB,YAAA0uB,OAAA,MAAA,WAAA,eAAA,qBAAA,yBAAA,MAAA,SAAA,SAAA,UAAA,SACAtuB,WAAAsuB,OAAA,SAAA,WACAp4E,SAAAo4E,OAAA,UAAA,SACAltC,YAAAktC,OAAA,SAAA,YACA12E,QAAA02E,OAAA,MAAA,SAAA,WACA32E,QAAA22E,OAAA,OAAA,SAAA,UACAzvC,MAAAjjD,QAAA,GACA0B,MAAA8sF,SAAA,EAAA9rD,MAAAhhC,EAAA,SACA+sF,YAAAD,SAAA,EAAA9rD,MAAAhhC,EAAA,eACA2T,SAAAm5E,SAAA,EAAA9rD,MAAAhhC,EAAA,YACA2rF,SAAAmB,SAAA,EAAA9rD,MAAA2qD,EAAA,YACAC,eAAAkB,SAAA,EAAA9rD,MAAA2qD,EAAA,kBACAE,YAAAiB,SAAA,EAAA9rD,MAAA2qD,EAAA,eACArxF,IAAAwyF,SAAA,EAAAxyF,IAAA,GACAg1D,KAAAtuB,MAAA,kDACAowD,UAAAA,UAAA,GACA74C,OAAA3uC,QAAA,EAAAq7D,MAAA,UAAA4pB,cAAA,OACAwE,cAAArC,OAAA,OAAA,eACAsC,kBAAA1pF,QAAA,EAAA+mF,UAAA,EAAAC,cAAA,EAAAn8E,IAAA,GAAAhR,IAAA,EAAAqtF,UAAA,GACAtpE,QACAiqE,SACA,wBAAA7nF,EAAA,cAAAA,EAAA,YACA,8BAAAA,EAAA,cAAAA,EAAA,cAAAA,EAAA,cAAAA,EAAA,aAEAonF,OACA,SACA,OAAA,UAAA,WAAA,cACA,eAAA,gBAAA,mBACA,eAAA,gBAAA,mBACA,gBAAA,iBAAA,oBACA,gBAAA,iBAAA,oBACA,gBAAA,iBAAA,oBACA,eAAA,gBAAA,mBACA,eAAA,gBAAA,qBAMA,IAAA/4F,GAAA+vF,EAAAp2B,MACAxmD,EAAA48E,EAAA/jD,aAEA5nC,KAAA,cAAAK,KAAAzE,EAAAqiB,SACAje,KAAA,cAAAK,KAAAzE,EAAAoiB,SACAhe,KAAA,QAAAK,KAAAzE,EAAA4qE,QACAxmE,KAAA,QAAAK,KAAAzE,EAAAspD,OACAllD,KAAA,qBAAAK,KAAAzE,EAAA4qE,QACAxmE,KAAA,qBAAAK,KAAAzE,EAAAmP,OACA/K,KAAA,uBAAAK,KAAAzE,EAAAk6F,gBACA91F,KAAA,eAAAK,KAAAzE,EAAAk6F,gBACA91F,KAAA,wBAAAK,KAAAzE,EAAA4qE,QACAxmE,KAAA,0BAAAK,KAAAzE,EAAAk6F,gBACA91F,KAAA,sBAAAK,KAAAzE,EAAAk6F,gBACA91F,KAAA,oBAAAK,KAAAzE,EAAA4qE,QACAxmE,KAAA,oBAAAK,KAAAzE,EAAAmP,OACA/K,KAAA,oBAAAK,KAAAzE,EAAA6wE,cACAzsE,KAAA,wBAAAK,KAAAzE,EAAAi7F,sBAEA72F,KAAA,iBAAAK,KAAAzE,EAAA0pD,gBACAtlD,KAAA,YAAAK,KAAAzE,EAAAg7F,WACA52F,KAAA,iBAAAK,KAAAzE,EAAAmP,OACA/K,KAAA,cAAAK,KAAAzE,EAAAkK,OAGA9F,KAAA,cAAAK,KAAAzE,EAAAyrD,aACArnD,KAAA,aAAAK,KAAAzE,EAAA0rD,YAEAtnD,KAAA,cAAAK,KAAAzE,EAAA2rD,aACAvnD,KAAA,YAAAK,KAAAzE,EAAAmP,OACA/K,KAAA,uBAAAK,KAAAzE,EAAAmP,OACA/K,KAAA,qBAAAK,KAAAzE,EAAAo7F,eAGAh3F,KAAA,SAAAK,KAAAzE,EAAAkK,OAGA9F,KAAA,UAAAK,KAAAzE,EAAA2gB,UACAvc,KAAA,aAAAK,KAAAzE,EAAA6rD,aACAznD,KAAA,UAAAK,KAAAzE,EAAAk6F,gBACA91F,KAAA,UAAAK,KAAAzE,EAAAo6F,iBAGAh2F,KAAA,kBAAAK,KAAAzE,EAAAmP,OACA/K,KAAA,gBAAAK,KAAAzE,EAAA4qE,QACAxmE,KAAA,kBAAAK,KAAAzE,EAAAk6F,gBAGA91F,KAAA,cAAAK,KAAAzE,EAAAmP,OACA/K,KAAA,eAAAK,KAAAzE,EAAA4qE,QACAxmE,KAAA,iBAAAK,KAAAzE,EAAAk6F,gBACA91F,KAAA,kBAAAK,KAAAzE,EAAAs6F,oBACAl2F,KAAA,kBAAAK,KAAAzE,EAAAs6F,oBAGAl2F,KAAA,mBAAAK,KAAAzE,EAAAmP,OACA/K,KAAA,oBAAAK,KAAAzE,EAAA4qE,QACAxmE,KAAA,sBAAAK,KAAAzE,EAAAk6F,gBACA91F,KAAA,uBAAAK,KAAAzE,EAAAs6F,oBACAl2F,KAAA,uBAAAK,KAAAzE,EAAAs6F,oBAGAl2F,KAAA,sBAAAK,KAAAzE,EAAAm5F,WACA/0F,KAAA,sBAAAK,KAAAzE,EAAA0D,OACAU,KAAA,mBAAAK,KAAAzE,EAAA0D,OACAU,KAAA,6BAAAK,KAAAzE,EAAAuvB,SAGAnrB,KAAA,SAAAK,KAAAzE,EAAAw6C,WACAp2C,KAAA,QAAAK,KAAAzE,EAAAw6C,WACAp2C,KAAA,QAAAK,KAAAzE,EAAAk7F,YACA92F,KAAA,uBAAAK,KAAAzE,EAAAq7F,mBACAj3F,KAAA,mBAAAK,KAAAzE,EAAA4qE,QACAxmE,KAAA,qBAAAK,KAAAzE,EAAAk6F,gBACA91F,KAAA,qBAAAK,KAAAzE,EAAAm6F,gBACA/1F,KAAA,eAAAK,KAAAzE,EAAAmP,OACA/K,KAAA,gBAAAK,KAAAzE,EAAAmP,OACA/K,KAAA,cAAAK,KAAAzE,EAAAmP,OACA/K,KAAA,iBAAAK,KAAAzE,EAAAmP,OAGA/K,KAAA,eAAAK,KAAAzE,EAAA4qE,QACAxmE,KAAA,iBAAAK,KAAAzE,EAAAk6F,gBACA91F,KAAA,eAAAK,KAAAzE,EAAAmP,OACA/K,KAAA,eAAAK,KAAAzE,EAAA6wE,cAGAzsE,KAAA,mBAAAK,KAAAzE,EAAAq3D,MACAjzD,KAAA,2BAAAK,KAAAzE,EAAAk6F,gBACA91F,KAAA,wBAAAK,KAAAzE,EAAA06F,QACAt2F,KAAA,wBAAAK,KAAAzE,EAAA06F,QACAt2F,KAAA,oBAAAK,KAAAzE,EAAA26F,WACAv2F,KAAA,iBAAAK,KAAAzE,EAAA46F,QACAx2F,KAAA,kBAAAK,KAAAzE,EAAA66F,SACAz2F,KAAA,mBAAAK,KAAAzE,EAAAy6F,OACAr2F,KAAA,oBAAAK,KAAAzE,EAAAy6F,OAGAr2F,KAAA,WAAAK,KAAAzE,EAAA6c,WACAzY,KAAA,6BAAAK,KAAAzE,EAAAm7F,wBAGA/2F,KAAA,aAAAK,KAAAzE,EAAAipE,YACA7kE,KAAA,aAAAK,KAAAzE,EAAA4qE,QACAxmE,KAAA,cAAAK,KAAAzE,EAAAiuD,aACA7pD,KAAA,kBAAAK,KAAAzE,EAAAk6F,gBACA91F,KAAA,0BAAAK,KAAAzE,EAAAmP,OACA/K,KAAA,0BAAAK,KAAAzE,EAAAu6F,qBACAn2F,KAAA,wBAAAK,KAAAzE,EAAAq6F,UACAj2F,KAAA,oBAAAK,KAAAzE,EAAAu6F,qBACAn2F,KAAA,kBAAAK,KAAAzE,EAAAq6F,UAGAj2F,KAAA,sBAAAK,KAAAzE,EAAA4qE,QACAxmE,KAAA,wBAAAK,KAAAzE,EAAAk6F,gBACA91F,KAAA,6BAAAK,KAAAzE,EAAA4qE,QACAxmE,KAAA,6BAAAK,KAAAzE,EAAAmP,OACA/K,KAAA,kBAAAK,KAAAzE,EAAA4qE,QACAxmE,KAAA,oBAAAK,KAAAzE,EAAAk6F,gBACA91F,KAAA,iBAAAK,KAAAzE,EAAAmP,OACA/K,KAAA,2BAAAK,KAAAzE,EAAA4qE,QACAxmE,KAAA,6BAAAK,KAAAzE,EAAAk6F,gBAIAoB,EAAAvL,EAAAuL,UACAl3F,KAAA,UAAAo0F,SAAA,UACAp0F,KAAA,yBAAAo0F,SAAA,4BACAp0F,KAAA,uBAAAo0F,SAAA,yBAIAzI,GAAAxe,eAAA,GACAp+D,EAAA7Q,MAAA8B,KAAA,WAAAK,KAAAzE,EAAAw6F,QACA,KAAA,GAAAh6F,GAAA,EAAAA,GAAAuvF,EAAAxe,eAAA/wE,IACA2S,EAAA7Q,MAAA8B,KAAA,OAAA5D,EAAA,oBAAAiE,KAAAzE,EAAA4qE,QACAz3D,EAAA7Q,MAAA8B,KAAA,OAAA5D,EAAA,mBAAAiE,KAAAzE,EAAA26B,UACAxnB,EAAA7Q,MAAA8B,KAAA,OAAA5D,EAAA,sBAAAiE,KAAAzE,EAAAk6F,eAIA,IAAAqB,GAAAxL,EAAAwL,eAAA,SAAA,aAAA,SAAA,gBAEAn3F,KAAA,cAAAK,KAAAzE,EAAAqqE,aACAjmE,KAAA,cAAAK,KAAAzE,EAAA4qE,QACAxmE,KAAA,aAAAK,KAAAzE,EAAAyqE,YACAt/D,QAAA,SAAAhH,GACAo3F,EAAApwF,QAAA,SAAAoe,GACA,GAAAnlB,GAAAmlB,EAAA,IAAAplB,EAAAC,KACAK,EAAAN,EAAAM,IAEA0O,GAAA7Q,MAAA8B,KAAAA,EAAAK,KAAAA,WAKAsrF,EAAAkG,cAAA9iF,EAAA6C,IAAA,SAAApS,GAAA,MAAAA,GAAAQ,MAGA,KAAA,GAAA5D,GAAA,EAAAA,EAAA2S,EAAAtS,OAAAL,IAAA,CACA,GAAA2D,GAAAgP,EAAA3S,EAEA2S,GAAAhP,EAAAC,MAAAD,EAIA,IAAA,GAAA3D,GAAA,EAAAA,EAAA86F,EAAAz6F,OAAAL,IAAA,CACA,GAAA+3F,GAAA+C,EAAA96F,GACAg7F,EAAAroF,EAAAolF,EAAAC,UACAiD,GACAr3F,KAAAm0F,EAAAn0F,KACAm0F,OAAA,EACAC,SAAAgD,EAIAroF,GAAA7Q,KAAAm5F,GAEAtoF,EAAAolF,EAAAn0F,MAAAq3F,MAKA1L,EAAAiH,qBAAA,WAEAn3F,KACA2Z,SAAA,cACA5X,IAAAZ,EAAAS,QACAimC,OAAA,MACAg0D,cAAA,KACAC,cAAA,MACAC,cAAA,SACAhxB,MAAA,OACAixB,qBAAA,OACAC,qBAAA,EACAC,uBAAA,EACAC,eAAA,EACAC,kBAAA,OACAC,iBAAA,OACAC,YAAA,OACAC,iBAAA,KACAC,wBAAA,OACAC,0BAAA,EACAC,sBAAA,EACAC,oBAAA,EACAC,oBAAA,QACAC,oBAAA,OACAC,wBAAA,YACAC,cAAA,wCACAC,aAAA,SAEAC,cAAA,SACAC,YAAA,GACAC,uBAAA,EACAC,qBAAA,OACApxC,WAAA,UACAlrC,QAAA,UACA8Q,QAAA,EACAyrE,UAAA,EACAh7E,MAAA,GACAi7E,kBAAA,EACAC,gBAAA,OACAC,kBAAA,GACAC,iBAAA,EACAC,eAAA,OACAC,cAAA,GACAC,kBAAA,EACAC,kBAAA,EACAC,sBAAA,EACAC,oBAAA,OACAC,mBAAA,EACAC,uBAAA,EACAC,uBAAA,EACAC,sBAAA,OACAC,sBAAA,EACAC,mBAAA,EACAC,6BAAA,SAGAC,qBAAA,EACAC,mBAAA,OACAC,qBAAA,EACAC,mBAAA,OACAC,2BAAA,EACAC,wBAAA,MACAC,wBAAA,MACAC,oBAAA,YACAC,iBAAA,OACAC,kBAAA,OACAC,mBAAA,OACAC,oBAAA,OACAC,eAAA,OACAC,iBAAA,EACAC,eAAA,EACAC,eAAA,QACAr4D,OAAA,GACAD,MAAA,GACA4d,MAAA,UACA26C,uBAAA,mCAGAC,cAAA,EACAC,iBAAA,EACAC,eAAA,EACAC,gBAAA,EACA3iF,SAAA,SACA4iF,6BAAA,YAGAC,WAAA,UAEAt7F,KAAA,6BAAAib,MAAA,UACAjb,KAAA,4BAAAib,MAAA,OACAjb,KAAA,+BAAAib,MAAA,IACAi9D,OAAA,SAAA16E,EAAAuC,GACA,IAAA,GAAA3D,GAAA,EAAAA,GAAAuvF,EAAAxe,eAAA/wE,IAAA,CACA,GAAA4D,GAAAD,EAAAC,KAAAy6E,QAAA,QAAAr+E,GACAwd,EAAA7Z,EAAAkb,KAEAzd,GAAAwC,GAAA4Z,EAGA,MAAApc,SAGA+9F,aAAA,QACAC,aAAA,OACAC,0BAAA,GACAC,wBAAA,GACAC,kBAAA,GACAC,oBAAA,GACAC,cAAA,SACAC,kBAAA,MAEA97F,KAAA,cAAAib,MAAA,SACAjb,KAAA,cAAAib,MAAA,SACAjb,KAAA,aAAAib,MAAA,WACAi9D,OAAA,SAAA16E,EAAAuC,GAQA,MAPA4rF,GAAAwL,cAAApwF,QAAA,SAAAoe,GACA,GAAAnlB,GAAAmlB,EAAA,IAAAplB,EAAAC,KACA4Z,EAAA7Z,EAAAkb,KAEAzd,GAAAwC,GAAA4Z,IAGApc,SAEA4X,SAAA,gBACA5X,KACAilC,MAAA,OACAC,OAAA,OACA2d,MAAA,YACA46C,cAAA,GACAG,gBAAA,GACAD,eAAA,GACAD,iBAAA,KAEA9lF,SAAA,QACA5X,KACAilC,MAAA,IAEArtB,SAAA,WACA5X,KACAw7F,gBAAA,QACAC,kBAAA,GACAF,kBAAA,MAEA3jF,SAAA,QACA5X,KxFuksBQu+F,sBAAuB,OyF5/sB/BC,wBAAA,IACAC,6BAAA,OACAC,6BAAA,EACAC,kBAAA,QACAC,oBAAA,IACAC,iBAAA,GACAC,2BAAA,OACAC,6BAAA,OAIA9gG,KAAAm4F,cAAAn4F,KAAAgB,QAGAvB,EAAAD,QAAA0wF,IAEA12E,UAAA,KAAAunF,IAAA,SAAA7/F,EAAAzB,EAAAD,GACA,YAEA,IAAA2B,GAAAD,EAAA,WACAwlB,EAAAxlB,EAAA,eAEAgvF,IAEAA,GAAA8Q,gBAAA,SAAAx6F,GAWA,QAAAy6F,KAGAlT,EADAA,EAAA/sF,OAAAkgG,EAAAlgG,OACA+sF,EAAAoT,OAAAD,EAAAlgG,QAEA,GAIA,QAAAogG,KAGAC,EADAA,EAAArgG,OAAAsgG,EAAAtgG,OACAqgG,EAAAF,OAAAG,EAAAtgG,QAEA,GAxBA,GAGAkgG,GACAG,EACAC,EALAvhG,EAAAC,KACA8B,EAAA9B,KACA+tF,EAAA,GAAAvnF,CA0BA,KApBAunF,EAAAA,EAAA/O,QAAA,0BAAA,MAoBA,CACA,GAAAuiB,GAAAxT,EAAA91E,MAAA,QACA,IAAAspF,EAAA,KAEA,IAAAC,GAAAzT,EAAA91E,MAAA,sCAEA,KAAAupF,EAAA,CACArgG,EAAAiI,MAAA,4GAAA2kF,EACA,OAGAmT,EAAAM,EAAA,EAGA,IAAAnK,GAAAmK,EAAA,EACA,IAAA,SAAAnK,EAAA,CACA,GAAA19E,GAAA,GAAA+M,GAAA2wE,EACA,IAAA19E,EAAAhY,SAAAqqF,QAAA,CACA7qF,EAAAiI,MAAA,2EAAAiuF,GAGA4J,GACA,WAKA,GAAAQ,GAAAD,EAAA,GACAE,GAAA,CACAL,GAAAI,CAGA,KAFA,GAAAnuF,QAEA,CACA,GAAAiuF,GAAAF,EAAAppF,MAAA,QACA,IAAAspF,EAAA,KAEA,IAAAI,GAAAN,EAAAppF,MAAA,4BAEA,KAAA0pF,EAAA,CACAxgG,EAAAiI,MAAA,kGAAAq4F,GACAC,GAAA,CACA,OAGAJ,EAAAK,EAAA,EACA,IAAAC,GAAAD,EAAA,GACA1S,EAAA0S,EAAA,GAEAr9F,EAAAvE,EAAAosC,WAAAy1D,EACA,IAAAt9F,EAAA,CAQA,GAAA+uF,GAAAvxF,EAAA+4B,MAAA+mE,EAAA3S,EAEAoE,IAQA//E,EAAA7Q,MACA8B,KAAAq9F,EACAzjF,IAAA8wE,IAEAmS,MAXAjgG,EAAAiI,MAAA,sDAAAk4F,GAGAF,SAbAjgG,GAAAiI,MAAA,gDAAAk4F,GAGAF,IAqBA,GAAAM,EAAA,CACAT,GACA,OAIAn/F,EAAA6X,SAAA09E,EACA,KAAA,GAAA12F,GAAA,EAAAA,EAAA2S,EAAAtS,OAAAL,IAAA,CACA,GAAA2D,GAAAgP,EAAA3S,EACAmB,GAAAC,IAAAuC,EAAAC,KAAAD,EAAA6Z,KzFggtBI8iF,I0FtotBJ,MAAAn/F,IAGAouF,EAAA3pD,WAAA,SAAA//B,GACA,GAAA1E,GAAA9B,IAKA,OAHA8B,GAAAs1F,iBACAt1F,EAAAk/F,gBAAAx6F,GAEA1E,GAGArC,EAAAD,QAAA0wF,IAEA7mE,cAAA,GAAA7P,UAAA,KAAAqoF,IAAA,SAAA3gG,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,QACAC,EAAAD,EAAA,UACAglC,EAAAhlC,EAAA,WAIAy+E,EAAA,WACA,MAAA3/E,gBAAA2/E,QAIA3/E,KAAAgB,OAAA,GAHA,GAAA2+E,IAMAmiB,EAAAniB,EAAAh9E,SAEAm/F,GAAAl/F,eAAA,WACA,MAAA,cAIAk/F,EAAAnoF,SAAA,SAAAA,GACA,GAAAhZ,GAAAX,KAAAgB,QAOA,OALAhB,MAAAW,IACAgZ,SAAAA,EACAwyB,eAGAnsC,MAIA8hG,EAAA//F,IAAA,SAAAwC,EAAAib,GACA,GAAA7e,GAAAX,KAAAgB,OAAA,CAEA,IAAAI,EAAAoF,OAAAjC,GACAvE,KAAAW,GAAAwrC,WAAA1pC,MACA8B,KAAAA,EACAib,MAAAA,QAEA,IAAApe,EAAAwL,YAAArI,GAGA,IAAA,GAFA4R,GAAA5R,EAEA0I,EAAA,EAAAA,EAAAi5B,EAAAiG,WAAAnrC,OAAAiM,IAAA,CACA,GAAA3I,GAAA4hC,EAAAiG,WAAAl/B,GACAqqF,EAAAnhF,EAAA7R,EAAAC,KAMA,IAJAT,SAAAwzF,IACAA,EAAAnhF,EAAAhV,EAAAuD,WAAAJ,EAAAC,QAGAT,SAAAwzF,EAAA,CACA,GAAA/yF,GAAAD,EAAAC,KACAib,EAAA83E,CAEAt3F,MAAAW,GAAAwrC,WAAA1pC,MACA8B,KAAAA,EACAib,MAAAA,KAMA,MAAAxf,OAGA8hG,EAAAhgG,MAAAggG,EAAA//F,IAGA+/F,EAAAz7D,cAAA,SAAAjjC,GAGA,IAAA,GAFAtB,GAAA,GAAAokC,GAAA9iC,GAEAzC,EAAA,EAAAA,EAAAX,KAAAgB,OAAAL,IAAA,CACA,GAAAykC,GAAAplC,KAAAW,G1F0otBQgZ,EAAWyrB,EAAQzrB,S2FvutB3BrG,EAAA8xB,EAAA+G,UAEArqC,GAAA6X,SAAAA,EAEA,KAAA,GAAA1M,GAAA,EAAAA,EAAAqG,EAAAtS,OAAAiM,IAAA,CACA,GAAA3I,GAAAgP,EAAArG,EAEAnL,GAAAC,IAAAuC,EAAAC,KAAAD,EAAAkb,QAIA,MAAA1d,IAGArC,EAAAD,QAAAmgF,IAEA36E,OAAA,GAAA+oB,UAAA,GAAA7oB,SAAA,KAAA68F,IAAA,SAAA7gG,QAAAzB,OAAAD,SAIA,YAEA,IAAAK,QAAAqB,QAAA,YACAC,KAAAD,QAAA,UACAG,QAAAH,QAAA,aACAynC,MAAAznC,QAAA,WACAxB,OAAAwB,QAAA,YACAE,GAAAF,QAAA,QAEAg0C,OAAA,SAAA1zC,GACA,KAAAxB,eAAAk1C,SACA,MAAA,IAAAA,QAAA1zC,EAGA,IAAAE,GAAA1B,KAAA2B,UACAqgG,YACAC,SACAh/F,MAAA,KACA0zC,QACAV,UAAA,EAGA70C,IAAAwL,YAAApL,IACA,MAAAA,EAAAy0C,WACAv0C,EAAAu0C,WAAAz0C,EAAAy0C,WAMAisD,MAAAhtD,OAAAvyC,UAEAw/F,kBAAA,SAAAhkF,GACA,GAAA8wE,GAAA7tF,GAAAoB,GAAA2b,GAAAA,EAAAi/B,WAAA,eAAAglD,KAAAC,UAAAlkF,GAAA,IAEA,OAAA8wE,IAIAqT,YAAA,SAAA9/F,GACA,GAAA+/F,GACAx0D,CAEA3sC,IAAA0/E,OAAAt+E,IAAAA,EAAAA,IACA+/F,EAAAC,KAAAhgG,EAAAA,GAAAA,EAAA+B,MACAwpC,EAAAvrC,EAAA+B,KACA/B,EAAAA,EAAAA,IACApB,GAAAoB,GAAAA,IACA+/F,EAAA//F,EAAA46C,WACArP,EAAAvrC,EAAA+B,MACAnD,GAAAoF,OAAAhE,GACA+/F,EAAA//F,EACApB,GAAA0/E,OAAAt+E,KAEA+/F,EADA//F,EAAAqnC,MACA,GAEArnC,EAAA+B,KAAA,SAGAwpC,EAAAvrC,EAAA+B,KACA/B,EAAAA,EAAAynB,KAGAs4E,GAAA,IAEA,IAAAE,GAAA,SAAAtkF,EAAAukF,GACA,GAAAvkF,EAAAxb,UAAA,CACA,GAAAggG,IAAA,CACA,KAAA,GAAAr+F,KAAA6Z,GAAAxb,UAAA,CAAAggG,GAAA,CAAA,OAEAA,IACAJ,GAAAD,aACA/9F,KAAAm+F,EACAz4E,IAAA9L,EACA0rB,OAAA,GACA1rB,KAMA,IAAA3b,EAAAG,WAAA,MAAAorC,EAEA,IAAA,GAAAxpC,KAAA/B,GAAAG,UAAA,CACA,GAAAigG,GAAA,GAEAzkF,EAAA3b,EAAAG,UAAA4B,GACA0qF,EAAAkT,kBAAAhkF,GACAukF,EAAA30D,EAAA,cAAAxpC,CAEAq+F,IAAAF,EAAA,MAAAzT,EAAA,MAEA2T,IACAL,GAAAK,GAGAH,EAAAtkF,EAAAukF,GAMA,IAAAthG,GAAAoF,OAAAhE,GAAA,IAAA,GAAA+B,KAAA/B,GAAA,CACA,GAAA+2F,GAAA,EAEA,IAAA/2F,EAAAqgG,eAAAt+F,GAAA,CACA,GAAA4Z,GAAA3b,EAAA+B,GACA0qF,EAAAkT,kBAAAhkF,GACAukF,EAAA30D,EAAA,KAAAxpC,EAAA,IAEAg1F,IAAAmJ,EAAA,MAAAzT,EAAA,MAGAsK,IACAgJ,GAAAhJ,GAGAkJ,EAAAtkF,EAAAukF,GAGA,MAAAH,IAGAO,UAAA,SAAA/V,GACA,MAAA3rF,IAAAoF,OAAAumF,IAAAA,EAAA90E,MAAA,SAGA9W,MAAAS,OAAAsgG,OAEAt/F,eAAA,WAAA,MAAA,UAEAlC,QAAA,SAAA8B,EAAAw4E,GACA,GAAAgnB,GAAAhiG,KAAA2B,SAAAqgG,QAEA,IAAAc,UAAAtgG,GAGA,MAFAxC,MAAA2B,SAAAsgG,MAAAx/F,KAAAD,GAEAxC,IAGA,IAAAg7E,EAEAx4E,EADApB,GAAAoB,GAAAA,IACA+B,KAAAy2E,EAAAx4E,GAAAA,IAEA+B,KAAAy2E,EAAA/wD,IAAAznB,OAGA,IAAApB,GAAAoB,GAAAA,GAAA,CACA,IAAAA,EAAA+B,KACA,KAAA,8GAGA/B,IAAA+B,KAAA/B,EAAA+B,KAAA/B,GAAAA,GAMA,MAFAw/F,GAAAv/F,KAAAD,GAEAxC,MAGA22C,KAAA,SAAAzuC,GAGA,MAFAlI,MAAA2B,SAAAg1C,KAAAl0C,KAAAyF,GAEAlI,MAGAskC,IAAA,SAAA9hC,GAAAm0C,MACA,GAAA52C,MAAAC,KACA0B,GAAA1B,KAAA2B,QAGA,IAFAg1C,KAAAA,MAAAj1C,GAAAi1C,KAAAxpC,QAEAzL,GAAA6B,QACA,KAAA,yGAGA,IAAA7B,GAAAqhG,QACA,MAAArhG,IAAAuB,MAAAvB,GAAAuB,MAAAk/B,KAAA,WACA,MAAApiC,MAAAukC,IAAA9hC,GAAAm0C,OAIA,IAAAqsD,OAAA,MAAAnjG,SAAA6B,GAAAu0C,SACAgtD,SAAApjG,QAAA,mBAAAJ,UAAAiC,GAAAu0C,QAEAl2C,MAAA6Y,QAAA,MAEA,IAAAyiE,MAAA,GAAAh6E,SAAA,SAAAyD,QAAAC,QAEArD,GAAAqhG,SAAA,CAEA,IAAAG,yBAAAxhG,GAAAyhG,IAEAC,UAAAhiG,GAAAoF,OAAAhE,IAAAA,GAAAA,GAAA46C,WAGAimD,MAAA,KAAA3hG,GAAAsgG,SAAA7rF,IAAA,SAAA9V,GACA,MAAAiiG,aAAAjiG,KACAqa,OAAAhZ,GAAAugG,MAAA9rF,IAAA,SAAA5W,GACA,GAAAyjG,MAAA,CACA,GAAAM,GAAA,SAAAC,GACA,MAAAA,GAAAtrF,MAAA,UAAAsrF,EAAAtrF,MAAA,SACApY,OAAA2jG,SAAA3kF,OAAAhf,OAAA2jG,SAAAC,SAAAF,EACAA,EAAAtrF,MAAA,OACApY,OAAA2jG,SAAA3kF,OAAA,IAAA0kF,EAEAA,EAGA,OAAA,kBAAAD,EAAA/jG,GAAA,MACA,GAAA0jG,QACA,MAAA,qCAAA1jG,EAAA,6BAEA,MAAA,kBAAAA,EAAA,6DAEAmb,QACA,gBACA,cAAA0oF,UAAA,KAAAhB,KAAAC,UAAA1rD,MAAA,KACA,2CACA,YACAnsB,KAAA,KAMA,IAHA9oB,GAAAsgG,YACAtgG,GAAAugG,SAEAe,MAAA,CACA,GAAAU,QAAAC,KAGA,KAAAT,wBAAA,CACA,GAAAU,OAAAP,MAAA,EAEAA,QACA,wCACA,+CACA,0CACA,uBACA,mDACA,8EACA,gBACA,sBACA,QACA,QACA,KACA,oGACA,yDACA,wDACA74E,KAAA;AAEA64E,OAAAO,MAEAF,OAAA,GAAAG,OAAAR,QACAz+F,KAAA,2BAEA++F,MAAA9jG,OAAAikG,IAAAC,gBAAAL,QAGA,GAAAM,IAAAtiG,GAAAuiG,UAAAviG,GAAAuiG,WAAA,GAAAC,QAAAP,MAEAT,0BACAc,GAAAG,aACAC,OAAAf,OAKA,IAAA1pE,GACAqqE,IAAAnsC,iBAAA,UAAAl+B,GAAA,SAAAkS,GACA,GAAAw4D,GAAAjjG,GAAA0/E,OAAAj1C,IAAAzqC,GAAA0/E,OAAAj1C,EAAA3jC,KAEAm8F,IAAA,aAAAx4D,GAAA3jC,MACA87F,GAAA3pC,oBAAA,UAAA1gC,IAEA70B,QAAA+mC,EAAA3jC,KAAAo8F,YACAD,GAAA,YAAAx4D,GAAA3jC,MACA87F,GAAA3pC,oBAAA,UAAA1gC,IAEA50B,OAAA8mC,EAAA3jC,KAAAq8F,WAEAxkG,KAAA6Y,QAAA,GAAA+vB,OAAAkD,GAAAjnC,KAAA,UAAAsoC,QAAArB,EAAA3jC,UAEA,GAEAg7F,yBACAc,GAAAG,YAAA,eAGA,IAAAlB,QAAA,CAGAvhG,GAAA4qF,QACA5qF,GAAA4qF,MAAAprF,QAAA,iBAAAsjG,KAAAtjG,QAAA,QAAAspB,KAAAi6E,UAAA,qBAGA,IAAAnY,OAAA5qF,GAAA4qF,MAGA3yD,EACA2yD,OAAAtmE,GAAA,UAAA2T,GAAA,SAAAkS,GACAzqC,GAAA0/E,OAAAj1C,IAAA,aAAAA,IACAygD,MAAAtiD,eAAA,UAAArQ,IAEA70B,QAAA+mC,EAAAy4D,YACAljG,GAAA0/E,OAAAj1C,IAAA,YAAAA,IACAygD,MAAAtiD,eAAA,UAAArQ,IAEA50B,OAAA8mC,EAAA04D,WAEAxkG,KAAA6Y,QAAA,GAAA+vB,WAAA/jC,KAAA,UAAAsoC,QAAArB,OAKAygD,MAAAoY,MACAN,OAAAf,YAGA,CAEA,GAAAsB,gBAAA7/F,QACA8/F,cAAA7/F,OAEA8/F,MAAAnjG,GAAAmjG,MAAAnjG,GAAAmjG,QAEAv/E,aAEAmoE,KAAA,WAEA4V,OACA,wCACA,+CACA,0FACA,sDACA,6CACA,4CACA74E,KAAA,MAAA64E,MAGAyB,KAAAzB,QAGAn2D,QAAA,SAAArB,GAGA,IAAA,GAFAk5D,GAAAF,MAAAv/E,UAEA3kB,EAAA,EAAAA,EAAAokG,EAAA/jG,OAAAL,IAAA,CACA,GAAA6B,GAAAuiG,EAAApkG,EAEA6B,GAAAqpC,KAMAg5D,OAAApX,UAGAtrD,KAAA,SAAA/2B,GAMA,MALA1J,IAAAqhG,SAAA,EACArhG,GAAAyhG,KAAA,EAEApjG,KAAA6Y,QAAA,OAEAxN,GAOA,OAJA,OAAA1J,GAAAuB,QACAvB,GAAAuB,MAAAo4E,MAGAA,MAIAnuC,QAAA,SAAArB,GACA,GAAAnqC,GAAA1B,KAAA2B,QAcA,OAZAD,GAAAuiG,WACAviG,EAAAuiG,UAAAE,YAAAt4D,GAGAnqC,EAAA4qF,OACA5qF,EAAA4qF,MAAAoY,KAAA74D,GAGAnqC,EAAAmjG,OACAnjG,EAAAmjG,MAAA33D,QAAArB,GAGA7rC,MAGA0D,KAAA,WACA,GAAAhC,GAAA1B,KAAA2B,QAgBA,OAdAD,GAAAuiG,WACAviG,EAAAuiG,UAAAtnB,YAGAj7E,EAAA4qF,OACA5qF,EAAA4qF,MAAA0Y,OAGAtjG,EAAAmjG,MAIAnjG,EAAA6B,SAAA,EAEAvD,KAAA4Y,QAAA,SAGArV,QAAA,WACA,MAAAvD,MAAA2B,SAAA4B,UAMA,IAAAi/F,MAAA,SAAAhgG,EAAA+B,GACA,GAAA8+F,GAAA7gG,EAAA46C,UAGA,OAFAimD,GAAAA,EAAArkB,QAAA,yBAAA,YAAAz6E,EAAA,MAKA0gG,WAAA,SAAAzjG,GAGA,MAFAA,GAAAA,MAEA,SAAAgB,EAAA85E,GACA,GAAA+mB,GAAAb,KAAAhgG,EAAA,QAAAhB,EAAA+C,KAIA,OAFAvE,MAAAU,QAAA2iG,GAEArjG,KAAAskC,KACA,oBACA,+BACA,kBACA,KACA,+BACA,uBACA,OACA,KACA,oBAAA9iC,EAAA+C,KAAA,UAAA/C,EAAA+C,MAAAuI,UAAA9L,OAAA,EAAA,KAAAohG,KAAAC,UAAA/lB,GAAA,IAAA,MACA,KACA,2BACA,2CACA,KACA9xD,KAAA,QAIArpB,MAAAS,OAAAsgG,OACAzlB,OAAAwoB,YAAA1gG,KAAA,WAEAm4E,YAAAuoB,YAAA1gG,KAAA,gBAEA4R,IAAA8uF,YAAA1gG,KAAA,S3F4utBA,IAAI/B,IAAK0/F,K4FzsuBT1/F,IAAAmC,QAAAnC,GAAA8hC,IACA9hC,GAAAm6E,UAAAn6E,GAAAo6E,KAAAp6E,GAAAkB,KACAlB,GAAA6lB,QAAA7lB,GAAA9B,QAGAS,KAAAS,OAAAsgG,OACAl8E,GAAAtmB,OAAAsmB,KACAC,IAAAvmB,OAAAsmB,IAAAE,qBAAA,IACAG,IAAA3mB,OAAA2mB,MACAzN,QAAAlZ,OAAAkZ,YAGAlZ,OAAA8mB,eAAA07E,OAEAziG,OAAAD,QAAA01C,SAEA/F,WAAA,GAAAxC,UAAA,GAAA3nC,OAAA,GAAAC,YAAA,GAAAC,SAAA,GAAAi7E,WAAA,IAAA+kB,cAAAphG,OAAA8D,KAAA9D,SAAAqhG,IAAA,SAAAjkG,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,QAEAzB,GAAAD,SAEA4lG,UAAA,SAAAC,GACA,IAAA,IAAAA,EAAArkG,QAAA,IAAAqkG,EAAArkG,SAAA,MAAAqkG,EAAA,GAAA,CAEA,GACAhlG,GAAAT,EAAAwE,EADAkhG,EAAA,IAAAD,EAAArkG,OAEAukG,EAAA,EAYA,OAVAD,IACAjlG,EAAAmlG,SAAAH,EAAA,GAAAA,EAAA,GAAAE,GACA3lG,EAAA4lG,SAAAH,EAAA,GAAAA,EAAA,GAAAE,GACAnhG,EAAAohG,SAAAH,EAAA,GAAAA,EAAA,GAAAE,KAEAllG,EAAAmlG,SAAAH,EAAA,GAAAA,EAAA,GAAAE,GACA3lG,EAAA4lG,SAAAH,EAAA,GAAAA,EAAA,GAAAE,GACAnhG,EAAAohG,SAAAH,EAAA,GAAAA,EAAA,GAAAE,KAGAllG,EAAAT,EAAAwE,KAIAqhG,UAAA,SAAAC,GAGA,QAAAC,GAAA5hG,EAAAjB,EAAA3C,GAGA,MAFA,GAAAA,IAAAA,GAAA,GACAA,EAAA,IAAAA,GAAA,GACA,EAAA,EAAAA,EAAA4D,EAAA,GAAAjB,EAAAiB,GAAA5D,EACA,GAAAA,EAAA2C,EACA,EAAA,EAAA3C,EAAA4D,GAAAjB,EAAAiB,IAAA,EAAA,EAAA5D,GAAA,EACA4D,EARA,GAAA8H,GACAwT,EAAA/e,EAAAQ,EAAAL,EAAAJ,EAAAT,EAAAwE,EAUAynC,EAAA,GAAAmhD,QAAA,IAAAhtF,KAAAkpC,MAAA8wD,KAAA,KAAAvM,KAAAiY,EACA,IAAA75D,EAAA,CAYA,GATAxsB,EAAAmmF,SAAA35D,EAAA,IACA,EAAAxsB,EACAA,GAAA,IAAA,IAAAA,EAAA,KAAA,IACAA,EAAA,MACAA,GAAA,KAEAA,GAAA,IAEA/e,EAAAu9B,WAAAgO,EAAA,IACA,EAAAvrC,GAAAA,EAAA,IAAA,MAIA,IAHAA,GAAA,IAEAQ,EAAA+8B,WAAAgO,EAAA,IACA,EAAA/qC,GAAAA,EAAA,IAAA,MAIA,IAHAA,GAAA,IAEAL,EAAAorC,EAAA,GACA/nC,SAAArD,IACAA,EAAAo9B,WAAAp9B,GAEA,EAAAA,GAAAA,EAAA,GAAA,MAKA,IAAA,IAAAH,EACAD,EAAAT,EAAAwE,EAAAqL,KAAA6sB,MAAA,IAAAx7B,OACA,CACA,GAAAgC,GAAA,GAAAhC,EAAAA,GAAA,EAAAR,GAAAQ,EAAAR,EAAAQ,EAAAR,EACAyD,EAAA,EAAAjD,EAAAgC,CACAzC,GAAAoP,KAAA6sB,MAAA,IAAAqpE,EAAA5hG,EAAAjB,EAAAuc,EAAA,EAAA,IACAzf,EAAA6P,KAAA6sB,MAAA,IAAAqpE,EAAA5hG,EAAAjB,EAAAuc,IACAjb,EAAAqL,KAAA6sB,MAAA,IAAAqpE,EAAA5hG,EAAAjB,EAAAuc,EAAA,EAAA,IAGAxT,GAAAxL,EAAAT,EAAAwE,EAAA3D,GAGA,MAAAoL,IAIA+5F,UAAA,SAAAC,GACA,GAAAh6F,GAEAggC,EAAA,GAAAmhD,QAAA,IAAAhtF,KAAAkpC,MAAA4wD,KAAA,KAAArM,KAAAoY,EACA,IAAAh6D,EAAA,CACAhgC,IAGA,KAAA,GADAi6F,MACAnlG,EAAA,EAAA,GAAAA,EAAAA,IAAA,CACA,GAAAolG,GAAAl6D,EAAAlrC,EAWA,IATA,MAAAolG,EAAAA,EAAA/kG,OAAA,KACA8kG,EAAAnlG,IAAA,GAEAolG,EAAAloE,WAAAkoE,GAEAD,EAAAnlG,KACAolG,EAAAA,EAAA,IAAA,KAGA,EAAAA,GAAAA,EAAA,IAAA,MAEAl6F,GAAApJ,KAAAgN,KAAAuF,MAAA+wF,IAGA,GAAAC,GAAAF,EAAA,IAAAA,EAAA,IAAAA,EAAA,GACAG,EAAAH,EAAA,IAAAA,EAAA,IAAAA,EAAA,EACA,IAAAE,IAAAC,EAAA,MAEA,IAAAp0F,GAAAg6B,EAAA,EACA,IAAA/nC,SAAA+N,EAAA,CAGA,GAFAA,EAAAgsB,WAAAhsB,GAEA,EAAAA,GAAAA,EAAA,EAAA,MAEAhG,GAAApJ,KAAAoP,IAIA,MAAAhG,IAGAq6F,gBAAA,SAAAn7B,GACA,MAAA/qE,MAAAmmG,OAAAp7B,EAAAhhB,gBAGA2vC,YAAA,SAAA3uB,GACA,OAAA3pE,EAAAitB,MAAA08C,GAAAA,EAAA,OACA/qE,KAAAkmG,gBAAAn7B,IACA/qE,KAAAolG,UAAAr6B,IACA/qE,KAAA4lG,UAAA76B,IACA/qE,KAAAylG,UAAA16B,IAGAo7B,QAEAt0E,aAAA,EAAA,EAAA,EAAA,GAGAu0E,WAAA,IAAA,IAAA,KACAC,cAAA,IAAA,IAAA,KACAC,MAAA,EAAA,IAAA,KACAC,YAAA,IAAA,IAAA,KACAC,OAAA,IAAA,IAAA,KACAC,OAAA,IAAA,IAAA,KACAC,QAAA,IAAA,IAAA,KACAC,OAAA,EAAA,EAAA,GACAC,gBAAA,IAAA,IAAA,KACAC,MAAA,EAAA,EAAA,KACAC,YAAA,IAAA,GAAA,KACAC,OAAA,IAAA,GAAA,IACAC,WAAA,IAAA,IAAA,KACAC,WAAA,GAAA,IAAA,KACAC,YAAA,IAAA,IAAA,GACAC,WAAA,IAAA,IAAA,IACAC,OAAA,IAAA,IAAA,IACAC,gBAAA,IAAA,IAAA,KACAC,UAAA,IAAA,IAAA,KACAC,SAAA,IAAA,GAAA,IACAC,MAAA,EAAA,IAAA,KACAC,UAAA,EAAA,EAAA,KACAC,UAAA,EAAA,IAAA,KACAC,eAAA,IAAA,IAAA,IACAC,UAAA,IAAA,IAAA,KACAC,WAAA,EAAA,IAAA,GACAC,UAAA,IAAA,IAAA,KACAC,WAAA,IAAA,IAAA,KACAC,aAAA,IAAA,EAAA,KACAC,gBAAA,GAAA,IAAA,IACAC,YAAA,IAAA,IAAA,GACAC,YAAA,IAAA,GAAA,KACAC,SAAA,IAAA,EAAA,GACAC,YAAA,IAAA,IAAA,KACAC,cAAA,IAAA,IAAA,KACAC,eAAA,GAAA,GAAA,KACAC,eAAA,GAAA,GAAA,IACAC,eAAA,GAAA,GAAA,IACAC,eAAA,EAAA,IAAA,KACAC,YAAA,IAAA,EAAA,KACAC,UAAA,IAAA,GAAA,KACAC,aAAA,EAAA,IAAA,KACAC,SAAA,IAAA,IAAA,KACAC,SAAA,IAAA,IAAA,KACAC,YAAA,GAAA,IAAA,KACAC,WAAA,IAAA,GAAA,IACAC,aAAA,IAAA,IAAA,KACAC,aAAA,GAAA,IAAA,IACAC,SAAA,IAAA,EAAA,KACAC,WAAA,IAAA,IAAA,KACAC,YAAA,IAAA,IAAA,KACAC,MAAA,IAAA,IAAA,GACAC,WAAA,IAAA,IAAA,IACAC,MAAA,IAAA,IAAA,KACAC,MAAA,IAAA,IAAA,KACAC,OAAA,EAAA,IAAA,GACAC,aAAA,IAAA,IAAA,IACAC,UAAA,IAAA,IAAA,KACAC,SAAA,IAAA,IAAA,KACAC,WAAA,IAAA,GAAA,IACAC,QAAA,GAAA,EAAA,KACAC,OAAA,IAAA,IAAA,KACAC,OAAA,IAAA,IAAA,KACAC,UAAA,IAAA,IAAA,KACAC,eAAA,IAAA,IAAA,KACAC,WAAA,IAAA,IAAA,GACAC,cAAA,IAAA,IAAA,KACAC,WAAA,IAAA,IAAA,KACAC,YAAA,IAAA,IAAA,KACAC,WAAA,IAAA,IAAA,KACAC,sBAAA,IAAA,IAAA,KACAC,WAAA,IAAA,IAAA,KACAC,YAAA,IAAA,IAAA,KACAC,WAAA,IAAA,IAAA,KACAC,WAAA,IAAA,IAAA,KACAC,aAAA,IAAA,IAAA,KACAC,eAAA,GAAA,IAAA,KACAC,cAAA,IAAA,IAAA,KACAC,gBAAA,IAAA,IAAA,KACAC,gBAAA,IAAA,IAAA,KACAC,gBAAA,IAAA,IAAA,KACAC,aAAA,IAAA,IAAA,KACAC,MAAA,EAAA,IAAA,GACAC,WAAA,GAAA,IAAA,IACAC,OAAA,IAAA,IAAA,KACAC,SAAA,IAAA,EAAA,KACAC,QAAA,IAAA,EAAA,GACAC,kBAAA,IAAA,IAAA,KACAC,YAAA,EAAA,EAAA,KACAC,cAAA,IAAA,GAAA,KACAC,cAAA,IAAA,IAAA,KACAC,gBAAA,GAAA,IAAA,KACAC,iBAAA,IAAA,IAAA,KACAC,mBAAA,EAAA,IAAA,KACAC,iBAAA,GAAA,IAAA,KACAC,iBAAA,IAAA,GAAA,KACAC,cAAA,GAAA,GAAA,KACAC,WAAA,IAAA,IAAA,KACAC,WAAA,IAAA,IAAA,KACAC,UAAA,IAAA,IAAA,KACAC,aAAA,IAAA,IAAA,KACAC,MAAA,EAAA,EAAA,KACAC,SAAA,IAAA,IAAA,KACAC,OAAA,IAAA,IAAA,GACAC,WAAA,IAAA,IAAA,IACAC,QAAA,IAAA,IAAA,GACAC,WAAA,IAAA,GAAA,GACAC,QAAA,IAAA,IAAA,KACAC,eAAA,IAAA,IAAA,KACAC,WAAA,IAAA,IAAA,KACAC,eAAA,IAAA,IAAA,KACAC,eAAA,IAAA,IAAA,KACAC,YAAA,IAAA,IAAA,KACAC,WAAA,IAAA,IAAA,KACAC,MAAA,IAAA,IAAA,IACAC,MAAA,IAAA,IAAA,KACAC,MAAA,IAAA,IAAA,KACAC,YAAA,IAAA,IAAA,KACAC,QAAA,IAAA,EAAA,KACAC,KAAA,IAAA,EAAA,GACAC,WAAA,IAAA,IAAA,KACAC,WAAA,GAAA,IAAA,KACAC,aAAA,IAAA,GAAA,IACAC,QAAA,IAAA,IAAA,KACAC,YAAA,IAAA,IAAA,IACAC,UAAA,GAAA,IAAA,IACAC,UAAA,IAAA,IAAA,KACAC,QAAA,IAAA,GAAA,IACAC,QAAA,IAAA,IAAA,KACAC,SAAA,IAAA,IAAA,KACAC,WAAA,IAAA,GAAA,KACAC,WAAA,IAAA,IAAA,KACAC,WAAA,IAAA,IAAA,K5F2suBIC,MAAO,IAAK,IAAK,K6Fh/uBrBC,aAAA,EAAA,IAAA,KACAC,WAAA,GAAA,IAAA,KACAC,KAAA,IAAA,IAAA,KACAC,MAAA,EAAA,IAAA,KACAC,SAAA,IAAA,IAAA,KACAC,QAAA,IAAA,GAAA,IACAC,WAAA,GAAA,IAAA,KACAC,QAAA,IAAA,IAAA,KACAC,OAAA,IAAA,IAAA,KACAC,OAAA,IAAA,IAAA,KACAC,YAAA,IAAA,IAAA,KACAC,QAAA,IAAA,IAAA,GACAC,aAAA,IAAA,IAAA,QAIAtqF,QAAA,KAAAuqF,IAAA,SAAAruG,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,SACAsuC,EAAAtuC,EAAA,WAEAC,GAEA2gD,QAAA,WAAA,OAAA,GAEAE,QAAA,WAAA,MAAA,IAEAD,KAAA,aAGA34C,MAAA,SAAAomG,GACAryD,QAAA/zC,OACA+zC,QAAA/zC,MAAA5F,MAAA25C,QAAArwC,WAEAqwC,QAAAsyD,OAAAtyD,QAAAsyD,UAEAtyD,QAAA9nC,IAAA7R,MAAA25C,QAAArwC,WAEAqwC,QAAAsyD,OAAAtyD,QAAAsyD,UAKA/kF,MAAA,SAAAT,GACA,MAAAjqB,MAAA4B,UAAAqoB,IAIAvR,KAAA,SAAAuR,GACA,MAAA,OAAAA,EACAA,EACA7oB,EAAAitB,MAAApE,GACAA,EAAArV,QACAxT,EAAAwL,YAAAqd,GACAjqB,KAAA0qB,MAAAT,GAEAA,GAMA9oB,GAAA2uC,gBAAAN,EAAAM,gBAAAnd,KAAA6c,GAEAruC,EAAAuuG,sBAEAvuG,EAAAmf,kBAAA,WACA,MAAAnf,GAAAuuG,oBAGAvuG,EAAAS,OAAA,MAAAgsC,OAAA+hE,OAAA/hE,OAAA+hE,OAAA,SAAAxkF,GAGA,IAAA,GAFAqH,GAAA1lB,UAEAnM,EAAA,EAAAA,EAAA6xB,EAAAxxB,OAAAL,IAAA,CACA,GAAAspB,GAAAuI,EAAA7xB,EAEA,KAAA,GAAA6R,KAAAyX,GACAkB,EAAA3Y,GAAAyX,EAAAzX,GC9EA,MAAA2Y,KAIAjqB,EAAA,YACAA,EAAA,WACA0uG,QAAA1uG,EAAA,cACAA,EAAA,WACAA,EAAA,aACAA,EAAA,aACAoK,QAAA,SAAAi3F,GACAphG,EAAAS,OAAAT,EAAAohG,KAGA9iG,EAAAD,QAAA2B,IAEA6jB,QAAA,GAAA6qF,UAAA,GAAAC,WAAA,GAAAC,SAAA,GAAAC,YAAA,GAAAC,UAAA,GAAAC,YAAA,GAAAC,WAAA,KAAAC,IAAA,SAAAlvG,EAAAzB,EAAAD,GACA,YAEA,IAAA4B,GAAAF,EAAA,QAEAzB,GAAAD,SAEA6wG,SAAA,SAAAl6F,GACA,GAAAoE,IAAA,CAEA,IAAA,MAAApE,EACA,IAAA,GAAAxV,KAAAwV,GAAA,CACAoE,GAAA,CACA,OAIA,MAAAA,IAIA+1F,QAAA,SAAAhrG,GACA,GAAA+oB,GAAAruB,KAAAyuC,OAAAnpC,EAEA,OAAA+oB,EACAruB,KAAAuuC,OAAAvuC,KAAA4B,UAAA0D,GACAka,OAAAla,EAAAka,UAGA6O,EAAA5rB,KAAA6C,EAAAka,QAKA+uB,OAAA,SAAAjpC,GAMA,IAAA,GAJAsG,GADAqe,EAAA3kB,EAAA6Q,IAEA0yB,EAAAvjC,EAAAujC,KACA/nC,EAAA+nC,EAAA7nC,OAEAL,EAAA,EAAAG,EAAAH,EAAAA,IAAA,CACA,GAAAiL,GAAAi9B,EAAAloC,EAEAS,GAAAwL,YAAAhB,IACA5L,KAAAoJ,MAAA,oCAGAzI,EAAAkoC,EAAA7nC,OAAA,GAGA,MAAAipB,EAAAre,KACAqe,EAAAre,OAGAqe,EAAAA,EAAAre,IAGAqe,EAAAre,GAAAtG,EAAAka,QAMAivB,OAAA,SAAAnpC,GAKA,IAAA,GAJA2kB,GAAA3kB,EAAA6Q,IACA0yB,EAAAvjC,EAAAujC,KACA/nC,EAAA+nC,EAAA7nC,OAEAL,EAAA,EAAAG,EAAAH,EAAAA,IAAA,CACA,GAAAiL,GAAAi9B,EAAAloC,EAQA,IANAS,EAAAwL,YAAAhB,IACA5L,KAAAoJ,MAAA,oCAGA6gB,EAAAA,EAAAre,GAEA,MAAAqe,EACA,MAAAA,GAIA,MAAAA,IAIAsmF,UAAA,SAAAjrG,GAMA,IAAA,GALA2kB,GAAA3kB,EAAA6Q,IACA0yB,EAAAvjC,EAAAujC,KACA/nC,EAAA+nC,EAAA7nC,OACAwvG,EAAAlrG,EAAAkrG,aAEA7vG,EAAA,EAAAG,EAAAH,EAAAA,IAAA,CACA,GAAAiL,GAAAi9B,EAAAloC,EAEAS,GAAAwL,YAAAhB,IACA5L,KAAAoJ,MAAA,sCAGA,IAAAqnG,GAAA9vG,IAAA2E,EAAAujC,KAAA7nC,OAAA,CACA,IAAAyvG,E9FqkvBQ,GAAID,E+FzrvBZ,IAAA,GAAAlkB,KAAAriE,GACAumF,EAAAlkB,KACAriE,EAAAqiE,GAAAxoF,YAIAmmB,GAAAre,GAAA9H,WAIAmmB,GAAAA,EAAAre,QAMAoZ,QAAA,KAAA0rF,IAAA,SAAAxvG,EAAAzB,EAAAD,GACA,YAEAC,GAAAD,QAAA,SAAAgD,EAAAmuG,GACA,GAAA5wG,GAAAC,KACAorD,IClBA,ODoBAulD,KACAA,EAAA,WACA,GAAA,IAAA7jG,UAAA9L,OACA,MAAA8L,WAAA,EAKA,KAAA,GAFA0lB,MAEA7xB,EAAA,EAAAA,EAAAmM,UAAA9L,OAAAL,IACA6xB,EAAA/vB,KAAAqK,UAAAnM,G/F6rvBM,OAAO6xB,GAAKhI,KAAK,OgG1tvBvB,WACA,GACA3e,GADA2mB,EAAA1lB,UAEA0F,EAAAm+F,EAAAntG,MAAAzD,EAAAyyB,EAMA,QAJA3mB,EAAAu/C,EAAA54C,MACA3G,EAAAu/C,EAAA54C,GAAAhQ,EAAAgB,MAAAzD,EAAAyyB,IAGA3mB,SAIA+kG,IAAA,SAAA1vG,EAAAzB,EAAAD,GACA,YAEA,IAAAsS,GAAA,sDAEAgoF,EAAA,cAAAhoF,EAAA,kBAAAA,EAAA,kBAAAA,EAAA,qBAAAA,EAAA,SACAioF,EAAA,gBAAAjoF,EAAA,oBAAAA,EAAA,oBAAAA,EAAA,uBAAAA,EAAA,SAEAkoF,EAAA,cAAAloF,EAAA,cAAAA,EAAA,iBAAAA,EAAA,oBAAAA,EAAA,ShG+tvBImoF,EAAiB,gBAAiBnoF,EAAQ,gBAAiBA,EAAQ,mBAAoBA,EAAQ,sBAAuBA,EAAQ,SiGtvvBlIooF,EAAA,oBACAC,EAAA,mBAEA16F,GAAAD,SACA0pC,OACAp3B,OAAAA,EACAgoF,KAAAA,EACAC,eAAAA,EACAC,KAAAA,EACAC,eAAAA,EACAC,KAAAA,EACAC,KAAAA,SAIA0W,IAAA,SAAA3vG,EAAAzB,EAAAD,GACA,YAEA,IAAAowG,GAAA1uG,EAAA,aACAE,EAAAF,EAAA,QAEAzB,GAAAD,SAEAw2F,WAAA4Z,EAAA,SAAA7iB,GACA,MAAAA,GAAA/N,QAAA,WAAA,SAAA5zE,GACA,MAAA,IAAAA,EAAA2+C,kBC1BArlD,WAAAkrG,EAAA,SAAA7iB,GACA,MAAAA,GAAA/N,QAAA,SAAA,SAAA5zE,GACA,MAAAA,GAAA,GAAA0+C,kBAIA9lC,WAAA,SAAA+oE,GACA,MAAA3rF,GAAA0pB,YAAAiiE,GACAA,EAGAA,EAAA+jB,OAAA,GAAAhnD,cAAAijC,EAAAW,UAAA,OAKA1oE,QAAA,GAAAgrF,YAAA,KAAAe,IAAA,SAAA7vG,EAAAzB,EAAAD,GACA,YAEA,IAAAK,GAAAqB,EAAA,aACAE,EAAAF,EAAA,SACA8vG,EAAAnxG,EAAAA,EAAAmxG,YAAA,KAEA7vG,KAEA8vG,EAAApxG,EAAAA,EAAAu5B,uBAAAv5B,EAAAqxG,0BACArxG,EAAAsxG,6BAAAtxG,EAAAuxG,wBADA,IAGAH,GAAAA,GAAA,SAAAzuG,GACAA,GACA+W,WAAA,WACA/W,EAAA6uG,MACA,IAAA,KAIAlwG,EAAAi4B,sBAAA,SAAA52B,GACAyuG,EAAAzuG,GAGA,IAAA6uG,GAAAL,GAAAA,EAAA33E,IAAA,WAAA,MAAA23E,GAAA33E,OAAA,WAAA,MAAA+T,MAAA/T,MAEAl4B,GAAAumE,eAAA2pC,EAGAlwG,EAAAmwG,SAAA,SAAApmB,EAAAqmB,EAAAjsG,GACA,GAAAksG,IAAA,EACAC,GAAA,CAaA,OAXAnsG,MAAA,EACAksG,GAAA,EACApwG,EAAAwL,YAAAtH,KACAksG,EAAA,WAAAlsG,GAAAA,EAAAksG,QAAAA,EACAC,EAAA,YAAAnsG,GAAAA,EAAAmsG,SAAAA,GAEAnsG,EAAAA,MACAA,EAAAksG,QAAAA,EACAlsG,EAAAosG,QAAAH,EACAjsG,EAAAmsG,SAAAA,EAEAtwG,EAAA47D,SAAAmuB,EAAAqmB,EAAAjsG,IAGAnE,EAAAk4B,IAAA,WACA,MAAA+T,MAAA/T,OAGAl4B,EAAA47D,SAAA,SAAAmuB,EAAAqmB,EAAAjsG,GACA,GACAktB,GACAm/E,EACAz0D,EACA00D,EACAjlG,EACAklG,EACAC,EAPA3wG,EAAAnB,KAQA+xG,EAAA,EACAL,GAAA,EACAD,GAAA,CAEA,IAAArwG,EAAAoB,GAAA0oF,GAAA,CAIA,GADAqmB,EAAA9hG,KAAA9D,IAAA,EAAA4lG,IAAA,EACAjsG,KAAA,EAAA,CACA,GAAAksG,IAAA,CACAC,IAAA,MACArwG,GAAAwL,YAAAtH,KACAksG,EAAAlsG,EAAAksG,QACAE,EAAA,WAAApsG,KAAAmK,KAAA9D,IAAA4lG,EAAAjsG,EAAAosG,UAAA,GACAD,EAAA,YAAAnsG,GAAAA,EAAAmsG,SAAAA,EAEA,IAAAO,GAAA,WACA,GAAAjkB,GAAAwjB,GAAApwG,EAAAk4B,MAAAu4E,EACA,IAAA,GAAA7jB,EAAA,CACA4jB,GACAn0C,aAAAm0C,EAEA,IAAAM,GAAAH,CACAH,GAAAE,EAAAC,EAAAhuG,OACAmuG,IACAF,EAAA5wG,EAAAk4B,MACA6jB,EAAAguC,EAAA1nF,MAAAmJ,EAAA6lB,GACAq/E,GAAAF,IACAn/E,EAAA7lB,EAAA,WAIAklG,GAAAt4F,WAAAy4F,EAAAjkB,IAIAmkB,EAAA,WACAL,GACAr0C,aAAAq0C,GAEAF,EAAAE,EAAAC,EAAAhuG,QACA2tG,GAAAC,IAAAH,KACAQ,EAAA5wG,EAAAk4B,MACA6jB,EAAAguC,EAAA1nF,MAAAmJ,EAAA6lB,GACAq/E,GAAAF,IACAn/E,EAAA7lB,EAAA,OAKA,OAAA,YAMA,GALA6lB,EAAA1lB,UACA8kG,EAAAzwG,EAAAk4B,MACA1sB,EAAA3M,KACA8xG,EAAAL,IAAAI,IAAAL,GAEAE,KAAA,EACA,GAAAS,GAAAX,IAAAK,MACA,CACAF,GAAAH,IACAO,EAAAH,EAEA,IAAA7jB,GAAA2jB,GAAAE,EAAAG,GACAE,EAAA,GAAAlkB,CAEAkkB,IACAN,IACAA,EAAAn0C,aAAAm0C,IAEAI,EAAAH,EACA10D,EAAAguC,EAAA1nF,MAAAmJ,EAAA6lB,IAEAm/E,IACAA,EAAAp4F,WAAA24F,EAAAnkB,IlGsyvBI,MkGnyvBJkkB,IAAAJ,EACAA,EAAAr0C,aAAAq0C,GCzJAA,GAAAN,IAAAG,IACAG,EAAAt4F,WAAAy4F,EAAAT,InGm7vBQY,IACFF,GAAW,EACX/0D,EAASguC,EAAK1nF,MAAMmJ,EAAS6lB,KAE3By/E,GAAaJ,GAAcF,IAC7Bn/E,EAAO7lB,EAAU,MAEZuwC,KAIXz9C,EAAOD,QAAU2B,IAEd6jB,QAAQ,GAAG6T,YAAY,MAAMu5E,KAAK,SAASlxG,EAAQzB,EAAOD,GAC7DC,EAAOD,QAA8B,mBAAXK,QAAyB,KAAOA,iBAE/C,KAAK","file":"cytoscape.min.js","sourcesContent":["'use strict';\n\nvar util = require('./util');\nvar is = require('./is');\nvar Promise = require('./promise');\n\nvar Animation = function( target, opts, opts2 ){\n if( !(this instanceof Animation) ){\n return new Animation( target, opts, opts2 );\n }\n\n var _p = this._private = util.extend( {\n duration: 1000\n }, opts, opts2 );\n\n _p.target = target;\n _p.style = _p.style || _p.css;\n _p.started = false;\n _p.playing = false;\n _p.hooked = false;\n _p.applying = false;\n _p.progress = 0;\n _p.completes = [];\n _p.frames = [];\n\n if( _p.complete && is.fn(_p.complete) ){\n _p.completes.push( _p.complete );\n }\n\n // for future timeline/animations impl\n this.length = 1;\n this[0] = this;\n};\n\nvar anifn = Animation.prototype;\n\nutil.extend( anifn, {\n\n instanceString: function(){ return 'animation'; },\n\n hook: function(){\n var _p = this._private;\n\n if( !_p.hooked ){\n // add to target's animation queue\n var q;\n var tAni = _p.target._private.animation;\n if( _p.queue ){\n q = tAni.queue;\n } else {\n q = tAni.current;\n }\n q.push( this );\n\n // add to the animation loop pool\n if( is.elementOrCollection( _p.target ) ){\n _p.target.cy().addToAnimationPool( _p.target );\n }\n\n _p.hooked = true;\n }\n\n return this;\n },\n\n play: function(){\n var _p = this._private;\n\n // autorewind\n if( _p.progress === 1 ){\n _p.progress = 0;\n }\n\n _p.playing = true;\n _p.started = false; // needs to be started by animation loop\n _p.stopped = false;\n\n this.hook();\n\n // the animation loop will start the animation...\n\n return this;\n },\n\n playing: function(){\n return this._private.playing;\n },\n\n apply: function(){\n var _p = this._private;\n\n _p.applying = true;\n _p.started = false; // needs to be started by animation loop\n _p.stopped = false;\n\n this.hook();\n\n // the animation loop will apply the animation at this progress\n\n return this;\n },\n\n applying: function(){\n return this._private.applying;\n },\n\n pause: function(){\n var _p = this._private;\n\n _p.playing = false;\n _p.started = false;\n\n return this;\n },\n\n stop: function(){\n var _p = this._private;\n\n _p.playing = false;\n _p.started = false;\n _p.stopped = true; // to be removed from animation queues\n\n return this;\n },\n\n rewind: function(){\n return this.progress(0);\n },\n\n fastforward: function(){\n return this.progress(1);\n },\n\n time: function( t ){\n var _p = this._private;\n\n if( t === undefined ){\n return _p.progress * _p.duration;\n } else {\n return this.progress( t / _p.duration );\n }\n },\n\n progress: function( p ){\n var _p = this._private;\n var wasPlaying = _p.playing;\n\n if( p === undefined ){\n return _p.progress;\n } else {\n if( wasPlaying ){\n this.pause();\n }\n\n _p.progress = p;\n _p.started = false;\n\n if( wasPlaying ){\n this.play();\n }\n }\n\n return this;\n },\n\n completed: function(){\n return this._private.progress === 1;\n },\n\n reverse: function(){\n var _p = this._private;\n var wasPlaying = _p.playing;\n\n if( wasPlaying ){\n this.pause();\n }\n\n _p.progress = 1 - _p.progress;\n _p.started = false;\n\n var swap = function( a, b ){\n var _pa = _p[a];\n\n _p[a] = _p[b];\n _p[b] = _pa;\n };\n\n swap( 'zoom', 'startZoom' );\n swap( 'pan', 'startPan' );\n swap( 'position', 'startPosition' );\n\n // swap styles\n for( var i = 0; i < _p.style.length; i++ ){\n var prop = _p.style[i];\n var name = prop.name;\n var startStyleProp = _p.startStyle[ name ];\n\n _p.startStyle[ name ] = _p.startStyle[ util.dash2camel( name ) ] = prop;\n _p.style[i] = startStyleProp;\n }\n\n if( wasPlaying ){\n this.play();\n }\n\n return this;\n },\n\n promise: function( type ){\n var _p = this._private;\n\n var arr;\n\n switch( type ){\n case 'frame':\n arr = _p.frames;\n break;\n default:\n case 'complete':\n case 'completed':\n arr = _p.completes;\n }\n\n return new Promise(function( resolve, reject ){\n arr.push(function(){\n resolve();\n });\n });\n }\n\n} );\n\nanifn.complete = anifn.completed;\n\nmodule.exports = Animation;\n",null,"'use strict';\n\nvar is = require('../../is');\n\nvar elesfn = ({\n\n // Implemented from pseudocode from wikipedia\n aStar: function(options) {\n var eles = this;\n\n options = options || {};\n\n // Reconstructs the path from Start to End, acumulating the result in pathAcum\n var reconstructPath = function(start, end, cameFromMap, pathAcum) {\n // Base case\n if (start == end) {\n pathAcum.push( cy.getElementById(end) );\n return pathAcum;\n }\n\n if (end in cameFromMap) {\n // We know which node is before the last one\n var previous = cameFromMap[end];\n var previousEdge = cameFromEdge[end];\n\n pathAcum.push( cy.getElementById(end) );\n pathAcum.push( cy.getElementById(previousEdge) );\n\n\n return reconstructPath(start,\n previous,\n cameFromMap,\n pathAcum);\n }\n\n // We should not reach here!\n return undefined;\n };\n\n // Returns the index of the element in openSet which has minimum fScore\n var findMin = function(openSet, fScore) {\n if (openSet.length === 0) {\n // Should never be the case\n return undefined;\n }\n var minPos = 0;\n var tempScore = fScore[openSet[0]];\n for (var i = 1; i < openSet.length; i++) {\n var s = fScore[openSet[i]];\n if (s < tempScore) {\n tempScore = s;\n minPos = i;\n }\n }\n return minPos;\n };\n\n var cy = this._private.cy;\n\n // root - mandatory!\n if (options != null && options.root != null) {\n var source = is.string(options.root) ?\n // use it as a selector, e.g. \"#rootID\n this.filter(options.root)[0] :\n options.root[0];\n } else {\n return undefined;\n }\n\n // goal - mandatory!\n if (options.goal != null) {\n var target = is.string(options.goal) ?\n // use it as a selector, e.g. \"#goalID\n this.filter(options.goal)[0] :\n options.goal[0];\n } else {\n return undefined;\n }\n\n // Heuristic function - optional\n if (options.heuristic != null && is.fn(options.heuristic)) {\n var heuristic = options.heuristic;\n } else {\n var heuristic = function(){ return 0; }; // use constant if unspecified\n }\n\n // Weight function - optional\n if (options.weight != null && is.fn(options.weight)) {\n var weightFn = options.weight;\n } else {\n // If not specified, assume each edge has equal weight (1)\n var weightFn = function(e) {return 1;};\n }\n\n // directed - optional\n if (options.directed != null) {\n var directed = options.directed;\n } else {\n var directed = false;\n }\n\n var closedSet = [];\n var openSet = [source.id()];\n var cameFrom = {};\n var cameFromEdge = {};\n var gScore = {};\n var fScore = {};\n\n gScore[source.id()] = 0;\n fScore[source.id()] = heuristic(source);\n\n var edges = this.edges().stdFilter(function(e){ return !e.isLoop(); });\n var nodes = this.nodes();\n\n // Counter\n var steps = 0;\n\n // Main loop\n while (openSet.length > 0) {\n var minPos = findMin(openSet, fScore);\n var cMin = cy.getElementById( openSet[minPos] );\n steps++;\n\n // If we've found our goal, then we are done\n if (cMin.id() == target.id()) {\n var rPath = reconstructPath(source.id(), target.id(), cameFrom, []);\n rPath.reverse();\n return {\n found : true,\n distance : gScore[cMin.id()],\n path : eles.spawn(rPath),\n steps : steps\n };\n }\n\n // Add cMin to processed nodes\n closedSet.push(cMin.id());\n // Remove cMin from boundary nodes\n openSet.splice(minPos, 1);\n\n // Update scores for neighbors of cMin\n // Take into account if graph is directed or not\n var vwEdges = cMin.connectedEdges();\n if( directed ){ vwEdges = vwEdges.stdFilter(function(ele){ return ele.data('source') === cMin.id(); }); }\n vwEdges = vwEdges.intersect(edges);\n\n for (var i = 0; i < vwEdges.length; i++) {\n var e = vwEdges[i];\n var w = e.connectedNodes().stdFilter(function(n){ return n.id() !== cMin.id(); }).intersect(nodes);\n\n // if node is in closedSet, ignore it\n if (closedSet.indexOf(w.id()) != -1) {\n continue;\n }\n\n // New tentative score for node w\n var tempScore = gScore[cMin.id()] + weightFn.apply(e, [e]);\n\n // Update gScore for node w if:\n // w not present in openSet\n // OR\n // tentative gScore is less than previous value\n\n // w not in openSet\n if (openSet.indexOf(w.id()) == -1) {\n gScore[w.id()] = tempScore;\n fScore[w.id()] = tempScore + heuristic(w);\n openSet.push(w.id()); // Add node to openSet\n cameFrom[w.id()] = cMin.id();\n cameFromEdge[w.id()] = e.id();\n continue;\n }\n // w already in openSet, but with greater gScore\n if (tempScore < gScore[w.id()]) {\n gScore[w.id()] = tempScore;\n fScore[w.id()] = tempScore + heuristic(w);\n cameFrom[w.id()] = cMin.id();\n }\n\n } // End of neighbors update\n\n } // End of main loop\n\n // If we've reached here, then we've not reached our goal\n return {\n found : false,\n distance : undefined,\n path : undefined,\n steps : steps\n };\n }\n\n}); // elesfn\n\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../../is');\nvar util = require('../../util');\n\nvar elesfn = ({\n\n // Implemented from pseudocode from wikipedia\n bellmanFord: function(options) {\n var eles = this;\n\n options = options || {};\n\n // Weight function - optional\n if (options.weight != null && is.fn(options.weight)) {\n var weightFn = options.weight;\n } else {\n // If not specified, assume each edge has equal weight (1)\n var weightFn = function(e) {return 1;};\n }\n\n // directed - optional\n if (options.directed != null) {\n var directed = options.directed;\n } else {\n var directed = false;\n }\n\n // root - mandatory!\n if (options.root != null) {\n if (is.string(options.root)) {\n // use it as a selector, e.g. \"#rootID\n var source = this.filter(options.root)[0];\n } else {\n var source = options.root[0];\n }\n } else {\n return undefined;\n }\n\n var cy = this._private.cy;\n var edges = this.edges().stdFilter(function(e){ return !e.isLoop(); });\n var nodes = this.nodes();\n var numNodes = nodes.length;\n\n // mapping: node id -> position in nodes array\n var id2position = {};\n for (var i = 0; i < numNodes; i++) {\n id2position[nodes[i].id()] = i;\n }\n\n // Initializations\n var cost = [];\n var predecessor = [];\n var predEdge = [];\n\n for (var i = 0; i < numNodes; i++) {\n if (nodes[i].id() === source.id()) {\n cost[i] = 0;\n } else {\n cost[i] = Infinity;\n }\n predecessor[i] = undefined;\n }\n\n // Edges relaxation\n var flag = false;\n for (var i = 1; i < numNodes; i++) {\n flag = false;\n for (var e = 0; e < edges.length; e++) {\n var sourceIndex = id2position[edges[e].source().id()];\n var targetIndex = id2position[edges[e].target().id()];\n var weight = weightFn.apply(edges[e], [edges[e]]);\n\n var temp = cost[sourceIndex] + weight;\n if (temp < cost[targetIndex]) {\n cost[targetIndex] = temp;\n predecessor[targetIndex] = sourceIndex;\n predEdge[targetIndex] = edges[e];\n flag = true;\n }\n\n // If undirected graph, we need to take into account the 'reverse' edge\n if (!directed) {\n var temp = cost[targetIndex] + weight;\n if (temp < cost[sourceIndex]) {\n cost[sourceIndex] = temp;\n predecessor[sourceIndex] = targetIndex;\n predEdge[sourceIndex] = edges[e];\n flag = true;\n }\n }\n }\n\n if (!flag) {\n break;\n }\n }\n\n if (flag) {\n // Check for negative weight cycles\n for (var e = 0; e < edges.length; e++) {\n var sourceIndex = id2position[edges[e].source().id()];\n var targetIndex = id2position[edges[e].target().id()];\n var weight = weightFn.apply(edges[e], [edges[e]]);\n\n if (cost[sourceIndex] + weight < cost[targetIndex]) {\n util.error(\"Graph contains a negative weight cycle for Bellman-Ford\");\n return { pathTo: undefined,\n distanceTo: undefined,\n hasNegativeWeightCycle: true};\n }\n }\n }\n\n // Build result object\n var position2id = [];\n for (var i = 0; i < numNodes; i++) {\n position2id.push(nodes[i].id());\n }\n\n\n var res = {\n distanceTo : function(to) {\n if (is.string(to)) {\n // to is a selector string\n var toId = (cy.filter(to)[0]).id();\n } else {\n // to is a node\n var toId = to.id();\n }\n\n return cost[id2position[toId]];\n },\n\n pathTo : function(to) {\n\n var reconstructPathAux = function(predecessor, fromPos, toPos, position2id, acumPath, predEdge) {\n for(;;){\n // Add toId to path\n acumPath.push( cy.getElementById(position2id[toPos]) );\n acumPath.push( predEdge[toPos] );\n\n if (fromPos === toPos) {\n // reached starting node\n return acumPath;\n }\n\n // If no path exists, discart acumulated path and return undefined\n var predPos = predecessor[toPos];\n if (typeof predPos === \"undefined\") {\n return undefined;\n }\n\n toPos = predPos;\n }\n\n };\n\n if (is.string(to)) {\n // to is a selector string\n var toId = (cy.filter(to)[0]).id();\n } else {\n // to is a node\n var toId = to.id();\n }\n var path = [];\n\n // This returns a reversed path\n var res = reconstructPathAux(predecessor,\n id2position[source.id()],\n id2position[toId],\n position2id,\n path,\n predEdge);\n\n // Get it in the correct order and return it\n if (res != null) {\n res.reverse();\n }\n\n return eles.spawn(res);\n },\n\n hasNegativeWeightCycle: false\n };\n\n return res;\n\n } // bellmanFord\n\n}); // elesfn\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../../is');\n\nvar elesfn = ({\n\n // Implemented from the algorithm in the paper \"On Variants of Shortest-Path Betweenness Centrality and their Generic Computation\" by Ulrik Brandes\n betweennessCentrality: function (options) {\n options = options || {};\n\n // Weight - optional\n if (options.weight != null && is.fn(options.weight)) {\n var weightFn = options.weight;\n var weighted = true;\n } else {\n var weighted = false;\n }\n\n // Directed - default false\n if (options.directed != null && is.bool(options.directed)) {\n var directed = options.directed;\n } else {\n var directed = false;\n }\n\n var priorityInsert = function (queue, ele) {\n queue.unshift(ele);\n for (var i = 0; d[queue[i]] < d[queue[i + 1]] && i < queue.length - 1; i++) {\n var tmp = queue[i];\n queue[i] = queue[i + 1];\n queue[i + 1] = tmp;\n }\n };\n\n var cy = this._private.cy;\n\n // starting\n var V = this.nodes();\n var A = {};\n var C = {};\n\n // A contains the neighborhoods of every node\n for (var i = 0; i < V.length; i++) {\n if (directed) {\n A[V[i].id()] = V[i].outgoers(\"node\"); // get outgoers of every node\n } else {\n A[V[i].id()] = V[i].openNeighborhood(\"node\"); // get neighbors of every node\n }\n }\n\n // C contains the betweenness values\n for (var i = 0; i < V.length; i++) {\n C[V[i].id()] = 0;\n }\n\n for (var s = 0; s < V.length; s++) {\n var S = []; // stack\n var P = {};\n var g = {};\n var d = {};\n var Q = []; // queue\n\n // init dictionaries\n for (var i = 0; i < V.length; i++) {\n P[V[i].id()] = [];\n g[V[i].id()] = 0;\n d[V[i].id()] = Number.POSITIVE_INFINITY;\n }\n\n g[V[s].id()] = 1; // sigma\n d[V[s].id()] = 0; // distance to s\n\n Q.unshift(V[s].id());\n\n while (Q.length > 0) {\n var v = Q.pop();\n S.push(v);\n if (weighted) {\n A[v].forEach(function (w) {\n if (cy.$('#' + v).edgesTo(w).length > 0) {\n var edge = cy.$('#' + v).edgesTo(w)[0];\n } else {\n var edge = w.edgesTo('#' + v)[0];\n }\n\n var edgeWeight = weightFn.apply(edge, [edge]);\n\n if (d[w.id()] > d[v] + edgeWeight) {\n d[w.id()] = d[v] + edgeWeight;\n if (Q.indexOf(w.id()) < 0) { //if w is not in Q\n priorityInsert(Q, w.id());\n } else { // update position if w is in Q\n Q.splice(Q.indexOf(w.id()), 1);\n priorityInsert(Q, w.id());\n }\n g[w.id()] = 0;\n P[w.id()] = [];\n }\n if (d[w.id()] == d[v] + edgeWeight) {\n g[w.id()] = g[w.id()] + g[v];\n P[w.id()].push(v);\n }\n });\n } else {\n A[v].forEach(function (w) {\n if (d[w.id()] == Number.POSITIVE_INFINITY) {\n Q.unshift(w.id());\n d[w.id()] = d[v] + 1;\n }\n if (d[w.id()] == d[v] + 1) {\n g[w.id()] = g[w.id()] + g[v];\n P[w.id()].push(v);\n }\n });\n }\n }\n\n var e = {};\n for (var i = 0; i < V.length; i++) {\n e[V[i].id()] = 0;\n }\n\n while (S.length > 0) {\n var w = S.pop();\n P[w].forEach(function (v) {\n e[v] = e[v] + (g[v] / g[w]) * (1 + e[w]);\n if (w != V[s].id())\n C[w] = C[w] + e[w];\n });\n }\n }\n\n var max = 0;\n for (var key in C) {\n if (max < C[key])\n max = C[key];\n }\n\n var ret = {\n betweenness: function (node) {\n if (is.string(node)) {\n var node = (cy.filter(node)[0]).id();\n } else {\n var node = node.id();\n }\n\n return C[node];\n },\n\n betweennessNormalized: function (node) {\n if (is.string(node)) {\n var node = (cy.filter(node)[0]).id();\n } else {\n var node = node.id();\n }\n\n return C[node] / max;\n }\n };\n\n // alias\n ret.betweennessNormalised = ret.betweennessNormalized;\n\n return ret;\n } // betweennessCentrality\n\n}); // elesfn\n\n// nice, short mathemathical alias\nelesfn.bc = elesfn.betweennessCentrality;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../../is');\nvar Heap = require('../../heap');\n\nvar defineSearch = function( params ){\n params = {\n bfs: params.bfs || !params.dfs,\n dfs: params.dfs || !params.bfs\n };\n\n // from pseudocode on wikipedia\n return function searchFn( roots, fn, directed ){\n var options;\n var std;\n var thisArg;\n if( is.plainObject(roots) && !is.elementOrCollection(roots) ){\n options = roots;\n roots = options.roots || options.root;\n fn = options.visit;\n directed = options.directed;\n std = options.std;\n thisArg = options.thisArg;\n }\n\n directed = arguments.length === 2 && !is.fn(fn) ? fn : directed;\n fn = is.fn(fn) ? fn : function(){};\n\n var cy = this._private.cy;\n var v = roots = is.string(roots) ? this.filter(roots) : roots;\n var Q = [];\n var connectedNodes = [];\n var connectedBy = {};\n var id2depth = {};\n var V = {};\n var j = 0;\n var found;\n var nodes = this.nodes();\n var edges = this.edges();\n\n // enqueue v\n for( var i = 0; i < v.length; i++ ){\n if( v[i].isNode() ){\n Q.unshift( v[i] );\n\n if( params.bfs ){\n V[ v[i].id() ] = true;\n\n connectedNodes.push( v[i] );\n }\n\n id2depth[ v[i].id() ] = 0;\n }\n }\n\n while( Q.length !== 0 ){\n var v = params.bfs ? Q.shift() : Q.pop();\n\n if( params.dfs ){\n if( V[ v.id() ] ){ continue; }\n\n V[ v.id() ] = true;\n\n connectedNodes.push( v );\n }\n\n var depth = id2depth[ v.id() ];\n var prevEdge = connectedBy[ v.id() ];\n var prevNode = prevEdge == null ? undefined : prevEdge.connectedNodes().not( v )[0];\n var ret;\n\n if( std ){\n ret = fn.call(thisArg, v, prevEdge, prevNode, j++, depth);\n } else {\n ret = fn.call(v, j++, depth, v, prevEdge, prevNode);\n }\n\n if( ret === true ){\n found = v;\n break;\n }\n\n if( ret === false ){\n break;\n }\n\n var vwEdges = v.connectedEdges(directed ? function(){ return this.data('source') === v.id(); } : undefined).intersect( edges );\n for( var i = 0; i < vwEdges.length; i++ ){\n var e = vwEdges[i];\n var w = e.connectedNodes(function(){ return this.id() !== v.id(); }).intersect( nodes );\n\n if( w.length !== 0 && !V[ w.id() ] ){\n w = w[0];\n\n Q.push( w );\n\n if( params.bfs ){\n V[ w.id() ] = true;\n\n connectedNodes.push( w );\n }\n\n connectedBy[ w.id() ] = e;\n\n id2depth[ w.id() ] = id2depth[ v.id() ] + 1;\n }\n }\n\n }\n\n var connectedEles = [];\n\n for( var i = 0; i < connectedNodes.length; i++ ){\n var node = connectedNodes[i];\n var edge = connectedBy[ node.id() ];\n\n if( edge ){\n connectedEles.push( edge );\n }\n\n connectedEles.push( node );\n }\n\n return {\n path: cy.collection( connectedEles, { unique: true } ),\n found: cy.collection( found )\n };\n };\n};\n\n// search, spanning trees, etc\nvar elesfn = ({\n\n breadthFirstSearch: defineSearch({ bfs: true }),\n depthFirstSearch: defineSearch({ dfs: true }),\n\n // kruskal's algorithm (finds min spanning tree, assuming undirected graph)\n // implemented from pseudocode from wikipedia\n kruskal: function( weightFn ){\n var cy = this.cy();\n\n weightFn = is.fn(weightFn) ? weightFn : function(){ return 1; }; // if not specified, assume each edge has equal weight (1)\n\n function findSet(ele){\n for( var i = 0; i < forest.length; i++ ){\n var eles = forest[i];\n\n if( eles.anySame(ele) ){\n return {\n eles: eles,\n index: i\n };\n }\n }\n }\n\n var A = cy.collection(cy, []);\n var forest = [];\n var nodes = this.nodes();\n\n for( var i = 0; i < nodes.length; i++ ){\n forest.push( nodes[i].collection() );\n }\n\n var edges = this.edges();\n var S = edges.toArray().sort(function(a, b){\n var weightA = weightFn.call(a, a);\n var weightB = weightFn.call(b, b);\n\n return weightA - weightB;\n });\n\n for(var i = 0; i < S.length; i++){\n var edge = S[i];\n var u = edge.source()[0];\n var v = edge.target()[0];\n var setU = findSet(u);\n var setV = findSet(v);\n\n if( setU.index !== setV.index ){\n A = A.add( edge );\n\n // combine forests for u and v\n forest[ setU.index ] = setU.eles.add( setV.eles );\n forest.splice( setV.index, 1 );\n }\n }\n\n return nodes.add( A );\n\n },\n\n dijkstra: function( root, weightFn, directed ){\n var options;\n if( is.plainObject(root) && !is.elementOrCollection(root) ){\n options = root;\n root = options.root;\n weightFn = options.weight;\n directed = options.directed;\n }\n\n var cy = this._private.cy;\n weightFn = is.fn(weightFn) ? weightFn : function(){ return 1; }; // if not specified, assume each edge has equal weight (1)\n\n var source = is.string(root) ? this.filter(root)[0] : root[0];\n var dist = {};\n var prev = {};\n var knownDist = {};\n\n var edges = this.edges().filter(function(){ return !this.isLoop(); });\n var nodes = this.nodes();\n\n var getDist = function(node){\n return dist[ node.id() ];\n };\n\n var setDist = function(node, d){\n dist[ node.id() ] = d;\n\n Q.updateItem( node );\n };\n\n var Q = new Heap(function( a, b ){\n return getDist(a) - getDist(b);\n });\n\n for( var i = 0; i < nodes.length; i++ ){\n var node = nodes[i];\n\n dist[ node.id() ] = node.same( source ) ? 0 : Infinity;\n Q.push( node );\n }\n\n var distBetween = function(u, v){\n var uvs = ( directed ? u.edgesTo(v) : u.edgesWith(v) ).intersect(edges);\n var smallestDistance = Infinity;\n var smallestEdge;\n\n for( var i = 0; i < uvs.length; i++ ){\n var edge = uvs[i];\n var weight = weightFn.apply( edge, [edge] );\n\n if( weight < smallestDistance || !smallestEdge ){\n smallestDistance = weight;\n smallestEdge = edge;\n }\n }\n\n return {\n edge: smallestEdge,\n dist: smallestDistance\n };\n };\n\n while( Q.size() > 0 ){\n var u = Q.pop();\n var smalletsDist = getDist(u);\n var uid = u.id();\n\n knownDist[uid] = smalletsDist;\n\n if( smalletsDist === Math.Infinite ){\n break;\n }\n\n var neighbors = u.neighborhood().intersect(nodes);\n for( var i = 0; i < neighbors.length; i++ ){\n var v = neighbors[i];\n var vid = v.id();\n var vDist = distBetween(u, v);\n\n var alt = smalletsDist + vDist.dist;\n\n if( alt < getDist(v) ){\n setDist(v, alt);\n\n prev[ vid ] = {\n node: u,\n edge: vDist.edge\n };\n }\n } // for\n } // while\n\n return {\n distanceTo: function(node){\n var target = is.string(node) ? nodes.filter(node)[0] : node[0];\n\n return knownDist[ target.id() ];\n },\n\n pathTo: function(node){\n var target = is.string(node) ? nodes.filter(node)[0] : node[0];\n var S = [];\n var u = target;\n\n if( target.length > 0 ){\n S.unshift( target );\n\n while( prev[ u.id() ] ){\n var p = prev[ u.id() ];\n\n S.unshift( p.edge );\n S.unshift( p.node );\n\n u = p.node;\n }\n }\n\n return cy.collection( S );\n }\n };\n }\n});\n\n// nice, short mathemathical alias\nelesfn.bfs = elesfn.breadthFirstSearch;\nelesfn.dfs = elesfn.depthFirstSearch;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../../is');\n\nvar elesfn = ({\n\n closenessCentralityNormalized: function (options) {\n options = options || {};\n\n var cy = this.cy();\n\n var harmonic = options.harmonic;\n if( harmonic === undefined ){\n harmonic = true;\n }\n\n var closenesses = {};\n var maxCloseness = 0;\n var nodes = this.nodes();\n var fw = this.floydWarshall({ weight: options.weight, directed: options.directed });\n\n // Compute closeness for every node and find the maximum closeness\n for(var i = 0; i < nodes.length; i++){\n var currCloseness = 0;\n for (var j = 0; j < nodes.length; j++) {\n if (i != j) {\n var d = fw.distance(nodes[i], nodes[j]);\n\n if( harmonic ){\n currCloseness += 1 / d;\n } else {\n currCloseness += d;\n }\n }\n }\n\n if( !harmonic ){\n currCloseness = 1 / currCloseness;\n }\n\n if (maxCloseness < currCloseness){\n maxCloseness = currCloseness;\n }\n\n closenesses[nodes[i].id()] = currCloseness;\n }\n\n return {\n closeness: function (node) {\n if (is.string(node)) {\n // from is a selector string\n var node = (cy.filter(node)[0]).id();\n } else {\n // from is a node\n var node = node.id();\n }\n\n return closenesses[node] / maxCloseness;\n }\n };\n },\n\n // Implemented from pseudocode from wikipedia\n closenessCentrality: function (options) {\n options = options || {};\n\n // root - mandatory!\n if (options.root != null) {\n if (is.string(options.root)) {\n // use it as a selector, e.g. \"#rootID\n var root = this.filter(options.root)[0];\n } else {\n var root = options.root[0];\n }\n } else {\n return undefined;\n }\n\n // weight - optional\n if (options.weight != null && is.fn(options.weight)) {\n var weight = options.weight;\n } else {\n var weight = function(){return 1;};\n }\n\n // directed - optional\n if (options.directed != null && is.bool(options.directed)) {\n var directed = options.directed;\n } else {\n var directed = false;\n }\n\n var harmonic = options.harmonic;\n if( harmonic === undefined ){\n harmonic = true;\n }\n\n // we need distance from this node to every other node\n var dijkstra = this.dijkstra({\n root: root,\n weight: weight,\n directed: directed\n });\n var totalDistance = 0;\n\n var nodes = this.nodes();\n for (var i = 0; i < nodes.length; i++){\n if (nodes[i].id() != root.id()){\n var d = dijkstra.distanceTo(nodes[i]);\n\n if( harmonic ){\n totalDistance += 1 / d;\n } else {\n totalDistance += d;\n }\n }\n }\n\n return harmonic ? totalDistance : 1 / totalDistance;\n } // closenessCentrality\n\n}); // elesfn\n\n// nice, short mathemathical alias\nelesfn.cc = elesfn.closenessCentrality;\nelesfn.ccn = elesfn.closenessCentralityNormalised = elesfn.closenessCentralityNormalized;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../../is');\nvar util = require('../../util');\n\nvar elesfn = ({\n\n degreeCentralityNormalized: function (options) {\n options = options || {};\n\n var cy = this.cy();\n\n // directed - optional\n if (options.directed != null) {\n var directed = options.directed;\n } else {\n var directed = false;\n }\n\n var nodes = this.nodes();\n var numNodes = nodes.length;\n\n if (!directed) {\n var degrees = {};\n var maxDegree = 0;\n\n for (var i = 0; i < numNodes; i++) {\n var node = nodes[i];\n // add current node to the current options object and call degreeCentrality\n var currDegree = this.degreeCentrality(util.extend({}, options, {root: node}));\n if (maxDegree < currDegree.degree)\n maxDegree = currDegree.degree;\n\n degrees[node.id()] = currDegree.degree;\n }\n\n return {\n degree: function (node) {\n if (is.string(node)) {\n // from is a selector string\n var node = (cy.filter(node)[0]).id();\n } else {\n // from is a node\n var node = node.id();\n }\n\n return degrees[node] / maxDegree;\n }\n };\n } else {\n var indegrees = {};\n var outdegrees = {};\n var maxIndegree = 0;\n var maxOutdegree = 0;\n\n for (var i = 0; i < numNodes; i++) {\n var node = nodes[i];\n // add current node to the current options object and call degreeCentrality\n var currDegree = this.degreeCentrality(util.extend({}, options, {root: node}));\n\n if (maxIndegree < currDegree.indegree)\n maxIndegree = currDegree.indegree;\n\n if (maxOutdegree < currDegree.outdegree)\n maxOutdegree = currDegree.outdegree;\n\n indegrees[node.id()] = currDegree.indegree;\n outdegrees[node.id()] = currDegree.outdegree;\n }\n\n return {\n indegree: function (node) {\n if (is.string(node)) {\n // from is a selector string\n var node = (cy.filter(node)[0]).id();\n } else {\n // from is a node\n var node = node.id();\n }\n\n return indegrees[node] / maxIndegree;\n },\n outdegree: function (node) {\n if (is.string(node)) {\n // from is a selector string\n var node = (cy.filter(node)[0]).id();\n } else {\n // from is a node\n var node = node.id();\n }\n\n return outdegrees[node] / maxOutdegree;\n }\n\n };\n }\n\n }, // degreeCentralityNormalized\n\n // Implemented from the algorithm in Opsahl's paper\n // \"Node centrality in weighted networks: Generalizing degree and shortest paths\"\n // check the heading 2 \"Degree\"\n degreeCentrality: function (options) {\n options = options || {};\n\n var callingEles = this;\n\n // root - mandatory!\n if (options != null && options.root != null) {\n var root = is.string(options.root) ? this.filter(options.root)[0] : options.root[0];\n } else {\n return undefined;\n }\n\n // weight - optional\n if (options.weight != null && is.fn(options.weight)) {\n var weightFn = options.weight;\n } else {\n // If not specified, assume each edge has equal weight (1)\n var weightFn = function (e) {\n return 1;\n };\n }\n\n // directed - optional\n if (options.directed != null) {\n var directed = options.directed;\n } else {\n var directed = false;\n }\n\n // alpha - optional\n if (options.alpha != null && is.number(options.alpha)) {\n var alpha = options.alpha;\n } else {\n alpha = 0;\n }\n\n\n if (!directed) {\n var connEdges = root.connectedEdges().intersection( callingEles );\n var k = connEdges.length;\n var s = 0;\n\n // Now, sum edge weights\n for (var i = 0; i < connEdges.length; i++) {\n var edge = connEdges[i];\n s += weightFn.apply(edge, [edge]);\n }\n\n return {\n degree: Math.pow(k, 1 - alpha) * Math.pow(s, alpha)\n };\n } else {\n var incoming = root.connectedEdges('edge[target = \"' + root.id() + '\"]').intersection( callingEles );\n var outgoing = root.connectedEdges('edge[source = \"' + root.id() + '\"]').intersection( callingEles );\n var k_in = incoming.length;\n var k_out = outgoing.length;\n var s_in = 0;\n var s_out = 0;\n\n // Now, sum incoming edge weights\n for (var i = 0; i < incoming.length; i++) {\n var edge = incoming[i];\n s_in += weightFn.apply(edge, [edge]);\n }\n\n // Now, sum outgoing edge weights\n for (var i = 0; i < outgoing.length; i++) {\n var edge = outgoing[i];\n s_out += weightFn.apply(edge, [edge]);\n }\n\n return {\n indegree: Math.pow(k_in, 1 - alpha) * Math.pow(s_in, alpha),\n outdegree: Math.pow(k_out, 1 - alpha) * Math.pow(s_out, alpha)\n };\n }\n } // degreeCentrality\n\n}); // elesfn\n\n// nice, short mathemathical alias\nelesfn.dc = elesfn.degreeCentrality;\nelesfn.dcn = elesfn.degreeCentralityNormalised = elesfn.degreeCentralityNormalized;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../../is');\n\nvar elesfn = ({\n\n // Implemented from pseudocode from wikipedia\n floydWarshall: function(options) {\n options = options || {};\n\n var cy = this.cy();\n\n // Weight function - optional\n if (options.weight != null && is.fn(options.weight)) {\n var weightFn = options.weight;\n } else {\n // If not specified, assume each edge has equal weight (1)\n var weightFn = function(e) {return 1;};\n }\n\n // directed - optional\n if (options.directed != null) {\n var directed = options.directed;\n } else {\n var directed = false;\n }\n\n var edges = this.edges().stdFilter(function(e){ return !e.isLoop(); });\n var nodes = this.nodes();\n var numNodes = nodes.length;\n\n // mapping: node id -> position in nodes array\n var id2position = {};\n for (var i = 0; i < numNodes; i++) {\n id2position[nodes[i].id()] = i;\n }\n\n // Initialize distance matrix\n var dist = [];\n for (var i = 0; i < numNodes; i++) {\n var newRow = new Array(numNodes);\n for (var j = 0; j < numNodes; j++) {\n if (i == j) {\n newRow[j] = 0;\n } else {\n newRow[j] = Infinity;\n }\n }\n dist.push(newRow);\n }\n\n // Initialize matrix used for path reconstruction\n // Initialize distance matrix\n var next = [];\n var edgeNext = [];\n\n var initMatrix = function(next){\n for (var i = 0; i < numNodes; i++) {\n var newRow = new Array(numNodes);\n for (var j = 0; j < numNodes; j++) {\n newRow[j] = undefined;\n }\n next.push(newRow);\n }\n };\n\n initMatrix(next);\n initMatrix(edgeNext);\n\n // Process edges\n for (var i = 0; i < edges.length ; i++) {\n var sourceIndex = id2position[edges[i].source().id()];\n var targetIndex = id2position[edges[i].target().id()];\n var weight = weightFn.apply(edges[i], [edges[i]]);\n\n // Check if already process another edge between same 2 nodes\n if (dist[sourceIndex][targetIndex] > weight) {\n dist[sourceIndex][targetIndex] = weight;\n next[sourceIndex][targetIndex] = targetIndex;\n edgeNext[sourceIndex][targetIndex] = edges[i];\n }\n }\n\n // If undirected graph, process 'reversed' edges\n if (!directed) {\n for (var i = 0; i < edges.length ; i++) {\n var sourceIndex = id2position[edges[i].target().id()];\n var targetIndex = id2position[edges[i].source().id()];\n var weight = weightFn.apply(edges[i], [edges[i]]);\n\n // Check if already process another edge between same 2 nodes\n if (dist[sourceIndex][targetIndex] > weight) {\n dist[sourceIndex][targetIndex] = weight;\n next[sourceIndex][targetIndex] = targetIndex;\n edgeNext[sourceIndex][targetIndex] = edges[i];\n }\n }\n }\n\n // Main loop\n for (var k = 0; k < numNodes; k++) {\n for (var i = 0; i < numNodes; i++) {\n for (var j = 0; j < numNodes; j++) {\n if (dist[i][k] + dist[k][j] < dist[i][j]) {\n dist[i][j] = dist[i][k] + dist[k][j];\n next[i][j] = next[i][k];\n }\n }\n }\n }\n\n // Build result object\n var position2id = [];\n for (var i = 0; i < numNodes; i++) {\n position2id.push(nodes[i].id());\n }\n\n var res = {\n distance: function(from, to) {\n if (is.string(from)) {\n // from is a selector string\n var fromId = (cy.filter(from)[0]).id();\n } else {\n // from is a node\n var fromId = from.id();\n }\n\n if (is.string(to)) {\n // to is a selector string\n var toId = (cy.filter(to)[0]).id();\n } else {\n // to is a node\n var toId = to.id();\n }\n\n return dist[id2position[fromId]][id2position[toId]];\n },\n\n path: function(from, to) {\n var reconstructPathAux = function(from, to, next, position2id, edgeNext) {\n if (from === to) {\n return cy.getElementById( position2id[from] );\n }\n if (next[from][to] === undefined) {\n return undefined;\n }\n\n var path = [ cy.getElementById(position2id[from]) ];\n var prev = from;\n while (from !== to) {\n prev = from;\n from = next[from][to];\n\n var edge = edgeNext[prev][from];\n path.push( edge );\n\n path.push( cy.getElementById(position2id[from]) );\n }\n return path;\n };\n\n if (is.string(from)) {\n // from is a selector string\n var fromId = (cy.filter(from)[0]).id();\n } else {\n // from is a node\n var fromId = from.id();\n }\n\n if (is.string(to)) {\n // to is a selector string\n var toId = (cy.filter(to)[0]).id();\n } else {\n // to is a node\n var toId = to.id();\n }\n\n var pathArr = reconstructPathAux(id2position[fromId],\n id2position[toId],\n next,\n position2id,\n edgeNext);\n\n return cy.collection( pathArr );\n }\n };\n\n return res;\n\n } // floydWarshall\n\n}); // elesfn\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar util = require('../../util');\n\nvar elesfn = {};\n\n[\n require('./bfs-dfs'),\n require('./a-star'),\n require('./floyd-warshall'),\n require('./bellman-ford'),\n require('./kerger-stein'),\n require('./page-rank'),\n require('./degree-centrality'),\n require('./closeness-centrality'),\n require('./betweenness-centrality')\n].forEach(function( props ){\n util.extend( elesfn, props );\n});\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar util = require('../../util');\n\nvar elesfn = ({\n\n // Computes the minimum cut of an undirected graph\n // Returns the correct answer with high probability\n kargerStein: function(options) {\n var eles = this;\n\n options = options || {};\n\n // Function which colapses 2 (meta) nodes into one\n // Updates the remaining edge lists\n // Receives as a paramater the edge which causes the collapse\n var colapse = function(edgeIndex, nodeMap, remainingEdges) {\n var edgeInfo = remainingEdges[edgeIndex];\n var sourceIn = edgeInfo[1];\n var targetIn = edgeInfo[2];\n var partition1 = nodeMap[sourceIn];\n var partition2 = nodeMap[targetIn];\n\n // Delete all edges between partition1 and partition2\n var newEdges = remainingEdges.filter(function(edge) {\n if (nodeMap[edge[1]] === partition1 && nodeMap[edge[2]] === partition2) {\n return false;\n }\n if (nodeMap[edge[1]] === partition2 && nodeMap[edge[2]] === partition1) {\n return false;\n }\n return true;\n });\n\n // All edges pointing to partition2 should now point to partition1\n for (var i = 0; i < newEdges.length; i++) {\n var edge = newEdges[i];\n if (edge[1] === partition2) { // Check source\n newEdges[i] = edge.slice(0);\n newEdges[i][1] = partition1;\n } else if (edge[2] === partition2) { // Check target\n newEdges[i] = edge.slice(0);\n newEdges[i][2] = partition1;\n }\n }\n\n // Move all nodes from partition2 to partition1\n for (var i = 0; i < nodeMap.length; i++) {\n if (nodeMap[i] === partition2) {\n nodeMap[i] = partition1;\n }\n }\n\n return newEdges;\n };\n\n\n // Contracts a graph until we reach a certain number of meta nodes\n var contractUntil = function(metaNodeMap,\n remainingEdges,\n size,\n sizeLimit) {\n // Stop condition\n if (size <= sizeLimit) {\n return remainingEdges;\n }\n\n // Choose an edge randomly\n var edgeIndex = Math.floor((Math.random() * remainingEdges.length));\n\n // Colapse graph based on edge\n var newEdges = colapse(edgeIndex, metaNodeMap, remainingEdges);\n\n return contractUntil(metaNodeMap,\n newEdges,\n size - 1,\n sizeLimit);\n };\n\n var cy = this._private.cy;\n var edges = this.edges().stdFilter(function(e){ return !e.isLoop(); });\n var nodes = this.nodes();\n var numNodes = nodes.length;\n var numEdges = edges.length;\n var numIter = Math.ceil(Math.pow(Math.log(numNodes) / Math.LN2, 2));\n var stopSize = Math.floor(numNodes / Math.sqrt(2));\n\n if (numNodes < 2) {\n util.error(\"At least 2 nodes are required for Karger-Stein algorithm\");\n return undefined;\n }\n\n // Create numerical identifiers for each node\n // mapping: node id -> position in nodes array\n // for reverse mapping, simply use nodes array\n var id2position = {};\n for (var i = 0; i < numNodes; i++) {\n id2position[nodes[i].id()] = i;\n }\n\n // Now store edge destination as indexes\n // Format for each edge (edge index, source node index, target node index)\n var edgeIndexes = [];\n for (var i = 0; i < numEdges; i++) {\n var e = edges[i];\n edgeIndexes.push([i, id2position[e.source().id()], id2position[e.target().id()]]);\n }\n\n // We will store the best cut found here\n var minCutSize = Infinity;\n var minCut;\n\n // Initial meta node partition\n var originalMetaNode = [];\n for (var i = 0; i < numNodes; i++) {\n originalMetaNode.push(i);\n }\n\n // Main loop\n for (var iter = 0; iter <= numIter; iter++) {\n // Create new meta node partition\n var metaNodeMap = originalMetaNode.slice(0);\n\n // Contract until stop point (stopSize nodes)\n var edgesState = contractUntil(metaNodeMap, edgeIndexes, numNodes, stopSize);\n\n // Create a copy of the colapsed nodes state\n var metaNodeMap2 = metaNodeMap.slice(0);\n\n // Run 2 iterations starting in the stop state\n var res1 = contractUntil(metaNodeMap, edgesState, stopSize, 2);\n var res2 = contractUntil(metaNodeMap2, edgesState, stopSize, 2);\n\n // Is any of the 2 results the best cut so far?\n if (res1.length <= res2.length && res1.length < minCutSize) {\n minCutSize = res1.length;\n minCut = [res1, metaNodeMap];\n } else if (res2.length <= res1.length && res2.length < minCutSize) {\n minCutSize = res2.length;\n minCut = [res2, metaNodeMap2];\n }\n } // end of main loop\n\n\n // Construct result\n var resEdges = (minCut[0]).map(function(e){ return edges[e[0]]; });\n var partition1 = [];\n var partition2 = [];\n\n // traverse metaNodeMap for best cut\n var witnessNodePartition = minCut[1][0];\n for (var i = 0; i < minCut[1].length; i++) {\n var partitionId = minCut[1][i];\n if (partitionId === witnessNodePartition) {\n partition1.push(nodes[i]);\n } else {\n partition2.push(nodes[i]);\n }\n }\n\n var ret = {\n cut: eles.spawn(cy, resEdges),\n partition1: eles.spawn(partition1),\n partition2: eles.spawn(partition2)\n };\n\n return ret;\n }\n}); // elesfn\n\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../../is');\n\nvar elesfn = ({\n\n pageRank: function(options) {\n options = options || {};\n\n var normalizeVector = function(vector) {\n var length = vector.length;\n\n // First, get sum of all elements\n var total = 0;\n for (var i = 0; i < length; i++) {\n total += vector[i];\n }\n\n // Now, divide each by the sum of all elements\n for (var i = 0; i < length; i++) {\n vector[i] = vector[i] / total;\n }\n };\n\n // dampingFactor - optional\n if (options != null &&\n options.dampingFactor != null) {\n var dampingFactor = options.dampingFactor;\n } else {\n var dampingFactor = 0.8; // Default damping factor\n }\n\n // desired precision - optional\n if (options != null &&\n options.precision != null) {\n var epsilon = options.precision;\n } else {\n var epsilon = 0.000001; // Default precision\n }\n\n // Max number of iterations - optional\n if (options != null &&\n options.iterations != null) {\n var numIter = options.iterations;\n } else {\n var numIter = 200; // Default number of iterations\n }\n\n // Weight function - optional\n if (options != null &&\n options.weight != null &&\n is.fn(options.weight)) {\n var weightFn = options.weight;\n } else {\n // If not specified, assume each edge has equal weight (1)\n var weightFn = function(e) {return 1;};\n }\n\n var cy = this._private.cy;\n var edges = this.edges().stdFilter(function(e){ return !e.isLoop(); });\n var nodes = this.nodes();\n var numNodes = nodes.length;\n var numEdges = edges.length;\n\n // Create numerical identifiers for each node\n // mapping: node id -> position in nodes array\n // for reverse mapping, simply use nodes array\n var id2position = {};\n for (var i = 0; i < numNodes; i++) {\n id2position[nodes[i].id()] = i;\n }\n\n // Construct transposed adjacency matrix\n // First lets have a zeroed matrix of the right size\n // We'll also keep track of the sum of each column\n var matrix = [];\n var columnSum = [];\n var additionalProb = (1 - dampingFactor) / numNodes;\n\n // Create null matric\n for (var i = 0; i < numNodes; i++) {\n var newRow = [];\n for (var j = 0; j < numNodes; j++) {\n newRow.push(0.0);\n }\n matrix.push(newRow);\n columnSum.push(0.0);\n }\n\n // Now, process edges\n for (var i = 0; i < numEdges; i++) {\n var edge = edges[i];\n var s = id2position[edge.source().id()];\n var t = id2position[edge.target().id()];\n var w = weightFn.apply(edge, [edge]);\n\n // Update matrix\n matrix[t][s] += w;\n\n // Update column sum\n columnSum[s] += w;\n }\n\n // Add additional probability based on damping factor\n // Also, take into account columns that have sum = 0\n var p = 1.0 / numNodes + additionalProb; // Shorthand\n // Traverse matrix, column by column\n for (var j = 0; j < numNodes; j++) {\n if (columnSum[j] === 0) {\n // No 'links' out from node jth, assume equal probability for each possible node\n for (var i = 0; i < numNodes; i++) {\n matrix[i][j] = p;\n }\n } else {\n // Node jth has outgoing link, compute normalized probabilities\n for (var i = 0; i < numNodes; i++) {\n matrix[i][j] = matrix[i][j] / columnSum[j] + additionalProb;\n }\n }\n }\n\n // Compute dominant eigenvector using power method\n var eigenvector = [];\n var nullVector = [];\n var previous;\n\n // Start with a vector of all 1's\n // Also, initialize a null vector which will be used as shorthand\n for (var i = 0; i < numNodes; i++) {\n eigenvector.push(1.0);\n nullVector.push(0.0);\n }\n\n for (var iter = 0; iter < numIter; iter++) {\n // New array with all 0's\n var temp = nullVector.slice(0);\n\n // Multiply matrix with previous result\n for (var i = 0; i < numNodes; i++) {\n for (var j = 0; j < numNodes; j++) {\n temp[i] += matrix[i][j] * eigenvector[j];\n }\n }\n\n normalizeVector(temp);\n previous = eigenvector;\n eigenvector = temp;\n\n var diff = 0;\n // Compute difference (squared module) of both vectors\n for (var i = 0; i < numNodes; i++) {\n diff += Math.pow(previous[i] - eigenvector[i], 2);\n }\n\n // If difference is less than the desired threshold, stop iterating\n if (diff < epsilon) {\n break;\n }\n }\n\n // Construct result\n var res = {\n rank : function(node) {\n if (is.string(node)) {\n // is a selector string\n var nodeId = (cy.filter(node)[0]).id();\n } else {\n // is a node object\n var nodeId = node.id();\n }\n return eigenvector[id2position[nodeId]];\n }\n };\n\n\n return res;\n } // pageRank\n\n}); // elesfn\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar define = require('../define');\n\nvar elesfn = ({\n animate: define.animate(),\n animation: define.animation(),\n animated: define.animated(),\n clearQueue: define.clearQueue(),\n delay: define.delay(),\n delayAnimation: define.delayAnimation(),\n stop: define.stop()\n});\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar util = require('../util');\n\nvar elesfn = ({\n classes: function( classes ){\n classes = classes.match(/\\S+/g) || [];\n var self = this;\n var changed = [];\n var classesMap = {};\n\n // fill in classes map\n for( var i = 0; i < classes.length; i++ ){\n var cls = classes[i];\n\n classesMap[ cls ] = true;\n }\n\n // check and update each ele\n for( var j = 0; j < self.length; j++ ){\n var ele = self[j];\n var _p = ele._private;\n var eleClasses = _p.classes;\n var changedEle = false;\n\n // check if ele has all of the passed classes\n for( var i = 0; i < classes.length; i++ ){\n var cls = classes[i];\n var eleHasClass = eleClasses[ cls ];\n\n if( !eleHasClass ){\n changedEle = true;\n break;\n }\n }\n\n // check if ele has classes outside of those passed\n if( !changedEle ){ for( var eleCls in eleClasses ){\n var eleHasClass = eleClasses[ eleCls ];\n var specdClass = classesMap[ eleCls ]; // i.e. this class is passed to the function\n\n if( eleHasClass && !specdClass ){\n changedEle = true;\n break;\n }\n } }\n\n if( changedEle ){\n _p.classes = util.copy( classesMap );\n\n changed.push( ele );\n }\n }\n\n // trigger update style on those eles that had class changes\n if( changed.length > 0 ){\n this.spawn(changed)\n .updateStyle()\n .trigger('class')\n ;\n }\n\n return self;\n },\n\n addClass: function( classes ){\n return this.toggleClass( classes, true );\n },\n\n hasClass: function( className ){\n var ele = this[0];\n return ( ele != null && ele._private.classes[className] ) ? true : false;\n },\n\n toggleClass: function( classesStr, toggle ){\n var classes = classesStr.match(/\\S+/g) || [];\n var self = this;\n var changed = []; // eles who had classes changed\n\n for( var i = 0, il = self.length; i < il; i++ ){\n var ele = self[i];\n var changedEle = false;\n\n for( var j = 0; j < classes.length; j++ ){\n var cls = classes[j];\n var eleClasses = ele._private.classes;\n var hasClass = eleClasses[cls];\n var shouldAdd = toggle || (toggle === undefined && !hasClass);\n\n if( shouldAdd ){\n eleClasses[cls] = true;\n\n if( !hasClass && !changedEle ){\n changed.push(ele);\n changedEle = true;\n }\n } else { // then remove\n eleClasses[cls] = false;\n\n if( hasClass && !changedEle ){\n changed.push(ele);\n changedEle = true;\n }\n }\n\n } // for j classes\n } // for i eles\n\n // trigger update style on those eles that had class changes\n if( changed.length > 0 ){\n this.spawn(changed)\n .updateStyle()\n .trigger('class')\n ;\n }\n\n return self;\n },\n\n removeClass: function( classes ){\n return this.toggleClass( classes, false );\n },\n\n flashClass: function( classes, duration ){\n var self = this;\n\n if( duration == null ){\n duration = 250;\n } else if( duration === 0 ){\n return self; // nothing to do really\n }\n\n self.addClass( classes );\n setTimeout(function(){\n self.removeClass( classes );\n }, duration);\n\n return self;\n }\n});\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar elesfn = ({\n allAre: function( selector ){\n return this.filter(selector).length === this.length;\n },\n\n is: function( selector ){\n return this.filter(selector).length > 0;\n },\n\n some: function( fn, thisArg ){\n for( var i = 0; i < this.length; i++ ){\n var ret = !thisArg ? fn( this[i], i, this ) : fn.apply( thisArg, [ this[i], i, this ] );\n\n if( ret ){\n return true;\n }\n }\n\n return false;\n },\n\n every: function( fn, thisArg ){\n for( var i = 0; i < this.length; i++ ){\n var ret = !thisArg ? fn( this[i], i, this ) : fn.apply( thisArg, [ this[i], i, this ] );\n\n if( !ret ){\n return false;\n }\n }\n\n return true;\n },\n\n same: function( collection ){\n collection = this.cy().collection( collection );\n\n // cheap extra check\n if( this.length !== collection.length ){\n return false;\n }\n\n return this.intersect( collection ).length === this.length;\n },\n\n anySame: function( collection ){\n collection = this.cy().collection( collection );\n\n return this.intersect( collection ).length > 0;\n },\n\n allAreNeighbors: function( collection ){\n collection = this.cy().collection( collection );\n\n return this.neighborhood().intersect( collection ).length === collection.length;\n }\n});\n\nelesfn.allAreNeighbours = elesfn.allAreNeighbors;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar elesfn = ({\n parent: function( selector ){\n var parents = [];\n var cy = this._private.cy;\n\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n var parent = cy.getElementById( ele._private.data.parent );\n\n if( parent.size() > 0 ){\n parents.push( parent );\n }\n }\n\n return this.spawn( parents, { unique: true } ).filter( selector );\n },\n\n parents: function( selector ){\n var parents = [];\n\n var eles = this.parent();\n while( eles.nonempty() ){\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n parents.push( ele );\n }\n\n eles = eles.parent();\n }\n\n return this.spawn( parents, { unique: true } ).filter( selector );\n },\n\n commonAncestors: function( selector ){\n var ancestors;\n\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n var parents = ele.parents();\n\n ancestors = ancestors || parents;\n\n ancestors = ancestors.intersect( parents ); // current list must be common with current ele parents set\n }\n\n return ancestors.filter( selector );\n },\n\n orphans: function( selector ){\n return this.stdFilter(function( ele ){\n return ele.isNode() && ele.parent().empty();\n }).filter( selector );\n },\n\n nonorphans: function( selector ){\n return this.stdFilter(function( ele ){\n return ele.isNode() && ele.parent().nonempty();\n }).filter( selector );\n },\n\n children: function( selector ){\n var children = [];\n\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n children = children.concat( ele._private.children );\n }\n\n return this.spawn( children, { unique: true } ).filter( selector );\n },\n\n siblings: function( selector ){\n return this.parent().children().not( this ).filter( selector );\n },\n\n isParent: function(){\n var ele = this[0];\n\n if( ele ){\n return ele._private.children.length !== 0;\n }\n },\n\n isChild: function(){\n var ele = this[0];\n\n if( ele ){\n return ele._private.data.parent !== undefined && ele.parent().length !== 0;\n }\n },\n\n descendants: function( selector ){\n var elements = [];\n\n function add( eles ){\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n\n elements.push( ele );\n\n if( ele.children().nonempty() ){\n add( ele.children() );\n }\n }\n }\n\n add( this.children() );\n\n return this.spawn( elements, { unique: true } ).filter( selector );\n }\n});\n\n// aliases\nelesfn.ancestors = elesfn.parents;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar define = require('../define');\nvar fn, elesfn;\n\nfn = elesfn = ({\n\n data: define.data({\n field: 'data',\n bindingEvent: 'data',\n allowBinding: true,\n allowSetting: true,\n settingEvent: 'data',\n settingTriggersEvent: true,\n triggerFnName: 'trigger',\n allowGetting: true,\n immutableKeys: {\n 'id': true,\n 'source': true,\n 'target': true,\n 'parent': true\n },\n updateStyle: true\n }),\n\n removeData: define.removeData({\n field: 'data',\n event: 'data',\n triggerFnName: 'trigger',\n triggerEvent: true,\n immutableKeys: {\n 'id': true,\n 'source': true,\n 'target': true,\n 'parent': true\n },\n updateStyle: true\n }),\n\n scratch: define.data({\n field: 'scratch',\n bindingEvent: 'scratch',\n allowBinding: true,\n allowSetting: true,\n settingEvent: 'scratch',\n settingTriggersEvent: true,\n triggerFnName: 'trigger',\n allowGetting: true,\n updateStyle: true\n }),\n\n removeScratch: define.removeData({\n field: 'scratch',\n event: 'scratch',\n triggerFnName: 'trigger',\n triggerEvent: true,\n updateStyle: true\n }),\n\n rscratch: define.data({\n field: 'rscratch',\n allowBinding: false,\n allowSetting: true,\n settingTriggersEvent: false,\n allowGetting: true\n }),\n\n removeRscratch: define.removeData({\n field: 'rscratch',\n triggerEvent: false\n }),\n\n id: function(){\n var ele = this[0];\n\n if( ele ){\n return ele._private.data.id;\n }\n }\n\n});\n\n// aliases\nfn.attr = fn.data;\nfn.removeAttr = fn.removeData;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar util = require('../util');\n\nvar elesfn = {};\n\nfunction defineDegreeFunction(callback){\n return function( includeLoops ){\n var self = this;\n\n if( includeLoops === undefined ){\n includeLoops = true;\n }\n\n if( self.length === 0 ){ return; }\n\n if( self.isNode() && !self.removed() ){\n var degree = 0;\n var node = self[0];\n var connectedEdges = node._private.edges;\n\n for( var i = 0; i < connectedEdges.length; i++ ){\n var edge = connectedEdges[i];\n\n if( !includeLoops && edge.isLoop() ){\n continue;\n }\n\n degree += callback( node, edge );\n }\n\n return degree;\n } else {\n return;\n }\n };\n}\n\nutil.extend(elesfn, {\n degree: defineDegreeFunction(function(node, edge){\n if( edge.source().same( edge.target() ) ){\n return 2;\n } else {\n return 1;\n }\n }),\n\n indegree: defineDegreeFunction(function(node, edge){\n if( edge.target().same(node) ){\n return 1;\n } else {\n return 0;\n }\n }),\n\n outdegree: defineDegreeFunction(function(node, edge){\n if( edge.source().same(node) ){\n return 1;\n } else {\n return 0;\n }\n })\n});\n\nfunction defineDegreeBoundsFunction(degreeFn, callback){\n return function( includeLoops ){\n var ret;\n var nodes = this.nodes();\n\n for( var i = 0; i < nodes.length; i++ ){\n var ele = nodes[i];\n var degree = ele[degreeFn]( includeLoops );\n if( degree !== undefined && (ret === undefined || callback(degree, ret)) ){\n ret = degree;\n }\n }\n\n return ret;\n };\n}\n\nutil.extend(elesfn, {\n minDegree: defineDegreeBoundsFunction('degree', function(degree, min){\n return degree < min;\n }),\n\n maxDegree: defineDegreeBoundsFunction('degree', function(degree, max){\n return degree > max;\n }),\n\n minIndegree: defineDegreeBoundsFunction('indegree', function(degree, min){\n return degree < min;\n }),\n\n maxIndegree: defineDegreeBoundsFunction('indegree', function(degree, max){\n return degree > max;\n }),\n\n minOutdegree: defineDegreeBoundsFunction('outdegree', function(degree, min){\n return degree < min;\n }),\n\n maxOutdegree: defineDegreeBoundsFunction('outdegree', function(degree, max){\n return degree > max;\n })\n});\n\nutil.extend(elesfn, {\n totalDegree: function( includeLoops ){\n var total = 0;\n var nodes = this.nodes();\n\n for( var i = 0; i < nodes.length; i++ ){\n total += nodes[i].degree( includeLoops );\n }\n\n return total;\n }\n});\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar define = require('../define');\nvar is = require('../is');\nvar util = require('../util');\nvar fn, elesfn;\n\nfn = elesfn = ({\n\n position: define.data({\n field: 'position',\n bindingEvent: 'position',\n allowBinding: true,\n allowSetting: true,\n settingEvent: 'position',\n settingTriggersEvent: true,\n triggerFnName: 'rtrigger',\n allowGetting: true,\n validKeys: ['x', 'y'],\n onSet: function( eles ){\n var updatedEles = eles.updateCompoundBounds();\n updatedEles.rtrigger('position');\n },\n canSet: function( ele ){\n return !ele.locked() && !ele.isParent();\n }\n }),\n\n // position but no notification to renderer\n silentPosition: define.data({\n field: 'position',\n bindingEvent: 'position',\n allowBinding: false,\n allowSetting: true,\n settingEvent: 'position',\n settingTriggersEvent: false,\n triggerFnName: 'trigger',\n allowGetting: true,\n validKeys: ['x', 'y'],\n onSet: function( eles ){\n eles.updateCompoundBounds();\n },\n canSet: function( ele ){\n return !ele.locked() && !ele.isParent();\n }\n }),\n\n positions: function( pos, silent ){\n if( is.plainObject(pos) ){\n this.position(pos);\n\n } else if( is.fn(pos) ){\n var fn = pos;\n\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n\n var pos = fn.apply(ele, [i, ele]);\n\n if( pos && !ele.locked() && !ele.isParent() ){\n var elePos = ele._private.position;\n elePos.x = pos.x;\n elePos.y = pos.y;\n }\n }\n\n var updatedEles = this.updateCompoundBounds();\n var toTrigger = updatedEles.length > 0 ? this.add( updatedEles ) : this;\n\n if( silent ){\n toTrigger.trigger('position');\n } else {\n toTrigger.rtrigger('position');\n }\n }\n\n return this; // chaining\n },\n\n silentPositions: function( pos ){\n return this.positions( pos, true );\n },\n\n // get/set the rendered (i.e. on screen) positon of the element\n renderedPosition: function( dim, val ){\n var ele = this[0];\n var cy = this.cy();\n var zoom = cy.zoom();\n var pan = cy.pan();\n var rpos = is.plainObject( dim ) ? dim : undefined;\n var setting = rpos !== undefined || ( val !== undefined && is.string(dim) );\n\n if( ele && ele.isNode() ){ // must have an element and must be a node to return position\n if( setting ){\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n\n if( val !== undefined ){ // set one dimension\n ele._private.position[dim] = ( val - pan[dim] )/zoom;\n } else if( rpos !== undefined ){ // set whole position\n ele._private.position = {\n x: ( rpos.x - pan.x ) /zoom,\n y: ( rpos.y - pan.y ) /zoom\n };\n }\n }\n\n this.rtrigger('position');\n } else { // getting\n var pos = ele._private.position;\n rpos = {\n x: pos.x * zoom + pan.x,\n y: pos.y * zoom + pan.y\n };\n\n if( dim === undefined ){ // then return the whole rendered position\n return rpos;\n } else { // then return the specified dimension\n return rpos[ dim ];\n }\n }\n } else if( !setting ){\n return undefined; // for empty collection case\n }\n\n return this; // chaining\n },\n\n // get/set the position relative to the parent\n relativePosition: function( dim, val ){\n var ele = this[0];\n var cy = this.cy();\n var ppos = is.plainObject( dim ) ? dim : undefined;\n var setting = ppos !== undefined || ( val !== undefined && is.string(dim) );\n var hasCompoundNodes = cy.hasCompoundNodes();\n\n if( ele && ele.isNode() ){ // must have an element and must be a node to return position\n if( setting ){\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n var parent = hasCompoundNodes ? ele.parent() : null;\n var hasParent = parent && parent.length > 0;\n var relativeToParent = hasParent;\n\n if( hasParent ){\n parent = parent[0];\n }\n\n var origin = relativeToParent ? parent._private.position : { x: 0, y: 0 };\n\n if( val !== undefined ){ // set one dimension\n ele._private.position[dim] = val + origin[dim];\n } else if( ppos !== undefined ){ // set whole position\n ele._private.position = {\n x: ppos.x + origin.x,\n y: ppos.y + origin.y\n };\n }\n }\n\n this.rtrigger('position');\n\n } else { // getting\n var pos = ele._private.position;\n var parent = hasCompoundNodes ? ele.parent() : null;\n var hasParent = parent && parent.length > 0;\n var relativeToParent = hasParent;\n\n if( hasParent ){\n parent = parent[0];\n }\n\n var origin = relativeToParent ? parent._private.position : { x: 0, y: 0 };\n\n ppos = {\n x: pos.x - origin.x,\n y: pos.y - origin.y\n };\n\n if( dim === undefined ){ // then return the whole rendered position\n return ppos;\n } else { // then return the specified dimension\n return ppos[ dim ];\n }\n }\n } else if( !setting ){\n return undefined; // for empty collection case\n }\n\n return this; // chaining\n },\n\n renderedBoundingBox: function( options ){\n var bb = this.boundingBox( options );\n var cy = this.cy();\n var zoom = cy.zoom();\n var pan = cy.pan();\n\n var x1 = bb.x1 * zoom + pan.x;\n var x2 = bb.x2 * zoom + pan.x;\n var y1 = bb.y1 * zoom + pan.y;\n var y2 = bb.y2 * zoom + pan.y;\n\n return {\n x1: x1,\n x2: x2,\n y1: y1,\n y2: y2,\n w: x2 - x1,\n h: y2 - y1\n };\n },\n\n updateCompoundBounds: function(){\n var cy = this.cy();\n\n if( !cy.styleEnabled() || !cy.hasCompoundNodes() ){ return cy.collection(); } // save cycles for non compound graphs or when style disabled\n\n var updated = [];\n\n function update( parent ){\n var children = parent.children();\n var style = parent._private.style;\n var includeLabels = style['compound-sizing-wrt-labels'].value === 'include';\n var bb = children.boundingBox({ includeLabels: includeLabels, includeEdges: true });\n var padding = {\n top: style['padding-top'].pfValue,\n bottom: style['padding-bottom'].pfValue,\n left: style['padding-left'].pfValue,\n right: style['padding-right'].pfValue\n };\n var pos = parent._private.position;\n var didUpdate = false;\n\n if( style['width'].value === 'auto' ){\n parent._private.autoWidth = bb.w;\n pos.x = (bb.x1 + bb.x2 - padding.left + padding.right)/2;\n didUpdate = true;\n }\n\n if( style['height'].value === 'auto' ){\n parent._private.autoHeight = bb.h;\n pos.y = (bb.y1 + bb.y2 - padding.top + padding.bottom)/2;\n didUpdate = true;\n }\n\n if( didUpdate ){\n updated.push( parent );\n }\n }\n\n // go up, level by level\n var eles = this.parent();\n while( eles.nonempty() ){\n\n // update each parent node in this level\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n\n update( ele );\n }\n\n // next level\n eles = eles.parent();\n }\n\n // return changed\n return this.spawn( updated );\n },\n\n // get the bounding box of the elements (in raw model position)\n boundingBox: function( options ){\n var eles = this;\n var cy = eles._private.cy;\n var cy_p = cy._private;\n var styleEnabled = cy_p.styleEnabled;\n\n options = options || util.staticEmptyObject();\n\n var includeNodes = options.includeNodes === undefined ? true : options.includeNodes;\n var includeEdges = options.includeEdges === undefined ? true : options.includeEdges;\n var includeLabels = options.includeLabels === undefined ? true : options.includeLabels;\n\n // recalculate projections etc\n if( styleEnabled ){\n cy_p.renderer.recalculateRenderedStyle( this );\n }\n\n var x1 = Infinity;\n var x2 = -Infinity;\n var y1 = Infinity;\n var y2 = -Infinity;\n\n // find bounds of elements\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var _p = ele._private;\n var style = _p.style;\n var display = styleEnabled ? _p.style['display'].value : 'element';\n var isNode = _p.group === 'nodes';\n var ex1, ex2, ey1, ey2, x, y;\n var includedEle = false;\n\n if( display === 'none' ){ continue; } // then ele doesn't take up space\n\n if( isNode && includeNodes ){\n includedEle = true;\n\n var pos = _p.position;\n x = pos.x;\n y = pos.y;\n var w = ele.outerWidth();\n var halfW = w/2;\n var h = ele.outerHeight();\n var halfH = h/2;\n\n // handle node dimensions\n /////////////////////////\n\n ex1 = x - halfW;\n ex2 = x + halfW;\n ey1 = y - halfH;\n ey2 = y + halfH;\n\n x1 = ex1 < x1 ? ex1 : x1;\n x2 = ex2 > x2 ? ex2 : x2;\n y1 = ey1 < y1 ? ey1 : y1;\n y2 = ey2 > y2 ? ey2 : y2;\n\n } else if( ele.isEdge() && includeEdges ){\n includedEle = true;\n\n var n1 = _p.source;\n var n1_p = n1._private;\n var n1pos = n1_p.position;\n\n var n2 = _p.target;\n var n2_p = n2._private;\n var n2pos = n2_p.position;\n\n\n // handle edge dimensions (rough box estimate)\n //////////////////////////////////////////////\n\n var rstyle = _p.rstyle || {};\n var w = 0;\n var wHalf = 0;\n\n if( styleEnabled ){\n w = style['width'].pfValue;\n wHalf = w/2;\n }\n\n ex1 = n1pos.x;\n ex2 = n2pos.x;\n ey1 = n1pos.y;\n ey2 = n2pos.y;\n\n if( ex1 > ex2 ){\n var temp = ex1;\n ex1 = ex2;\n ex2 = temp;\n }\n\n if( ey1 > ey2 ){\n var temp = ey1;\n ey1 = ey2;\n ey2 = temp;\n }\n\n // take into account edge width\n ex1 -= wHalf;\n ex2 += wHalf;\n ey1 -= wHalf;\n ey2 += wHalf;\n\n x1 = ex1 < x1 ? ex1 : x1;\n x2 = ex2 > x2 ? ex2 : x2;\n y1 = ey1 < y1 ? ey1 : y1;\n y2 = ey2 > y2 ? ey2 : y2;\n\n // handle points along edge (sanity check)\n //////////////////////////////////////////\n\n if( styleEnabled ){\n var pts = rstyle.bezierPts || rstyle.linePts || [];\n\n for( var j = 0; j < pts.length; j++ ){\n var pt = pts[j];\n\n ex1 = pt.x - wHalf;\n ex2 = pt.x + wHalf;\n ey1 = pt.y - wHalf;\n ey2 = pt.y + wHalf;\n\n x1 = ex1 < x1 ? ex1 : x1;\n x2 = ex2 > x2 ? ex2 : x2;\n y1 = ey1 < y1 ? ey1 : y1;\n y2 = ey2 > y2 ? ey2 : y2;\n }\n }\n\n // precise haystacks (sanity check)\n ///////////////////////////////////\n\n if( styleEnabled && style['curve-style'].strValue === 'haystack' ){\n var hpts = rstyle.haystackPts;\n\n ex1 = hpts[0].x;\n ey1 = hpts[0].y;\n ex2 = hpts[1].x;\n ey2 = hpts[1].y;\n\n if( ex1 > ex2 ){\n var temp = ex1;\n ex1 = ex2;\n ex2 = temp;\n }\n\n if( ey1 > ey2 ){\n var temp = ey1;\n ey1 = ey2;\n ey2 = temp;\n }\n\n x1 = ex1 < x1 ? ex1 : x1;\n x2 = ex2 > x2 ? ex2 : x2;\n y1 = ey1 < y1 ? ey1 : y1;\n y2 = ey2 > y2 ? ey2 : y2;\n }\n\n } // edges\n\n\n // handle label dimensions\n //////////////////////////\n\n if( styleEnabled ){\n\n var _p = ele._private;\n var style = _p.style;\n var rstyle = _p.rstyle;\n var label = style['label'].strValue;\n var fontSize = style['font-size'];\n var halign = style['text-halign'];\n var valign = style['text-valign'];\n var labelWidth = rstyle.labelWidth;\n var labelHeight = rstyle.labelHeight;\n var labelX = rstyle.labelX;\n var labelY = rstyle.labelY;\n var isEdge = ele.isEdge();\n var autorotate = style['edge-text-rotation'].strValue === 'autorotate';\n\n if( includeLabels && label && fontSize && labelHeight != null && labelWidth != null && labelX != null && labelY != null && halign && valign ){\n var lh = labelHeight;\n var lw = labelWidth;\n var lx1, lx2, ly1, ly2;\n\n if( isEdge ){\n lx1 = labelX - lw/2;\n lx2 = labelX + lw/2;\n ly1 = labelY - lh/2;\n ly2 = labelY + lh/2;\n\n if( autorotate ){\n var theta = _p.rscratch.labelAngle;\n var cos = Math.cos( theta );\n var sin = Math.sin( theta );\n\n var rotate = function( x, y ){\n x = x - labelX;\n y = y - labelY;\n\n return {\n x: x*cos - y*sin + labelX,\n y: x*sin + y*cos + labelY\n };\n };\n\n var px1y1 = rotate( lx1, ly1 );\n var px1y2 = rotate( lx1, ly2 );\n var px2y1 = rotate( lx2, ly1 );\n var px2y2 = rotate( lx2, ly2 );\n\n lx1 = Math.min( px1y1.x, px1y2.x, px2y1.x, px2y2.x );\n lx2 = Math.max( px1y1.x, px1y2.x, px2y1.x, px2y2.x );\n ly1 = Math.min( px1y1.y, px1y2.y, px2y1.y, px2y2.y );\n ly2 = Math.max( px1y1.y, px1y2.y, px2y1.y, px2y2.y );\n }\n } else {\n switch( halign.value ){\n case 'left':\n lx1 = labelX - lw;\n lx2 = labelX;\n break;\n\n case 'center':\n lx1 = labelX - lw/2;\n lx2 = labelX + lw/2;\n break;\n\n case 'right':\n lx1 = labelX;\n lx2 = labelX + lw;\n break;\n }\n\n switch( valign.value ){\n case 'top':\n ly1 = labelY - lh;\n ly2 = labelY;\n break;\n\n case 'center':\n ly1 = labelY - lh/2;\n ly2 = labelY + lh/2;\n break;\n\n case 'bottom':\n ly1 = labelY;\n ly2 = labelY + lh;\n break;\n }\n }\n\n x1 = lx1 < x1 ? lx1 : x1;\n x2 = lx2 > x2 ? lx2 : x2;\n y1 = ly1 < y1 ? ly1 : y1;\n y2 = ly2 > y2 ? ly2 : y2;\n }\n } // style enabled for labels\n } // for\n\n var noninf = function(x){\n if( x === Infinity || x === -Infinity ){\n return 0;\n }\n\n return x;\n };\n\n x1 = noninf(x1);\n x2 = noninf(x2);\n y1 = noninf(y1);\n y2 = noninf(y2);\n\n return {\n x1: x1,\n x2: x2,\n y1: y1,\n y2: y2,\n w: x2 - x1,\n h: y2 - y1\n };\n }\n});\n\nvar defineDimFns = function( opts ){\n opts.uppercaseName = util.capitalize( opts.name );\n opts.autoName = 'auto' + opts.uppercaseName;\n opts.labelName = 'label' + opts.uppercaseName;\n opts.outerName = 'outer' + opts.uppercaseName;\n opts.uppercaseOuterName = util.capitalize( opts.outerName );\n\n fn[ opts.name ] = function dimImpl(){\n var ele = this[0];\n var _p = ele._private;\n var cy = _p.cy;\n var styleEnabled = cy._private.styleEnabled;\n\n if( ele ){\n if( styleEnabled ){\n var d = _p.style[ opts.name ];\n\n switch( d.strValue ){\n case 'auto':\n return _p[ opts.autoName ] || 0;\n case 'label':\n return _p.rstyle[ opts.labelName ] || 0;\n default:\n return d.pfValue;\n }\n } else {\n return 1;\n }\n }\n };\n\n fn[ 'outer' + opts.uppercaseName ] = function outerDimImpl(){\n var ele = this[0];\n var _p = ele._private;\n var cy = _p.cy;\n var styleEnabled = cy._private.styleEnabled;\n\n if( ele ){\n if( styleEnabled ){\n var style = _p.style;\n var dim = ele[ opts.name ]();\n var border = style['border-width'].pfValue;\n var padding = style[ opts.paddings[0] ].pfValue + style[ opts.paddings[1] ].pfValue;\n\n return dim + border + padding;\n } else {\n return 1;\n }\n }\n };\n\n fn[ 'rendered' + opts.uppercaseName ] = function renderedDimImpl(){\n var ele = this[0];\n\n if( ele ){\n var d = ele[ opts.name ]();\n return d * this.cy().zoom();\n }\n };\n\n fn[ 'rendered' + opts.uppercaseOuterName ] = function renderedOuterDimImpl(){\n var ele = this[0];\n\n if( ele ){\n var od = ele[ opts.outerName ]();\n return od * this.cy().zoom();\n }\n };\n};\n\ndefineDimFns({\n name: 'width',\n paddings: ['padding-left', 'padding-right']\n});\n\ndefineDimFns({\n name: 'height',\n paddings: ['padding-top', 'padding-bottom']\n});\n\n// aliases\nfn.modelPosition = fn.point = fn.position;\nfn.modelPositions = fn.points = fn.positions;\nfn.renderedPoint = fn.renderedPosition;\nfn.relativePoint = fn.relativePosition;\nfn.boundingbox = fn.boundingBox;\nfn.renderedBoundingbox = fn.renderedBoundingBox;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar util = require('../util');\nvar is = require('../is');\n\n// represents a node or an edge\nvar Element = function(cy, params, restore){\n if( !(this instanceof Element) ){\n return new Element(cy, params, restore);\n }\n\n var self = this;\n restore = (restore === undefined || restore ? true : false);\n\n if( cy === undefined || params === undefined || !is.core(cy) ){\n util.error('An element must have a core reference and parameters set');\n return;\n }\n\n var group = params.group;\n\n // try to automatically infer the group if unspecified\n if( group == null ){\n if( params.data.source != null && params.data.target != null ){\n group = 'edges';\n } else {\n group = 'nodes';\n }\n }\n\n // validate group\n if( group !== 'nodes' && group !== 'edges' ){\n util.error('An element must be of type `nodes` or `edges`; you specified `' + group + '`');\n return;\n }\n\n // make the element array-like, just like a collection\n this.length = 1;\n this[0] = this;\n\n // NOTE: when something is added here, add also to ele.json()\n this._private = {\n cy: cy,\n single: true, // indicates this is an element\n data: params.data || {}, // data object\n position: params.position || {}, // (x, y) position pair\n autoWidth: undefined, // width and height of nodes calculated by the renderer when set to special 'auto' value\n autoHeight: undefined,\n listeners: [], // array of bound listeners\n group: group, // string; 'nodes' or 'edges'\n style: {}, // properties as set by the style\n rstyle: {}, // properties for style sent from the renderer to the core\n styleCxts: [], // applied style contexts from the styler\n removed: true, // whether it's inside the vis; true if removed (set true here since we call restore)\n selected: params.selected ? true : false, // whether it's selected\n selectable: params.selectable === undefined ? true : ( params.selectable ? true : false ), // whether it's selectable\n locked: params.locked ? true : false, // whether the element is locked (cannot be moved)\n grabbed: false, // whether the element is grabbed by the mouse; renderer sets this privately\n grabbable: params.grabbable === undefined ? true : ( params.grabbable ? true : false ), // whether the element can be grabbed\n active: false, // whether the element is active from user interaction\n classes: {}, // map ( className => true )\n animation: { // object for currently-running animations\n current: [],\n queue: []\n },\n rscratch: {}, // object in which the renderer can store information\n scratch: params.scratch || {}, // scratch objects\n edges: [], // array of connected edges\n children: [] // array of children\n };\n\n // renderedPosition overrides if specified\n if( params.renderedPosition ){\n var rpos = params.renderedPosition;\n var pan = cy.pan();\n var zoom = cy.zoom();\n\n this._private.position = {\n x: (rpos.x - pan.x)/zoom,\n y: (rpos.y - pan.y)/zoom\n };\n }\n\n if( is.string(params.classes) ){\n var classes = params.classes.split(/\\s+/);\n for( var i = 0, l = classes.length; i < l; i++ ){\n var cls = classes[i];\n if( !cls || cls === '' ){ continue; }\n\n self._private.classes[cls] = true;\n }\n }\n\n if( params.style || params.css ){\n cy.style().applyBypass( this, params.style || params.css );\n }\n\n if( restore === undefined || restore ){\n this.restore();\n }\n\n};\n\nmodule.exports = Element;\n","'use strict';\n\nvar define = require('../define');\n\nvar elesfn = ({\n on: define.on(), // .on( events [, selector] [, data], handler)\n one: define.on({ unbindSelfOnTrigger: true }),\n once: define.on({ unbindAllBindersOnTrigger: true }),\n off: define.off(), // .off( events [, selector] [, handler] )\n trigger: define.trigger(), // .trigger( events [, extraParams] )\n\n rtrigger: function(event, extraParams){ // for internal use only\n if( this.length === 0 ){ return; } // empty collections don't need to notify anything\n\n // notify renderer\n this.cy().notify({\n type: event,\n collection: this\n });\n\n this.trigger(event, extraParams);\n return this;\n }\n});\n\n// aliases:\ndefine.eventAliasesOn( elesfn );\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../is');\nvar Selector = require('../selector');\n\nvar elesfn = ({\n nodes: function( selector ){\n return this.filter(function(i, element){\n return element.isNode();\n }).filter(selector);\n },\n\n edges: function( selector ){\n return this.filter(function(i, element){\n return element.isEdge();\n }).filter(selector);\n },\n\n filter: function( filter ){\n if( is.fn(filter) ){\n var elements = [];\n\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n\n if( filter.apply(ele, [i, ele]) ){\n elements.push(ele);\n }\n }\n\n return this.spawn(elements);\n\n } else if( is.string(filter) || is.elementOrCollection(filter) ){\n return Selector(filter).filter(this);\n\n } else if( filter === undefined ){\n return this;\n }\n\n return this.spawn(); // if not handled by above, give 'em an empty collection\n },\n\n not: function( toRemove ){\n if( !toRemove ){\n return this;\n } else {\n\n if( is.string( toRemove ) ){\n toRemove = this.filter( toRemove );\n }\n\n var elements = [];\n\n for( var i = 0; i < this.length; i++ ){\n var element = this[i];\n\n var remove = toRemove._private.ids[ element.id() ];\n if( !remove ){\n elements.push( element );\n }\n }\n\n return this.spawn( elements );\n }\n\n },\n\n absoluteComplement: function(){\n var cy = this._private.cy;\n\n return cy.elements().not( this );\n },\n\n intersect: function( other ){\n // if a selector is specified, then filter by it instead\n if( is.string(other) ){\n var selector = other;\n return this.filter( selector );\n }\n\n var elements = [];\n var col1 = this;\n var col2 = other;\n var col1Smaller = this.length < other.length;\n // var ids1 = col1Smaller ? col1._private.ids : col2._private.ids;\n var ids2 = col1Smaller ? col2._private.ids : col1._private.ids;\n var col = col1Smaller ? col1 : col2;\n\n for( var i = 0; i < col.length; i++ ){\n var id = col[i]._private.data.id;\n var ele = ids2[ id ];\n\n if( ele ){\n elements.push( ele );\n }\n }\n\n return this.spawn( elements );\n },\n\n xor: function( other ){\n var cy = this._private.cy;\n\n if( is.string(other) ){\n other = cy.$( other );\n }\n\n var elements = [];\n var col1 = this;\n var col2 = other;\n\n var add = function( col, other ){\n\n for( var i = 0; i < col.length; i++ ){\n var ele = col[i];\n var id = ele._private.data.id;\n var inOther = other._private.ids[ id ];\n\n if( !inOther ){\n elements.push( ele );\n }\n }\n\n };\n\n add( col1, col2 );\n add( col2, col1 );\n\n return this.spawn( elements );\n },\n\n diff: function( other ){\n var cy = this._private.cy;\n\n if( is.string(other) ){\n other = cy.$( other );\n }\n\n var left = [];\n var right = [];\n var both = [];\n var col1 = this;\n var col2 = other;\n\n var add = function( col, other, retEles ){\n\n for( var i = 0; i < col.length; i++ ){\n var ele = col[i];\n var id = ele._private.data.id;\n var inOther = other._private.ids[ id ];\n\n if( inOther ){\n both.push( ele );\n } else {\n retEles.push( ele );\n }\n }\n\n };\n\n add( col1, col2, left );\n add( col2, col1, right );\n\n return {\n left: this.spawn( left, { unique: true } ),\n right: this.spawn( right, { unique: true } ),\n both: this.spawn( both, { unique: true } )\n };\n },\n\n add: function( toAdd ){\n var cy = this._private.cy;\n\n if( !toAdd ){\n return this;\n }\n\n if( is.string(toAdd) ){\n var selector = toAdd;\n toAdd = cy.elements(selector);\n }\n\n var elements = [];\n\n for( var i = 0; i < this.length; i++ ){\n elements.push( this[i] );\n }\n\n for( var i = 0; i < toAdd.length; i++ ){\n\n var add = !this._private.ids[ toAdd[i].id() ];\n if( add ){\n elements.push( toAdd[i] );\n }\n }\n\n return this.spawn(elements);\n },\n\n // in place merge on calling collection\n merge: function( toAdd ){\n var _p = this._private;\n var cy = _p.cy;\n\n if( !toAdd ){\n return this;\n }\n\n if( is.string(toAdd) ){\n var selector = toAdd;\n toAdd = cy.elements(selector);\n }\n\n for( var i = 0; i < toAdd.length; i++ ){\n var toAddEle = toAdd[i];\n var id = toAddEle.id();\n var add = !_p.ids[ id ];\n\n if( add ){\n var index = this.length++;\n\n this[ index ] = toAddEle;\n _p.ids[ id ] = toAddEle;\n _p.indexes[ id ] = index;\n }\n }\n\n return this; // chaining\n },\n\n // remove single ele in place in calling collection\n unmergeOne: function( ele ){\n ele = ele[0];\n\n var _p = this._private;\n var id = ele.id();\n var i = _p.indexes[ id ];\n\n if( i == null ){\n return this; // no need to remove\n }\n\n // remove ele\n this[i] = undefined;\n _p.ids[ id ] = undefined;\n _p.indexes[ id ] = undefined;\n\n var unmergedLastEle = i === this.length - 1;\n\n // replace empty spot with last ele in collection\n if( this.length > 1 && !unmergedLastEle ){\n var lastEleI = this.length - 1;\n var lastEle = this[ lastEleI ];\n\n this[ lastEleI ] = undefined;\n this[i] = lastEle;\n _p.indexes[ lastEle.id() ] = i;\n }\n\n // the collection is now 1 ele smaller\n this.length--;\n\n return this;\n },\n\n // remove eles in place on calling collection\n unmerge: function( toRemove ){\n var cy = this._private.cy;\n\n if( !toRemove ){\n return this;\n }\n\n if( is.string(toRemove) ){\n var selector = toRemove;\n toRemove = cy.elements(selector);\n }\n\n for( var i = 0; i < toRemove.length; i++ ){\n this.unmergeOne( toRemove[i] );\n }\n\n return this; // chaining\n },\n\n map: function( mapFn, thisArg ){\n var arr = [];\n var eles = this;\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var ret = thisArg ? mapFn.apply( thisArg, [ele, i, eles] ) : mapFn( ele, i, eles );\n\n arr.push( ret );\n }\n\n return arr;\n },\n\n stdFilter: function( fn, thisArg ){\n var filterEles = [];\n var eles = this;\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var include = thisArg ? fn.apply( thisArg, [ele, i, eles] ) : fn( ele, i, eles );\n\n if( include ){\n filterEles.push( ele );\n }\n }\n\n return this.spawn( filterEles );\n },\n\n max: function( valFn, thisArg ){\n var max = -Infinity;\n var maxEle;\n var eles = this;\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var val = thisArg ? valFn.apply( thisArg, [ ele, i, eles ] ) : valFn( ele, i, eles );\n\n if( val > max ){\n max = val;\n maxEle = ele;\n }\n }\n\n return {\n value: max,\n ele: maxEle\n };\n },\n\n min: function( valFn, thisArg ){\n var min = Infinity;\n var minEle;\n var eles = this;\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var val = thisArg ? valFn.apply( thisArg, [ ele, i, eles ] ) : valFn( ele, i, eles );\n\n if( val < min ){\n min = val;\n minEle = ele;\n }\n }\n\n return {\n value: min,\n ele: minEle\n };\n }\n});\n\n// aliases\nvar fn = elesfn;\nfn['u'] = fn['|'] = fn['+'] = fn.union = fn.or = fn.add;\nfn['\\\\'] = fn['!'] = fn['-'] = fn.difference = fn.relativeComplement = fn.subtract = fn.not;\nfn['n'] = fn['&'] = fn['.'] = fn.and = fn.intersection = fn.intersect;\nfn['^'] = fn['(+)'] = fn['(-)'] = fn.symmetricDifference = fn.symdiff = fn.xor;\nfn.fnFilter = fn.filterFn = fn.stdFilter;\nfn.complement = fn.abscomp = fn.absoluteComplement;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar elesfn = ({\n isNode: function(){\n return this.group() === 'nodes';\n },\n\n isEdge: function(){\n return this.group() === 'edges';\n },\n\n isLoop: function(){\n return this.isEdge() && this.source().id() === this.target().id();\n },\n\n isSimple: function(){\n return this.isEdge() && this.source().id() !== this.target().id();\n },\n\n group: function(){\n var ele = this[0];\n\n if( ele ){\n return ele._private.group;\n }\n }\n});\n\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar util = require('../util');\nvar is = require('../is');\n\nvar Element = require('./element');\n\n// factory for generating edge ids when no id is specified for a new element\nvar idFactory = {\n prefix: 'ele',\n id: 0,\n generate: function(cy, element, tryThisId){\n var json = is.element( element ) ? element._private : element;\n var id = tryThisId != null ? tryThisId : this.prefix + this.id;\n\n if( cy.getElementById(id).empty() ){\n this.id++; // we've used the current id, so move it up\n } else { // otherwise keep trying successive unused ids\n while( !cy.getElementById(id).empty() ){\n id = this.prefix + ( ++this.id );\n }\n }\n\n return id;\n }\n};\n\n// represents a set of nodes, edges, or both together\nvar Collection = function(cy, elements, options){\n if( !(this instanceof Collection) ){\n return new Collection(cy, elements, options);\n }\n\n if( cy === undefined || !is.core(cy) ){\n util.error('A collection must have a reference to the core');\n return;\n }\n\n var ids = {};\n var indexes = {};\n var createdElements = false;\n\n if( !elements ){\n elements = [];\n } else if( elements.length > 0 && is.plainObject( elements[0] ) && !is.element( elements[0] ) ){\n createdElements = true;\n\n // make elements from json and restore all at once later\n var eles = [];\n var elesIds = {};\n\n for( var i = 0, l = elements.length; i < l; i++ ){\n var json = elements[i];\n\n if( json.data == null ){\n json.data = {};\n }\n\n var data = json.data;\n\n // make sure newly created elements have valid ids\n if( data.id == null ){\n data.id = idFactory.generate( cy, json );\n } else if( cy.getElementById( data.id ).length !== 0 || elesIds[ data.id ] ){\n continue; // can't create element if prior id already exists\n }\n\n var ele = new Element( cy, json, false );\n eles.push( ele );\n elesIds[ data.id ] = true;\n }\n\n elements = eles;\n }\n\n this.length = 0;\n\n for( var i = 0, l = elements.length; i < l; i++ ){\n var element = elements[i];\n if( !element ){ continue; }\n\n var id = element._private.data.id;\n\n if( !options || (options.unique && !ids[ id ] ) ){\n ids[ id ] = element;\n indexes[ id ] = this.length;\n\n this[ this.length ] = element;\n this.length++;\n }\n }\n\n this._private = {\n cy: cy,\n ids: ids,\n indexes: indexes\n };\n\n // restore the elements if we created them from json\n if( createdElements ){\n this.restore();\n }\n};\n\n// Functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n// keep the prototypes in sync (an element has the same functions as a collection)\n// and use elefn and elesfn as shorthands to the prototypes\nvar elesfn = Element.prototype = Collection.prototype;\n\nelesfn.instanceString = function(){\n return 'collection';\n};\n\nelesfn.spawn = function( cy, eles, opts ){\n if( !is.core(cy) ){ // cy is optional\n opts = eles;\n eles = cy;\n cy = this.cy();\n }\n\n return new Collection( cy, eles, opts );\n};\n\nelesfn.cy = function(){\n return this._private.cy;\n};\n\nelesfn.element = function(){\n return this[0];\n};\n\nelesfn.collection = function(){\n if( is.collection(this) ){\n return this;\n } else { // an element\n return new Collection( this._private.cy, [this] );\n }\n};\n\nelesfn.unique = function(){\n return new Collection( this._private.cy, this, { unique: true } );\n};\n\nelesfn.getElementById = function( id ){\n var cy = this._private.cy;\n var ele = this._private.ids[ id ];\n\n return ele ? ele : new Collection(cy); // get ele or empty collection\n};\n\nelesfn.json = function( obj ){\n var ele = this.element();\n var cy = this.cy();\n\n if( ele == null && obj ){ return this; } // can't set to no eles\n\n if( ele == null ){ return undefined; } // can't get from no eles\n\n var p = ele._private;\n\n if( is.plainObject(obj) ){ // set\n\n cy.startBatch();\n\n if( obj.data ){\n ele.data( obj.data );\n }\n\n if( obj.position ){\n ele.position( obj.position );\n }\n\n // ignore group -- immutable\n\n var checkSwitch = function( k, trueFnName, falseFnName ){\n var obj_k = obj[k];\n\n if( obj_k != null && obj_k !== p[k] ){\n if( obj_k ){\n ele[ trueFnName ]();\n } else {\n ele[ falseFnName ]();\n }\n }\n };\n\n checkSwitch( 'removed', 'remove', 'restore' );\n\n checkSwitch( 'selected', 'select', 'unselect' );\n\n checkSwitch( 'selectable', 'selectify', 'unselectify' );\n\n checkSwitch( 'locked', 'lock', 'unlock' );\n\n checkSwitch( 'grabbable', 'grabify', 'ungrabify' );\n\n if( obj.classes != null ){\n ele.classes( obj.classes );\n }\n\n cy.endBatch();\n\n return this;\n\n } else if( obj === undefined ){ // get\n\n var json = {\n data: util.copy( p.data ),\n position: util.copy( p.position ),\n group: p.group,\n removed: p.removed,\n selected: p.selected,\n selectable: p.selectable,\n locked: p.locked,\n grabbable: p.grabbable,\n classes: null\n };\n\n var classes = [];\n for( var cls in p.classes ){\n if( p.classes[cls] ){\n classes.push(cls);\n }\n }\n json.classes = classes.join(' ');\n\n return json;\n }\n};\n\nelesfn.jsons = function(){\n var jsons = [];\n\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n var json = ele.json();\n\n jsons.push( json );\n }\n\n return jsons;\n};\n\nelesfn.clone = function(){\n var cy = this.cy();\n var elesArr = [];\n\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n var json = ele.json();\n var clone = new Element(cy, json, false); // NB no restore\n\n elesArr.push( clone );\n }\n\n return new Collection( cy, elesArr );\n};\nelesfn.copy = elesfn.clone;\n\nelesfn.restore = function( notifyRenderer ){\n var self = this;\n var restored = [];\n var cy = self.cy();\n\n if( notifyRenderer === undefined ){\n notifyRenderer = true;\n }\n\n // create arrays of nodes and edges, since we need to\n // restore the nodes first\n var elements = [];\n var nodes = [], edges = [];\n var numNodes = 0;\n var numEdges = 0;\n for( var i = 0, l = self.length; i < l; i++ ){\n var ele = self[i];\n\n // keep nodes first in the array and edges after\n if( ele.isNode() ){ // put to front of array if node\n nodes.push( ele );\n numNodes++;\n } else { // put to end of array if edge\n edges.push( ele );\n numEdges++;\n }\n }\n\n elements = nodes.concat( edges );\n\n // now, restore each element\n for( var i = 0, l = elements.length; i < l; i++ ){\n var ele = elements[i];\n\n if( !ele.removed() ){\n // don't need to do anything\n continue;\n }\n\n var _private = ele._private;\n var data = _private.data;\n\n // set id and validate\n if( data.id === undefined ){\n data.id = idFactory.generate( cy, ele );\n\n } else if( is.number(data.id) ){\n data.id = '' + data.id; // now it's a string\n\n } else if( is.emptyString(data.id) || !is.string(data.id) ){\n util.error('Can not create element with invalid string ID `' + data.id + '`');\n\n // can't create element if it has empty string as id or non-string id\n continue;\n } else if( cy.getElementById( data.id ).length !== 0 ){\n util.error('Can not create second element with ID `' + data.id + '`');\n\n // can't create element if one already has that id\n continue;\n }\n\n var id = data.id; // id is finalised, now let's keep a ref\n\n if( ele.isNode() ){ // extra checks for nodes\n var node = ele;\n var pos = _private.position;\n\n // make sure the nodes have a defined position\n\n if( pos.x == null ){\n pos.x = 0;\n }\n\n if( pos.y == null ){\n pos.y = 0;\n }\n }\n\n if( ele.isEdge() ){ // extra checks for edges\n\n var edge = ele;\n var fields = ['source', 'target'];\n var fieldsLength = fields.length;\n var badSourceOrTarget = false;\n for(var j = 0; j < fieldsLength; j++){\n\n var field = fields[j];\n var val = data[field];\n\n if( is.number(val) ){\n val = data[field] = '' + data[field]; // now string\n }\n\n if( val == null || val === '' ){\n // can't create if source or target is not defined properly\n util.error('Can not create edge `' + id + '` with unspecified ' + field);\n badSourceOrTarget = true;\n } else if( cy.getElementById(val).empty() ){\n // can't create edge if one of its nodes doesn't exist\n util.error('Can not create edge `' + id + '` with nonexistant ' + field + ' `' + val + '`');\n badSourceOrTarget = true;\n }\n }\n\n if( badSourceOrTarget ){ continue; } // can't create this\n\n var src = cy.getElementById( data.source );\n var tgt = cy.getElementById( data.target );\n\n src._private.edges.push( edge );\n tgt._private.edges.push( edge );\n\n edge._private.source = src;\n edge._private.target = tgt;\n\n } // if is edge\n\n // create mock ids map for element so it can be used like collections\n _private.ids = {};\n _private.ids[ id ] = ele;\n\n _private.removed = false;\n cy.addToPool( ele );\n\n restored.push( ele );\n } // for each element\n\n // do compound node sanity checks\n for( var i = 0; i < numNodes; i++ ){ // each node\n var node = elements[i];\n var data = node._private.data;\n\n if( is.number(data.parent) ){ // then automake string\n data.parent = '' + data.parent;\n }\n\n var parentId = data.parent;\n\n var specifiedParent = parentId != null;\n\n if( specifiedParent ){\n var parent = cy.getElementById( parentId );\n\n if( parent.empty() ){\n // non-existant parent; just remove it\n data.parent = undefined;\n } else {\n var selfAsParent = false;\n var ancestor = parent;\n while( !ancestor.empty() ){\n if( node.same(ancestor) ){\n // mark self as parent and remove from data\n selfAsParent = true;\n data.parent = undefined; // remove parent reference\n\n // exit or we loop forever\n break;\n }\n\n ancestor = ancestor.parent();\n }\n\n if( !selfAsParent ){\n // connect with children\n parent[0]._private.children.push( node );\n node._private.parent = parent[0];\n\n // let the core know we have a compound graph\n cy._private.hasCompoundNodes = true;\n }\n } // else\n } // if specified parent\n } // for each node\n\n restored = new Collection( cy, restored );\n if( restored.length > 0 ){\n\n var toUpdateStyle = restored.add( restored.connectedNodes() ).add( restored.parent() );\n toUpdateStyle.updateStyle( notifyRenderer );\n\n if( notifyRenderer ){\n restored.rtrigger('add');\n } else {\n restored.trigger('add');\n }\n }\n\n return self; // chainability\n};\n\nelesfn.removed = function(){\n var ele = this[0];\n return ele && ele._private.removed;\n};\n\nelesfn.inside = function(){\n var ele = this[0];\n return ele && !ele._private.removed;\n};\n\nelesfn.remove = function( notifyRenderer ){\n var self = this;\n var removed = [];\n var elesToRemove = [];\n var elesToRemoveIds = {};\n var cy = self._private.cy;\n\n if( notifyRenderer === undefined ){\n notifyRenderer = true;\n }\n\n // add connected edges\n function addConnectedEdges(node){\n var edges = node._private.edges;\n for( var i = 0; i < edges.length; i++ ){\n add( edges[i] );\n }\n }\n\n\n // add descendant nodes\n function addChildren(node){\n var children = node._private.children;\n\n for( var i = 0; i < children.length; i++ ){\n add( children[i] );\n }\n }\n\n function add( ele ){\n var alreadyAdded = elesToRemoveIds[ ele.id() ];\n if( alreadyAdded ){\n return;\n } else {\n elesToRemoveIds[ ele.id() ] = true;\n }\n\n if( ele.isNode() ){\n elesToRemove.push( ele ); // nodes are removed last\n\n addConnectedEdges( ele );\n addChildren( ele );\n } else {\n elesToRemove.unshift( ele ); // edges are removed first\n }\n }\n\n // make the list of elements to remove\n // (may be removing more than specified due to connected edges etc)\n\n for( var i = 0, l = self.length; i < l; i++ ){\n var ele = self[i];\n\n add( ele );\n }\n\n function removeEdgeRef(node, edge){\n var connectedEdges = node._private.edges;\n for( var j = 0; j < connectedEdges.length; j++ ){\n var connectedEdge = connectedEdges[j];\n\n if( edge === connectedEdge ){\n connectedEdges.splice( j, 1 );\n break;\n }\n }\n }\n\n function removeChildRef(parent, ele){\n ele = ele[0];\n parent = parent[0];\n var children = parent._private.children;\n\n for( var j = 0; j < children.length; j++ ){\n if( children[j][0] === ele[0] ){\n children.splice(j, 1);\n break;\n }\n }\n }\n\n for( var i = 0; i < elesToRemove.length; i++ ){\n var ele = elesToRemove[i];\n\n // mark as removed\n ele._private.removed = true;\n\n // remove from core pool\n cy.removeFromPool( ele );\n\n // add to list of removed elements\n removed.push( ele );\n\n if( ele.isEdge() ){ // remove references to this edge in its connected nodes\n var src = ele.source()[0];\n var tgt = ele.target()[0];\n\n removeEdgeRef( src, ele );\n removeEdgeRef( tgt, ele );\n\n } else { // remove reference to parent\n var parent = ele.parent();\n\n if( parent.length !== 0 ){\n removeChildRef(parent, ele);\n }\n }\n }\n\n // check to see if we have a compound graph or not\n var elesStillInside = cy._private.elements;\n cy._private.hasCompoundNodes = false;\n for( var i = 0; i < elesStillInside.length; i++ ){\n var ele = elesStillInside[i];\n\n if( ele.isParent() ){\n cy._private.hasCompoundNodes = true;\n break;\n }\n }\n\n var removedElements = new Collection( this.cy(), removed );\n if( removedElements.size() > 0 ){\n // must manually notify since trigger won't do this automatically once removed\n\n if( notifyRenderer ){\n this.cy().notify({\n type: 'remove',\n collection: removedElements\n });\n }\n\n removedElements.trigger('remove');\n }\n\n // check for empty remaining parent nodes\n var checkedParentId = {};\n for( var i = 0; i < elesToRemove.length; i++ ){\n var ele = elesToRemove[i];\n var isNode = ele._private.group === 'nodes';\n var parentId = ele._private.data.parent;\n\n if( isNode && parentId !== undefined && !checkedParentId[ parentId ] ){\n checkedParentId[ parentId ] = true;\n var parent = cy.getElementById( parentId );\n\n if( parent && parent.length !== 0 && !parent._private.removed && parent.children().length === 0 ){\n parent.updateStyle();\n }\n }\n }\n\n return new Collection( cy, removed );\n};\n\nelesfn.move = function( struct ){\n var cy = this._private.cy;\n\n if( struct.source !== undefined || struct.target !== undefined ){\n var srcId = struct.source;\n var tgtId = struct.target;\n var srcExists = cy.getElementById( srcId ).length > 0;\n var tgtExists = cy.getElementById( tgtId ).length > 0;\n\n if( srcExists || tgtExists ){\n var jsons = this.jsons();\n\n this.remove();\n\n for( var i = 0; i < jsons.length; i++ ){\n var json = jsons[i];\n\n if( json.group === 'edges' ){\n if( srcExists ){ json.data.source = srcId; }\n if( tgtExists ){ json.data.target = tgtId; }\n }\n }\n\n return cy.add( jsons );\n }\n\n } else if( struct.parent !== undefined ){ // move node to new parent\n var parentId = struct.parent;\n var parentExists = parentId === null || cy.getElementById( parentId ).length > 0;\n\n if( parentExists ){\n var jsons = this.jsons();\n var descs = this.descendants();\n var descsEtc = descs.merge( descs.add(this).connectedEdges() );\n\n this.remove(); // NB: also removes descendants and their connected edges\n\n for( var i = 0; i < this.length; i++ ){\n var json = jsons[i];\n\n if( json.group === 'nodes' ){\n json.data.parent = parentId === null ? undefined : parentId;\n }\n }\n }\n\n return cy.add( jsons ).merge( descsEtc.restore() );\n }\n\n return this; // if nothing done\n};\n\n[\n require('./algorithms'),\n require('./animation'),\n require('./class'),\n require('./comparators'),\n require('./compounds'),\n require('./data'),\n require('./degree'),\n require('./dimensions'),\n require('./events'),\n require('./filter'),\n require('./group'),\n require('./index'),\n require('./iteration'),\n require('./layout'),\n require('./style'),\n require('./switch-functions'),\n require('./traversing')\n].forEach(function( props ){\n util.extend( elesfn, props );\n});\n\nmodule.exports = Collection;\n","'use strict';\n\nvar is = require('../is');\nvar zIndexSort = require('./zsort');\n\nvar elesfn = ({\n each: function(fn){\n if( is.fn(fn) ){\n for(var i = 0; i < this.length; i++){\n var ele = this[i];\n var ret = fn.apply( ele, [ i, ele ] );\n\n if( ret === false ){ break; } // exit each early on return false\n }\n }\n return this;\n },\n\n forEach: function(fn, thisArg){\n if( is.fn(fn) ){\n\n for(var i = 0; i < this.length; i++){\n var ele = this[i];\n var ret = thisArg ? fn.apply( thisArg, [ ele, i, this ] ) : fn( ele, i, this );\n\n if( ret === false ){ break; } // exit each early on return false\n }\n }\n\n return this;\n },\n\n toArray: function(){\n var array = [];\n\n for(var i = 0; i < this.length; i++){\n array.push( this[i] );\n }\n\n return array;\n },\n\n slice: function(start, end){\n var array = [];\n var thisSize = this.length;\n\n if( end == null ){\n end = thisSize;\n }\n\n if( start == null ){\n start = 0;\n }\n\n if( start < 0 ){\n start = thisSize + start;\n }\n\n if( end < 0 ){\n end = thisSize + end;\n }\n\n for(var i = start; i >= 0 && i < end && i < thisSize; i++){\n array.push( this[i] );\n }\n\n return this.spawn(array);\n },\n\n size: function(){\n return this.length;\n },\n\n eq: function(i){\n return this[i] || this.spawn();\n },\n\n first: function(){\n return this[0] || this.spawn();\n },\n\n last: function(){\n return this[ this.length - 1 ] || this.spawn();\n },\n\n empty: function(){\n return this.length === 0;\n },\n\n nonempty: function(){\n return !this.empty();\n },\n\n sort: function( sortFn ){\n if( !is.fn( sortFn ) ){\n return this;\n }\n\n var sorted = this.toArray().sort( sortFn );\n\n return this.spawn(sorted);\n },\n\n sortByZIndex: function(){\n return this.sort( zIndexSort );\n },\n\n zDepth: function(){\n var ele = this[0];\n if( !ele ){ return undefined; }\n\n // var cy = ele.cy();\n var _p = ele._private;\n var group = _p.group;\n\n if( group === 'nodes' ){\n var depth = _p.data.parent ? ele.parents().size() : 0;\n\n if( !ele.isParent() ){\n return Number.MAX_VALUE; // childless nodes always on top\n }\n\n return depth;\n } else {\n var src = _p.source;\n var tgt = _p.target;\n var srcDepth = src.zDepth();\n var tgtDepth = tgt.zDepth();\n\n return Math.max( srcDepth, tgtDepth, 0 ); // depth of deepest parent\n }\n }\n});\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../is');\nvar util = require('../util');\n\nvar elesfn = ({\n\n // using standard layout options, apply position function (w/ or w/o animation)\n layoutPositions: function( layout, options, fn ){\n var nodes = this.nodes();\n var cy = this.cy();\n\n layout.trigger({ type: 'layoutstart', layout: layout });\n\n layout.animations = [];\n\n if( options.animate ){\n for( var i = 0; i < nodes.length; i++ ){\n var node = nodes[i];\n var lastNode = i === nodes.length - 1;\n\n var newPos = fn.call( node, i, node );\n var pos = node.position();\n\n if( !is.number(pos.x) || !is.number(pos.y) ){\n node.silentPosition({ x: 0, y: 0 });\n }\n\n var ani = node.animation({\n position: newPos,\n duration: options.animationDuration,\n easing: options.animationEasing,\n step: !lastNode ? undefined : function(){\n if( options.fit ){\n cy.fit( options.eles, options.padding );\n }\n },\n complete: !lastNode ? undefined : function(){\n if( options.zoom != null ){\n cy.zoom( options.zoom );\n }\n\n if( options.pan ){\n cy.pan( options.pan );\n }\n\n if( options.fit ){\n cy.fit( options.eles, options.padding );\n }\n\n layout.one('layoutstop', options.stop);\n layout.trigger({ type: 'layoutstop', layout: layout });\n }\n });\n\n layout.animations.push( ani );\n\n ani.play();\n }\n\n layout.one('layoutready', options.ready);\n layout.trigger({ type: 'layoutready', layout: layout });\n } else {\n nodes.positions( fn );\n\n if( options.fit ){\n cy.fit( options.eles, options.padding );\n }\n\n if( options.zoom != null ){\n cy.zoom( options.zoom );\n }\n\n if( options.pan ){\n cy.pan( options.pan );\n }\n\n layout.one('layoutready', options.ready);\n layout.trigger({ type: 'layoutready', layout: layout });\n\n layout.one('layoutstop', options.stop);\n layout.trigger({ type: 'layoutstop', layout: layout });\n }\n\n return this; // chaining\n },\n\n layout: function( options ){\n var cy = this.cy();\n\n cy.layout( util.extend({}, options, {\n eles: this\n }) );\n\n return this;\n },\n\n makeLayout: function( options ){\n var cy = this.cy();\n\n return cy.makeLayout( util.extend({}, options, {\n eles: this\n }) );\n }\n\n});\n\n// aliases:\nelesfn.createLayout = elesfn.makeLayout;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar is = require('../is');\n\nvar elesfn = ({\n\n // fully updates (recalculates) the style for the elements\n updateStyle: function( notifyRenderer ){\n var cy = this._private.cy;\n\n if( !cy.styleEnabled() ){ return this; }\n\n if( cy._private.batchingStyle ){\n var bEles = cy._private.batchStyleEles;\n\n bEles.merge( this );\n\n return this; // chaining and exit early when batching\n }\n\n var style = cy.style();\n notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false;\n\n style.apply( this );\n\n var updatedCompounds = this.updateCompoundBounds();\n var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;\n\n if( notifyRenderer ){\n toNotify.rtrigger('style'); // let renderer know we changed style\n } else {\n toNotify.trigger('style'); // just fire the event\n }\n return this; // chaining\n },\n\n // just update the mappers in the elements' styles; cheaper than eles.updateStyle()\n updateMappers: function( notifyRenderer ){\n var cy = this._private.cy;\n var style = cy.style();\n notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false;\n\n if( !cy.styleEnabled() ){ return this; }\n\n style.updateMappers( this );\n\n var updatedCompounds = this.updateCompoundBounds();\n var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;\n\n if( notifyRenderer ){\n toNotify.rtrigger('style'); // let renderer know we changed style\n } else {\n toNotify.trigger('style'); // just fire the event\n }\n return this; // chaining\n },\n\n // get the specified css property as a rendered value (i.e. on-screen value)\n // or get the whole rendered style if no property specified (NB doesn't allow setting)\n renderedCss: function( property ){\n var cy = this.cy();\n if( !cy.styleEnabled() ){ return this; }\n\n var ele = this[0];\n\n if( ele ){\n var renstyle = ele.cy().style().getRenderedStyle( ele );\n\n if( property === undefined ){\n return renstyle;\n } else {\n return renstyle[ property ];\n }\n }\n },\n\n // read the calculated css style of the element or override the style (via a bypass)\n css: function( name, value ){\n var cy = this.cy();\n\n if( !cy.styleEnabled() ){ return this; }\n\n var updateTransitions = false;\n var style = cy.style();\n\n if( is.plainObject(name) ){ // then extend the bypass\n var props = name;\n style.applyBypass( this, props, updateTransitions );\n\n var updatedCompounds = this.updateCompoundBounds();\n var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;\n toNotify.rtrigger('style'); // let the renderer know we've updated style\n\n } else if( is.string(name) ){\n\n if( value === undefined ){ // then get the property from the style\n var ele = this[0];\n\n if( ele ){\n return style.getStylePropertyValue( ele, name );\n } else { // empty collection => can't get any value\n return;\n }\n\n } else { // then set the bypass with the property value\n style.applyBypass( this, name, value, updateTransitions );\n\n var updatedCompounds = this.updateCompoundBounds();\n var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;\n toNotify.rtrigger('style'); // let the renderer know we've updated style\n }\n\n } else if( name === undefined ){\n var ele = this[0];\n\n if( ele ){\n return style.getRawStyle( ele );\n } else { // empty collection => can't get any value\n return;\n }\n }\n\n return this; // chaining\n },\n\n removeCss: function( names ){\n var cy = this.cy();\n\n if( !cy.styleEnabled() ){ return this; }\n\n var updateTransitions = false;\n var style = cy.style();\n var eles = this;\n\n if( names === undefined ){\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n\n style.removeAllBypasses( ele, updateTransitions );\n }\n } else {\n names = names.split(/\\s+/);\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n\n style.removeBypasses( ele, names, updateTransitions );\n }\n }\n\n var updatedCompounds = this.updateCompoundBounds();\n var toNotify = updatedCompounds.length > 0 ? this.add( updatedCompounds ) : this;\n toNotify.rtrigger('style'); // let the renderer know we've updated style\n\n return this; // chaining\n },\n\n show: function(){\n this.css('display', 'element');\n return this; // chaining\n },\n\n hide: function(){\n this.css('display', 'none');\n return this; // chaining\n },\n\n visible: function(){\n var cy = this.cy();\n if( !cy.styleEnabled() ){ return true; }\n\n var ele = this[0];\n var hasCompoundNodes = cy.hasCompoundNodes();\n\n if( ele ){\n var style = ele._private.style;\n\n if(\n style['visibility'].value !== 'visible'\n || style['display'].value !== 'element'\n ){\n return false;\n }\n\n if( ele._private.group === 'nodes' ){\n if( !hasCompoundNodes ){ return true; }\n\n var parents = ele._private.data.parent ? ele.parents() : null;\n\n if( parents ){\n for( var i = 0; i < parents.length; i++ ){\n var parent = parents[i];\n var pStyle = parent._private.style;\n var pVis = pStyle['visibility'].value;\n var pDis = pStyle['display'].value;\n\n if( pVis !== 'visible' || pDis !== 'element' ){\n return false;\n }\n }\n }\n\n return true;\n } else {\n var src = ele._private.source;\n var tgt = ele._private.target;\n\n return src.visible() && tgt.visible();\n }\n\n }\n },\n\n hidden: function(){\n var ele = this[0];\n\n if( ele ){\n return !ele.visible();\n }\n },\n\n effectiveOpacity: function(){\n var cy = this.cy();\n if( !cy.styleEnabled() ){ return 1; }\n\n var hasCompoundNodes = cy.hasCompoundNodes();\n var ele = this[0];\n\n if( ele ){\n var _p = ele._private;\n var parentOpacity = _p.style.opacity.value;\n\n if( !hasCompoundNodes ){ return parentOpacity; }\n\n var parents = !_p.data.parent ? null : ele.parents();\n\n if( parents ){\n for( var i = 0; i < parents.length; i++ ){\n var parent = parents[i];\n var opacity = parent._private.style.opacity.value;\n\n parentOpacity = opacity * parentOpacity;\n }\n }\n\n return parentOpacity;\n }\n },\n\n transparent: function(){\n var cy = this.cy();\n if( !cy.styleEnabled() ){ return false; }\n\n var ele = this[0];\n var hasCompoundNodes = ele.cy().hasCompoundNodes();\n\n if( ele ){\n if( !hasCompoundNodes ){\n return ele._private.style.opacity.value === 0;\n } else {\n return ele.effectiveOpacity() === 0;\n }\n }\n },\n\n isFullAutoParent: function(){\n var cy = this.cy();\n if( !cy.styleEnabled() ){ return false; }\n\n var ele = this[0];\n\n if( ele ){\n var autoW = ele._private.style['width'].value === 'auto';\n var autoH = ele._private.style['height'].value === 'auto';\n\n return ele.isParent() && autoW && autoH;\n }\n },\n\n backgrounding: function(){\n var cy = this.cy();\n if( !cy.styleEnabled() ){ return false; }\n\n var ele = this[0];\n\n return ele._private.backgrounding ? true : false;\n }\n\n});\n\n\nelesfn.bypass = elesfn.style = elesfn.css;\nelesfn.renderedStyle = elesfn.renderedCss;\nelesfn.removeBypass = elesfn.removeStyle = elesfn.removeCss;\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar elesfn = {};\n\nfunction defineSwitchFunction(params){\n return function(){\n var args = arguments;\n var changedEles = [];\n\n // e.g. cy.nodes().select( data, handler )\n if( args.length === 2 ){\n var data = args[0];\n var handler = args[1];\n this.bind( params.event, data, handler );\n }\n\n // e.g. cy.nodes().select( handler )\n else if( args.length === 1 ){\n var handler = args[0];\n this.bind( params.event, handler );\n }\n\n // e.g. cy.nodes().select()\n else if( args.length === 0 ){\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n var able = !params.ableField || ele._private[params.ableField];\n var changed = ele._private[params.field] != params.value;\n\n if( params.overrideAble ){\n var overrideAble = params.overrideAble(ele);\n\n if( overrideAble !== undefined ){\n able = overrideAble;\n\n if( !overrideAble ){ return this; } // to save cycles assume not able for all on override\n }\n }\n\n if( able ){\n ele._private[params.field] = params.value;\n\n if( changed ){\n changedEles.push( ele );\n }\n }\n }\n\n var changedColl = this.spawn( changedEles );\n changedColl.updateStyle(); // change of state => possible change of style\n changedColl.trigger( params.event );\n }\n\n return this;\n };\n}\n\nfunction defineSwitchSet( params ){\n elesfn[ params.field ] = function(){\n var ele = this[0];\n\n if( ele ){\n if( params.overrideField ){\n var val = params.overrideField(ele);\n\n if( val !== undefined ){\n return val;\n }\n }\n\n return ele._private[ params.field ];\n }\n };\n\n elesfn[ params.on ] = defineSwitchFunction({\n event: params.on,\n field: params.field,\n ableField: params.ableField,\n overrideAble: params.overrideAble,\n value: true\n });\n\n elesfn[ params.off ] = defineSwitchFunction({\n event: params.off,\n field: params.field,\n ableField: params.ableField,\n overrideAble: params.overrideAble,\n value: false\n });\n}\n\ndefineSwitchSet({\n field: 'locked',\n overrideField: function(ele){\n return ele.cy().autolock() ? true : undefined;\n },\n on: 'lock',\n off: 'unlock'\n});\n\ndefineSwitchSet({\n field: 'grabbable',\n overrideField: function(ele){\n return ele.cy().autoungrabify() ? false : undefined;\n },\n on: 'grabify',\n off: 'ungrabify'\n});\n\ndefineSwitchSet({\n field: 'selected',\n ableField: 'selectable',\n overrideAble: function(ele){\n return ele.cy().autounselectify() ? false : undefined;\n },\n on: 'select',\n off: 'unselect'\n});\n\ndefineSwitchSet({\n field: 'selectable',\n overrideField: function(ele){\n return ele.cy().autounselectify() ? false : undefined;\n },\n on: 'selectify',\n off: 'unselectify'\n});\n\nelesfn.deselect = elesfn.unselect;\n\nelesfn.grabbed = function(){\n var ele = this[0];\n if( ele ){\n return ele._private.grabbed;\n }\n};\n\ndefineSwitchSet({\n field: 'active',\n on: 'activate',\n off: 'unactivate'\n});\n\nelesfn.inactive = function(){\n var ele = this[0];\n if( ele ){\n return !ele._private.active;\n }\n};\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar util = require('../util');\nvar is = require('../is');\n\nvar elesfn = {};\n\nutil.extend(elesfn, {\n // get the root nodes in the DAG\n roots: function( selector ){\n var eles = this;\n var roots = [];\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n if( !ele.isNode() ){\n continue;\n }\n\n var hasEdgesPointingIn = ele.connectedEdges(function(){\n return this.data('target') === ele.id() && this.data('source') !== ele.id();\n }).length > 0;\n\n if( !hasEdgesPointingIn ){\n roots.push( ele );\n }\n }\n\n return this.spawn( roots, { unique: true } ).filter( selector );\n },\n\n // get the leaf nodes in the DAG\n leaves: function( selector ){\n var eles = this;\n var leaves = [];\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n if( !ele.isNode() ){\n continue;\n }\n\n var hasEdgesPointingOut = ele.connectedEdges(function(){\n return this.data('source') === ele.id() && this.data('target') !== ele.id();\n }).length > 0;\n\n if( !hasEdgesPointingOut ){\n leaves.push( ele );\n }\n }\n\n return this.spawn( leaves, { unique: true } ).filter( selector );\n },\n\n // normally called children in graph theory\n // these nodes =edges=> outgoing nodes\n outgoers: function( selector ){\n var eles = this;\n var oEles = [];\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var eleId = ele.id();\n\n if( !ele.isNode() ){ continue; }\n\n var edges = ele._private.edges;\n for( var j = 0; j < edges.length; j++ ){\n var edge = edges[j];\n var srcId = edge._private.data.source;\n var tgtId = edge._private.data.target;\n\n if( srcId === eleId && tgtId !== eleId ){\n oEles.push( edge );\n oEles.push( edge.target()[0] );\n }\n }\n }\n\n return this.spawn( oEles, { unique: true } ).filter( selector );\n },\n\n // aka DAG descendants\n successors: function( selector ){\n var eles = this;\n var sEles = [];\n var sElesIds = {};\n\n for(;;){\n var outgoers = eles.outgoers();\n\n if( outgoers.length === 0 ){ break; } // done if no outgoers left\n\n var newOutgoers = false;\n for( var i = 0; i < outgoers.length; i++ ){\n var outgoer = outgoers[i];\n var outgoerId = outgoer.id();\n\n if( !sElesIds[ outgoerId ] ){\n sElesIds[ outgoerId ] = true;\n sEles.push( outgoer );\n newOutgoers = true;\n }\n }\n\n if( !newOutgoers ){ break; } // done if touched all outgoers already\n\n eles = outgoers;\n }\n\n return this.spawn( sEles, { unique: true } ).filter( selector );\n },\n\n // normally called parents in graph theory\n // these nodes <=edges= incoming nodes\n incomers: function( selector ){\n var eles = this;\n var oEles = [];\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var eleId = ele.id();\n\n if( !ele.isNode() ){ continue; }\n\n var edges = ele._private.edges;\n for( var j = 0; j < edges.length; j++ ){\n var edge = edges[j];\n var srcId = edge._private.data.source;\n var tgtId = edge._private.data.target;\n\n if( tgtId === eleId && srcId !== eleId ){\n oEles.push( edge );\n oEles.push( edge.source()[0] );\n }\n }\n }\n\n return this.spawn( oEles, { unique: true } ).filter( selector );\n },\n\n // aka DAG ancestors\n predecessors: function( selector ){\n var eles = this;\n var pEles = [];\n var pElesIds = {};\n\n for(;;){\n var incomers = eles.incomers();\n\n if( incomers.length === 0 ){ break; } // done if no incomers left\n\n var newIncomers = false;\n for( var i = 0; i < incomers.length; i++ ){\n var incomer = incomers[i];\n var incomerId = incomer.id();\n\n if( !pElesIds[ incomerId ] ){\n pElesIds[ incomerId ] = true;\n pEles.push( incomer );\n newIncomers = true;\n }\n }\n\n if( !newIncomers ){ break; } // done if touched all incomers already\n\n eles = incomers;\n }\n\n return this.spawn( pEles, { unique: true } ).filter( selector );\n }\n});\n\n\n// Neighbourhood functions\n//////////////////////////\n\nutil.extend(elesfn, {\n neighborhood: function(selector){\n var elements = [];\n var nodes = this.nodes();\n\n for( var i = 0; i < nodes.length; i++ ){ // for all nodes\n var node = nodes[i];\n var connectedEdges = node.connectedEdges();\n\n // for each connected edge, add the edge and the other node\n for( var j = 0; j < connectedEdges.length; j++ ){\n var edge = connectedEdges[j];\n var src = edge._private.source;\n var tgt = edge._private.target;\n var otherNode = node === src ? tgt : src;\n\n // need check in case of loop\n if( otherNode.length > 0 ){\n elements.push( otherNode[0] ); // add node 1 hop away\n }\n\n // add connected edge\n elements.push( edge[0] );\n }\n\n }\n\n return ( this.spawn( elements, { unique: true } ) ).filter( selector );\n },\n\n closedNeighborhood: function(selector){\n return this.neighborhood().add( this ).filter( selector );\n },\n\n openNeighborhood: function(selector){\n return this.neighborhood( selector );\n }\n});\n\n// aliases\nelesfn.neighbourhood = elesfn.neighborhood;\nelesfn.closedNeighbourhood = elesfn.closedNeighborhood;\nelesfn.openNeighbourhood = elesfn.openNeighborhood;\n\n// Edge functions\n/////////////////\n\nutil.extend(elesfn, {\n source: function( selector ){\n var ele = this[0];\n var src;\n\n if( ele ){\n src = ele._private.source;\n }\n\n return src && selector ? src.filter( selector ) : src;\n },\n\n target: function( selector ){\n var ele = this[0];\n var tgt;\n\n if( ele ){\n tgt = ele._private.target;\n }\n\n return tgt && selector ? tgt.filter( selector ) : tgt;\n },\n\n sources: defineSourceFunction({\n attr: 'source'\n }),\n\n targets: defineSourceFunction({\n attr: 'target'\n })\n});\n\nfunction defineSourceFunction( params ){\n return function( selector ){\n var sources = [];\n\n for( var i = 0; i < this.length; i++ ){\n var ele = this[i];\n var src = ele._private[ params.attr ];\n\n if( src ){\n sources.push( src );\n }\n }\n\n return this.spawn( sources, { unique: true } ).filter( selector );\n };\n}\n\nutil.extend(elesfn, {\n edgesWith: defineEdgesWithFunction(),\n\n edgesTo: defineEdgesWithFunction({\n thisIs: 'source'\n })\n});\n\nfunction defineEdgesWithFunction( params ){\n\n return function edgesWithImpl( otherNodes ){\n var elements = [];\n var cy = this._private.cy;\n var p = params || {};\n\n // get elements if a selector is specified\n if( is.string(otherNodes) ){\n otherNodes = cy.$( otherNodes );\n }\n\n var thisIds = this._private.ids;\n var otherIds = otherNodes._private.ids;\n\n for( var h = 0; h < otherNodes.length; h++ ){\n var edges = otherNodes[h]._private.edges;\n\n for( var i = 0; i < edges.length; i++ ){\n var edge = edges[i];\n var edgeData = edge._private.data;\n var thisToOther = thisIds[ edgeData.source ] && otherIds[ edgeData.target ];\n var otherToThis = otherIds[ edgeData.source ] && thisIds[ edgeData.target ];\n var edgeConnectsThisAndOther = thisToOther || otherToThis;\n\n if( !edgeConnectsThisAndOther ){ continue; }\n\n if( p.thisIs ){\n if( p.thisIs === 'source' && !thisToOther ){ continue; }\n\n if( p.thisIs === 'target' && !otherToThis ){ continue; }\n }\n\n elements.push( edge );\n }\n }\n\n return this.spawn( elements, { unique: true } );\n };\n}\n\nutil.extend(elesfn, {\n connectedEdges: function( selector ){\n var retEles = [];\n\n var eles = this;\n for( var i = 0; i < eles.length; i++ ){\n var node = eles[i];\n if( !node.isNode() ){ continue; }\n\n var edges = node._private.edges;\n\n for( var j = 0; j < edges.length; j++ ){\n var edge = edges[j];\n retEles.push( edge );\n }\n }\n\n return this.spawn( retEles, { unique: true } ).filter( selector );\n },\n\n connectedNodes: function( selector ){\n var retEles = [];\n\n var eles = this;\n for( var i = 0; i < eles.length; i++ ){\n var edge = eles[i];\n if( !edge.isEdge() ){ continue; }\n\n retEles.push( edge.source()[0] );\n retEles.push( edge.target()[0] );\n }\n\n return this.spawn( retEles, { unique: true } ).filter( selector );\n },\n\n parallelEdges: defineParallelEdgesFunction(),\n\n codirectedEdges: defineParallelEdgesFunction({\n codirected: true\n })\n});\n\nfunction defineParallelEdgesFunction(params){\n var defaults = {\n codirected: false\n };\n params = util.extend({}, defaults, params);\n\n return function( selector ){\n var elements = [];\n var edges = this.edges();\n var p = params;\n\n // look at all the edges in the collection\n for( var i = 0; i < edges.length; i++ ){\n var edge1 = edges[i];\n var src1 = edge1.source()[0];\n var srcid1 = src1.id();\n var tgt1 = edge1.target()[0];\n var tgtid1 = tgt1.id();\n var srcEdges1 = src1._private.edges;\n\n // look at edges connected to the src node of this edge\n for( var j = 0; j < srcEdges1.length; j++ ){\n var edge2 = srcEdges1[j];\n var edge2data = edge2._private.data;\n var tgtid2 = edge2data.target;\n var srcid2 = edge2data.source;\n\n var codirected = tgtid2 === tgtid1 && srcid2 === srcid1;\n var oppdirected = srcid1 === tgtid2 && tgtid1 === srcid2;\n\n if( (p.codirected && codirected) || (!p.codirected && (codirected || oppdirected)) ){\n elements.push( edge2 );\n }\n }\n }\n\n return this.spawn( elements, { unique: true } ).filter( selector );\n };\n\n}\n\n// Misc functions\n/////////////////\n\nutil.extend(elesfn, {\n components: function(){\n var cy = this.cy();\n var visited = cy.collection();\n var unvisited = this.nodes();\n var components = [];\n\n var visitInComponent = function( node, component ){\n visited.merge( node );\n unvisited.unmerge( node );\n component.merge( node );\n };\n\n do {\n var component = cy.collection();\n components.push( component );\n\n var root = unvisited[0];\n visitInComponent( root, component );\n\n this.bfs({\n directed: false,\n roots: root,\n visit: function( i, depth, v, e, u ){\n visitInComponent( v, component );\n }\n });\n\n } while( unvisited.length > 0 );\n\n return components.map(function( component ){\n return component.closedNeighborhood(); // add the edges\n });\n }\n});\n\nmodule.exports = elesfn;\n","'use strict';\n\nvar zIndexSort = function( a, b ){\n var cy = a.cy();\n var a_p = a._private;\n var b_p = b._private;\n var zDiff = a_p.style['z-index'].value - b_p.style['z-index'].value;\n var depthA = 0;\n var depthB = 0;\n var hasCompoundNodes = cy.hasCompoundNodes();\n var aIsNode = a_p.group === 'nodes';\n var aIsEdge = a_p.group === 'edges';\n var bIsNode = b_p.group === 'nodes';\n var bIsEdge = b_p.group === 'edges';\n\n // no need to calculate element depth if there is no compound node\n if( hasCompoundNodes ){\n depthA = a.zDepth();\n depthB = b.zDepth();\n }\n\n var depthDiff = depthA - depthB;\n var sameDepth = depthDiff === 0;\n\n if( sameDepth ){\n\n if( aIsNode && bIsEdge ){\n return 1; // 'a' is a node, it should be drawn later\n\n } else if( aIsEdge && bIsNode ){\n return -1; // 'a' is an edge, it should be drawn first\n\n } else { // both nodes or both edges\n if( zDiff === 0 ){ // same z-index => compare indices in the core (order added to graph w/ last on top)\n return a_p.index - b_p.index;\n } else {\n return zDiff;\n }\n }\n\n // elements on different level\n } else {\n return depthDiff; // deeper element should be drawn later\n }\n\n};\n\nmodule.exports = zIndexSort;\n","'use strict';\n\nvar is = require('../is');\nvar util = require('../util');\nvar Collection = require('../collection');\nvar Element = require('../collection/element');\nvar window = require('../window');\nvar document = window ? window.document : null;\nvar NullRenderer = require('../extensions/renderer/null');\n\nvar corefn = {\n add: function(opts){\n\n var elements;\n var cy = this;\n\n // add the elements\n if( is.elementOrCollection(opts) ){\n var eles = opts;\n\n if( eles._private.cy === cy ){ // same instance => just restore\n elements = eles.restore();\n\n } else { // otherwise, copy from json\n var jsons = [];\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n jsons.push( ele.json() );\n }\n\n elements = new Collection( cy, jsons );\n }\n }\n\n // specify an array of options\n else if( is.array(opts) ){\n var jsons = opts;\n\n elements = new Collection(cy, jsons);\n }\n\n // specify via opts.nodes and opts.edges\n else if( is.plainObject(opts) && (is.array(opts.nodes) || is.array(opts.edges)) ){\n var elesByGroup = opts;\n var jsons = [];\n\n var grs = ['nodes', 'edges'];\n for( var i = 0, il = grs.length; i < il; i++ ){\n var group = grs[i];\n var elesArray = elesByGroup[group];\n\n if( is.array(elesArray) ){\n\n for( var j = 0, jl = elesArray.length; j < jl; j++ ){\n var json = util.extend( { group: group }, elesArray[j] );\n\n jsons.push( json );\n }\n }\n }\n\n elements = new Collection(cy, jsons);\n }\n\n // specify options for one element\n else {\n var json = opts;\n elements = (new Element( cy, json )).collection();\n }\n\n return elements;\n },\n\n remove: function(collection){\n if( is.elementOrCollection(collection) ){\n collection = collection;\n } else if( is.string(collection) ){\n var selector = collection;\n collection = this.$( selector );\n }\n\n return collection.remove();\n },\n\n load: function(elements, onload, ondone){\n var cy = this;\n\n cy.notifications(false);\n\n // remove old elements\n var oldEles = cy.elements();\n if( oldEles.length > 0 ){\n oldEles.remove();\n }\n\n if( elements != null ){\n if( is.plainObject(elements) || is.array(elements) ){\n cy.add( elements );\n }\n }\n\n cy.one('layoutready', function(e){\n cy.notifications(true);\n cy.trigger(e); // we missed this event by turning notifications off, so pass it on\n\n cy.notify({\n type: 'load',\n collection: cy.elements()\n });\n\n cy.one('load', onload);\n cy.trigger('load');\n }).one('layoutstop', function(){\n cy.one('done', ondone);\n cy.trigger('done');\n });\n\n var layoutOpts = util.extend({}, cy._private.options.layout);\n layoutOpts.eles = cy.$();\n\n cy.layout( layoutOpts );\n\n return this;\n }\n};\n\nmodule.exports = corefn;\n","'use strict';\n\nvar define = require('../define');\nvar util = require('../util');\nvar is = require('../is');\n\nvar corefn = ({\n\n // pull in animation functions\n animate: define.animate(),\n animation: define.animation(),\n animated: define.animated(),\n clearQueue: define.clearQueue(),\n delay: define.delay(),\n delayAnimation: define.delayAnimation(),\n stop: define.stop(),\n\n addToAnimationPool: function( eles ){\n var cy = this;\n\n if( !cy.styleEnabled() ){ return; } // save cycles when no style used\n\n cy._private.aniEles.merge( eles );\n },\n\n stopAnimationLoop: function(){\n this._private.animationsRunning = false;\n },\n\n startAnimationLoop: function(){\n var cy = this;\n\n cy._private.animationsRunning = true;\n\n if( !cy.styleEnabled() ){ return; } // save cycles when no style used\n\n // NB the animation loop will exec in headless environments if style enabled\n // and explicit cy.destroy() is necessary to stop the loop\n\n function globalAnimationStep(){\n if( !cy._private.animationsRunning ){ return; }\n\n util.requestAnimationFrame(function(now){\n handleElements(now);\n globalAnimationStep();\n });\n }\n\n globalAnimationStep(); // first call\n\n function handleElements( now ){\n var eles = cy._private.aniEles;\n var doneEles = [];\n\n function handleElement( ele, isCore ){\n var _p = ele._private;\n var current = _p.animation.current;\n var queue = _p.animation.queue;\n var ranAnis = false;\n\n // if nothing currently animating, get something from the queue\n if( current.length === 0 ){\n var next = queue.shift();\n\n if( next ){\n current.push( next );\n }\n }\n\n var callbacks = function( callbacks ){\n for( var j = callbacks.length - 1; j >= 0; j-- ){\n var cb = callbacks[j];\n\n cb();\n }\n\n callbacks.splice( 0, callbacks.length );\n };\n\n // step and remove if done\n for( var i = current.length - 1; i >= 0; i-- ){\n var ani = current[i];\n var ani_p = ani._private;\n\n if( ani_p.stopped ){\n current.splice( i, 1 );\n\n ani_p.hooked = false;\n ani_p.playing = false;\n ani_p.started = false;\n\n callbacks( ani_p.frames );\n\n continue;\n }\n\n if( !ani_p.playing && !ani_p.applying ){ continue; }\n\n // an apply() while playing shouldn't do anything\n if( ani_p.playing && ani_p.applying ){\n ani_p.applying = false;\n }\n\n if( !ani_p.started ){\n startAnimation( ele, ani, now );\n }\n\n step( ele, ani, now, isCore );\n\n if( ani_p.applying ){\n ani_p.applying = false;\n }\n\n callbacks( ani_p.frames );\n\n if( ani.completed() ){\n current.splice(i, 1);\n\n ani_p.hooked = false;\n ani_p.playing = false;\n ani_p.started = false;\n\n callbacks( ani_p.completes );\n }\n\n ranAnis = true;\n }\n\n if( !isCore && current.length === 0 && queue.length === 0 ){\n doneEles.push( ele );\n }\n\n return ranAnis;\n } // handleElement\n\n // handle all eles\n var ranEleAni = false;\n for( var e = 0; e < eles.length; e++ ){\n var ele = eles[e];\n var handledThisEle = handleElement( ele );\n\n ranEleAni = ranEleAni || handledThisEle;\n } // each element\n\n var ranCoreAni = handleElement( cy, true );\n\n // notify renderer\n if( ranEleAni || ranCoreAni ){\n var toNotify;\n\n if( eles.length > 0 ){\n var updatedEles = eles.updateCompoundBounds();\n toNotify = updatedEles.length > 0 ? eles.add( updatedEles ) : eles;\n }\n\n cy.notify({\n type: 'draw',\n collection: toNotify\n });\n }\n\n // remove elements from list of currently animating if its queues are empty\n eles.unmerge( doneEles );\n\n } // handleElements\n\n function startAnimation( self, ani, now ){\n var isCore = is.core( self );\n var isEles = !isCore;\n var ele = self;\n var style = cy._private.style;\n var ani_p = ani._private;\n\n if( isEles ){\n var pos = ele._private.position;\n\n ani_p.startPosition = ani_p.startPosition || {\n x: pos.x,\n y: pos.y\n };\n\n ani_p.startStyle = ani_p.startStyle || style.getValueStyle( ele );\n }\n\n if( isCore ){\n var pan = cy._private.pan;\n\n ani_p.startPan = ani_p.startPan || {\n x: pan.x,\n y: pan.y\n };\n\n ani_p.startZoom = ani_p.startZoom != null ? ani_p.startZoom : cy._private.zoom;\n }\n\n ani_p.started = true;\n ani_p.startTime = now - ani_p.progress * ani_p.duration;\n }\n\n function step( self, ani, now, isCore ){\n var style = cy._private.style;\n var isEles = !isCore;\n var _p = self._private;\n var ani_p = ani._private;\n var pEasing = ani_p.easing;\n var startTime = ani_p.startTime;\n\n if( !ani_p.easingImpl ){\n\n if( pEasing == null ){ // use default\n ani_p.easingImpl = easings['linear'];\n\n } else { // then define w/ name\n var easingVals;\n\n if( is.string( pEasing ) ){\n var easingProp = style.parse('transition-timing-function', pEasing);\n\n easingVals = easingProp.value;\n\n } else { // then assume preparsed array\n easingVals = pEasing;\n }\n\n var name, args;\n\n if( is.string( easingVals ) ){\n name = easingVals;\n args = [];\n } else {\n name = easingVals[1];\n args = easingVals.slice(2).map(function(n){ return +n; });\n }\n\n if( args.length > 0 ){ // create with args\n if( name === 'spring' ){\n args.push( ani_p.duration ); // need duration to generate spring\n }\n\n ani_p.easingImpl = easings[ name ].apply( null, args );\n } else { // static impl by name\n ani_p.easingImpl = easings[ name ];\n }\n }\n\n }\n\n var easing = ani_p.easingImpl;\n var percent;\n\n if( ani_p.duration === 0 ){\n percent = 1;\n } else {\n percent = (now - startTime) / ani_p.duration;\n }\n\n if( ani_p.applying ){\n percent = ani_p.progress;\n }\n\n if( percent < 0 ){\n percent = 0;\n } else if( percent > 1 ){\n percent = 1;\n }\n\n if( ani_p.delay == null ){ // then update\n\n var startPos = ani_p.startPosition;\n var endPos = ani_p.position;\n var pos = _p.position;\n if( endPos && isEles ){\n if( valid( startPos.x, endPos.x ) ){\n pos.x = ease( startPos.x, endPos.x, percent, easing );\n }\n\n if( valid( startPos.y, endPos.y ) ){\n pos.y = ease( startPos.y, endPos.y, percent, easing );\n }\n }\n\n var startPan = ani_p.startPan;\n var endPan = ani_p.pan;\n var pan = _p.pan;\n var animatingPan = endPan != null && isCore;\n if( animatingPan ){\n if( valid( startPan.x, endPan.x ) ){\n pan.x = ease( startPan.x, endPan.x, percent, easing );\n }\n\n if( valid( startPan.y, endPan.y ) ){\n pan.y = ease( startPan.y, endPan.y, percent, easing );\n }\n\n self.trigger('pan');\n }\n\n var startZoom = ani_p.startZoom;\n var endZoom = ani_p.zoom;\n var animatingZoom = endZoom != null && isCore;\n if( animatingZoom ){\n if( valid( startZoom, endZoom ) ){\n _p.zoom = ease( startZoom, endZoom, percent, easing );\n }\n\n self.trigger('zoom');\n }\n\n if( animatingPan || animatingZoom ){\n self.trigger('viewport');\n }\n\n var props = ani_p.style;\n if( props && isEles ){\n\n for( var i = 0; i < props.length; i++ ){\n var prop = props[i];\n var name = prop.name;\n var end = prop;\n\n var start = ani_p.startStyle[ name ];\n var easedVal = ease( start, end, percent, easing );\n\n style.overrideBypass( self, name, easedVal );\n } // for props\n\n } // if\n\n }\n\n if( is.fn(ani_p.step) ){\n ani_p.step.apply( self, [ now ] );\n }\n\n ani_p.progress = percent;\n\n return percent;\n }\n\n function valid(start, end){\n if( start == null || end == null ){\n return false;\n }\n\n if( is.number(start) && is.number(end) ){\n return true;\n } else if( (start) && (end) ){\n return true;\n }\n\n return false;\n }\n\n // assumes p0 = 0, p3 = 1\n function evalCubicBezier( p1, p2, t ){\n var one_t = 1 - t;\n var tsq = t*t;\n\n return ( 3 * one_t * one_t * t * p1 ) + ( 3 * one_t * tsq * p2 ) + tsq * t;\n }\n\n function cubicBezier( p1, p2 ){\n return function( start, end, percent ){\n return start + (end - start) * evalCubicBezier( p1, p2, percent );\n };\n }\n\n /* Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */\n /* 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\n then adjusts the time delta -- using the relation between actual time and duration -- to calculate the path for the duration-constrained animation. */\n var generateSpringRK4 = (function () {\n function springAccelerationForState (state) {\n return (-state.tension * state.x) - (state.friction * state.v);\n }\n\n function springEvaluateStateWithDerivative (initialState, dt, derivative) {\n var state = {\n x: initialState.x + derivative.dx * dt,\n v: initialState.v + derivative.dv * dt,\n tension: initialState.tension,\n friction: initialState.friction\n };\n\n return { dx: state.v, dv: springAccelerationForState(state) };\n }\n\n function springIntegrateState (state, dt) {\n var a = {\n dx: state.v,\n dv: springAccelerationForState(state)\n },\n b = springEvaluateStateWithDerivative(state, dt * 0.5, a),\n c = springEvaluateStateWithDerivative(state, dt * 0.5, b),\n d = springEvaluateStateWithDerivative(state, dt, c),\n dxdt = 1.0 / 6.0 * (a.dx + 2.0 * (b.dx + c.dx) + d.dx),\n dvdt = 1.0 / 6.0 * (a.dv + 2.0 * (b.dv + c.dv) + d.dv);\n\n state.x = state.x + dxdt * dt;\n state.v = state.v + dvdt * dt;\n\n return state;\n }\n\n return function springRK4Factory (tension, friction, duration) {\n\n var initState = {\n x: -1,\n v: 0,\n tension: null,\n friction: null\n },\n path = [0],\n time_lapsed = 0,\n tolerance = 1 / 10000,\n DT = 16 / 1000,\n have_duration, dt, last_state;\n\n tension = parseFloat(tension) || 500;\n friction = parseFloat(friction) || 20;\n duration = duration || null;\n\n initState.tension = tension;\n initState.friction = friction;\n\n have_duration = duration !== null;\n\n /* Calculate the actual time it takes for this animation to complete with the provided conditions. */\n if (have_duration) {\n /* Run the simulation without a duration. */\n time_lapsed = springRK4Factory(tension, friction);\n /* Compute the adjusted time delta. */\n dt = time_lapsed / duration * DT;\n } else {\n dt = DT;\n }\n\n while (true) {\n /* Next/step function .*/\n last_state = springIntegrateState(last_state || initState, dt);\n /* Store the position. */\n path.push(1 + last_state.x);\n time_lapsed += 16;\n /* If the change threshold is reached, break. */\n if (!(Math.abs(last_state.x) > tolerance && Math.abs(last_state.v) > tolerance)) {\n break;\n }\n }\n\n /* If duration is not defined, return the actual time required for completing this animation. Otherwise, return a closure that holds the\n computed path and returns a snapshot of the position according to a given percentComplete. */\n return !have_duration ? time_lapsed : function(percentComplete) { return path[ (percentComplete * (path.length - 1)) | 0 ]; };\n };\n }());\n\n var easings = {\n 'linear': function( start, end, percent ){\n return start + (end - start) * percent;\n },\n\n // default easings\n 'ease': cubicBezier( 0.25, 0.1, 0.25, 1 ),\n 'ease-in': cubicBezier( 0.42, 0, 1, 1 ),\n 'ease-out': cubicBezier( 0, 0, 0.58, 1 ),\n 'ease-in-out': cubicBezier( 0.42, 0, 0.58, 1 ),\n\n // sine\n 'ease-in-sine': cubicBezier( 0.47, 0, 0.745, 0.715 ),\n 'ease-out-sine': cubicBezier( 0.39, 0.575, 0.565, 1 ),\n 'ease-in-out-sine': cubicBezier( 0.445, 0.05, 0.55, 0.95 ),\n\n // quad\n 'ease-in-quad': cubicBezier( 0.55, 0.085, 0.68, 0.53 ),\n 'ease-out-quad': cubicBezier( 0.25, 0.46, 0.45, 0.94 ),\n 'ease-in-out-quad': cubicBezier( 0.455, 0.03, 0.515, 0.955 ),\n\n // cubic\n 'ease-in-cubic': cubicBezier( 0.55, 0.055, 0.675, 0.19 ),\n 'ease-out-cubic': cubicBezier( 0.215, 0.61, 0.355, 1 ),\n 'ease-in-out-cubic': cubicBezier( 0.645, 0.045, 0.355, 1 ),\n\n // quart\n 'ease-in-quart': cubicBezier( 0.895, 0.03, 0.685, 0.22 ),\n 'ease-out-quart': cubicBezier( 0.165, 0.84, 0.44, 1 ),\n 'ease-in-out-quart': cubicBezier( 0.77, 0, 0.175, 1 ),\n\n // quint\n 'ease-in-quint': cubicBezier( 0.755, 0.05, 0.855, 0.06 ),\n 'ease-out-quint': cubicBezier( 0.23, 1, 0.32, 1 ),\n 'ease-in-out-quint': cubicBezier( 0.86, 0, 0.07, 1 ),\n\n // expo\n 'ease-in-expo': cubicBezier( 0.95, 0.05, 0.795, 0.035 ),\n 'ease-out-expo': cubicBezier( 0.19, 1, 0.22, 1 ),\n 'ease-in-out-expo': cubicBezier( 1, 0, 0, 1 ),\n\n // circ\n 'ease-in-circ': cubicBezier( 0.6, 0.04, 0.98, 0.335 ),\n 'ease-out-circ': cubicBezier( 0.075, 0.82, 0.165, 1 ),\n 'ease-in-out-circ': cubicBezier( 0.785, 0.135, 0.15, 0.86 ),\n\n\n // user param easings...\n\n 'spring': function( tension, friction, duration ){\n var spring = generateSpringRK4( tension, friction, duration );\n\n return function( start, end, percent ){\n return start + (end - start) * spring( percent );\n };\n },\n\n 'cubic-bezier': function( x1, y1, x2, y2 ){\n return cubicBezier( x1, y1, x2, y2 );\n }\n };\n\n function ease( startProp, endProp, percent, easingFn ){\n if( percent < 0 ){\n percent = 0;\n } else if( percent > 1 ){\n percent = 1;\n }\n\n var start, end;\n\n if( startProp.pfValue != null || startProp.value != null ){\n start = startProp.pfValue != null ? startProp.pfValue : startProp.value;\n } else {\n start = startProp;\n }\n\n if( endProp.pfValue != null || endProp.value != null ){\n end = endProp.pfValue != null ? endProp.pfValue : endProp.value;\n } else {\n end = endProp;\n }\n\n if( is.number(start) && is.number(end) ){\n return easingFn( start, end, percent );\n\n } else if( is.array(start) && is.array(end) ){\n var easedArr = [];\n\n for( var i = 0; i < end.length; i++ ){\n var si = start[i];\n var ei = end[i];\n\n if( si != null && ei != null ){\n var val = easingFn(si, ei, percent);\n\n if( startProp.roundValue ){ val = Math.round( val ); }\n\n easedArr.push( val );\n } else {\n easedArr.push( ei );\n }\n }\n\n return easedArr;\n }\n\n return undefined;\n }\n\n }\n\n});\n\nmodule.exports = corefn;\n","'use strict';\n\nvar define = require('../define');\n\nvar corefn = ({\n on: define.on(), // .on( events [, selector] [, data], handler)\n one: define.on({ unbindSelfOnTrigger: true }),\n once: define.on({ unbindAllBindersOnTrigger: true }),\n off: define.off(), // .off( events [, selector] [, handler] )\n trigger: define.trigger() // .trigger( events [, extraParams] )\n});\n\ndefine.eventAliasesOn( corefn );\n\nmodule.exports = corefn;\n","'use strict';\n\nvar corefn = ({\n\n png: function( options ){\n var renderer = this._private.renderer;\n options = options || {};\n\n return renderer.png( options );\n },\n\n jpg: function( options ){\n var renderer = this._private.renderer;\n options = options || {};\n\n options.bg = options.bg || '#fff';\n\n return renderer.jpg( options );\n }\n\n});\n\ncorefn.jpeg = corefn.jpg;\n\nmodule.exports = corefn;\n","'use strict';\n\nvar window = require('../window');\nvar util = require('../util');\nvar Collection = require('../collection');\nvar is = require('../is');\nvar Promise = require('../promise');\nvar define = require('../define');\n\nvar Core = function( opts ){\n if( !(this instanceof Core) ){\n return new Core(opts);\n }\n var cy = this;\n\n opts = util.extend({}, opts);\n\n var container = opts.container;\n\n // allow for passing a wrapped jquery object\n // e.g. cytoscape({ container: $('#cy') })\n if( container && !is.htmlElement( container ) && is.htmlElement( container[0] ) ){\n container = container[0];\n }\n\n var reg = container ? container._cyreg : null; // e.g. already registered some info (e.g. readies) via jquery\n reg = reg || {};\n\n if( reg && reg.cy ){\n reg.cy.destroy();\n\n reg = {}; // old instance => replace reg completely\n }\n\n var readies = reg.readies = reg.readies || [];\n\n if( container ){ container._cyreg = reg; } // make sure container assoc'd reg points to this cy\n reg.cy = cy;\n\n var head = window !== undefined && container !== undefined && !opts.headless;\n var options = opts;\n options.layout = util.extend( { name: head ? 'grid' : 'null' }, options.layout );\n options.renderer = util.extend( { name: head ? 'canvas' : 'null' }, options.renderer );\n\n var defVal = function( def, val, altVal ){\n if( val !== undefined ){\n return val;\n } else if( altVal !== undefined ){\n return altVal;\n } else {\n return def;\n }\n };\n\n var _p = this._private = {\n container: container, // html dom ele container\n ready: false, // whether ready has been triggered\n initrender: false, // has initrender has been triggered\n options: options, // cached options\n elements: [], // array of elements\n id2index: {}, // element id => index in elements array\n listeners: [], // list of listeners\n onRenders: [], // rendering listeners\n aniEles: Collection(this), // elements being animated\n scratch: {}, // scratch object for core\n layout: null,\n renderer: null,\n notificationsEnabled: true, // whether notifications are sent to the renderer\n minZoom: 1e-50,\n maxZoom: 1e50,\n zoomingEnabled: defVal(true, options.zoomingEnabled),\n userZoomingEnabled: defVal(true, options.userZoomingEnabled),\n panningEnabled: defVal(true, options.panningEnabled),\n userPanningEnabled: defVal(true, options.userPanningEnabled),\n boxSelectionEnabled: defVal(true, options.boxSelectionEnabled),\n autolock: defVal(false, options.autolock, options.autolockNodes),\n autoungrabify: defVal(false, options.autoungrabify, options.autoungrabifyNodes),\n autounselectify: defVal(false, options.autounselectify),\n styleEnabled: options.styleEnabled === undefined ? head : options.styleEnabled,\n zoom: is.number(options.zoom) ? options.zoom : 1,\n pan: {\n x: is.plainObject(options.pan) && is.number(options.pan.x) ? options.pan.x : 0,\n y: is.plainObject(options.pan) && is.number(options.pan.y) ? options.pan.y : 0\n },\n animation: { // object for currently-running animations\n current: [],\n queue: []\n },\n hasCompoundNodes: false,\n deferredExecQueue: []\n };\n\n // set selection type\n var selType = options.selectionType;\n if( selType === undefined || (selType !== 'additive' && selType !== 'single') ){\n // then set default\n\n _p.selectionType = 'single';\n } else {\n _p.selectionType = selType;\n }\n\n // init zoom bounds\n if( is.number(options.minZoom) && is.number(options.maxZoom) && options.minZoom < options.maxZoom ){\n _p.minZoom = options.minZoom;\n _p.maxZoom = options.maxZoom;\n } else if( is.number(options.minZoom) && options.maxZoom === undefined ){\n _p.minZoom = options.minZoom;\n } else if( is.number(options.maxZoom) && options.minZoom === undefined ){\n _p.maxZoom = options.maxZoom;\n }\n\n var loadExtData = function( next ){\n var anyIsPromise = false;\n\n for( var i = 0; i < extData.length; i++ ){\n var datum = extData[i];\n\n if( is.promise(datum) ){\n anyIsPromise = true;\n break;\n }\n }\n\n if( anyIsPromise ){\n return Promise.all( extData ).then( next ); // load all data asynchronously, then exec rest of init\n } else {\n next( extData ); // exec synchronously for convenience\n }\n };\n\n // create the renderer\n cy.initRenderer( util.extend({\n hideEdgesOnViewport: options.hideEdgesOnViewport,\n hideLabelsOnViewport: options.hideLabelsOnViewport,\n textureOnViewport: options.textureOnViewport,\n wheelSensitivity: is.number(options.wheelSensitivity) && options.wheelSensitivity > 0 ? options.wheelSensitivity : 1,\n motionBlur: options.motionBlur === undefined ? true : options.motionBlur, // on by default\n motionBlurOpacity: options.motionBlurOpacity === undefined ? 0.05 : options.motionBlurOpacity,\n pixelRatio: is.number(options.pixelRatio) && options.pixelRatio > 0 ? options.pixelRatio : undefined,\n desktopTapThreshold: options.desktopTapThreshold === undefined ? 4 : options.desktopTapThreshold,\n touchTapThreshold: options.touchTapThreshold === undefined ? 8 : options.touchTapThreshold\n }, options.renderer) );\n\n var extData = [ options.style, options.elements ];\n loadExtData(function( thens ){\n var initStyle = thens[0];\n var initEles = thens[1];\n\n // init style\n if( _p.styleEnabled ){\n cy.setStyle( initStyle );\n }\n\n // trigger the passed function for the `initrender` event\n if( options.initrender ){\n cy.on('initrender', options.initrender);\n cy.on('initrender', function(){\n _p.initrender = true;\n });\n }\n\n // initial load\n cy.load(initEles, function(){ // onready\n cy.startAnimationLoop();\n _p.ready = true;\n\n // if a ready callback is specified as an option, the bind it\n if( is.fn( options.ready ) ){\n cy.on('ready', options.ready);\n }\n\n // bind all the ready handlers registered before creating this instance\n for( var i = 0; i < readies.length; i++ ){\n var fn = readies[i];\n cy.on('ready', fn);\n }\n 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\n\n cy.trigger('ready');\n }, options.done);\n\n });\n};\n\nvar corefn = Core.prototype; // short alias\n\nutil.extend(corefn, {\n instanceString: function(){\n return 'core';\n },\n\n isReady: function(){\n return this._private.ready;\n },\n\n ready: function( fn ){\n if( this.isReady() ){\n this.trigger('ready', [], fn); // just calls fn as though triggered via ready event\n } else {\n this.on('ready', fn);\n }\n\n return this;\n },\n\n initrender: function(){\n return this._private.initrender;\n },\n\n destroy: function(){\n var cy = this;\n\n cy.stopAnimationLoop();\n\n cy.notify({ type: 'destroy' }); // destroy the renderer\n\n var domEle = cy.container();\n if( domEle ){\n domEle._cyreg = null;\n\n while( domEle.childNodes.length > 0 ){\n domEle.removeChild( domEle.childNodes[0] );\n }\n }\n\n return cy;\n },\n\n getElementById: function( id ){\n var index = this._private.id2index[ id ];\n if( index !== undefined ){\n return this._private.elements[ index ];\n }\n\n // worst case, return an empty collection\n return Collection( this );\n },\n\n selectionType: function(){\n return this._private.selectionType;\n },\n\n hasCompoundNodes: function(){\n return this._private.hasCompoundNodes;\n },\n\n styleEnabled: function(){\n return this._private.styleEnabled;\n },\n\n addToPool: function( eles ){\n var elements = this._private.elements;\n var id2index = this._private.id2index;\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n\n var id = ele._private.data.id;\n var index = id2index[ id ];\n var alreadyInPool = index !== undefined;\n\n if( !alreadyInPool ){\n index = elements.length;\n elements.push( ele );\n id2index[ id ] = index;\n ele._private.index = index;\n }\n }\n\n return this; // chaining\n },\n\n removeFromPool: function( eles ){\n var elements = this._private.elements;\n var id2index = this._private.id2index;\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n\n var id = ele._private.data.id;\n var index = id2index[ id ];\n var inPool = index !== undefined;\n\n if( inPool ){\n this._private.id2index[ id ] = undefined;\n elements.splice(index, 1);\n\n // adjust the index of all elements past this index\n for( var j = index; j < elements.length; j++ ){\n var jid = elements[j]._private.data.id;\n id2index[ jid ]--;\n elements[j]._private.index--;\n }\n }\n }\n },\n\n container: function(){\n return this._private.container;\n },\n\n options: function(){\n return util.copy( this._private.options );\n },\n\n json: function( obj ){\n var cy = this;\n var _p = cy._private;\n\n if( is.plainObject(obj) ){ // set\n\n cy.startBatch();\n\n if( obj.elements ){\n var idInJson = {};\n\n var updateEles = function( jsons, gr ){\n for( var i = 0; i < jsons.length; i++ ){\n var json = jsons[i];\n var id = json.data.id;\n var ele = cy.getElementById( id );\n\n idInJson[ id ] = true;\n\n if( ele.length !== 0 ){ // existing element should be updated\n ele.json( json );\n } else { // otherwise should be added\n if( gr ){\n cy.add( util.extend({ group: gr }, json) );\n } else {\n cy.add( json );\n }\n }\n }\n };\n\n if( is.array(obj.elements) ){ // elements: []\n updateEles( obj.elements );\n\n } else { // elements: { nodes: [], edges: [] }\n var grs = ['nodes', 'edges'];\n for( var i = 0; i < grs.length; i++ ){\n var gr = grs[i];\n var elements = obj.elements[ gr ];\n\n if( is.array(elements) ){\n updateEles( elements, gr );\n }\n }\n }\n\n // elements not specified in json should be removed\n cy.elements().stdFilter(function( ele ){\n return !idInJson[ ele.id() ];\n }).remove();\n }\n\n if( obj.style ){\n cy.style( obj.style );\n }\n\n if( obj.zoom != null && obj.zoom !== _p.zoom ){\n cy.zoom( obj.zoom );\n }\n\n if( obj.pan ){\n if( obj.pan.x !== _p.pan.x || obj.pan.y !== _p.pan.y ){\n cy.pan( obj.pan );\n }\n }\n\n var fields = [\n 'minZoom', 'maxZoom', 'zoomingEnabled', 'userZoomingEnabled',\n 'panningEnabled', 'userPanningEnabled',\n 'boxSelectionEnabled',\n 'autolock', 'autoungrabify', 'autounselectify'\n ];\n\n for( var i = 0; i < fields.length; i++ ){\n var f = fields[i];\n\n if( obj[f] != null ){\n cy[f]( obj[f] );\n }\n }\n\n cy.endBatch();\n\n return this; // chaining\n } else if( obj === undefined ){ // get\n var json = {};\n\n json.elements = {};\n cy.elements().each(function(i, ele){\n var group = ele.group();\n\n if( !json.elements[group] ){\n json.elements[group] = [];\n }\n\n json.elements[group].push( ele.json() );\n });\n\n if( this._private.styleEnabled ){\n json.style = cy.style().json();\n }\n\n json.zoomingEnabled = cy._private.zoomingEnabled;\n json.userZoomingEnabled = cy._private.userZoomingEnabled;\n json.zoom = cy._private.zoom;\n json.minZoom = cy._private.minZoom;\n json.maxZoom = cy._private.maxZoom;\n json.panningEnabled = cy._private.panningEnabled;\n json.userPanningEnabled = cy._private.userPanningEnabled;\n json.pan = util.copy( cy._private.pan );\n json.boxSelectionEnabled = cy._private.boxSelectionEnabled;\n json.renderer = util.copy( cy._private.options.renderer );\n json.hideEdgesOnViewport = cy._private.options.hideEdgesOnViewport;\n json.hideLabelsOnViewport = cy._private.options.hideLabelsOnViewport;\n json.textureOnViewport = cy._private.options.textureOnViewport;\n json.wheelSensitivity = cy._private.options.wheelSensitivity;\n json.motionBlur = cy._private.options.motionBlur;\n\n return json;\n }\n },\n\n scratch: define.data({\n field: 'scratch',\n bindingEvent: 'scratch',\n allowBinding: true,\n allowSetting: true,\n settingEvent: 'scratch',\n settingTriggersEvent: true,\n triggerFnName: 'trigger',\n allowGetting: true\n }),\n\n removeScratch: define.removeData({\n field: 'scratch',\n event: 'scratch',\n triggerFnName: 'trigger',\n triggerEvent: true\n })\n\n});\n\n[\n require('./add-remove'),\n require('./animation'),\n require('./events'),\n require('./export'),\n require('./layout'),\n require('./notification'),\n require('./renderer'),\n require('./search'),\n require('./style'),\n require('./viewport')\n].forEach(function( props ){\n util.extend( corefn, props );\n});\n\nmodule.exports = Core;\n","'use strict';\n\nvar util = require('../util');\nvar is = require('../is');\n\nvar corefn = ({\n\n layout: function( params ){\n var layout = this._private.prevLayout = ( params == null ? this._private.prevLayout : this.makeLayout( params ) );\n\n layout.run();\n\n return this; // chaining\n },\n\n makeLayout: function( options ){\n var cy = this;\n\n if( options == null ){\n util.error('Layout options must be specified to make a layout');\n return;\n }\n\n if( options.name == null ){\n util.error('A `name` must be specified to make a layout');\n return;\n }\n\n var name = options.name;\n var Layout = cy.extension('layout', name);\n\n if( Layout == null ){\n util.error('Can not apply layout: No such layout `' + name + '` found; did you include its JS file?');\n return;\n }\n\n var eles;\n if( is.string( options.eles ) ){\n eles = cy.$( options.eles );\n } else {\n eles = options.eles != null ? options.eles : cy.$();\n }\n\n var layout = new Layout( util.extend({}, options, {\n cy: cy,\n eles: eles\n }) );\n\n return layout;\n }\n\n});\n\ncorefn.createLayout = corefn.makeLayout;\n\nmodule.exports = corefn;\n","'use strict';\n\nvar corefn = ({\n notify: function( params ){\n var _p = this._private;\n\n if( _p.batchingNotify ){\n var bEles = _p.batchNotifyEles;\n var bTypes = _p.batchNotifyTypes;\n\n if( params.collection ){\n bEles.merge( params.collection );\n }\n\n if( !bTypes.ids[ params.type ] ){\n bTypes.push( params.type );\n }\n\n return; // notifications are disabled during batching\n }\n\n if( !_p.notificationsEnabled ){ return; } // exit on disabled\n\n var renderer = this.renderer();\n\n renderer.notify(params);\n },\n\n notifications: function( bool ){\n var p = this._private;\n\n if( bool === undefined ){\n return p.notificationsEnabled;\n } else {\n p.notificationsEnabled = bool ? true : false;\n }\n },\n\n noNotifications: function( callback ){\n this.notifications(false);\n callback();\n this.notifications(true);\n },\n\n startBatch: function(){\n var _p = this._private;\n\n if( _p.batchCount == null ){\n _p.batchCount = 0;\n }\n\n if( _p.batchCount === 0 ){\n _p.batchingStyle = _p.batchingNotify = true;\n _p.batchStyleEles = this.collection();\n _p.batchNotifyEles = this.collection();\n _p.batchNotifyTypes = [];\n\n _p.batchNotifyTypes.ids = {};\n }\n\n _p.batchCount++;\n\n return this;\n },\n\n endBatch: function(){\n var _p = this._private;\n\n _p.batchCount--;\n\n if( _p.batchCount === 0 ){\n // update style for dirty eles\n _p.batchingStyle = false;\n _p.batchStyleEles.updateStyle();\n\n // notify the renderer of queued eles and event types\n _p.batchingNotify = false;\n this.notify({\n type: _p.batchNotifyTypes,\n collection: _p.batchNotifyEles\n });\n }\n\n return this;\n },\n\n batch: function( callback ){\n this.startBatch();\n callback();\n this.endBatch();\n\n return this;\n },\n\n // for backwards compatibility\n batchData: function( map ){\n var cy = this;\n\n return this.batch(function(){\n for( var id in map ){\n var data = map[id];\n var ele = cy.getElementById( id );\n\n ele.data( data );\n }\n });\n }\n});\n\nmodule.exports = corefn;\n","'use strict';\n\nvar util = require('../util');\n\nvar corefn = ({\n\n renderTo: function( context, zoom, pan, pxRatio ){\n var r = this._private.renderer;\n\n r.renderTo( context, zoom, pan, pxRatio );\n return this;\n },\n\n renderer: function(){\n return this._private.renderer;\n },\n\n forceRender: function(){\n this.notify({\n type: 'draw'\n });\n\n return this;\n },\n\n resize: function(){\n this.notify({\n type: 'resize'\n });\n\n this.trigger('resize');\n\n return this;\n },\n\n initRenderer: function( options ){\n var cy = this;\n\n var RendererProto = cy.extension('renderer', options.name);\n if( RendererProto == null ){\n util.error('Can not initialise: No such renderer `%s` found; did you include its JS file?', options.name);\n return;\n }\n\n var rOpts = util.extend({}, options, {\n cy: cy\n });\n var renderer = cy._private.renderer = new RendererProto( rOpts );\n\n renderer.init( rOpts );\n\n },\n\n triggerOnRender: function(){\n var cbs = this._private.onRenders;\n\n for( var i = 0; i < cbs.length; i++ ){\n var cb = cbs[i];\n\n cb();\n }\n\n return this;\n },\n\n onRender: function( cb ){\n this._private.onRenders.push( cb );\n\n return this;\n },\n\n offRender: function( fn ){\n var cbs = this._private.onRenders;\n\n if( fn == null ){ // unbind all\n this._private.onRenders = [];\n return this;\n }\n\n for( var i = 0; i < cbs.length; i++ ){ // unbind specified\n var cb = cbs[i];\n\n if( fn === cb ){\n cbs.splice( i, 1 );\n break;\n }\n }\n\n return this;\n }\n\n});\n\ncorefn.invalidateDimensions = corefn.resize;\n\nmodule.exports = corefn;\n","'use strict';\n\nvar is = require('../is');\nvar Collection = require('../collection');\n\nvar corefn = ({\n\n // get a collection\n // - empty collection on no args\n // - collection of elements in the graph on selector arg\n // - guarantee a returned collection when elements or collection specified\n collection: function( eles, opts ){\n\n if( is.string( eles ) ){\n return this.$( eles );\n\n } else if( is.elementOrCollection( eles ) ){\n return eles.collection();\n\n } else if( is.array( eles ) ){\n return Collection( this, eles, opts );\n }\n\n return Collection( this );\n },\n\n nodes: function( selector ){\n var nodes = this.$(function(){\n return this.isNode();\n });\n\n if( selector ){\n return nodes.filter( selector );\n }\n\n return nodes;\n },\n\n edges: function( selector ){\n var edges = this.$(function(){\n return this.isEdge();\n });\n\n if( selector ){\n return edges.filter( selector );\n }\n\n return edges;\n },\n\n // search the graph like jQuery\n $: function( selector ){\n var eles = new Collection( this, this._private.elements );\n\n if( selector ){\n return eles.filter( selector );\n }\n\n return eles;\n }\n\n});\n\n// aliases\ncorefn.elements = corefn.filter = corefn.$;\n\nmodule.exports = corefn;\n","'use strict';\n\nvar is = require('../is');\nvar Style = require('../style');\n\nvar corefn = ({\n\n style: function( newStyle ){\n if( newStyle ){\n var s = this.setStyle( newStyle );\n\n s.update();\n }\n\n return this._private.style;\n },\n\n setStyle: function( style ){\n var _p = this._private;\n\n if( is.stylesheet(style) ){\n _p.style = style.generateStyle(this);\n\n } else if( is.array(style) ) {\n _p.style = Style.fromJson(this, style);\n\n } else if( is.string(style) ){\n _p.style = Style.fromString(this, style);\n\n } else {\n _p.style = Style( this );\n }\n\n return _p.style;\n }\n});\n\nmodule.exports = corefn;\n","'use strict';\n\nvar is = require('../is');\n\nvar corefn = ({\n\n autolock: function(bool){\n if( bool !== undefined ){\n this._private.autolock = bool ? true : false;\n } else {\n return this._private.autolock;\n }\n\n return this; // chaining\n },\n\n autoungrabify: function(bool){\n if( bool !== undefined ){\n this._private.autoungrabify = bool ? true : false;\n } else {\n return this._private.autoungrabify;\n }\n\n return this; // chaining\n },\n\n autounselectify: function(bool){\n if( bool !== undefined ){\n this._private.autounselectify = bool ? true : false;\n } else {\n return this._private.autounselectify;\n }\n\n return this; // chaining\n },\n\n panningEnabled: function( bool ){\n if( bool !== undefined ){\n this._private.panningEnabled = bool ? true : false;\n } else {\n return this._private.panningEnabled;\n }\n\n return this; // chaining\n },\n\n userPanningEnabled: function( bool ){\n if( bool !== undefined ){\n this._private.userPanningEnabled = bool ? true : false;\n } else {\n return this._private.userPanningEnabled;\n }\n\n return this; // chaining\n },\n\n zoomingEnabled: function( bool ){\n if( bool !== undefined ){\n this._private.zoomingEnabled = bool ? true : false;\n } else {\n return this._private.zoomingEnabled;\n }\n\n return this; // chaining\n },\n\n userZoomingEnabled: function( bool ){\n if( bool !== undefined ){\n this._private.userZoomingEnabled = bool ? true : false;\n } else {\n return this._private.userZoomingEnabled;\n }\n\n return this; // chaining\n },\n\n boxSelectionEnabled: function( bool ){\n if( bool !== undefined ){\n this._private.boxSelectionEnabled = bool ? true : false;\n } else {\n return this._private.boxSelectionEnabled;\n }\n\n return this; // chaining\n },\n\n pan: function(){\n var args = arguments;\n var pan = this._private.pan;\n var dim, val, dims, x, y;\n\n switch( args.length ){\n case 0: // .pan()\n return pan;\n\n case 1:\n\n if( is.string( args[0] ) ){ // .pan('x')\n dim = args[0];\n return pan[ dim ];\n\n } else if( is.plainObject( args[0] ) ) { // .pan({ x: 0, y: 100 })\n if( !this._private.panningEnabled ){\n return this;\n }\n\n dims = args[0];\n x = dims.x;\n y = dims.y;\n\n if( is.number(x) ){\n pan.x = x;\n }\n\n if( is.number(y) ){\n pan.y = y;\n }\n\n this.trigger('pan viewport');\n }\n break;\n\n case 2: // .pan('x', 100)\n if( !this._private.panningEnabled ){\n return this;\n }\n\n dim = args[0];\n val = args[1];\n\n if( (dim === 'x' || dim === 'y') && is.number(val) ){\n pan[dim] = val;\n }\n\n this.trigger('pan viewport');\n break;\n\n default:\n break; // invalid\n }\n\n this.notify({ // notify the renderer that the viewport changed\n type: 'viewport'\n });\n\n return this; // chaining\n },\n\n panBy: function(params){\n var args = arguments;\n var pan = this._private.pan;\n var dim, val, dims, x, y;\n\n if( !this._private.panningEnabled ){\n return this;\n }\n\n switch( args.length ){\n case 1:\n\n if( is.plainObject( args[0] ) ) { // .panBy({ x: 0, y: 100 })\n dims = args[0];\n x = dims.x;\n y = dims.y;\n\n if( is.number(x) ){\n pan.x += x;\n }\n\n if( is.number(y) ){\n pan.y += y;\n }\n\n this.trigger('pan viewport');\n }\n break;\n\n case 2: // .panBy('x', 100)\n dim = args[0];\n val = args[1];\n\n if( (dim === 'x' || dim === 'y') && is.number(val) ){\n pan[dim] += val;\n }\n\n this.trigger('pan viewport');\n break;\n\n default:\n break; // invalid\n }\n\n this.notify({ // notify the renderer that the viewport changed\n type: 'viewport'\n });\n\n return this; // chaining\n },\n\n fit: function( elements, padding ){\n var viewportState = this.getFitViewport( elements, padding );\n\n if( viewportState ){\n var _p = this._private;\n _p.zoom = viewportState.zoom;\n _p.pan = viewportState.pan;\n\n this.trigger('pan zoom viewport');\n\n this.notify({ // notify the renderer that the viewport changed\n type: 'viewport'\n });\n }\n\n return this; // chaining\n },\n\n getFitViewport: function( elements, padding ){\n if( is.number(elements) && padding === undefined ){ // elements is optional\n padding = elements;\n elements = undefined;\n }\n\n if( !this._private.panningEnabled || !this._private.zoomingEnabled ){\n return;\n }\n\n var bb;\n\n if( is.string(elements) ){\n var sel = elements;\n elements = this.$( sel );\n\n } else if( is.boundingBox(elements) ){ // assume bb\n var bbe = elements;\n bb = {\n x1: bbe.x1,\n y1: bbe.y1,\n x2: bbe.x2,\n y2: bbe.y2\n };\n\n bb.w = bb.x2 - bb.x1;\n bb.h = bb.y2 - bb.y1;\n\n } else if( !is.elementOrCollection(elements) ){\n elements = this.elements();\n }\n\n bb = bb || elements.boundingBox();\n\n var w = this.width();\n var h = this.height();\n var zoom;\n padding = is.number(padding) ? padding : 0;\n\n if( !isNaN(w) && !isNaN(h) && w > 0 && h > 0 && !isNaN(bb.w) && !isNaN(bb.h) && bb.w > 0 && bb.h > 0 ){\n zoom = Math.min( (w - 2*padding)/bb.w, (h - 2*padding)/bb.h );\n\n // crop zoom\n zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom;\n zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom;\n\n var pan = { // now pan to middle\n x: (w - zoom*( bb.x1 + bb.x2 ))/2,\n y: (h - zoom*( bb.y1 + bb.y2 ))/2\n };\n\n return {\n zoom: zoom,\n pan: pan\n };\n }\n\n return;\n },\n\n minZoom: function( zoom ){\n if( zoom === undefined ){\n return this._private.minZoom;\n } else if( is.number(zoom) ){\n this._private.minZoom = zoom;\n }\n\n return this;\n },\n\n maxZoom: function( zoom ){\n if( zoom === undefined ){\n return this._private.maxZoom;\n } else if( is.number(zoom) ){\n this._private.maxZoom = zoom;\n }\n\n return this;\n },\n\n zoom: function( params ){\n var pos; // in rendered px\n var zoom;\n\n if( params === undefined ){ // then get the zoom\n return this._private.zoom;\n\n } else if( is.number(params) ){ // then set the zoom\n zoom = params;\n\n } else if( is.plainObject(params) ){ // then zoom about a point\n zoom = params.level;\n\n if( params.position ){\n var p = params.position;\n var pan = this._private.pan;\n var z = this._private.zoom;\n\n pos = { // convert to rendered px\n x: p.x * z + pan.x,\n y: p.y * z + pan.y\n };\n } else if( params.renderedPosition ){\n pos = params.renderedPosition;\n }\n\n if( pos && !this._private.panningEnabled ){\n return this; // panning disabled\n }\n }\n\n if( !this._private.zoomingEnabled ){\n return this; // zooming disabled\n }\n\n if( !is.number(zoom) || ( pos && (!is.number(pos.x) || !is.number(pos.y)) ) ){\n return this; // can't zoom with invalid params\n }\n\n // crop zoom\n zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom;\n zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom;\n\n if( pos ){ // set zoom about position\n var pan1 = this._private.pan;\n var zoom1 = this._private.zoom;\n var zoom2 = zoom;\n\n var pan2 = {\n x: -zoom2/zoom1 * (pos.x - pan1.x) + pos.x,\n y: -zoom2/zoom1 * (pos.y - pan1.y) + pos.y\n };\n\n this._private.zoom = zoom;\n this._private.pan = pan2;\n\n var posChanged = pan1.x !== pan2.x || pan1.y !== pan2.y;\n this.trigger(' zoom ' + (posChanged ? ' pan ' : '') + ' viewport ' );\n\n } else { // just set the zoom\n this._private.zoom = zoom;\n this.trigger('zoom viewport');\n }\n\n this.notify({ // notify the renderer that the viewport changed\n type: 'viewport'\n });\n\n return this; // chaining\n },\n\n viewport: function( opts ){\n var _p = this._private;\n var zoomDefd = true;\n var panDefd = true;\n var events = []; // to trigger\n var zoomFailed = false;\n var panFailed = false;\n\n if( !opts ){ return this; }\n if( !is.number(opts.zoom) ){ zoomDefd = false; }\n if( !is.plainObject(opts.pan) ){ panDefd = false; }\n if( !zoomDefd && !panDefd ){ return this; }\n\n if( zoomDefd ){\n var z = opts.zoom;\n\n if( z < _p.minZoom || z > _p.maxZoom || !_p.zoomingEnabled ){\n zoomFailed = true;\n\n } else {\n _p.zoom = z;\n\n events.push('zoom');\n }\n }\n\n if( panDefd && (!zoomFailed || !opts.cancelOnFailedZoom) && _p.panningEnabled ){\n var p = opts.pan;\n\n if( is.number(p.x) ){\n _p.pan.x = p.x;\n panFailed = false;\n }\n\n if( is.number(p.y) ){\n _p.pan.y = p.y;\n panFailed = false;\n }\n\n if( !panFailed ){\n events.push('pan');\n }\n }\n\n if( events.length > 0 ){\n events.push('viewport');\n this.trigger( events.join(' ') );\n\n this.notify({\n type: 'viewport'\n });\n }\n\n return this; // chaining\n },\n\n center: function( elements ){\n var pan = this.getCenterPan( elements );\n\n if( pan ){\n this._private.pan = pan;\n\n this.trigger('pan viewport');\n\n this.notify({ // notify the renderer that the viewport changed\n type: 'viewport'\n });\n }\n\n return this; // chaining\n },\n\n getCenterPan: function( elements, zoom ){\n if( !this._private.panningEnabled ){\n return;\n }\n\n if( is.string(elements) ){\n var selector = elements;\n elements = this.elements( selector );\n } else if( !is.elementOrCollection(elements) ){\n elements = this.elements();\n }\n\n var bb = elements.boundingBox();\n var w = this.width();\n var h = this.height();\n zoom = zoom === undefined ? this._private.zoom : zoom;\n\n var pan = { // middle\n x: (w - zoom*( bb.x1 + bb.x2 ))/2,\n y: (h - zoom*( bb.y1 + bb.y2 ))/2\n };\n\n return pan;\n },\n\n reset: function(){\n if( !this._private.panningEnabled || !this._private.zoomingEnabled ){\n return this;\n }\n\n this.viewport({\n pan: { x: 0, y: 0 },\n zoom: 1\n });\n\n return this; // chaining\n },\n\n width: function(){\n var container = this._private.container;\n\n if( container ){\n return container.clientWidth;\n }\n\n return 1; // fallback if no container (not 0 b/c can be used for dividing etc)\n },\n\n height: function(){\n var container = this._private.container;\n\n if( container ){\n return container.clientHeight;\n }\n\n return 1; // fallback if no container (not 0 b/c can be used for dividing etc)\n },\n\n extent: function(){\n var pan = this._private.pan;\n var zoom = this._private.zoom;\n var rb = this.renderedExtent();\n\n var b = {\n x1: ( rb.x1 - pan.x )/zoom,\n x2: ( rb.x2 - pan.x )/zoom,\n y1: ( rb.y1 - pan.y )/zoom,\n y2: ( rb.y2 - pan.y )/zoom\n };\n\n b.w = b.x2 - b.x1;\n b.h = b.y2 - b.y1;\n\n return b;\n },\n\n renderedExtent: function(){\n var width = this.width();\n var height = this.height();\n\n return {\n x1: 0,\n y1: 0,\n x2: width,\n y2: height,\n w: width,\n h: height\n };\n }\n});\n\n// aliases\ncorefn.centre = corefn.center;\n\n// backwards compatibility\ncorefn.autolockNodes = corefn.autolock;\ncorefn.autoungrabifyNodes = corefn.autoungrabify;\n\nmodule.exports = corefn;\n","'use strict';\n\n// use this module to cherry pick functions into your prototype\n// (useful for functions shared between the core and collections, for example)\n\n// e.g.\n// var foo = define.foo({ /* params... */ })\n\nvar util = require('./util');\nvar is = require('./is');\nvar Selector = require('./selector');\nvar Promise = require('./promise');\nvar Event = require('./event');\nvar Animation = require('./animation');\n\nvar define = {\n\n // access data field\n data: function( params ){\n var defaults = {\n field: 'data',\n bindingEvent: 'data',\n allowBinding: false,\n allowSetting: false,\n allowGetting: false,\n settingEvent: 'data',\n settingTriggersEvent: false,\n triggerFnName: 'trigger',\n immutableKeys: {}, // key => true if immutable\n updateStyle: false,\n onSet: function( self ){},\n canSet: function( self ){ return true; }\n };\n params = util.extend({}, defaults, params);\n\n return function dataImpl( name, value ){\n var p = params;\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var single = selfIsArrayLike ? self[0] : self;\n\n // .data('foo', ...)\n if( is.string(name) ){ // set or get property\n\n // .data('foo')\n if( p.allowGetting && value === undefined ){ // get\n\n var ret;\n if( single ){\n ret = single._private[ p.field ][ name ];\n }\n return ret;\n\n // .data('foo', 'bar')\n } else if( p.allowSetting && value !== undefined ) { // set\n var valid = !p.immutableKeys[name];\n if( valid ){\n for( var i = 0, l = all.length; i < l; i++ ){\n if( p.canSet( all[i] ) ){\n all[i]._private[ p.field ][ name ] = value;\n }\n }\n\n // update mappers if asked\n if( p.updateStyle ){ self.updateStyle(); }\n\n // call onSet callback\n p.onSet( self );\n\n if( p.settingTriggersEvent ){\n self[ p.triggerFnName ]( p.settingEvent );\n }\n }\n }\n\n // .data({ 'foo': 'bar' })\n } else if( p.allowSetting && is.plainObject(name) ){ // extend\n var obj = name;\n var k, v;\n\n for( k in obj ){\n v = obj[ k ];\n\n var valid = !p.immutableKeys[k];\n if( valid ){\n for( var i = 0, l = all.length; i < l; i++ ){\n if( p.canSet( all[i] ) ){\n all[i]._private[ p.field ][ k ] = v;\n }\n }\n }\n }\n\n // update mappers if asked\n if( p.updateStyle ){ self.updateStyle(); }\n\n // call onSet callback\n p.onSet( self );\n\n if( p.settingTriggersEvent ){\n self[ p.triggerFnName ]( p.settingEvent );\n }\n\n // .data(function(){ ... })\n } else if( p.allowBinding && is.fn(name) ){ // bind to event\n var fn = name;\n self.bind( p.bindingEvent, fn );\n\n // .data()\n } else if( p.allowGetting && name === undefined ){ // get whole object\n var ret;\n if( single ){\n ret = single._private[ p.field ];\n }\n return ret;\n }\n\n return self; // maintain chainability\n }; // function\n }, // data\n\n // remove data field\n removeData: function( params ){\n var defaults = {\n field: 'data',\n event: 'data',\n triggerFnName: 'trigger',\n triggerEvent: false,\n immutableKeys: {} // key => true if immutable\n };\n params = util.extend({}, defaults, params);\n\n return function removeDataImpl( names ){\n var p = params;\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n\n // .removeData('foo bar')\n if( is.string(names) ){ // then get the list of keys, and delete them\n var keys = names.split(/\\s+/);\n var l = keys.length;\n\n for( var i = 0; i < l; i++ ){ // delete each non-empty key\n var key = keys[i];\n if( is.emptyString(key) ){ continue; }\n\n var valid = !p.immutableKeys[ key ]; // not valid if immutable\n if( valid ){\n for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){\n all[ i_a ]._private[ p.field ][ key ] = undefined;\n }\n }\n }\n\n if( p.triggerEvent ){\n self[ p.triggerFnName ]( p.event );\n }\n\n // .removeData()\n } else if( names === undefined ){ // then delete all keys\n\n for( var i_a = 0, l_a = all.length; i_a < l_a; i_a++ ){\n var _privateFields = all[ i_a ]._private[ p.field ];\n\n for( var key in _privateFields ){\n var validKeyToDelete = !p.immutableKeys[ key ];\n\n if( validKeyToDelete ){\n _privateFields[ key ] = undefined;\n }\n }\n }\n\n if( p.triggerEvent ){\n self[ p.triggerFnName ]( p.event );\n }\n }\n\n return self; // maintain chaining\n }; // function\n }, // removeData\n\n // event function reusable stuff\n event: {\n regex: /(\\w+)(\\.\\w+)?/, // regex for matching event strings (e.g. \"click.namespace\")\n optionalTypeRegex: /(\\w+)?(\\.\\w+)?/,\n falseCallback: function(){ return false; }\n },\n\n // event binding\n on: function( params ){\n var defaults = {\n unbindSelfOnTrigger: false,\n unbindAllBindersOnTrigger: false\n };\n params = util.extend({}, defaults, params);\n\n return function onImpl(events, selector, data, callback){\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var eventsIsString = is.string(events);\n var p = params;\n\n if( is.plainObject(selector) ){ // selector is actually data\n callback = data;\n data = selector;\n selector = undefined;\n } else if( is.fn(selector) || selector === false ){ // selector is actually callback\n callback = selector;\n data = undefined;\n selector = undefined;\n }\n\n if( is.fn(data) || data === false ){ // data is actually callback\n callback = data;\n data = undefined;\n }\n\n // if there isn't a callback, we can't really do anything\n // (can't speak for mapped events arg version)\n if( !(is.fn(callback) || callback === false) && eventsIsString ){\n return self; // maintain chaining\n }\n\n if( eventsIsString ){ // then convert to map\n var map = {};\n map[ events ] = callback;\n events = map;\n }\n\n for( var evts in events ){\n callback = events[evts];\n if( callback === false ){\n callback = define.event.falseCallback;\n }\n\n if( !is.fn(callback) ){ continue; }\n\n evts = evts.split(/\\s+/);\n for( var i = 0; i < evts.length; i++ ){\n var evt = evts[i];\n if( is.emptyString(evt) ){ continue; }\n\n var match = evt.match( define.event.regex ); // type[.namespace]\n\n if( match ){\n var type = match[1];\n var namespace = match[2] ? match[2] : undefined;\n\n var listener = {\n callback: callback, // callback to run\n data: data, // extra data in eventObj.data\n delegated: selector ? true : false, // whether the evt is delegated\n selector: selector, // the selector to match for delegated events\n selObj: new Selector(selector), // cached selector object to save rebuilding\n type: type, // the event type (e.g. 'click')\n namespace: namespace, // the event namespace (e.g. \".foo\")\n unbindSelfOnTrigger: p.unbindSelfOnTrigger,\n unbindAllBindersOnTrigger: p.unbindAllBindersOnTrigger,\n binders: all // who bound together\n };\n\n for( var j = 0; j < all.length; j++ ){\n var _p = all[j]._private;\n\n _p.listeners = _p.listeners || [];\n _p.listeners.push( listener );\n }\n }\n } // for events array\n } // for events map\n\n return self; // maintain chaining\n }; // function\n }, // on\n\n eventAliasesOn: function( proto ){\n var p = proto;\n\n p.addListener = p.listen = p.bind = p.on;\n p.removeListener = p.unlisten = p.unbind = p.off;\n p.emit = p.trigger;\n\n // this is just a wrapper alias of .on()\n p.pon = p.promiseOn = function( events, selector ){\n var self = this;\n var args = Array.prototype.slice.call( arguments, 0 );\n\n return new Promise(function( resolve, reject ){\n var callback = function( e ){\n self.off.apply( self, offArgs );\n\n resolve( e );\n };\n\n var onArgs = args.concat([ callback ]);\n var offArgs = onArgs.concat([]);\n\n self.on.apply( self, onArgs );\n });\n };\n },\n\n off: function offImpl( params ){\n var defaults = {\n };\n params = util.extend({}, defaults, params);\n\n return function(events, selector, callback){\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var eventsIsString = is.string(events);\n\n if( arguments.length === 0 ){ // then unbind all\n\n for( var i = 0; i < all.length; i++ ){\n all[i]._private.listeners = [];\n }\n\n return self; // maintain chaining\n }\n\n if( is.fn(selector) || selector === false ){ // selector is actually callback\n callback = selector;\n selector = undefined;\n }\n\n if( eventsIsString ){ // then convert to map\n var map = {};\n map[ events ] = callback;\n events = map;\n }\n\n for( var evts in events ){\n callback = events[evts];\n\n if( callback === false ){\n callback = define.event.falseCallback;\n }\n\n evts = evts.split(/\\s+/);\n for( var h = 0; h < evts.length; h++ ){\n var evt = evts[h];\n if( is.emptyString(evt) ){ continue; }\n\n var match = evt.match( define.event.optionalTypeRegex ); // [type][.namespace]\n if( match ){\n var type = match[1] ? match[1] : undefined;\n var namespace = match[2] ? match[2] : undefined;\n\n for( var i = 0; i < all.length; i++ ){ //\n var listeners = all[i]._private.listeners = all[i]._private.listeners || [];\n\n for( var j = 0; j < listeners.length; j++ ){\n var listener = listeners[j];\n var nsMatches = !namespace || namespace === listener.namespace;\n var typeMatches = !type || listener.type === type;\n var cbMatches = !callback || callback === listener.callback;\n var listenerMatches = nsMatches && typeMatches && cbMatches;\n\n // delete listener if it matches\n if( listenerMatches ){\n listeners.splice(j, 1);\n j--;\n }\n } // for listeners\n } // for all\n } // if match\n } // for events array\n\n } // for events map\n\n return self; // maintain chaining\n }; // function\n }, // off\n\n trigger: function( params ){\n var defaults = {};\n params = util.extend({}, defaults, params);\n\n return function triggerImpl(events, extraParams, fnToTrigger){\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var eventsIsString = is.string(events);\n var eventsIsObject = is.plainObject(events);\n var eventsIsEvent = is.event(events);\n var cy = this._private.cy || ( is.core(this) ? this : null );\n var hasCompounds = cy ? cy.hasCompoundNodes() : false;\n\n if( eventsIsString ){ // then make a plain event object for each event name\n var evts = events.split(/\\s+/);\n events = [];\n\n for( var i = 0; i < evts.length; i++ ){\n var evt = evts[i];\n if( is.emptyString(evt) ){ continue; }\n\n var match = evt.match( define.event.regex ); // type[.namespace]\n var type = match[1];\n var namespace = match[2] ? match[2] : undefined;\n\n events.push( {\n type: type,\n namespace: namespace\n } );\n }\n } else if( eventsIsObject ){ // put in length 1 array\n var eventArgObj = events;\n\n events = [ eventArgObj ];\n }\n\n if( extraParams ){\n if( !is.array(extraParams) ){ // make sure extra params are in an array if specified\n extraParams = [ extraParams ];\n }\n } else { // otherwise, we've got nothing\n extraParams = [];\n }\n\n for( var i = 0; i < events.length; i++ ){ // trigger each event in order\n var evtObj = events[i];\n\n for( var j = 0; j < all.length; j++ ){ // for each\n var triggerer = all[j];\n var listeners = triggerer._private.listeners = triggerer._private.listeners || [];\n var triggererIsElement = is.element(triggerer);\n var bubbleUp = triggererIsElement || params.layout;\n\n // create the event for this element from the event object\n var evt;\n\n if( eventsIsEvent ){ // then just get the object\n evt = evtObj;\n\n evt.cyTarget = evt.cyTarget || triggerer;\n evt.cy = evt.cy || cy;\n\n } else { // then we have to make one\n evt = new Event( evtObj, {\n cyTarget: triggerer,\n cy: cy,\n namespace: evtObj.namespace\n } );\n }\n\n // if a layout was specified, then put it in the typed event\n if( evtObj.layout ){\n evt.layout = evtObj.layout;\n }\n\n // if triggered by layout, put in event\n if( params.layout ){\n evt.layout = triggerer;\n }\n\n // create a rendered position based on the passed position\n if( evt.cyPosition ){\n var pos = evt.cyPosition;\n var zoom = cy.zoom();\n var pan = cy.pan();\n\n evt.cyRenderedPosition = {\n x: pos.x * zoom + pan.x,\n y: pos.y * zoom + pan.y\n };\n }\n\n if( fnToTrigger ){ // then override the listeners list with just the one we specified\n listeners = [{\n namespace: evt.namespace,\n type: evt.type,\n callback: fnToTrigger\n }];\n }\n\n for( var k = 0; k < listeners.length; k++ ){ // check each listener\n var lis = listeners[k];\n var nsMatches = !lis.namespace || lis.namespace === evt.namespace;\n var typeMatches = lis.type === evt.type;\n var targetMatches = lis.delegated ? ( triggerer !== evt.cyTarget && is.element(evt.cyTarget) && lis.selObj.matches(evt.cyTarget) ) : (true); // we're not going to validate the hierarchy; that's too expensive\n var listenerMatches = nsMatches && typeMatches && targetMatches;\n\n if( listenerMatches ){ // then trigger it\n var args = [ evt ];\n args = args.concat( extraParams ); // add extra params to args list\n\n if( lis.data ){ // add on data plugged into binding\n evt.data = lis.data;\n } else { // or clear it in case the event obj is reused\n evt.data = undefined;\n }\n\n if( lis.unbindSelfOnTrigger || lis.unbindAllBindersOnTrigger ){ // then remove listener\n listeners.splice(k, 1);\n k--;\n }\n\n if( lis.unbindAllBindersOnTrigger ){ // then delete the listener for all binders\n var binders = lis.binders;\n for( var l = 0; l < binders.length; l++ ){\n var binder = binders[l];\n if( !binder || binder === triggerer ){ continue; } // already handled triggerer or we can't handle it\n\n var binderListeners = binder._private.listeners;\n for( var m = 0; m < binderListeners.length; m++ ){\n var binderListener = binderListeners[m];\n\n if( binderListener === lis ){ // delete listener from list\n binderListeners.splice(m, 1);\n m--;\n }\n }\n }\n }\n\n // run the callback\n var context = lis.delegated ? evt.cyTarget : triggerer;\n var ret = lis.callback.apply( context, args );\n\n if( ret === false || evt.isPropagationStopped() ){\n // then don't bubble\n bubbleUp = false;\n\n if( ret === false ){\n // returning false is a shorthand for stopping propagation and preventing the def. action\n evt.stopPropagation();\n evt.preventDefault();\n }\n }\n } // if listener matches\n } // for each listener\n\n // bubble up event for elements\n if( bubbleUp ){\n var parent = hasCompounds ? triggerer._private.parent : null;\n var hasParent = parent != null && parent.length !== 0;\n\n if( hasParent ){ // then bubble up to parent\n parent = parent[0];\n parent.trigger(evt);\n } else { // otherwise, bubble up to the core\n cy.trigger(evt);\n }\n }\n\n } // for each of all\n } // for each event\n\n return self; // maintain chaining\n }; // function\n }, // trigger\n\n animated: function( fnParams ){\n var defaults = {};\n fnParams = util.extend({}, defaults, fnParams);\n\n return function animatedImpl(){\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var cy = this._private.cy || this;\n\n if( !cy.styleEnabled() ){ return false; }\n\n var ele = all[0];\n\n if( ele ){\n return ele._private.animation.current.length > 0;\n }\n };\n }, // animated\n\n clearQueue: function( fnParams ){\n var defaults = {};\n fnParams = util.extend({}, defaults, fnParams);\n\n return function clearQueueImpl(){\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var cy = this._private.cy || this;\n\n if( !cy.styleEnabled() ){ return this; }\n\n for( var i = 0; i < all.length; i++ ){\n var ele = all[i];\n ele._private.animation.queue = [];\n }\n\n return this;\n };\n }, // clearQueue\n\n delay: function( fnParams ){\n var defaults = {};\n fnParams = util.extend({}, defaults, fnParams);\n\n return function delayImpl( time, complete ){\n var cy = this._private.cy || this;\n\n if( !cy.styleEnabled() ){ return this; }\n\n return this.animate({\n delay: time,\n duration: time,\n complete: complete\n });\n };\n }, // delay\n\n delayAnimation: function( fnParams ){\n var defaults = {};\n fnParams = util.extend({}, defaults, fnParams);\n\n return function delayAnimationImpl( time, complete ){\n var cy = this._private.cy || this;\n\n if( !cy.styleEnabled() ){ return this; }\n\n return this.animation({\n delay: time,\n duration: time,\n complete: complete\n });\n };\n }, // delay\n\n animation: function( fnParams ){\n var defaults = {};\n fnParams = util.extend({}, defaults, fnParams);\n\n return function animationImpl( properties, params ){\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var cy = this._private.cy || this;\n var isCore = !selfIsArrayLike;\n var isEles = !isCore;\n\n if( !cy.styleEnabled() ){ return this; }\n\n var style = cy.style();\n\n properties = util.extend( {}, properties, params );\n\n if( properties.duration === undefined ){\n properties.duration = 400;\n }\n\n switch( properties.duration ){\n case 'slow':\n properties.duration = 600;\n break;\n case 'fast':\n properties.duration = 200;\n break;\n }\n\n var propertiesEmpty = true;\n if( properties ){ for( var i in properties ){ // jshint ignore:line\n propertiesEmpty = false;\n break;\n } }\n\n if( propertiesEmpty ){\n return new Animation( all[0], properties ); // nothing to animate\n }\n\n if( isEles ){\n properties.style = style.getPropsList( properties.style || properties.css );\n\n properties.css = undefined;\n }\n\n if( properties.renderedPosition && isEles ){\n var rpos = properties.renderedPosition;\n var pan = cy.pan();\n var zoom = cy.zoom();\n\n properties.position = {\n x: ( rpos.x - pan.x ) /zoom,\n y: ( rpos.y - pan.y ) /zoom\n };\n }\n\n // override pan w/ panBy if set\n if( properties.panBy && isCore ){\n var panBy = properties.panBy;\n var cyPan = cy.pan();\n\n properties.pan = {\n x: cyPan.x + panBy.x,\n y: cyPan.y + panBy.y\n };\n }\n\n // override pan w/ center if set\n var center = properties.center || properties.centre;\n if( center && isCore ){\n var centerPan = cy.getCenterPan( center.eles, properties.zoom );\n\n if( centerPan ){\n properties.pan = centerPan;\n }\n }\n\n // override pan & zoom w/ fit if set\n if( properties.fit && isCore ){\n var fit = properties.fit;\n var fitVp = cy.getFitViewport( fit.eles || fit.boundingBox, fit.padding );\n\n if( fitVp ){\n properties.pan = fitVp.pan;\n properties.zoom = fitVp.zoom;\n }\n }\n\n return new Animation( all[0], properties );\n };\n }, // animate\n\n animate: function( fnParams ){\n var defaults = {};\n fnParams = util.extend({}, defaults, fnParams);\n\n return function animateImpl( properties, params ){\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var cy = this._private.cy || this;\n\n if( !cy.styleEnabled() ){ return this; }\n\n if( params ){\n properties = util.extend( {}, properties, params );\n }\n\n // manually hook and run the animation\n for( var i = 0; i < all.length; i++ ){\n var ele = all[i];\n var queue = ele.animated() && (properties.queue === undefined || properties.queue);\n\n var ani = ele.animation( properties, (queue ? { queue: true } : undefined) );\n\n ani.play();\n }\n\n return this; // chaining\n };\n }, // animate\n\n stop: function( fnParams ){\n var defaults = {};\n fnParams = util.extend({}, defaults, fnParams);\n\n return function stopImpl( clearQueue, jumpToEnd ){\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var cy = this._private.cy || this;\n\n if( !cy.styleEnabled() ){ return this; }\n\n for( var i = 0; i < all.length; i++ ){\n var ele = all[i];\n var _p = ele._private;\n var anis = _p.animation.current;\n\n for( var j = 0; j < anis.length; j++ ){\n var ani = anis[j];\n var ani_p = ani._private;\n\n if( jumpToEnd ){\n // next iteration of the animation loop, the animation\n // will go straight to the end and be removed\n ani_p.duration = 0;\n }\n }\n\n // clear the queue of future animations\n if( clearQueue ){\n _p.animation.queue = [];\n }\n\n if( !jumpToEnd ){\n _p.animation.current = [];\n }\n }\n\n // we have to notify (the animation loop doesn't do it for us on `stop`)\n cy.notify({\n collection: this,\n type: 'draw'\n });\n\n return this;\n };\n } // stop\n\n}; // define\n\nmodule.exports = define;\n","'use strict';\n\n// ref\n// https://github.com/jquery/jquery/blob/master/src/event.js\n\nvar Event = function( src, props ) {\n // Allow instantiation without the 'new' keyword\n if ( !(this instanceof Event) ) {\n return new Event( src, props );\n }\n\n // Event object\n if ( src && src.type ) {\n this.originalEvent = src;\n this.type = src.type;\n\n // Events bubbling up the document may have been marked as prevented\n // by a handler lower down the tree; reflect the correct value.\n this.isDefaultPrevented = ( src.defaultPrevented ) ? returnTrue : returnFalse;\n\n // Event type\n } else {\n this.type = src;\n }\n\n // Put explicitly provided properties onto the event object\n if ( props ) {\n // util.extend( this, props );\n\n // more efficient to manually copy fields we use\n this.type = props.type !== undefined ? props.type : this.type;\n this.cy = props.cy;\n this.cyTarget = props.cyTarget;\n this.cyPosition = props.cyPosition;\n this.cyRenderedPosition = props.cyRenderedPosition;\n this.namespace = props.namespace;\n this.layout = props.layout;\n this.data = props.data;\n this.message = props.message;\n }\n\n // Create a timestamp if incoming event doesn't have one\n this.timeStamp = src && src.timeStamp || Date.now();\n};\n\nfunction returnFalse() {\n return false;\n}\n\nfunction returnTrue() {\n return true;\n}\n\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\nEvent.prototype = {\n instanceString: function(){\n return 'event';\n },\n\n preventDefault: function() {\n this.isDefaultPrevented = returnTrue;\n\n var e = this.originalEvent;\n if ( !e ) {\n return;\n }\n\n // if preventDefault exists run it on the original event\n if ( e.preventDefault ) {\n e.preventDefault();\n }\n },\n\n stopPropagation: function() {\n this.isPropagationStopped = returnTrue;\n\n var e = this.originalEvent;\n if ( !e ) {\n return;\n }\n\n // if stopPropagation exists run it on the original event\n if ( e.stopPropagation ) {\n e.stopPropagation();\n }\n },\n\n stopImmediatePropagation: function() {\n this.isImmediatePropagationStopped = returnTrue;\n this.stopPropagation();\n },\n\n isDefaultPrevented: returnFalse,\n isPropagationStopped: returnFalse,\n isImmediatePropagationStopped: returnFalse\n};\n\nmodule.exports = Event;\n","'use strict';\n\nvar util = require('./util');\nvar define = require('./define');\nvar Collection = require('./collection');\nvar Core = require('./core');\nvar incExts = require('./extensions');\nvar is = require('./is');\n\n// registered extensions to cytoscape, indexed by name\nvar extensions = {};\n\n// registered modules for extensions, indexed by name\nvar modules = {};\n\nfunction setExtension( type, name, registrant ){\n\n var ext = registrant;\n\n if( type === 'core' ){\n Core.prototype[ name ] = registrant;\n\n } else if( type === 'collection' ){\n Collection.prototype[ name ] = registrant;\n\n } else if( type === 'layout' ){\n // fill in missing layout functions in the prototype\n\n var Layout = function( options ){\n this.options = options;\n\n registrant.call( this, options );\n\n // make sure layout has _private for use w/ std apis like .on()\n if( !is.plainObject(this._private) ){\n this._private = {};\n }\n\n this._private.cy = options.cy;\n this._private.listeners = [];\n };\n\n var layoutProto = Layout.prototype = Object.create( registrant.prototype );\n\n var optLayoutFns = [];\n\n for( var i = 0; i < optLayoutFns.length; i++ ){\n var fnName = optLayoutFns[i];\n\n layoutProto[fnName] = layoutProto[fnName] || function(){ return this; };\n }\n\n // either .start() or .run() is defined, so autogen the other\n if( layoutProto.start && !layoutProto.run ){\n layoutProto.run = function(){ this.start(); return this; };\n } else if( !layoutProto.start && layoutProto.run ){\n layoutProto.start = function(){ this.run(); return this; };\n }\n\n if( !layoutProto.stop ){\n layoutProto.stop = function(){\n var opts = this.options;\n\n if( opts && opts.animate ){\n var anis = this.animations;\n for( var i = 0; i < anis.length; i++ ){\n anis[i].stop();\n }\n }\n\n this.trigger('layoutstop');\n\n return this;\n };\n }\n\n if( !layoutProto.destroy ){\n layoutProto.destroy = function(){\n return this;\n };\n }\n\n layoutProto.on = define.on({ layout: true });\n layoutProto.one = define.on({ layout: true, unbindSelfOnTrigger: true });\n layoutProto.once = define.on({ layout: true, unbindAllBindersOnTrigger: true });\n layoutProto.off = define.off({ layout: true });\n layoutProto.trigger = define.trigger({ layout: true });\n\n define.eventAliasesOn( layoutProto );\n\n ext = Layout; // replace with our wrapped layout\n\n } else if( type === 'renderer' && name !== 'null' && name !== 'base' ){\n // user registered renderers inherit from base\n\n var bProto = getExtension( 'renderer', 'base' ).prototype;\n var rProto = registrant.prototype;\n\n for( var pName in bProto ){\n var pVal = bProto[ pName ];\n var existsInR = rProto[ pName ] != null;\n\n if( existsInR ){\n util.error('Can not register renderer `' + name + '` since it overrides `' + pName + '` in its prototype');\n return;\n }\n\n rProto[ pName ] = pVal; // take impl from base\n }\n\n bProto.clientFunctions.forEach(function( name ){\n rProto[ name ] = rProto[ name ] || function(){\n util.error('Renderer does not implement `renderer.' + name + '()` on its prototype');\n };\n });\n\n }\n\n return util.setMap({\n map: extensions,\n keys: [ type, name ],\n value: ext\n });\n}\n\nfunction getExtension(type, name){\n return util.getMap({\n map: extensions,\n keys: [ type, name ]\n });\n}\n\nfunction setModule(type, name, moduleType, moduleName, registrant){\n return util.setMap({\n map: modules,\n keys: [ type, name, moduleType, moduleName ],\n value: registrant\n });\n}\n\nfunction getModule(type, name, moduleType, moduleName){\n return util.getMap({\n map: modules,\n keys: [ type, name, moduleType, moduleName ]\n });\n}\n\nvar extension = function(){\n // e.g. extension('renderer', 'svg')\n if( arguments.length === 2 ){\n return getExtension.apply(null, arguments);\n }\n\n // e.g. extension('renderer', 'svg', { ... })\n else if( arguments.length === 3 ){\n return setExtension.apply(null, arguments);\n }\n\n // e.g. extension('renderer', 'svg', 'nodeShape', 'ellipse')\n else if( arguments.length === 4 ){\n return getModule.apply(null, arguments);\n }\n\n // e.g. extension('renderer', 'svg', 'nodeShape', 'ellipse', { ... })\n else if( arguments.length === 5 ){\n return setModule.apply(null, arguments);\n }\n\n else {\n util.error('Invalid extension access syntax');\n }\n\n};\n\n// allows a core instance to access extensions internally\nCore.prototype.extension = extension;\n\n// included extensions\nincExts.forEach(function( group ){\n group.extensions.forEach(function( ext ){\n setExtension( group.type, ext.name, ext.impl );\n });\n});\n\nmodule.exports = extension;\n","'use strict';\n\nmodule.exports = [\n {\n type: 'layout',\n extensions: require('./layout')\n },\n\n {\n type: 'renderer',\n extensions: require('./renderer')\n }\n];\n","'use strict';\n\nvar util = require('../../util');\nvar math = require('../../math');\nvar is = require('../../is');\n\nvar defaults = {\n fit: true, // whether to fit the viewport to the graph\n directed: false, // whether the tree is directed downwards (or edges can point in any direction if false)\n padding: 30, // padding on fit\n circle: false, // put depths in concentric circles if true, put depths top down if false\n spacingFactor: 1.75, // positive spacing factor, larger => more space between nodes (N.B. n/a if causes overlap)\n boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n avoidOverlap: true, // prevents node overlap, may overflow boundingBox if not enough space\n roots: undefined, // the roots of the trees\n maximalAdjustments: 0, // how many times to try to position the nodes in a maximal way (i.e. no backtracking)\n animate: false, // whether to transition the node positions\n animationDuration: 500, // duration of animation in ms if enabled\n animationEasing: undefined, // easing of animation if enabled\n ready: undefined, // callback on layoutready\n stop: undefined // callback on layoutstop\n};\n\nfunction BreadthFirstLayout( options ){\n this.options = util.extend({}, defaults, options);\n}\n\nBreadthFirstLayout.prototype.run = function(){\n var params = this.options;\n var options = params;\n\n var cy = params.cy;\n var eles = options.eles;\n var nodes = eles.nodes().not(':parent');\n var graph = eles;\n\n var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : {\n x1: 0, y1: 0, w: cy.width(), h: cy.height()\n } );\n\n var roots;\n if( is.elementOrCollection(options.roots) ){\n roots = options.roots;\n } else if( is.array(options.roots) ){\n var rootsArray = [];\n\n for( var i = 0; i < options.roots.length; i++ ){\n var id = options.roots[i];\n var ele = cy.getElementById( id );\n rootsArray.push( ele );\n }\n\n roots = cy.collection( rootsArray );\n } else if( is.string(options.roots) ){\n roots = cy.$( options.roots );\n\n } else {\n if( options.directed ){\n roots = nodes.roots();\n } else {\n var components = [];\n var unhandledNodes = nodes;\n\n while( unhandledNodes.length > 0 ){\n var currComp = cy.collection();\n\n eles.bfs({\n roots: unhandledNodes[0],\n visit: function(i, depth, node, edge, pNode){\n currComp = currComp.add( node );\n },\n directed: false\n });\n\n unhandledNodes = unhandledNodes.not( currComp );\n components.push( currComp );\n }\n\n roots = cy.collection();\n for( var i = 0; i < components.length; i++ ){\n var comp = components[i];\n var maxDegree = comp.maxDegree( false );\n var compRoots = comp.filter(function(){\n return this.degree(false) === maxDegree;\n });\n\n roots = roots.add( compRoots );\n }\n\n }\n }\n\n\n var depths = [];\n var foundByBfs = {};\n var id2depth = {};\n var prevNode = {};\n var prevEdge = {};\n var successors = {};\n\n // find the depths of the nodes\n graph.bfs({\n roots: roots,\n directed: options.directed,\n visit: function(i, depth, node, edge, pNode){\n var ele = this[0];\n var id = ele.id();\n\n if( !depths[depth] ){\n depths[depth] = [];\n }\n\n depths[depth].push( ele );\n foundByBfs[ id ] = true;\n id2depth[ id ] = depth;\n prevNode[ id ] = pNode;\n prevEdge[ id ] = edge;\n\n if( pNode ){\n var prevId = pNode.id();\n var succ = successors[ prevId ] = successors[ prevId ] || [];\n\n succ.push( node );\n }\n }\n });\n\n // check for nodes not found by bfs\n var orphanNodes = [];\n for( var i = 0; i < nodes.length; i++ ){\n var ele = nodes[i];\n\n if( foundByBfs[ ele.id() ] ){\n continue;\n } else {\n orphanNodes.push( ele );\n }\n }\n\n // assign orphan nodes a depth from their neighborhood\n var maxChecks = orphanNodes.length * 3;\n var checks = 0;\n while( orphanNodes.length !== 0 && checks < maxChecks ){\n var node = orphanNodes.shift();\n var neighbors = node.neighborhood().nodes();\n var assignedDepth = false;\n\n for( var i = 0; i < neighbors.length; i++ ){\n var depth = id2depth[ neighbors[i].id() ];\n\n if( depth !== undefined ){\n depths[depth].push( node );\n assignedDepth = true;\n break;\n }\n }\n\n if( !assignedDepth ){\n orphanNodes.push( node );\n }\n\n checks++;\n }\n\n // assign orphan nodes that are still left to the depth of their subgraph\n while( orphanNodes.length !== 0 ){\n var node = orphanNodes.shift();\n //var subgraph = graph.bfs( node ).path;\n var assignedDepth = false;\n\n // for( var i = 0; i < subgraph.length; i++ ){\n // var depth = id2depth[ subgraph[i].id() ];\n\n // if( depth !== undefined ){\n // depths[depth].push( node );\n // assignedDepth = true;\n // break;\n // }\n // }\n\n if( !assignedDepth ){ // worst case if the graph really isn't tree friendly, then just dump it in 0\n if( depths.length === 0 ){\n depths.push([]);\n }\n\n depths[0].push( node );\n }\n }\n\n // assign the nodes a depth and index\n var assignDepthsToEles = function(){\n for( var i = 0; i < depths.length; i++ ){\n var eles = depths[i];\n\n for( var j = 0; j < eles.length; j++ ){\n var ele = eles[j];\n\n ele._private.scratch.breadthfirst = {\n depth: i,\n index: j\n };\n }\n }\n };\n assignDepthsToEles();\n\n\n var intersectsDepth = function( node ){ // returns true if has edges pointing in from a higher depth\n var edges = node.connectedEdges(function(){\n return this.data('target') === node.id();\n });\n var thisInfo = node._private.scratch.breadthfirst;\n var highestDepthOfOther = 0;\n var highestOther;\n for( var i = 0; i < edges.length; i++ ){\n var edge = edges[i];\n var otherNode = edge.source()[0];\n var otherInfo = otherNode._private.scratch.breadthfirst;\n\n if( thisInfo.depth <= otherInfo.depth && highestDepthOfOther < otherInfo.depth ){\n highestDepthOfOther = otherInfo.depth;\n highestOther = otherNode;\n }\n }\n\n return highestOther;\n };\n\n // make maximal if so set by adjusting depths\n for( var adj = 0; adj < options.maximalAdjustments; adj++ ){\n\n var nDepths = depths.length;\n var elesToMove = [];\n for( var i = 0; i < nDepths; i++ ){\n var depth = depths[i];\n\n var nDepth = depth.length;\n for( var j = 0; j < nDepth; j++ ){\n var ele = depth[j];\n var info = ele._private.scratch.breadthfirst;\n var intEle = intersectsDepth(ele);\n\n if( intEle ){\n info.intEle = intEle;\n elesToMove.push( ele );\n }\n }\n }\n\n for( var i = 0; i < elesToMove.length; i++ ){\n var ele = elesToMove[i];\n var info = ele._private.scratch.breadthfirst;\n var intEle = info.intEle;\n var intInfo = intEle._private.scratch.breadthfirst;\n\n depths[ info.depth ].splice( info.index, 1 ); // remove from old depth & index\n\n // add to end of new depth\n var newDepth = intInfo.depth + 1;\n while( newDepth > depths.length - 1 ){\n depths.push([]);\n }\n depths[ newDepth ].push( ele );\n\n info.depth = newDepth;\n info.index = depths[newDepth].length - 1;\n }\n\n assignDepthsToEles();\n }\n\n // find min distance we need to leave between nodes\n var minDistance = 0;\n if( options.avoidOverlap ){\n for( var i = 0; i < nodes.length; i++ ){\n var n = nodes[i];\n var nbb = n.boundingBox();\n var w = nbb.w;\n var h = nbb.h;\n\n minDistance = Math.max(minDistance, w, h);\n }\n minDistance *= options.spacingFactor; // just to have some nice spacing\n }\n\n // get the weighted percent for an element based on its connectivity to other levels\n var cachedWeightedPercent = {};\n var getWeightedPercent = function( ele ){\n if( cachedWeightedPercent[ ele.id() ] ){\n return cachedWeightedPercent[ ele.id() ];\n }\n\n var eleDepth = ele._private.scratch.breadthfirst.depth;\n var neighbors = ele.neighborhood().nodes().not(':parent');\n var percent = 0;\n var samples = 0;\n\n for( var i = 0; i < neighbors.length; i++ ){\n var neighbor = neighbors[i];\n var bf = neighbor._private.scratch.breadthfirst;\n var index = bf.index;\n var depth = bf.depth;\n var nDepth = depths[depth].length;\n\n if( eleDepth > depth || eleDepth === 0 ){ // only get influenced by elements above\n percent += index / nDepth;\n samples++;\n }\n }\n\n samples = Math.max(1, samples);\n percent = percent / samples;\n\n if( samples === 0 ){ // so lone nodes have a \"don't care\" state in sorting\n percent = undefined;\n }\n\n cachedWeightedPercent[ ele.id() ] = percent;\n return percent;\n };\n\n\n // rearrange the indices in each depth level based on connectivity\n\n var sortFn = function(a, b){\n var apct = getWeightedPercent( a );\n var bpct = getWeightedPercent( b );\n\n return apct - bpct;\n };\n\n for( var times = 0; times < 3; times++ ){ // do it a few times b/c the depths are dynamic and we want a more stable result\n\n for( var i = 0; i < depths.length; i++ ){\n depths[i] = depths[i].sort( sortFn );\n }\n assignDepthsToEles(); // and update\n\n }\n\n var biggestDepthSize = 0;\n for( var i = 0; i < depths.length; i++ ){\n biggestDepthSize = Math.max( depths[i].length, biggestDepthSize );\n }\n\n var center = {\n x: bb.x1 + bb.w/2,\n y: bb.x1 + bb.h/2\n };\n\n var getPosition = function( ele, isBottomDepth ){\n var info = ele._private.scratch.breadthfirst;\n var depth = info.depth;\n var index = info.index;\n var depthSize = depths[depth].length;\n\n var distanceX = Math.max( bb.w / (depthSize + 1), minDistance );\n var distanceY = Math.max( bb.h / (depths.length + 1), minDistance );\n var radiusStepSize = Math.min( bb.w / 2 / depths.length, bb.h / 2 / depths.length );\n radiusStepSize = Math.max( radiusStepSize, minDistance );\n\n if( !options.circle ){\n\n var epos = {\n x: center.x + (index + 1 - (depthSize + 1)/2) * distanceX,\n y: (depth + 1) * distanceY\n };\n\n if( isBottomDepth ){\n return epos;\n }\n\n // var succs = successors[ ele.id() ];\n // if( succs ){\n // epos.x = 0;\n //\n // for( var i = 0 ; i < succs.length; i++ ){\n // var spos = pos[ succs[i].id() ];\n //\n // epos.x += spos.x;\n // }\n //\n // epos.x /= succs.length;\n // } else {\n // //debugger;\n // }\n\n return epos;\n\n } else {\n if( options.circle ){\n var radius = radiusStepSize * depth + radiusStepSize - (depths.length > 0 && depths[0].length <= 3 ? radiusStepSize/2 : 0);\n var theta = 2 * Math.PI / depths[depth].length * index;\n\n if( depth === 0 && depths[0].length === 1 ){\n radius = 1;\n }\n\n return {\n x: center.x + radius * Math.cos(theta),\n y: center.y + radius * Math.sin(theta)\n };\n\n } else {\n return {\n x: center.x + (index + 1 - (depthSize + 1)/2) * distanceX,\n y: (depth + 1) * distanceY\n };\n }\n }\n\n };\n\n // get positions in reverse depth order\n var pos = {};\n for( var i = depths.length - 1; i >=0; i-- ){\n var depth = depths[i];\n\n for( var j = 0; j < depth.length; j++ ){\n var node = depth[j];\n\n pos[ node.id() ] = getPosition( node, i === depths.length - 1 );\n }\n }\n\n nodes.layoutPositions(this, options, function(){\n return pos[ this.id() ];\n });\n\n return this; // chaining\n};\n\nmodule.exports = BreadthFirstLayout;\n","'use strict';\n\nvar util = require('../../util');\nvar math = require('../../math');\nvar is = require('../../is');\n\nvar defaults = {\n fit: true, // whether to fit the viewport to the graph\n padding: 30, // the padding on fit\n boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n avoidOverlap: true, // prevents node overlap, may overflow boundingBox and radius if not enough space\n radius: undefined, // the radius of the circle\n startAngle: 3/2 * Math.PI, // where nodes start in radians\n sweep: undefined, // how many radians should be between the first and last node (defaults to full circle)\n clockwise: true, // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false)\n sort: undefined, // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') }\n animate: false, // whether to transition the node positions\n animationDuration: 500, // duration of animation in ms if enabled\n animationEasing: undefined, // easing of animation if enabled\n ready: undefined, // callback on layoutready\n stop: undefined // callback on layoutstop\n};\n\nfunction CircleLayout( options ){\n this.options = util.extend({}, defaults, options);\n}\n\nCircleLayout.prototype.run = function(){\n var params = this.options;\n var options = params;\n\n var cy = params.cy;\n var eles = options.eles;\n\n var clockwise = options.counterclockwise !== undefined ? !options.counterclockwise : options.clockwise;\n\n var nodes = eles.nodes().not(':parent');\n\n if( options.sort ){\n nodes = nodes.sort( options.sort );\n }\n\n var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : {\n x1: 0, y1: 0, w: cy.width(), h: cy.height()\n } );\n\n var center = {\n x: bb.x1 + bb.w/2,\n y: bb.y1 + bb.h/2\n };\n\n var sweep = options.sweep === undefined ? 2*Math.PI - 2*Math.PI/nodes.length : options.sweep;\n\n var dTheta = sweep / ( Math.max(1, nodes.length - 1) );\n var r;\n\n var minDistance = 0;\n for( var i = 0; i < nodes.length; i++ ){\n var n = nodes[i];\n var nbb = n.boundingBox();\n var w = nbb.w;\n var h = nbb.h;\n\n minDistance = Math.max(minDistance, w, h);\n }\n\n if( is.number(options.radius) ){\n r = options.radius;\n } else if( nodes.length <= 1 ){\n r = 0;\n } else {\n r = Math.min( bb.h, bb.w )/2 - minDistance;\n }\n\n // calculate the radius\n if( nodes.length > 1 && options.avoidOverlap ){ // but only if more than one node (can't overlap)\n minDistance *= 1.75; // just to have some nice spacing\n\n var dcos = Math.cos(dTheta) - Math.cos(0);\n var dsin = Math.sin(dTheta) - Math.sin(0);\n var rMin = Math.sqrt( minDistance * minDistance / ( dcos*dcos + dsin*dsin ) ); // s.t. no nodes overlapping\n r = Math.max( rMin, r );\n }\n\n var getPos = function( i, ele ){\n var theta = options.startAngle + i * dTheta * ( clockwise ? 1 : -1 );\n\n var rx = r * Math.cos( theta );\n var ry = r * Math.sin( theta );\n var pos = {\n x: center.x + rx,\n y: center.y + ry\n };\n\n return pos;\n };\n\n nodes.layoutPositions( this, options, getPos );\n\n return this; // chaining\n};\n\nmodule.exports = CircleLayout;\n","'use strict';\n\nvar util = require('../../util');\nvar math = require('../../math');\n\nvar defaults = {\n fit: true, // whether to fit the viewport to the graph\n padding: 30, // the padding on fit\n startAngle: 3/2 * Math.PI, // where nodes start in radians\n sweep: undefined, // how many radians should be between the first and last node (defaults to full circle)\n clockwise: true, // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false)\n equidistant: false, // whether levels have an equal radial distance betwen them, may cause bounding box overflow\n minNodeSpacing: 10, // min spacing between outside of nodes (used for radius adjustment)\n boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n avoidOverlap: true, // prevents node overlap, may overflow boundingBox if not enough space\n height: undefined, // height of layout area (overrides container height)\n width: undefined, // width of layout area (overrides container width)\n concentric: function(node){ // returns numeric value for each node, placing higher nodes in levels towards the centre\n return node.degree();\n },\n levelWidth: function(nodes){ // the variation of concentric values in each level\n return nodes.maxDegree() / 4;\n },\n animate: false, // whether to transition the node positions\n animationDuration: 500, // duration of animation in ms if enabled\n animationEasing: undefined, // easing of animation if enabled\n ready: undefined, // callback on layoutready\n stop: undefined // callback on layoutstop\n};\n\nfunction ConcentricLayout( options ){\n this.options = util.extend({}, defaults, options);\n}\n\nConcentricLayout.prototype.run = function(){\n var params = this.options;\n var options = params;\n\n var clockwise = options.counterclockwise !== undefined ? !options.counterclockwise : options.clockwise;\n\n var cy = params.cy;\n\n var eles = options.eles;\n var nodes = eles.nodes().not(':parent');\n\n var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : {\n x1: 0, y1: 0, w: cy.width(), h: cy.height()\n } );\n\n var center = {\n x: bb.x1 + bb.w/2,\n y: bb.y1 + bb.h/2\n };\n\n var nodeValues = []; // { node, value }\n var theta = options.startAngle;\n var maxNodeSize = 0;\n\n for( var i = 0; i < nodes.length; i++ ){\n var node = nodes[i];\n var value;\n\n // calculate the node value\n value = options.concentric.apply(node, [ node ]);\n nodeValues.push({\n value: value,\n node: node\n });\n\n // for style mapping\n node._private.scratch.concentric = value;\n }\n\n // in case we used the `concentric` in style\n nodes.updateStyle();\n\n // calculate max size now based on potentially updated mappers\n for( var i = 0; i < nodes.length; i++ ){\n var node = nodes[i];\n var nbb = node.boundingBox();\n\n maxNodeSize = Math.max( maxNodeSize, nbb.w, nbb.h );\n }\n\n // sort node values in descreasing order\n nodeValues.sort(function(a, b){\n return b.value - a.value;\n });\n\n var levelWidth = options.levelWidth( nodes );\n\n // put the values into levels\n var levels = [ [] ];\n var currentLevel = levels[0];\n for( var i = 0; i < nodeValues.length; i++ ){\n var val = nodeValues[i];\n\n if( currentLevel.length > 0 ){\n var diff = Math.abs( currentLevel[0].value - val.value );\n\n if( diff >= levelWidth ){\n currentLevel = [];\n levels.push( currentLevel );\n }\n }\n\n currentLevel.push( val );\n }\n\n // create positions from levels\n\n var minDist = maxNodeSize + options.minNodeSpacing; // min dist between nodes\n\n if( !options.avoidOverlap ){ // then strictly constrain to bb\n var firstLvlHasMulti = levels.length > 0 && levels[0].length > 1;\n var maxR = ( Math.min(bb.w, bb.h) / 2 - minDist );\n var rStep = maxR / ( levels.length + firstLvlHasMulti ? 1 : 0 );\n\n minDist = Math.min( minDist, rStep );\n }\n\n // find the metrics for each level\n var r = 0;\n for( var i = 0; i < levels.length; i++ ){\n var level = levels[i];\n var sweep = options.sweep === undefined ? 2*Math.PI - 2*Math.PI/level.length : options.sweep;\n var dTheta = level.dTheta = sweep / ( Math.max(1, level.length - 1) );\n\n // calculate the radius\n if( level.length > 1 && options.avoidOverlap ){ // but only if more than one node (can't overlap)\n var dcos = Math.cos(dTheta) - Math.cos(0);\n var dsin = Math.sin(dTheta) - Math.sin(0);\n var rMin = Math.sqrt( minDist * minDist / ( dcos*dcos + dsin*dsin ) ); // s.t. no nodes overlapping\n\n r = Math.max( rMin, r );\n }\n\n level.r = r;\n\n r += minDist;\n }\n\n if( options.equidistant ){\n var rDeltaMax = 0;\n var r = 0;\n\n for( var i = 0; i < levels.length; i++ ){\n var level = levels[i];\n var rDelta = level.r - r;\n\n rDeltaMax = Math.max( rDeltaMax, rDelta );\n }\n\n r = 0;\n for( var i = 0; i < levels.length; i++ ){\n var level = levels[i];\n\n if( i === 0 ){\n r = level.r;\n }\n\n level.r = r;\n\n r += rDeltaMax;\n }\n }\n\n // calculate the node positions\n var pos = {}; // id => position\n for( var i = 0; i < levels.length; i++ ){\n var level = levels[i];\n var dTheta = level.dTheta;\n var r = level.r;\n\n for( var j = 0; j < level.length; j++ ){\n var val = level[j];\n var theta = options.startAngle + (clockwise ? 1 : -1) * dTheta * j;\n\n var p = {\n x: center.x + r * Math.cos(theta),\n y: center.y + r * Math.sin(theta)\n };\n\n pos[ val.node.id() ] = p;\n }\n }\n\n // position the nodes\n nodes.layoutPositions(this, options, function(){\n var id = this.id();\n\n return pos[id];\n });\n\n return this; // chaining\n};\n\nmodule.exports = ConcentricLayout;\n","'use strict';\n\n/*\nThe CoSE layout was written by Gerardo Huck.\nhttps://www.linkedin.com/in/gerardohuck/\n\nBased on the following article:\nhttp://dl.acm.org/citation.cfm?id=1498047\n\nModifications tracked on Github.\n*/\n\nvar util = require('../../util');\nvar math = require('../../math');\nvar Thread = require('../../thread');\nvar is = require('../../is');\n\nvar DEBUG;\n\n/**\n * @brief : default layout options\n */\nvar defaults = {\n // Called on `layoutready`\n ready : function() {},\n\n // Called on `layoutstop`\n stop : function() {},\n\n // Whether to animate while running the layout\n animate : true,\n\n // The layout animates only after this many milliseconds\n // (prevents flashing on fast runs)\n animationThreshold : 250,\n\n // Number of iterations between consecutive screen positions update\n // (0 -> only updated on the end)\n refresh : 20,\n\n // Whether to fit the network view after when done\n fit : true,\n\n // Padding on fit\n padding : 30,\n\n // Constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n boundingBox : undefined,\n\n // Extra spacing between components in non-compound graphs\n componentSpacing : 100,\n\n // Node repulsion (non overlapping) multiplier\n nodeRepulsion : function( node ){ return 400000; },\n\n // Node repulsion (overlapping) multiplier\n nodeOverlap : 10,\n\n // Ideal edge (non nested) length\n idealEdgeLength : function( edge ){ return 10; },\n\n // Divisor to compute edge forces\n edgeElasticity : function( edge ){ return 100; },\n\n // Nesting factor (multiplier) to compute ideal edge length for nested edges\n nestingFactor : 5,\n\n // Gravity force (constant)\n gravity : 80,\n\n // Maximum number of iterations to perform\n numIter : 1000,\n\n // Initial temperature (maximum node displacement)\n initialTemp : 200,\n\n // Cooling factor (how the temperature is reduced between consecutive iterations\n coolingFactor : 0.95,\n\n // Lower temperature threshold (below this point the layout will end)\n minTemp : 1.0,\n\n // Whether to use threading to speed up the layout\n useMultitasking : true\n};\n\n\n/**\n * @brief : constructor\n * @arg options : object containing layout options\n */\nfunction CoseLayout(options) {\n this.options = util.extend({}, defaults, options);\n\n this.options.layout = this;\n}\n\n\n/**\n * @brief : runs the layout\n */\nCoseLayout.prototype.run = function() {\n var options = this.options;\n var cy = options.cy;\n var layout = this;\n var thread = this.thread;\n\n if( !thread || thread.stopped() ){\n thread = this.thread = Thread({ disabled: !options.useMultitasking });\n }\n\n layout.stopped = false;\n\n layout.trigger({ type: 'layoutstart', layout: layout });\n\n // Set DEBUG - Global variable\n if (true === options.debug) {\n DEBUG = true;\n } else {\n DEBUG = false;\n }\n\n // Initialize layout info\n var layoutInfo = createLayoutInfo(cy, layout, options);\n\n // Show LayoutInfo contents if debugging\n if (DEBUG) {\n printLayoutInfo(layoutInfo);\n }\n\n // If required, randomize node positions\n // if (true === options.randomize) {\n randomizePositions(layoutInfo, cy);\n // }\n\n var startTime = Date.now();\n var refreshRequested = false;\n var refresh = function( rOpts ){\n rOpts = rOpts || {};\n\n if( refreshRequested ){\n return;\n }\n\n if( !rOpts.force && Date.now() - startTime < options.animationThreshold ){\n return;\n }\n\n refreshRequested = true;\n\n util.requestAnimationFrame(function(){\n refreshPositions(layoutInfo, cy, options);\n\n // Fit the graph if necessary\n if (true === options.fit) {\n cy.fit( options.padding );\n }\n\n refreshRequested = false;\n });\n };\n\n thread.on('message', function( e ){\n var layoutNodes = e.message;\n\n layoutInfo.layoutNodes = layoutNodes;\n refresh();\n });\n\n thread.pass({\n layoutInfo: layoutInfo,\n options: {\n animate: options.animate,\n refresh: options.refresh,\n componentSpacing: options.componentSpacing,\n nodeOverlap: options.nodeOverlap,\n nestingFactor: options.nestingFactor,\n gravity: options.gravity,\n numIter: options.numIter,\n initialTemp: options.initialTemp,\n coolingFactor: options.coolingFactor,\n minTemp: options.minTemp\n }\n }).run(function( pass ){\n var layoutInfo = pass.layoutInfo;\n var options = pass.options;\n var stopped = false;\n\n /**\n * @brief : Performs one iteration of the physical simulation\n * @arg layoutInfo : LayoutInfo object already initialized\n * @arg cy : Cytoscape object\n * @arg options : Layout options\n */\n var step = function(layoutInfo, options, step) {\n // var s = \"\\n\\n###############################\";\n // s += \"\\nSTEP: \" + step;\n // s += \"\\n###############################\\n\";\n // logDebug(s);\n\n // Calculate node repulsions\n calculateNodeForces(layoutInfo, options);\n // Calculate edge forces\n calculateEdgeForces(layoutInfo, options);\n // Calculate gravity forces\n calculateGravityForces(layoutInfo, options);\n // Propagate forces from parent to child\n propagateForces(layoutInfo, options);\n // Update positions based on calculated forces\n updatePositions(layoutInfo, options);\n };\n\n /**\n * @brief : Computes the node repulsion forces\n */\n var calculateNodeForces = function(layoutInfo, options) {\n // Go through each of the graphs in graphSet\n // Nodes only repel each other if they belong to the same graph\n // var s = 'calculateNodeForces';\n // logDebug(s);\n for (var i = 0; i < layoutInfo.graphSet.length; i ++) {\n var graph = layoutInfo.graphSet[i];\n var numNodes = graph.length;\n\n // s = \"Set: \" + graph.toString();\n // logDebug(s);\n\n // Now get all the pairs of nodes\n // Only get each pair once, (A, B) = (B, A)\n for (var j = 0; j < numNodes; j++) {\n var node1 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]];\n\n for (var k = j + 1; k < numNodes; k++) {\n var node2 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[k]]];\n\n nodeRepulsion(node1, node2, layoutInfo, options);\n }\n }\n }\n };\n\n /**\n * @brief : Compute the node repulsion forces between a pair of nodes\n */\n var nodeRepulsion = function(node1, node2, layoutInfo, options) {\n // var s = \"Node repulsion. Node1: \" + node1.id + \" Node2: \" + node2.id;\n\n var cmptId1 = node1.cmptId;\n var cmptId2 = node2.cmptId;\n\n if( cmptId1 !== cmptId2 && !layoutInfo.isCompound ){ return; }\n\n // Get direction of line connecting both node centers\n var directionX = node2.positionX - node1.positionX;\n var directionY = node2.positionY - node1.positionY;\n // s += \"\\ndirectionX: \" + directionX + \", directionY: \" + directionY;\n\n // If both centers are the same, apply a random force\n if (0 === directionX && 0 === directionY) {\n // s += \"\\nNodes have the same position.\";\n return; // TODO could be improved with random force\n }\n\n var overlap = nodesOverlap(node1, node2, directionX, directionY);\n\n if (overlap > 0) {\n // s += \"\\nNodes DO overlap.\";\n // s += \"\\nOverlap: \" + overlap;\n // If nodes overlap, repulsion force is proportional\n // to the overlap\n var force = options.nodeOverlap * overlap;\n\n // Compute the module and components of the force vector\n var distance = Math.sqrt(directionX * directionX + directionY * directionY);\n // s += \"\\nDistance: \" + distance;\n var forceX = force * directionX / distance;\n var forceY = force * directionY / distance;\n\n } else {\n // s += \"\\nNodes do NOT overlap.\";\n // If there's no overlap, force is inversely proportional\n // to squared distance\n\n // Get clipping points for both nodes\n var point1 = findClippingPoint(node1, directionX, directionY);\n var point2 = findClippingPoint(node2, -1 * directionX, -1 * directionY);\n\n // Use clipping points to compute distance\n var distanceX = point2.x - point1.x;\n var distanceY = point2.y - point1.y;\n var distanceSqr = distanceX * distanceX + distanceY * distanceY;\n var distance = Math.sqrt(distanceSqr);\n // s += \"\\nDistance: \" + distance;\n\n // Compute the module and components of the force vector\n var force = ( node1.nodeRepulsion + node2.nodeRepulsion ) / distanceSqr;\n var forceX = force * distanceX / distance;\n var forceY = force * distanceY / distance;\n }\n\n // Apply force\n if( !node1.isLocked ){\n node1.offsetX -= forceX;\n node1.offsetY -= forceY;\n }\n\n if( !node2.isLocked ){\n node2.offsetX += forceX;\n node2.offsetY += forceY;\n }\n\n // s += \"\\nForceX: \" + forceX + \" ForceY: \" + forceY;\n // logDebug(s);\n\n return;\n };\n\n /**\n * @brief : Determines whether two nodes overlap or not\n * @return : Amount of overlapping (0 => no overlap)\n */\n var nodesOverlap = function(node1, node2, dX, dY) {\n\n if (dX > 0) {\n var overlapX = node1.maxX - node2.minX;\n } else {\n var overlapX = node2.maxX - node1.minX;\n }\n\n if (dY > 0) {\n var overlapY = node1.maxY - node2.minY;\n } else {\n var overlapY = node2.maxY - node1.minY;\n }\n\n if (overlapX >= 0 && overlapY >= 0) {\n return Math.sqrt(overlapX * overlapX + overlapY * overlapY);\n } else {\n return 0;\n }\n };\n\n /**\n * @brief : Finds the point in which an edge (direction dX, dY) intersects\n * the rectangular bounding box of it's source/target node\n */\n var findClippingPoint = function(node, dX, dY) {\n\n // Shorcuts\n var X = node.positionX;\n var Y = node.positionY;\n var H = node.height || 1;\n var W = node.width || 1;\n var dirSlope = dY / dX;\n var nodeSlope = H / W;\n\n // var s = 'Computing clipping point of node ' + node.id +\n // \" . Height: \" + H + \", Width: \" + W +\n // \"\\nDirection \" + dX + \", \" + dY;\n //\n // Compute intersection\n var res = {};\n do {\n // Case: Vertical direction (up)\n if (0 === dX && 0 < dY) {\n res.x = X;\n // s += \"\\nUp direction\";\n res.y = Y + H / 2;\n break;\n }\n\n // Case: Vertical direction (down)\n if (0 === dX && 0 > dY) {\n res.x = X;\n res.y = Y + H / 2;\n // s += \"\\nDown direction\";\n break;\n }\n\n // Case: Intersects the right border\n if (0 < dX &&\n -1 * nodeSlope <= dirSlope &&\n dirSlope <= nodeSlope) {\n res.x = X + W / 2;\n res.y = Y + (W * dY / 2 / dX);\n // s += \"\\nRightborder\";\n break;\n }\n\n // Case: Intersects the left border\n if (0 > dX &&\n -1 * nodeSlope <= dirSlope &&\n dirSlope <= nodeSlope) {\n res.x = X - W / 2;\n res.y = Y - (W * dY / 2 / dX);\n // s += \"\\nLeftborder\";\n break;\n }\n\n // Case: Intersects the top border\n if (0 < dY &&\n ( dirSlope <= -1 * nodeSlope ||\n dirSlope >= nodeSlope )) {\n res.x = X + (H * dX / 2 / dY);\n res.y = Y + H / 2;\n // s += \"\\nTop border\";\n break;\n }\n\n // Case: Intersects the bottom border\n if (0 > dY &&\n ( dirSlope <= -1 * nodeSlope ||\n dirSlope >= nodeSlope )) {\n res.x = X - (H * dX / 2 / dY);\n res.y = Y - H / 2;\n // s += \"\\nBottom border\";\n break;\n }\n\n } while (false);\n\n // s += \"\\nClipping point found at \" + res.x + \", \" + res.y;\n // logDebug(s);\n return res;\n };\n\n /**\n * @brief : Calculates all edge forces\n */\n var calculateEdgeForces = function(layoutInfo, options) {\n // Iterate over all edges\n for (var i = 0; i < layoutInfo.edgeSize; i++) {\n // Get edge, source & target nodes\n var edge = layoutInfo.layoutEdges[i];\n var sourceIx = layoutInfo.idToIndex[edge.sourceId];\n var source = layoutInfo.layoutNodes[sourceIx];\n var targetIx = layoutInfo.idToIndex[edge.targetId];\n var target = layoutInfo.layoutNodes[targetIx];\n\n // Get direction of line connecting both node centers\n var directionX = target.positionX - source.positionX;\n var directionY = target.positionY - source.positionY;\n\n // If both centers are the same, do nothing.\n // A random force has already been applied as node repulsion\n if (0 === directionX && 0 === directionY) {\n return;\n }\n\n // Get clipping points for both nodes\n var point1 = findClippingPoint(source, directionX, directionY);\n var point2 = findClippingPoint(target, -1 * directionX, -1 * directionY);\n\n\n var lx = point2.x - point1.x;\n var ly = point2.y - point1.y;\n var l = Math.sqrt(lx * lx + ly * ly);\n\n var force = Math.pow(edge.idealLength - l, 2) / edge.elasticity;\n\n if (0 !== l) {\n var forceX = force * lx / l;\n var forceY = force * ly / l;\n } else {\n var forceX = 0;\n var forceY = 0;\n }\n\n // Add this force to target and source nodes\n if( !source.isLocked ){\n source.offsetX += forceX;\n source.offsetY += forceY;\n }\n\n if( !target.isLocked ){\n target.offsetX -= forceX;\n target.offsetY -= forceY;\n }\n\n // var s = 'Edge force between nodes ' + source.id + ' and ' + target.id;\n // s += \"\\nDistance: \" + l + \" Force: (\" + forceX + \", \" + forceY + \")\";\n // logDebug(s);\n }\n };\n\n /**\n * @brief : Computes gravity forces for all nodes\n */\n var calculateGravityForces = function(layoutInfo, options) {\n var distThreshold = 1;\n\n // var s = 'calculateGravityForces';\n // logDebug(s);\n for (var i = 0; i < layoutInfo.graphSet.length; i ++) {\n var graph = layoutInfo.graphSet[i];\n var numNodes = graph.length;\n\n // s = \"Set: \" + graph.toString();\n // logDebug(s);\n\n // Compute graph center\n if (0 === i) {\n var centerX = layoutInfo.clientHeight / 2;\n var centerY = layoutInfo.clientWidth / 2;\n } else {\n // Get Parent node for this graph, and use its position as center\n var temp = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[0]]];\n var parent = layoutInfo.layoutNodes[layoutInfo.idToIndex[temp.parentId]];\n var centerX = parent.positionX;\n var centerY = parent.positionY;\n }\n // s = \"Center found at: \" + centerX + \", \" + centerY;\n // logDebug(s);\n\n // Apply force to all nodes in graph\n for (var j = 0; j < numNodes; j++) {\n var node = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]];\n // s = \"Node: \" + node.id;\n\n if( node.isLocked ){ continue; }\n\n var dx = centerX - node.positionX;\n var dy = centerY - node.positionY;\n var d = Math.sqrt(dx * dx + dy * dy);\n if (d > distThreshold) {\n var fx = options.gravity * dx / d;\n var fy = options.gravity * dy / d;\n node.offsetX += fx;\n node.offsetY += fy;\n // s += \": Applied force: \" + fx + \", \" + fy;\n } else {\n // s += \": skypped since it's too close to center\";\n }\n // logDebug(s);\n }\n }\n };\n\n /**\n * @brief : This function propagates the existing offsets from\n * parent nodes to its descendents.\n * @arg layoutInfo : layoutInfo Object\n * @arg cy : cytoscape Object\n * @arg options : Layout options\n */\n var propagateForces = function(layoutInfo, options) {\n // Inline implementation of a queue, used for traversing the graph in BFS order\n var queue = [];\n var start = 0; // Points to the start the queue\n var end = -1; // Points to the end of the queue\n\n // logDebug('propagateForces');\n\n // Start by visiting the nodes in the root graph\n queue.push.apply(queue, layoutInfo.graphSet[0]);\n end += layoutInfo.graphSet[0].length;\n\n // Traverse the graph, level by level,\n while (start <= end) {\n // Get the node to visit and remove it from queue\n var nodeId = queue[start++];\n var nodeIndex = layoutInfo.idToIndex[nodeId];\n var node = layoutInfo.layoutNodes[nodeIndex];\n var children = node.children;\n\n // We only need to process the node if it's compound\n if (0 < children.length && !node.isLocked) {\n var offX = node.offsetX;\n var offY = node.offsetY;\n\n // var s = \"Propagating offset from parent node : \" + node.id +\n // \". OffsetX: \" + offX + \". OffsetY: \" + offY;\n // s += \"\\n Children: \" + children.toString();\n // logDebug(s);\n\n for (var i = 0; i < children.length; i++) {\n var childNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[children[i]]];\n // Propagate offset\n childNode.offsetX += offX;\n childNode.offsetY += offY;\n // Add children to queue to be visited\n queue[++end] = children[i];\n }\n\n // Reset parent offsets\n node.offsetX = 0;\n node.offsetY = 0;\n }\n\n }\n };\n\n /**\n * @brief : Updates the layout model positions, based on\n * the accumulated forces\n */\n var updatePositions = function(layoutInfo, options) {\n // var s = 'Updating positions';\n // logDebug(s);\n\n // Reset boundaries for compound nodes\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n if (0 < n.children.length) {\n // logDebug(\"Resetting boundaries of compound node: \" + n.id);\n n.maxX = undefined;\n n.minX = undefined;\n n.maxY = undefined;\n n.minY = undefined;\n }\n }\n\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n if (0 < n.children.length || n.isLocked) {\n // No need to set compound or locked node position\n // logDebug(\"Skipping position update of node: \" + n.id);\n continue;\n }\n // s = \"Node: \" + n.id + \" Previous position: (\" +\n // n.positionX + \", \" + n.positionY + \").\";\n\n // Limit displacement in order to improve stability\n var tempForce = limitForce(n.offsetX, n.offsetY, layoutInfo.temperature);\n n.positionX += tempForce.x;\n n.positionY += tempForce.y;\n n.offsetX = 0;\n n.offsetY = 0;\n n.minX = n.positionX - n.width;\n n.maxX = n.positionX + n.width;\n n.minY = n.positionY - n.height;\n n.maxY = n.positionY + n.height;\n // s += \" New Position: (\" + n.positionX + \", \" + n.positionY + \").\";\n // logDebug(s);\n\n // Update ancestry boudaries\n updateAncestryBoundaries(n, layoutInfo);\n }\n\n // Update size, position of compund nodes\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n if ( 0 < n.children.length && !n.isLocked ) {\n n.positionX = (n.maxX + n.minX) / 2;\n n.positionY = (n.maxY + n.minY) / 2;\n n.width = n.maxX - n.minX;\n n.height = n.maxY - n.minY;\n // s = \"Updating position, size of compound node \" + n.id;\n // s += \"\\nPositionX: \" + n.positionX + \", PositionY: \" + n.positionY;\n // s += \"\\nWidth: \" + n.width + \", Height: \" + n.height;\n // logDebug(s);\n }\n }\n };\n\n /**\n * @brief : Limits a force (forceX, forceY) to be not\n * greater (in modulo) than max.\n 8 Preserves force direction.\n */\n var limitForce = function(forceX, forceY, max) {\n // var s = \"Limiting force: (\" + forceX + \", \" + forceY + \"). Max: \" + max;\n var force = Math.sqrt(forceX * forceX + forceY * forceY);\n\n if (force > max) {\n var res = {\n x : max * forceX / force,\n y : max * forceY / force\n };\n\n } else {\n var res = {\n x : forceX,\n y : forceY\n };\n }\n\n // s += \".\\nResult: (\" + res.x + \", \" + res.y + \")\";\n // logDebug(s);\n\n return res;\n };\n\n /**\n * @brief : Function used for keeping track of compound node\n * sizes, since they should bound all their subnodes.\n */\n var updateAncestryBoundaries = function(node, layoutInfo) {\n // var s = \"Propagating new position/size of node \" + node.id;\n var parentId = node.parentId;\n if (null == parentId) {\n // If there's no parent, we are done\n // s += \". No parent node.\";\n // logDebug(s);\n return;\n }\n\n // Get Parent Node\n var p = layoutInfo.layoutNodes[layoutInfo.idToIndex[parentId]];\n var flag = false;\n\n // MaxX\n if (null == p.maxX || node.maxX + p.padRight > p.maxX) {\n p.maxX = node.maxX + p.padRight;\n flag = true;\n // s += \"\\nNew maxX for parent node \" + p.id + \": \" + p.maxX;\n }\n\n // MinX\n if (null == p.minX || node.minX - p.padLeft < p.minX) {\n p.minX = node.minX - p.padLeft;\n flag = true;\n // s += \"\\nNew minX for parent node \" + p.id + \": \" + p.minX;\n }\n\n // MaxY\n if (null == p.maxY || node.maxY + p.padBottom > p.maxY) {\n p.maxY = node.maxY + p.padBottom;\n flag = true;\n // s += \"\\nNew maxY for parent node \" + p.id + \": \" + p.maxY;\n }\n\n // MinY\n if (null == p.minY || node.minY - p.padTop < p.minY) {\n p.minY = node.minY - p.padTop;\n flag = true;\n // s += \"\\nNew minY for parent node \" + p.id + \": \" + p.minY;\n }\n\n // If updated boundaries, propagate changes upward\n if (flag) {\n // logDebug(s);\n return updateAncestryBoundaries(p, layoutInfo);\n }\n\n // s += \". No changes in boundaries/position of parent node \" + p.id;\n // logDebug(s);\n return;\n };\n\n var separateComponents = function(layutInfo, options){\n var nodes = layoutInfo.layoutNodes;\n var components = [];\n\n for( var i = 0; i < nodes.length; i++ ){\n var node = nodes[i];\n var cid = node.cmptId;\n var component = components[ cid ] = components[ cid ] || [];\n\n component.push( node );\n }\n\n var totalA = 0;\n\n for( var i = 0; i < components.length; i++ ){\n var c = components[i];\n c.x1 = Infinity;\n c.x2 = -Infinity;\n c.y1 = Infinity;\n c.y2 = -Infinity;\n\n for( var j = 0; j < c.length; j++ ){\n var n = c[j];\n\n c.x1 = Math.min( c.x1, n.positionX - n.width/2 );\n c.x2 = Math.max( c.x2, n.positionX + n.width/2 );\n c.y1 = Math.min( c.y1, n.positionY - n.height/2 );\n c.y2 = Math.max( c.y2, n.positionY + n.height/2 );\n }\n\n c.w = c.x2 - c.x1;\n c.h = c.y2 - c.y1;\n\n totalA += c.w * c.h;\n }\n\n components.sort(function( c1, c2 ){\n return c2.w*c2.h - c1.w*c1.h;\n });\n\n var x = 0;\n var y = 0;\n var usedW = 0;\n var rowH = 0;\n var maxRowW = Math.sqrt( totalA ) * layoutInfo.clientWidth / layoutInfo.clientHeight;\n\n for( var i = 0; i < components.length; i++ ){\n var c = components[i];\n\n for( var j = 0; j < c.length; j++ ){\n var n = c[j];\n\n if( !n.isLocked ){\n n.positionX += x;\n n.positionY += y;\n }\n }\n\n x += c.w + options.componentSpacing;\n usedW += c.w + options.componentSpacing;\n rowH = Math.max( rowH, c.h );\n\n if( usedW > maxRowW ){\n y += rowH + options.componentSpacing;\n x = 0;\n usedW = 0;\n rowH = 0;\n }\n }\n };\n\n var mainLoop = function(i){\n if( stopped ){\n // logDebug(\"Layout manually stopped. Stopping computation in step \" + i);\n return false;\n }\n\n // Do one step in the phisical simulation\n step(layoutInfo, options, i);\n\n // Update temperature\n layoutInfo.temperature = layoutInfo.temperature * options.coolingFactor;\n // logDebug(\"New temperature: \" + layoutInfo.temperature);\n\n if (layoutInfo.temperature < options.minTemp) {\n // logDebug(\"Temperature drop below minimum threshold. Stopping computation in step \" + i);\n return false;\n }\n\n return true;\n };\n\n var i = 0;\n var loopRet;\n\n do {\n var f = 0;\n\n while( f < options.refresh && i < options.numIter ){\n var loopRet = mainLoop(i);\n if( !loopRet ){ break; }\n\n f++;\n i++;\n }\n\n if( options.animate ){\n broadcast( layoutInfo.layoutNodes ); // jshint ignore:line\n }\n\n } while ( loopRet && i + 1 < options.numIter );\n\n separateComponents( layoutInfo, options );\n\n return layoutInfo;\n }).then(function( layoutInfoUpdated ){\n layoutInfo.layoutNodes = layoutInfoUpdated.layoutNodes; // get the positions\n\n thread.stop();\n done();\n });\n\n var done = function(){\n refresh({ force: true });\n\n // Layout has finished\n layout.one('layoutstop', options.stop);\n layout.trigger({ type: 'layoutstop', layout: layout });\n };\n\n return this; // chaining\n};\n\n\n/**\n * @brief : called on continuous layouts to stop them before they finish\n */\nCoseLayout.prototype.stop = function(){\n this.stopped = true;\n\n if( this.thread ){\n this.thread.stop();\n }\n\n this.trigger('layoutstop');\n\n return this; // chaining\n};\n\nCoseLayout.prototype.destroy = function(){\n if( this.thread ){\n this.thread.stop();\n }\n\n return this; // chaining\n};\n\n\n/**\n * @brief : Creates an object which is contains all the data\n * used in the layout process\n * @arg cy : cytoscape.js object\n * @return : layoutInfo object initialized\n */\nvar createLayoutInfo = function(cy, layout, options) {\n // Shortcut\n var edges = options.eles.edges();\n var nodes = options.eles.nodes();\n\n var layoutInfo = {\n isCompound : cy.hasCompoundNodes(),\n layoutNodes : [],\n idToIndex : {},\n nodeSize : nodes.size(),\n graphSet : [],\n indexToGraph : [],\n layoutEdges : [],\n edgeSize : edges.size(),\n temperature : options.initialTemp,\n clientWidth : cy.width(),\n clientHeight : cy.width(),\n boundingBox : math.makeBoundingBox( options.boundingBox ? options.boundingBox : {\n x1: 0, y1: 0, w: cy.width(), h: cy.height()\n } )\n };\n\n var components = options.eles.components();\n var id2cmptId = {};\n\n for( var i = 0; i < components.length; i++ ){\n var component = components[i];\n\n for( var j = 0; j < component.length; j++ ){\n var node = component[j];\n\n id2cmptId[ node.id() ] = i;\n }\n }\n\n // Iterate over all nodes, creating layout nodes\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = nodes[i];\n var nbb = n.boundingBox();\n\n var tempNode = {};\n tempNode.isLocked = n.locked();\n tempNode.id = n.data('id');\n tempNode.parentId = n.data('parent');\n tempNode.cmptId = id2cmptId[ n.id() ];\n tempNode.children = [];\n tempNode.positionX = n.position('x');\n tempNode.positionY = n.position('y');\n tempNode.offsetX = 0;\n tempNode.offsetY = 0;\n tempNode.height = nbb.w;\n tempNode.width = nbb.h;\n tempNode.maxX = tempNode.positionX + tempNode.width / 2;\n tempNode.minX = tempNode.positionX - tempNode.width / 2;\n tempNode.maxY = tempNode.positionY + tempNode.height / 2;\n tempNode.minY = tempNode.positionY - tempNode.height / 2;\n tempNode.padLeft = parseFloat( n.style('padding-left') );\n tempNode.padRight = parseFloat( n.style('padding-right') );\n tempNode.padTop = parseFloat( n.style('padding-top') );\n tempNode.padBottom = parseFloat( n.style('padding-bottom') );\n\n // forces\n tempNode.nodeRepulsion = is.fn( options.nodeRepulsion ) ? options.nodeRepulsion.call( n, n ) : options.nodeRepulsion;\n\n // Add new node\n layoutInfo.layoutNodes.push(tempNode);\n // Add entry to id-index map\n layoutInfo.idToIndex[tempNode.id] = i;\n }\n\n // Inline implementation of a queue, used for traversing the graph in BFS order\n var queue = [];\n var start = 0; // Points to the start the queue\n var end = -1; // Points to the end of the queue\n\n var tempGraph = [];\n\n // Second pass to add child information and\n // initialize queue for hierarchical traversal\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n var p_id = n.parentId;\n // Check if node n has a parent node\n if (null != p_id) {\n // Add node Id to parent's list of children\n layoutInfo.layoutNodes[layoutInfo.idToIndex[p_id]].children.push(n.id);\n } else {\n // If a node doesn't have a parent, then it's in the root graph\n queue[++end] = n.id;\n tempGraph.push(n.id);\n }\n }\n\n // Add root graph to graphSet\n layoutInfo.graphSet.push(tempGraph);\n\n // Traverse the graph, level by level,\n while (start <= end) {\n // Get the node to visit and remove it from queue\n var node_id = queue[start++];\n var node_ix = layoutInfo.idToIndex[node_id];\n var node = layoutInfo.layoutNodes[node_ix];\n var children = node.children;\n if (children.length > 0) {\n // Add children nodes as a new graph to graph set\n layoutInfo.graphSet.push(children);\n // Add children to que queue to be visited\n for (var i = 0; i < children.length; i++) {\n queue[++end] = children[i];\n }\n }\n }\n\n // Create indexToGraph map\n for (var i = 0; i < layoutInfo.graphSet.length; i++) {\n var graph = layoutInfo.graphSet[i];\n for (var j = 0; j < graph.length; j++) {\n var index = layoutInfo.idToIndex[graph[j]];\n layoutInfo.indexToGraph[index] = i;\n }\n }\n\n // Iterate over all edges, creating Layout Edges\n for (var i = 0; i < layoutInfo.edgeSize; i++) {\n var e = edges[i];\n var tempEdge = {};\n tempEdge.id = e.data('id');\n tempEdge.sourceId = e.data('source');\n tempEdge.targetId = e.data('target');\n\n // Compute ideal length\n var idealLength = is.fn( options.idealEdgeLength ) ? options.idealEdgeLength.call( e, e ) : options.idealEdgeLength;\n var elasticity = is.fn( options.edgeElasticity ) ? options.edgeElasticity.call( e, e ) : options.edgeElasticity;\n\n // Check if it's an inter graph edge\n var sourceIx = layoutInfo.idToIndex[tempEdge.sourceId];\n var targetIx = layoutInfo.idToIndex[tempEdge.targetId];\n var sourceGraph = layoutInfo.indexToGraph[sourceIx];\n var targetGraph = layoutInfo.indexToGraph[targetIx];\n\n if (sourceGraph != targetGraph) {\n // Find lowest common graph ancestor\n var lca = findLCA(tempEdge.sourceId, tempEdge.targetId, layoutInfo);\n\n // Compute sum of node depths, relative to lca graph\n var lcaGraph = layoutInfo.graphSet[lca];\n var depth = 0;\n\n // Source depth\n var tempNode = layoutInfo.layoutNodes[sourceIx];\n while ( -1 === lcaGraph.indexOf(tempNode.id) ) {\n tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]];\n depth++;\n }\n\n // Target depth\n tempNode = layoutInfo.layoutNodes[targetIx];\n while ( -1 === lcaGraph.indexOf(tempNode.id) ) {\n tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]];\n depth++;\n }\n\n // logDebug('LCA of nodes ' + tempEdge.sourceId + ' and ' + tempEdge.targetId +\n // \". Index: \" + lca + \" Contents: \" + lcaGraph.toString() +\n // \". Depth: \" + depth);\n\n // Update idealLength\n idealLength *= depth * options.nestingFactor;\n }\n\n tempEdge.idealLength = idealLength;\n tempEdge.elasticity = elasticity;\n\n layoutInfo.layoutEdges.push(tempEdge);\n }\n\n // Finally, return layoutInfo object\n return layoutInfo;\n};\n\n\n/**\n * @brief : This function finds the index of the lowest common\n * graph ancestor between 2 nodes in the subtree\n * (from the graph hierarchy induced tree) whose\n * root is graphIx\n *\n * @arg node1: node1's ID\n * @arg node2: node2's ID\n * @arg layoutInfo: layoutInfo object\n *\n */\nvar findLCA = function(node1, node2, layoutInfo) {\n // Find their common ancester, starting from the root graph\n var res = findLCA_aux(node1, node2, 0, layoutInfo);\n if (2 > res.count) {\n // If aux function couldn't find the common ancester,\n // then it is the root graph\n return 0;\n } else {\n return res.graph;\n }\n};\n\n\n/**\n * @brief : Auxiliary function used for LCA computation\n *\n * @arg node1 : node1's ID\n * @arg node2 : node2's ID\n * @arg graphIx : subgraph index\n * @arg layoutInfo : layoutInfo object\n *\n * @return : object of the form {count: X, graph: Y}, where:\n * X is the number of ancesters (max: 2) found in\n * graphIx (and it's subgraphs),\n * Y is the graph index of the lowest graph containing\n * all X nodes\n */\nvar findLCA_aux = function(node1, node2, graphIx, layoutInfo) {\n var graph = layoutInfo.graphSet[graphIx];\n // If both nodes belongs to graphIx\n if (-1 < graph.indexOf(node1) && -1 < graph.indexOf(node2)) {\n return {count:2, graph:graphIx};\n }\n\n // Make recursive calls for all subgraphs\n var c = 0;\n for (var i = 0; i < graph.length; i++) {\n var nodeId = graph[i];\n var nodeIx = layoutInfo.idToIndex[nodeId];\n var children = layoutInfo.layoutNodes[nodeIx].children;\n\n // If the node has no child, skip it\n if (0 === children.length) {\n continue;\n }\n\n var childGraphIx = layoutInfo.indexToGraph[layoutInfo.idToIndex[children[0]]];\n var result = findLCA_aux(node1, node2, childGraphIx, layoutInfo);\n if (0 === result.count) {\n // Neither node1 nor node2 are present in this subgraph\n continue;\n } else if (1 === result.count) {\n // One of (node1, node2) is present in this subgraph\n c++;\n if (2 === c) {\n // We've already found both nodes, no need to keep searching\n break;\n }\n } else {\n // Both nodes are present in this subgraph\n return result;\n }\n }\n\n return {count:c, graph:graphIx};\n};\n\n\n/**\n * @brief: printsLayoutInfo into js console\n * Only used for debbuging\n */\nvar printLayoutInfo = function(layoutInfo) {\n /* jshint ignore:start */\n\n if (!DEBUG) {\n return;\n }\n console.debug(\"layoutNodes:\");\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n var s =\n \"\\nindex: \" + i +\n \"\\nId: \" + n.id +\n \"\\nChildren: \" + n.children.toString() +\n \"\\nparentId: \" + n.parentId +\n \"\\npositionX: \" + n.positionX +\n \"\\npositionY: \" + n.positionY +\n \"\\nOffsetX: \" + n.offsetX +\n \"\\nOffsetY: \" + n.offsetY +\n \"\\npadLeft: \" + n.padLeft +\n \"\\npadRight: \" + n.padRight +\n \"\\npadTop: \" + n.padTop +\n \"\\npadBottom: \" + n.padBottom;\n\n console.debug(s);\n }\n\n console.debug('idToIndex');\n for (var i in layoutInfo.idToIndex) {\n console.debug(\"Id: \" + i + \"\\nIndex: \" + layoutInfo.idToIndex[i]);\n }\n\n console.debug('Graph Set');\n var set = layoutInfo.graphSet;\n for (var i = 0; i < set.length; i ++) {\n console.debug(\"Set : \" + i + \": \" + set[i].toString());\n }\n\n var s = 'IndexToGraph';\n for (var i = 0; i < layoutInfo.indexToGraph.length; i ++) {\n s += \"\\nIndex : \" + i + \" Graph: \"+ layoutInfo.indexToGraph[i];\n }\n console.debug(s);\n\n s = 'Layout Edges';\n for (var i = 0; i < layoutInfo.layoutEdges.length; i++) {\n var e = layoutInfo.layoutEdges[i];\n s += \"\\nEdge Index: \" + i + \" ID: \" + e.id +\n \" SouceID: \" + e.sourceId + \" TargetId: \" + e.targetId +\n \" Ideal Length: \" + e.idealLength;\n }\n console.debug(s);\n\n s = \"nodeSize: \" + layoutInfo.nodeSize;\n s += \"\\nedgeSize: \" + layoutInfo.edgeSize;\n s += \"\\ntemperature: \" + layoutInfo.temperature;\n console.debug(s);\n\n return;\n /* jshint ignore:end */\n};\n\n\n/**\n * @brief : Randomizes the position of all nodes\n */\nvar randomizePositions = function(layoutInfo, cy) {\n var width = layoutInfo.clientWidth;\n var height = layoutInfo.clientHeight;\n\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n\n // No need to randomize compound nodes or locked nodes\n if ( 0 === n.children.length && !n.isLocked ) {\n n.positionX = Math.random() * width;\n n.positionY = Math.random() * height;\n }\n }\n};\n\n\n/**\n * @brief : Updates the positions of nodes in the network\n * @arg layoutInfo : LayoutInfo object\n * @arg cy : Cytoscape object\n * @arg options : Layout options\n */\nvar refreshPositions = function(layoutInfo, cy, options) {\n // var s = 'Refreshing positions';\n // logDebug(s);\n\n var layout = options.layout;\n var nodes = options.eles.nodes();\n var bb = layoutInfo.boundingBox;\n var coseBB = { x1: Infinity, x2: -Infinity, y1: Infinity, y2: -Infinity };\n\n if( options.boundingBox ){\n nodes.forEach(function( node ){\n var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[node.data('id')]];\n\n coseBB.x1 = Math.min( coseBB.x1, lnode.positionX );\n coseBB.x2 = Math.max( coseBB.x2, lnode.positionX );\n\n coseBB.y1 = Math.min( coseBB.y1, lnode.positionY );\n coseBB.y2 = Math.max( coseBB.y2, lnode.positionY );\n });\n\n coseBB.w = coseBB.x2 - coseBB.x1;\n coseBB.h = coseBB.y2 - coseBB.y1;\n }\n\n nodes.positions(function(i, ele) {\n var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[ele.data('id')]];\n // s = \"Node: \" + lnode.id + \". Refreshed position: (\" +\n // lnode.positionX + \", \" + lnode.positionY + \").\";\n // logDebug(s);\n\n if( options.boundingBox ){ // then add extra bounding box constraint\n var pctX = (lnode.positionX - coseBB.x1) / coseBB.w;\n var pctY = (lnode.positionY - coseBB.y1) / coseBB.h;\n\n return {\n x: bb.x1 + pctX * bb.w,\n y: bb.y1 + pctY * bb.h\n };\n } else {\n return {\n x: lnode.positionX,\n y: lnode.positionY\n };\n }\n });\n\n // Trigger layoutReady only on first call\n if (true !== layoutInfo.ready) {\n // s = 'Triggering layoutready';\n // logDebug(s);\n layoutInfo.ready = true;\n layout.one('layoutready', options.ready);\n layout.trigger({ type: 'layoutready', layout: this });\n }\n};\n\n/**\n * @brief : Logs a debug message in JS console, if DEBUG is ON\n */\n// var logDebug = function(text) {\n// if (DEBUG) {\n// console.debug(text);\n// }\n// };\n\nmodule.exports = CoseLayout;\n","'use strict';\n\nvar util = require('../../util');\nvar math = require('../../math');\n\nvar defaults = {\n fit: true, // whether to fit the viewport to the graph\n padding: 30, // padding used on fit\n boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n avoidOverlap: true, // prevents node overlap, may overflow boundingBox if not enough space\n avoidOverlapPadding: 10, // extra spacing around nodes when avoidOverlap: true\n condense: false, // uses all available space on false, uses minimal space on true\n rows: undefined, // force num of rows in the grid\n cols: undefined, // force num of columns in the grid\n position: function( node ){}, // returns { row, col } for element\n sort: undefined, // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') }\n animate: false, // whether to transition the node positions\n animationDuration: 500, // duration of animation in ms if enabled\n animationEasing: undefined, // easing of animation if enabled\n ready: undefined, // callback on layoutready\n stop: undefined // callback on layoutstop\n};\n\nfunction GridLayout( options ){\n this.options = util.extend({}, defaults, options);\n}\n\nGridLayout.prototype.run = function(){\n var params = this.options;\n var options = params;\n\n var cy = params.cy;\n var eles = options.eles;\n var nodes = eles.nodes().not(':parent');\n\n if( options.sort ){\n nodes = nodes.sort( options.sort );\n }\n\n var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : {\n x1: 0, y1: 0, w: cy.width(), h: cy.height()\n } );\n\n if( bb.h === 0 || bb.w === 0){\n nodes.layoutPositions(this, options, function(){\n return { x: bb.x1, y: bb.y1 };\n });\n\n } else {\n\n // width/height * splits^2 = cells where splits is number of times to split width\n var cells = nodes.size();\n var splits = Math.sqrt( cells * bb.h/bb.w );\n var rows = Math.round( splits );\n var cols = Math.round( bb.w/bb.h * splits );\n\n var small = function(val){\n if( val == null ){\n return Math.min(rows, cols);\n } else {\n var min = Math.min(rows, cols);\n if( min == rows ){\n rows = val;\n } else {\n cols = val;\n }\n }\n };\n\n var large = function(val){\n if( val == null ){\n return Math.max(rows, cols);\n } else {\n var max = Math.max(rows, cols);\n if( max == rows ){\n rows = val;\n } else {\n cols = val;\n }\n }\n };\n\n var oRows = options.rows;\n var oCols = options.cols != null ? options.cols : options.columns;\n\n // if rows or columns were set in options, use those values\n if( oRows != null && oCols != null ){\n rows = oRows;\n cols = oCols;\n } else if( oRows != null && oCols == null ){\n rows = oRows;\n cols = Math.ceil( cells / rows );\n } else if( oRows == null && oCols != null ){\n cols = oCols;\n rows = Math.ceil( cells / cols );\n }\n\n // otherwise use the automatic values and adjust accordingly\n\n // if rounding was up, see if we can reduce rows or columns\n else if( cols * rows > cells ){\n var sm = small();\n var lg = large();\n\n // reducing the small side takes away the most cells, so try it first\n if( (sm - 1) * lg >= cells ){\n small(sm - 1);\n } else if( (lg - 1) * sm >= cells ){\n large(lg - 1);\n }\n } else {\n\n // if rounding was too low, add rows or columns\n while( cols * rows < cells ){\n var sm = small();\n var lg = large();\n\n // try to add to larger side first (adds less in multiplication)\n if( (lg + 1) * sm >= cells ){\n large(lg + 1);\n } else {\n small(sm + 1);\n }\n }\n }\n\n var cellWidth = bb.w / cols;\n var cellHeight = bb.h / rows;\n\n if( options.condense ){\n cellWidth = 0;\n cellHeight = 0;\n }\n\n if( options.avoidOverlap ){\n for( var i = 0; i < nodes.length; i++ ){\n var node = nodes[i];\n var pos = node._private.position;\n\n if( pos.x == null || pos.y == null ){ // for bb\n pos.x = 0;\n pos.y = 0;\n }\n\n var nbb = node.boundingBox();\n var p = options.avoidOverlapPadding;\n\n var w = nbb.w + p;\n var h = nbb.h + p;\n\n cellWidth = Math.max( cellWidth, w );\n cellHeight = Math.max( cellHeight, h );\n }\n }\n\n var cellUsed = {}; // e.g. 'c-0-2' => true\n\n var used = function(row, col){\n return cellUsed['c-' + row + '-' + col] ? true : false;\n };\n\n var use = function(row, col){\n cellUsed['c-' + row + '-' + col] = true;\n };\n\n // to keep track of current cell position\n var row = 0;\n var col = 0;\n var moveToNextCell = function(){\n col++;\n if( col >= cols ){\n col = 0;\n row++;\n }\n };\n\n // get a cache of all the manual positions\n var id2manPos = {};\n for( var i = 0; i < nodes.length; i++ ){\n var node = nodes[i];\n var rcPos = options.position( node );\n\n if( rcPos && (rcPos.row !== undefined || rcPos.col !== undefined) ){ // must have at least row or col def'd\n var pos = {\n row: rcPos.row,\n col: rcPos.col\n };\n\n if( pos.col === undefined ){ // find unused col\n pos.col = 0;\n\n while( used(pos.row, pos.col) ){\n pos.col++;\n }\n } else if( pos.row === undefined ){ // find unused row\n pos.row = 0;\n\n while( used(pos.row, pos.col) ){\n pos.row++;\n }\n }\n\n id2manPos[ node.id() ] = pos;\n use( pos.row, pos.col );\n }\n }\n\n var getPos = function(i, element){\n var x, y;\n\n if( element.locked() || element.isFullAutoParent() ){\n return false;\n }\n\n // see if we have a manual position set\n var rcPos = id2manPos[ element.id() ];\n if( rcPos ){\n x = rcPos.col * cellWidth + cellWidth/2 + bb.x1;\n y = rcPos.row * cellHeight + cellHeight/2 + bb.y1;\n\n } else { // otherwise set automatically\n\n while( used(row, col) ){\n moveToNextCell();\n }\n\n x = col * cellWidth + cellWidth/2 + bb.x1;\n y = row * cellHeight + cellHeight/2 + bb.y1;\n use( row, col );\n\n moveToNextCell();\n }\n\n return { x: x, y: y };\n\n };\n\n nodes.layoutPositions( this, options, getPos );\n }\n\n return this; // chaining\n\n};\n\nmodule.exports = GridLayout;\n","'use strict';\n\nmodule.exports = [\n { name: 'breadthfirst', impl: require('./breadthfirst') },\n { name: 'circle', impl: require('./circle') },\n { name: 'concentric',impl: require('./concentric') },\n { name: 'cose', impl: require('./cose') },\n { name: 'grid', impl: require('./grid') },\n { name: 'null', impl: require('./null') },\n { name: 'preset', impl: require('./preset') },\n { name: 'random', impl: require('./random') }\n];\n","'use strict';\n\nvar util = require('../../util');\n\n// default layout options\nvar defaults = {\n ready: function(){}, // on layoutready\n stop: function(){} // on layoutstop\n};\n\n// constructor\n// options : object containing layout options\nfunction NullLayout( options ){\n this.options = util.extend({}, defaults, options);\n}\n\n// runs the layout\nNullLayout.prototype.run = function(){\n var options = this.options;\n var eles = options.eles; // elements to consider in the layout\n var layout = this;\n\n // cy is automatically populated for us in the constructor\n var cy = options.cy; // jshint ignore:line\n\n layout.trigger('layoutstart');\n\n // puts all nodes at (0, 0)\n eles.nodes().positions(function(){\n return {\n x: 0,\n y: 0\n };\n });\n\n // trigger layoutready when each node has had its position set at least once\n layout.one('layoutready', options.ready);\n layout.trigger('layoutready');\n\n // trigger layoutstop when the layout stops (e.g. finishes)\n layout.one('layoutstop', options.stop);\n layout.trigger('layoutstop');\n\n return this; // chaining\n};\n\n// called on continuous layouts to stop them before they finish\nNullLayout.prototype.stop = function(){\n return this; // chaining\n};\n\nmodule.exports = NullLayout;\n","'use strict';\n\nvar util = require('../../util');\nvar is = require('../../is');\n\nvar defaults = {\n positions: undefined, // map of (node id) => (position obj); or function(node){ return somPos; }\n zoom: undefined, // the zoom level to set (prob want fit = false if set)\n pan: undefined, // the pan level to set (prob want fit = false if set)\n fit: true, // whether to fit to viewport\n padding: 30, // padding on fit\n animate: false, // whether to transition the node positions\n animationDuration: 500, // duration of animation in ms if enabled\n animationEasing: undefined, // easing of animation if enabled\n ready: undefined, // callback on layoutready\n stop: undefined // callback on layoutstop\n};\n\nfunction PresetLayout( options ){\n this.options = util.extend({}, defaults, options);\n}\n\nPresetLayout.prototype.run = function(){\n var options = this.options;\n var eles = options.eles;\n\n var nodes = eles.nodes();\n var posIsFn = is.fn( options.positions );\n\n function getPosition(node){\n if( options.positions == null ){\n return null;\n }\n\n if( posIsFn ){\n return options.positions.apply( node, [ node ] );\n }\n\n var pos = options.positions[node._private.data.id];\n\n if( pos == null ){\n return null;\n }\n\n return pos;\n }\n\n nodes.layoutPositions(this, options, function(i, node){\n var position = getPosition(node);\n\n if( node.locked() || position == null ){\n return false;\n }\n\n return position;\n });\n\n return this; // chaining\n};\n\nmodule.exports = PresetLayout;\n","'use strict';\n\nvar util = require('../../util');\nvar math = require('../../math');\n\nvar defaults = {\n fit: true, // whether to fit to viewport\n padding: 30, // fit padding\n boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n animate: false, // whether to transition the node positions\n animationDuration: 500, // duration of animation in ms if enabled\n animationEasing: undefined, // easing of animation if enabled\n ready: undefined, // callback on layoutready\n stop: undefined // callback on layoutstop\n};\n\nfunction RandomLayout( options ){\n this.options = util.extend({}, defaults, options);\n}\n\nRandomLayout.prototype.run = function(){\n var options = this.options;\n var cy = options.cy;\n var eles = options.eles;\n var nodes = eles.nodes().not(':parent');\n\n var bb = math.makeBoundingBox( options.boundingBox ? options.boundingBox : {\n x1: 0, y1: 0, w: cy.width(), h: cy.height()\n } );\n\n var getPos = function( i, node ){\n return {\n x: bb.x1 + Math.round( Math.random() * bb.w ),\n y: bb.y1 + Math.round( Math.random() * bb.h )\n };\n };\n\n nodes.layoutPositions( this, options, getPos );\n\n return this; // chaining\n};\n\nmodule.exports = RandomLayout;\n","'use strict';\n\nvar math = require('../../../math');\nvar is = require('../../../is');\nvar util = require('../../../util');\n\nvar BRp = {};\n\nBRp.arrowShapeHeight = 0.3;\n\nBRp.registerArrowShapes = function(){\n var arrowShapes = this.arrowShapes = {};\n var renderer = this;\n\n // Contract for arrow shapes:\n // 0, 0 is arrow tip\n // (0, 1) is direction towards node\n // (1, 0) is right\n //\n // functional api:\n // collide: check x, y in shape\n // roughCollide: called before collide, no false negatives\n // draw: draw\n // spacing: dist(arrowTip, nodeBoundary)\n // gap: dist(edgeTip, nodeBoundary), edgeTip may != arrowTip\n\n var bbCollide = function( x, y, size, angle, translation, padding ){\n var x1 = translation.x - size/2 - padding;\n var x2 = translation.x + size/2 + padding;\n var y1 = translation.y - size/2 - padding;\n var y2 = translation.y + size/2 + padding;\n\n var inside = (x1 <= x && x <= x2) && (y1 <= y && y <= y2);\n\n return inside;\n };\n\n var transform = function( x, y, size, angle, translation ){\n var xRotated = x * Math.cos(angle) - y * Math.sin(angle);\n var yRotated = x * Math.sin(angle) + y * Math.cos(angle);\n\n var xScaled = xRotated * size;\n var yScaled = yRotated * size;\n\n var xTranslated = xScaled + translation.x;\n var yTranslated = yScaled + translation.y;\n\n return {\n x: xTranslated,\n y: yTranslated\n };\n };\n\n var transformPoints = function( pts, size, angle, translation ){\n var retPts = [];\n\n for( var i = 0; i < pts.length; i += 2 ){\n var x = pts[i];\n var y = pts[i + 1];\n\n retPts.push( transform(x, y, size, angle, translation) );\n }\n\n return retPts;\n };\n\n var pointsToArr = function( pts ){\n var ret = [];\n\n for( var i = 0; i < pts.length; i++ ){\n var p = pts[i];\n\n ret.push( p.x, p.y );\n }\n\n return ret;\n };\n\n var defineArrowShape = function( name, defn ){\n if( is.string(defn) ){\n defn = arrowShapes[ defn ];\n }\n\n arrowShapes[ name ] = util.extend( {\n name: name,\n\n points: [\n -0.15, -0.3,\n 0.15, -0.3,\n 0.15, 0.3,\n -0.15, 0.3\n ],\n\n collide: function( x, y, size, angle, translation, padding ){\n var points = pointsToArr( transformPoints( this.points, size + 2*padding, angle, translation ) );\n var inside = math.pointInsidePolygonPoints( x, y, points );\n\n return inside;\n },\n\n roughCollide: bbCollide,\n\n draw: function( context, size, angle, translation ){\n var points = transformPoints( this.points, size, angle, translation );\n\n renderer.arrowShapeImpl('polygon')( context, points );\n },\n\n spacing: function( edge ){\n return 0;\n },\n\n gap: function( edge ){\n return edge._private.style['width'].pfValue * 2;\n }\n }, defn );\n };\n\n defineArrowShape( 'none', {\n collide: util.falsify,\n\n roughCollide: util.falsify,\n\n draw: util.noop,\n\n spacing: util.zeroify,\n\n gap: util.zeroify\n } );\n\n defineArrowShape( 'triangle', {\n points: [\n -0.15, -0.3,\n 0, 0,\n 0.15, -0.3\n ]\n } );\n\n defineArrowShape( 'arrow', 'triangle' );\n\n defineArrowShape( 'triangle-backcurve', {\n points: arrowShapes['triangle'].points,\n\n controlPoint: [ 0, -0.15 ],\n\n roughCollide: bbCollide,\n\n draw: function( context, size, angle, translation ){\n var ptsTrans = transformPoints( this.points, size, angle, translation );\n var ctrlPt = this.controlPoint;\n var ctrlPtTrans = transform( ctrlPt[0], ctrlPt[1], size, angle, translation );\n\n renderer.arrowShapeImpl( this.name )( context, ptsTrans, ctrlPtTrans );\n },\n\n gap: function( edge ){\n return edge._private.style['width'].pfValue;\n }\n } );\n\n\n defineArrowShape( 'triangle-tee', {\n points: [\n -0.15, -0.3,\n 0, 0,\n 0.15, -0.3,\n -0.15, -0.3\n ],\n\n pointsTee: [\n -0.15, -0.4,\n -0.15, -0.5,\n 0.15, -0.5,\n 0.15, -0.4\n ],\n\n collide: function( x, y, size, angle, translation, padding ){\n var triPts = pointsToArr( transformPoints( this.points, size + 2*padding, angle, translation ) );\n var teePts = pointsToArr( transformPoints( this.pointsTee, size + 2*padding, angle, translation ) );\n\n var inside = math.pointInsidePolygonPoints( x, y, triPts ) || math.pointInsidePolygonPoints( x, y, teePts );\n\n return inside;\n },\n\n draw: function( context, size, angle, translation ){\n var triPts = transformPoints( this.points, size, angle, translation );\n var teePts = transformPoints( this.pointsTee, size, angle, translation );\n\n renderer.arrowShapeImpl( this.name )( context, triPts, teePts );\n }\n } );\n\n defineArrowShape( 'vee', {\n points: [\n -0.15, -0.3,\n 0, 0,\n 0.15, -0.3,\n 0, -0.15\n ],\n\n gap: function( edge ){\n return edge._private.style['width'].pfValue;\n }\n } );\n\n defineArrowShape( 'half-triangle-overshot', {\n points: [\n 0, -0.25,\n -0.5, -0.25,\n 0.5, 0.25\n ],\n\n leavePathOpen: true,\n\n matchEdgeWidth: true\n } );\n\n defineArrowShape( 'circle', {\n radius: 0.15,\n\n collide: function( x, y, size, angle, translation, padding ){\n var t = translation;\n var inside = ( Math.pow(t.x - x, 2) + Math.pow(t.y - y, 2) <= Math.pow((size + 2*padding) * this.radius, 2) );\n\n return inside;\n },\n\n draw: function( context, size, angle, translation ){\n renderer.arrowShapeImpl( this.name )( context, translation.x, translation.y, this.radius * size );\n },\n\n spacing: function( edge ){\n return renderer.getArrowWidth(edge._private.style['width'].pfValue)\n * this.radius;\n }\n } );\n\n defineArrowShape( 'inhibitor', {\n points: [\n -0.25, 0,\n -0.25, -0.1,\n 0.25, -0.1,\n 0.25, 0\n ],\n\n spacing: function( edge ){\n return 1;\n },\n\n gap: function( edge ){\n return 1;\n }\n } );\n\n defineArrowShape( 'tee', 'inhibitor' );\n\n defineArrowShape( 'square', {\n points: [\n -0.15, 0.00,\n 0.15, 0.00,\n 0.15, -0.3,\n -0.15, -0.3\n ]\n } );\n\n defineArrowShape( 'diamond', {\n points: [\n -0.15, -0.15,\n 0, -0.3,\n 0.15, -0.15,\n 0, 0\n ],\n\n gap: function( edge ){\n return edge._private.style['width'].pfValue;\n }\n } );\n\n};\n\nmodule.exports = BRp;\n","'use strict';\n\nvar BRp = {};\n\nvar delEleCache = function( r ){\n r.eleEache = null;\n};\n\nvar getEleCache = function( r ){\n if( !r.eleEache ){\n r.eleEache = {\n nodes: r.cy.nodes(),\n edges: r.cy.edges()\n };\n }\n\n return r.eleEache;\n};\n\nBRp.getCachedElements = function(){\n return getEleCache( this );\n};\n\nBRp.getCachedNodes = function(){\n return getEleCache( this ).nodes;\n};\n\nBRp.getCachedEdges = function(){\n return getEleCache( this ).edges;\n};\n\nBRp.updateElementsCache = function(){\n var r = this;\n\n delEleCache( r );\n\n return getEleCache( r );\n};\n\nmodule.exports = BRp;\n","'use strict';\n\nvar math = require('../../../math');\nvar is = require('../../../is');\nvar zIndexSort = require('../../../collection/zsort');\n\nvar BRp = {};\n\n// Project mouse\nBRp.projectIntoViewport = function(clientX, clientY) {\n var offsets = this.findContainerClientCoords();\n var offsetLeft = offsets[0];\n var offsetTop = offsets[1];\n\n var x = clientX - offsetLeft;\n var y = clientY - offsetTop;\n\n x -= this.cy.pan().x; y -= this.cy.pan().y; x /= this.cy.zoom(); y /= this.cy.zoom();\n return [x, y];\n};\n\nBRp.findContainerClientCoords = function() {\n var container = this.container;\n\n var bb = this.containerBB = this.containerBB || container.getBoundingClientRect();\n\n return [bb.left, bb.top, bb.right - bb.left, bb.bottom - bb.top];\n};\n\nBRp.invalidateContainerClientCoordsCache = function(){\n this.containerBB = null;\n};\n\n// Find nearest element\nBRp.findNearestElement = function(x, y, visibleElementsOnly, isTouch){\n var self = this;\n var r = this;\n var eles = r.getCachedZSortedEles();\n var near = [];\n var zoom = r.cy.zoom();\n var hasCompounds = r.cy.hasCompoundNodes();\n var edgeThreshold = (isTouch ? 24 : 8) / zoom;\n var nodeThreshold = (isTouch ? 8 : 2) / zoom;\n var labelThreshold = (isTouch ? 8 : 2) / zoom;\n\n function checkNode(node){\n var _p = node._private;\n\n if( _p.style['events'].strValue === 'no' ){ return; }\n\n var width = node.outerWidth() + 2*nodeThreshold;\n var height = node.outerHeight() + 2*nodeThreshold;\n var hw = width/2;\n var hh = height/2;\n var pos = _p.position;\n\n if(\n pos.x - hw <= x && x <= pos.x + hw // bb check x\n &&\n pos.y - hh <= y && y <= pos.y + hh // bb check y\n ){\n var visible = !visibleElementsOnly || ( node.visible() && !node.transparent() );\n\n // exit early if invisible edge and must be visible\n if( visibleElementsOnly && !visible ){\n return;\n }\n\n var shape = r.nodeShapes[ self.getNodeShape(node) ];\n\n if(\n shape.checkPoint(x, y, 0, width, height, pos.x, pos.y)\n ){\n near.push( node );\n }\n\n }\n }\n\n function checkEdge(edge){\n var _p = edge._private;\n\n if( _p.style['events'].strValue === 'no' ){ return; }\n\n var rs = _p.rscratch;\n var style = _p.style;\n var width = style['width'].pfValue/2 + edgeThreshold; // more like a distance radius from centre\n var widthSq = width * width;\n var width2 = width * 2;\n var src = _p.source;\n var tgt = _p.target;\n var inEdgeBB = false;\n var sqDist;\n\n // exit early if invisible edge and must be visible\n var passedVisibilityCheck;\n var passesVisibilityCheck = function(){\n if( passedVisibilityCheck !== undefined ){\n return passedVisibilityCheck;\n }\n\n if( !visibleElementsOnly ){\n passedVisibilityCheck = true;\n return true;\n }\n\n var visible = edge.visible() && !edge.transparent();\n if( visible ){\n passedVisibilityCheck = true;\n return true;\n }\n\n passedVisibilityCheck = false;\n return false;\n };\n\n if( rs.edgeType === 'segments' || rs.edgeType === 'straight' || rs.edgeType === 'haystack' ){\n var pts = rs.allpts;\n\n for( var i = 0; i + 3 < pts.length; i += 2 ){\n if(\n (inEdgeBB = math.inLineVicinity(x, y, pts[i], pts[i+1], pts[i+2], pts[i+3], width2))\n && passesVisibilityCheck() &&\n widthSq > ( sqDist = math.sqDistanceToFiniteLine(x, y, pts[i], pts[i+1], pts[i+2], pts[i+3]) )\n ){\n near.push( edge );\n }\n }\n\n } else if( rs.edgeType === 'bezier' || rs.edgeType === 'multibezier' || rs.edgeType === 'self' || rs.edgeType === 'compound' ){\n var pts = rs.allpts;\n for( var i = 0; i + 5 < rs.allpts.length; i += 4 ){\n if(\n (inEdgeBB = math.inBezierVicinity(x, y, pts[i], pts[i+1], pts[i+2], pts[i+3], pts[i+4], pts[i+5], width2))\n && passesVisibilityCheck() &&\n (widthSq > (sqDist = math.sqDistanceToQuadraticBezier(x, y, pts[i], pts[i+1], pts[i+2], pts[i+3], pts[i+4], pts[i+5])) )\n ){\n near.push( edge );\n }\n }\n }\n\n // if we're close to the edge but didn't hit it, maybe we hit its arrows\n if( inEdgeBB && passesVisibilityCheck() && near.length === 0 || near[near.length - 1] !== edge ){\n var src = src || _p.source;\n var tgt = tgt || _p.target;\n\n var eWidth = style['width'].pfValue;\n var arSize = self.getArrowWidth( eWidth );\n\n var arrows = [\n { name: 'source', x: rs.arrowStartX, y: rs.arrowStartY, angle: rs.srcArrowAngle },\n { name: 'target', x: rs.arrowEndX, y: rs.arrowEndY, angle: rs.tgtArrowAngle },\n { name: 'mid-source', x: rs.midX, y: rs.midY, angle: rs.midsrcArrowAngle },\n { name: 'mid-target', x: rs.midX, y: rs.midY, angle: rs.midtgtArrowAngle }\n ];\n\n for( var i = 0; i < arrows.length; i++ ){\n var ar = arrows[i];\n var shape = r.arrowShapes[ style[ar.name+'-arrow-shape'].value ];\n\n if(\n shape.roughCollide(x, y, arSize, ar.angle, { x: ar.x, y: ar.y }, edgeThreshold)\n &&\n shape.collide(x, y, arSize, ar.angle, { x: ar.x, y: ar.y }, edgeThreshold)\n ){\n near.push( edge );\n break;\n }\n }\n }\n\n // for compound graphs, hitting edge may actually want a connected node instead (b/c edge may have greater z-index precedence)\n if( hasCompounds && near.length > 0 && near[ near.length - 1 ] === edge ){\n checkNode( src );\n checkNode( tgt );\n }\n }\n\n function checkLabel(ele){\n var _p = ele._private;\n var th = labelThreshold;\n\n if( _p.style['text-events'].strValue === 'no' ){ return; }\n\n // adjust bb w/ angle\n if( _p.group === 'edges' && _p.style['edge-text-rotation'].strValue === 'autorotate' ){\n\n var rstyle = _p.rstyle;\n var lw = rstyle.labelWidth + 2*th;\n var lh = rstyle.labelHeight + 2*th;\n var lx = rstyle.labelX;\n var ly = rstyle.labelY;\n\n var theta = _p.rscratch.labelAngle;\n var cos = Math.cos( theta );\n var sin = Math.sin( theta );\n\n var rotate = function( x, y ){\n x = x - lx;\n y = y - ly;\n\n return {\n x: x*cos - y*sin + lx,\n y: x*sin + y*cos + ly\n };\n };\n\n var lx1 = lx - lw/2;\n var lx2 = lx + lw/2;\n var ly1 = ly - lh/2;\n var ly2 = ly + lh/2;\n\n var px1y1 = rotate( lx1, ly1 );\n var px1y2 = rotate( lx1, ly2 );\n var px2y1 = rotate( lx2, ly1 );\n var px2y2 = rotate( lx2, ly2 );\n\n var points = [\n px1y1.x, px1y1.y,\n px2y1.x, px2y1.y,\n px2y2.x, px2y2.y,\n px1y2.x, px1y2.y\n ];\n\n if( math.pointInsidePolygonPoints( x, y, points ) ){\n near.push( ele );\n }\n\n } else {\n var bb = ele.boundingBox({\n includeLabels: true,\n includeNodes: false,\n includeEdges: false\n });\n\n // adjust bb w/ threshold\n bb.x1 -= th;\n bb.y1 -= th;\n bb.x2 += th;\n bb.y2 += th;\n bb.w = bb.x2 - bb.x1;\n bb.h = bb.y2 - bb.y1;\n\n if( math.inBoundingBox( bb, x, y ) ){\n near.push( ele );\n }\n }\n\n }\n\n for( var i = eles.length - 1; i >= 0; i-- ){ // reverse order for precedence\n var ele = eles[i];\n var _p = ele._private;\n\n if( near.length > 0 ){ break; } // since we check in z-order, first found is top and best result => exit early\n\n if( _p.group === 'nodes' ){\n checkNode( ele );\n\n } else { // then edge\n checkEdge( ele );\n }\n\n checkLabel( ele );\n\n }\n\n\n if( near.length > 0 ){\n return near[ near.length - 1 ];\n } else {\n return null;\n }\n};\n\n// 'Give me everything from this box'\nBRp.getAllInBox = function(x1, y1, x2, y2) {\n var nodes = this.getCachedNodes();\n var edges = this.getCachedEdges();\n var box = [];\n\n var x1c = Math.min(x1, x2);\n var x2c = Math.max(x1, x2);\n var y1c = Math.min(y1, y2);\n var y2c = Math.max(y1, y2);\n\n x1 = x1c;\n x2 = x2c;\n y1 = y1c;\n y2 = y2c;\n\n var boxBb = math.makeBoundingBox({\n x1: x1, y1: y1,\n x2: x2, y2: y2\n });\n\n for ( var i = 0; i < nodes.length; i++ ){\n var node = nodes[i];\n var nodeBb = node.boundingBox({\n includeNodes: true,\n includeEdges: false,\n includeLabels: false\n });\n\n if( math.boundingBoxesIntersect(boxBb, nodeBb) ){\n box.push(nodes[i]);\n }\n }\n\n for( var e = 0; e < edges.length; e++ ){\n var edge = edges[e];\n var _p = edge._private;\n var rs = _p.rscratch;\n\n if( rs.startX != null && rs.startY != null && !math.inBoundingBox( boxBb, rs.startX, rs.startY ) ){ continue; }\n if( rs.endX != null && rs.endY != null && !math.inBoundingBox( boxBb, rs.endX, rs.endY ) ){ continue; }\n\n if( rs.edgeType === 'bezier' || rs.edgeType === 'multibezier' || rs.edgeType === 'self' || rs.edgeType === 'compound' || rs.edgeType === 'segments' || rs.edgeType === 'haystack' ){\n\n var pts = _p.rstyle.bezierPts || _p.rstyle.linePts || _p.rstyle.haystackPts;\n var allInside = true;\n\n for( var i = 0; i < pts.length; i++ ){\n if( !math.pointInBoundingBox( boxBb, pts[i] ) ){\n allInside = false;\n break;\n }\n }\n\n if( allInside ){\n box.push( edge );\n }\n\n } else if( rs.edgeType === 'haystack' || rs.edgeType === 'straight' ){\n box.push( edge );\n }\n\n }\n\n return box;\n};\n\n\n/**\n * Returns the shape of the given node. If the height or width of the given node\n * is set to auto, the node is considered to be a compound.\n *\n * @param node a node\n * @return {String} shape of the node\n */\nBRp.getNodeShape = function( node ){\n var r = this;\n var style = node._private.style;\n var shape = style['shape'].value;\n\n if( node.isParent() ){\n if( shape === 'rectangle' || shape === 'roundrectangle' ){\n return shape;\n } else {\n return 'rectangle';\n }\n }\n\n if( shape === 'polygon' ){\n var points = style['shape-polygon-points'].value;\n\n return r.nodeShapes.makePolygon( points ).name;\n }\n\n return shape;\n};\n\nBRp.updateCachedZSortedEles = function(){\n this.getCachedZSortedEles( true );\n};\n\nBRp.getCachedZSortedEles = function( forceRecalc ){\n var lastNodes = this.lastZOrderCachedNodes;\n var lastEdges = this.lastZOrderCachedEdges;\n var nodes = this.getCachedNodes();\n var edges = this.getCachedEdges();\n var eles = [];\n\n if( forceRecalc || !lastNodes || !lastEdges || lastNodes !== nodes || lastEdges !== edges ){\n //console.time('cachezorder')\n\n for( var i = 0; i < nodes.length; i++ ){\n var n = nodes[i];\n\n if( n.animated() || (n.visible() && !n.transparent()) ){\n eles.push( n );\n }\n }\n\n for( var i = 0; i < edges.length; i++ ){\n var e = edges[i];\n\n if( e.animated() || (e.visible() && !e.transparent()) ){\n eles.push( e );\n }\n }\n\n eles.sort( zIndexSort );\n this.cachedZSortedEles = eles;\n //console.log('make cache')\n\n //console.timeEnd('cachezorder')\n } else {\n eles = this.cachedZSortedEles;\n //console.log('read cache')\n }\n\n this.lastZOrderCachedNodes = nodes;\n this.lastZOrderCachedEdges = edges;\n\n return eles;\n};\n\nfunction pushBezierPts(edge, pts){\n var qbezierAt = function( p1, p2, p3, t ){ return math.qbezierAt(p1, p2, p3, t); };\n var _p = edge._private;\n var bpts = _p.rstyle.bezierPts;\n\n bpts.push({\n x: qbezierAt( pts[0], pts[2], pts[4], 0.05 ),\n y: qbezierAt( pts[1], pts[3], pts[5], 0.05 )\n });\n\n bpts.push({\n x: qbezierAt( pts[0], pts[2], pts[4], 0.25 ),\n y: qbezierAt( pts[1], pts[3], pts[5], 0.25 )\n });\n\n bpts.push({\n x: qbezierAt( pts[0], pts[2], pts[4], 0.4 ),\n y: qbezierAt( pts[1], pts[3], pts[5], 0.4 )\n });\n\n bpts.push({\n x: qbezierAt( pts[0], pts[2], pts[4], 0.5 ),\n y: qbezierAt( pts[1], pts[3], pts[5], 0.5 )\n });\n\n bpts.push({\n x: qbezierAt( pts[0], pts[2], pts[4], 0.6 ),\n y: qbezierAt( pts[1], pts[3], pts[5], 0.6 )\n });\n\n bpts.push({\n x: qbezierAt( pts[0], pts[2], pts[4], 0.75 ),\n y: qbezierAt( pts[1], pts[3], pts[5], 0.75 )\n });\n\n bpts.push({\n x: qbezierAt( pts[0], pts[2], pts[4], 0.95 ),\n y: qbezierAt( pts[1], pts[3], pts[5], 0.95 )\n });\n}\n\nBRp.projectLines = function( edge ){\n var _p = edge._private;\n var rs = _p.rscratch;\n var et = rs.edgeType;\n\n if( et === 'multibezier' || et === 'bezier' || et === 'self' || et === 'compound' ){\n var bpts = _p.rstyle.bezierPts = []; // jshint ignore:line\n\n for( var i = 0; i + 5 < rs.allpts.length; i += 4 ){\n pushBezierPts( edge, rs.allpts.slice(i, i+6) );\n }\n } else if( et === 'segments' ){\n var lpts = _p.rstyle.linePts = [];\n\n for( var i = 0; i + 1 < rs.allpts.length; i += 2 ){\n lpts.push({\n x: rs.allpts[i],\n y: rs.allpts[i+1]\n });\n }\n } else if( et === 'haystack' ){\n var hpts = rs.haystackPts;\n\n _p.rstyle.haystackPts = [\n { x: hpts[0], y: hpts[1] },\n { x: hpts[2], y: hpts[3] }\n ];\n }\n};\n\nBRp.projectBezier = BRp.projectLines;\n\nBRp.recalculateNodeLabelProjection = function( node ){\n var content = node._private.style['label'].strValue;\n if( !content || content.match(/^\\s+$/) ){ return; }\n\n var textX, textY;\n var nodeWidth = node.outerWidth();\n var nodeHeight = node.outerHeight();\n var nodePos = node._private.position;\n var textHalign = node._private.style['text-halign'].strValue;\n var textValign = node._private.style['text-valign'].strValue;\n var rs = node._private.rscratch;\n var rstyle = node._private.rstyle;\n\n switch( textHalign ){\n case 'left':\n textX = nodePos.x - nodeWidth / 2;\n break;\n\n case 'right':\n textX = nodePos.x + nodeWidth / 2;\n break;\n\n default: // e.g. center\n textX = nodePos.x;\n }\n\n switch( textValign ){\n case 'top':\n textY = nodePos.y - nodeHeight / 2;\n break;\n\n case 'bottom':\n textY = nodePos.y + nodeHeight / 2;\n break;\n\n default: // e.g. middle\n textY = nodePos.y;\n }\n\n rs.labelX = textX;\n rs.labelY = textY;\n rstyle.labelX = textX;\n rstyle.labelY = textY;\n\n this.applyLabelDimensions( node );\n};\n\nBRp.recalculateEdgeLabelProjection = function( edge ){\n var content = edge._private.style['label'].strValue;\n if( !content || content.match(/^\\s+$/) ){ return; }\n\n var textX, textY;\n var _p = edge._private;\n var rs = _p.rscratch;\n //var style = _p.style;\n var rstyle = _p.rstyle;\n\n textX = rs.midX;\n textY = rs.midY;\n\n // add center point to style so bounding box calculations can use it\n rs.labelX = textX;\n rs.labelY = textY;\n rstyle.labelX = textX;\n rstyle.labelY = textY;\n\n this.applyLabelDimensions( edge );\n};\n\nBRp.applyLabelDimensions = function( ele ){\n var rs = ele._private.rscratch;\n var rstyle = ele._private.rstyle;\n\n var text = this.getLabelText( ele );\n var labelDims = this.calculateLabelDimensions( ele, text );\n\n rstyle.labelWidth = labelDims.width;\n rs.labelWidth = labelDims.width;\n\n rstyle.labelHeight = labelDims.height;\n rs.labelHeight = labelDims.height;\n};\n\nBRp.getLabelText = function( ele ){\n var style = ele._private.style;\n var text = ele._private.style['label'].strValue;\n var textTransform = style['text-transform'].value;\n var rscratch = ele._private.rscratch;\n\n if (textTransform == 'none') {\n } else if (textTransform == 'uppercase') {\n text = text.toUpperCase();\n } else if (textTransform == 'lowercase') {\n text = text.toLowerCase();\n }\n\n if( style['text-wrap'].value === 'wrap' ){\n //console.log('wrap');\n\n // save recalc if the label is the same as before\n if( rscratch.labelWrapKey === rscratch.labelKey ){\n // console.log('wrap cache hit');\n return rscratch.labelWrapCachedText;\n }\n // console.log('wrap cache miss');\n\n var lines = text.split('\\n');\n var maxW = style['text-max-width'].pfValue;\n var wrappedLines = [];\n\n for( var l = 0; l < lines.length; l++ ){\n var line = lines[l];\n var lineDims = this.calculateLabelDimensions( ele, line, 'line=' + line );\n var lineW = lineDims.width;\n\n if( lineW > maxW ){ // line is too long\n var words = line.split(/\\s+/); // NB: assume collapsed whitespace into single space\n var subline = '';\n\n for( var w = 0; w < words.length; w++ ){\n var word = words[w];\n var testLine = subline.length === 0 ? word : subline + ' ' + word;\n var testDims = this.calculateLabelDimensions( ele, testLine, 'testLine=' + testLine );\n var testW = testDims.width;\n\n if( testW <= maxW ){ // word fits on current line\n subline += word + ' ';\n } else { // word starts new line\n wrappedLines.push( subline );\n subline = word + ' ';\n }\n }\n\n // if there's remaining text, put it in a wrapped line\n if( !subline.match(/^\\s+$/) ){\n wrappedLines.push( subline );\n }\n } else { // line is already short enough\n wrappedLines.push( line );\n }\n } // for\n\n rscratch.labelWrapCachedLines = wrappedLines;\n rscratch.labelWrapCachedText = text = wrappedLines.join('\\n');\n rscratch.labelWrapKey = rscratch.labelKey;\n\n // console.log(text)\n } // if wrap\n\n return text;\n};\n\nBRp.calculateLabelDimensions = function( ele, text, extraKey ){\n var r = this;\n var style = ele._private.style;\n var fStyle = style['font-style'].strValue;\n var size = style['font-size'].pfValue + 'px';\n var family = style['font-family'].strValue;\n // var variant = style['font-variant'].strValue;\n var weight = style['font-weight'].strValue;\n\n var cacheKey = ele._private.labelKey;\n\n if( extraKey ){\n cacheKey += '$@$' + extraKey;\n }\n\n var cache = r.labelDimCache || (r.labelDimCache = {});\n\n if( cache[cacheKey] ){\n return cache[cacheKey];\n }\n\n var div = this.labelCalcDiv;\n\n if( !div ){\n div = this.labelCalcDiv = document.createElement('div');\n document.body.appendChild( div );\n }\n\n var ds = div.style;\n\n // from ele style\n ds.fontFamily = family;\n ds.fontStyle = fStyle;\n ds.fontSize = size;\n // ds.fontVariant = variant;\n ds.fontWeight = weight;\n\n // forced style\n ds.position = 'absolute';\n ds.left = '-9999px';\n ds.top = '-9999px';\n ds.zIndex = '-1';\n ds.visibility = 'hidden';\n ds.pointerEvents = 'none';\n ds.padding = '0';\n ds.lineHeight = '1';\n\n if( style['text-wrap'].value === 'wrap' ){\n ds.whiteSpace = 'pre'; // so newlines are taken into account\n } else {\n ds.whiteSpace = 'normal';\n }\n\n // put label content in div\n div.textContent = text;\n\n cache[cacheKey] = {\n width: div.clientWidth,\n height: div.clientHeight\n };\n\n return cache[cacheKey];\n};\n\nBRp.recalculateRenderedStyle = function( eles ){\n var edges = [];\n var nodes = [];\n var handledEdge = {};\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var _p = ele._private;\n var style = _p.style;\n var rs = _p.rscratch;\n var rstyle = _p.rstyle;\n var id = _p.data.id;\n var bbStyleSame = rs.boundingBoxKey != null && _p.boundingBoxKey === rs.boundingBoxKey;\n var labelStyleSame = rs.labelKey != null && _p.labelKey === rs.labelKey;\n var styleSame = bbStyleSame && labelStyleSame;\n\n if( _p.group === 'nodes' ){\n var pos = _p.position;\n var posSame = rstyle.nodeX != null && rstyle.nodeY != null && pos.x === rstyle.nodeX && pos.y === rstyle.nodeY;\n var wSame = rstyle.nodeW != null && rstyle.nodeW === style['width'].pfValue;\n var hSame = rstyle.nodeH != null && rstyle.nodeH === style['height'].pfValue;\n\n if( !posSame || !styleSame || !wSame || !hSame ){\n nodes.push( ele );\n }\n\n rstyle.nodeX = pos.x;\n rstyle.nodeY = pos.y;\n rstyle.nodeW = style['width'].pfValue;\n rstyle.nodeH = style['height'].pfValue;\n } else { // edges\n\n var srcPos = _p.source._private.position;\n var tgtPos = _p.target._private.position;\n var srcSame = rstyle.srcX != null && rstyle.srcY != null && srcPos.x === rstyle.srcX && srcPos.y === rstyle.srcY;\n var tgtSame = rstyle.tgtX != null && rstyle.tgtY != null && tgtPos.x === rstyle.tgtX && tgtPos.y === rstyle.tgtY;\n var positionsSame = srcSame && tgtSame;\n\n if( !positionsSame || !styleSame ){\n if( rs.edgeType === 'bezier' || rs.edgeType === 'straight' || rs.edgeType === 'self' || rs.edgeType === 'compound' ){\n if( !handledEdge[ id ] ){\n edges.push( ele );\n handledEdge[ id ] = true;\n\n var parallelEdges = ele.parallelEdges();\n for( var i = 0; i < parallelEdges.length; i++ ){\n var pEdge = parallelEdges[i];\n var pId = pEdge._private.data.id;\n\n if( !handledEdge[ pId ] ){\n edges.push( pEdge );\n handledEdge[ pId ] = true;\n }\n\n }\n }\n } else {\n edges.push( ele );\n }\n } // if positions diff\n\n // update rstyle positions\n rstyle.srcX = srcPos.x;\n rstyle.srcY = srcPos.y;\n rstyle.tgtX = tgtPos.x;\n rstyle.tgtY = tgtPos.y;\n\n } // if edges\n\n rs.boundingBoxKey = _p.boundingBoxKey;\n rs.labelKey = _p.labelKey;\n }\n\n this.recalculateEdgeProjections( edges );\n this.recalculateLabelProjections( nodes, edges );\n};\n\nBRp.recalculateLabelProjections = function( nodes, edges ){\n for( var i = 0; i < nodes.length; i++ ){\n this.recalculateNodeLabelProjection( nodes[i] );\n }\n\n for( var i = 0; i < edges.length; i++ ){\n this.recalculateEdgeLabelProjection( edges[i] );\n }\n};\n\nBRp.recalculateEdgeProjections = function( edges ){\n this.findEdgeControlPoints( edges );\n};\n\n\n// Find edge control points\nBRp.findEdgeControlPoints = function(edges) {\n if( !edges || edges.length === 0 ){ return; }\n\n var r = this;\n var cy = r.cy;\n var hasCompounds = cy.hasCompoundNodes();\n var hashTable = {};\n var pairIds = [];\n var haystackEdges = [];\n var autorotateEdges = [];\n\n // create a table of edge (src, tgt) => list of edges between them\n var pairId;\n for (var i = 0; i < edges.length; i++){\n var edge = edges[i];\n var _p = edge._private;\n var data = _p.data;\n var style = _p.style;\n var curveStyle = style['curve-style'].value;\n var edgeIsUnbundled = curveStyle === 'unbundled-bezier' || curveStyle === 'segments';\n\n // ignore edges who are not to be displayed\n // they shouldn't take up space\n if( style.display.value === 'none' ){\n continue;\n }\n\n if( style['edge-text-rotation'].strValue === 'autorotate' ){\n autorotateEdges.push( edge );\n }\n\n if( curveStyle === 'haystack' ){\n haystackEdges.push( edge );\n continue;\n }\n\n var srcId = data.source;\n var tgtId = data.target;\n\n pairId = srcId > tgtId ?\n tgtId + '$-$' + srcId :\n srcId + '$-$' + tgtId ;\n\n if( edgeIsUnbundled ){\n pairId = 'unbundled' + '$-$' + data.id;\n }\n\n if( hashTable[pairId] == null ){\n hashTable[pairId] = [];\n pairIds.push( pairId );\n }\n\n hashTable[pairId].push( edge );\n\n if( edgeIsUnbundled ){\n hashTable[pairId].hasUnbundled = true;\n }\n }\n\n var src, tgt, src_p, tgt_p, srcPos, tgtPos, srcW, srcH, tgtW, tgtH, srcShape, tgtShape;\n var vectorNormInverse;\n var badBezier;\n\n // for each pair (src, tgt), create the ctrl pts\n // Nested for loop is OK; total number of iterations for both loops = edgeCount\n for (var p = 0; p < pairIds.length; p++) {\n pairId = pairIds[p];\n var pairEdges = hashTable[pairId];\n\n // for each pair id, the edges should be sorted by index\n pairEdges.sort(function(edge1, edge2){\n return edge1._private.index - edge2._private.index;\n });\n\n src = pairEdges[0]._private.source;\n tgt = pairEdges[0]._private.target;\n\n src_p = src._private;\n tgt_p = tgt._private;\n\n // make sure src/tgt distinction is consistent\n // (src/tgt in this case are just for ctrlpts and don't actually have to be true src/tgt)\n if( src_p.data.id > tgt_p.data.id ){\n var temp = src;\n src = tgt;\n tgt = temp;\n }\n\n srcPos = src_p.position;\n tgtPos = tgt_p.position;\n\n srcW = src.outerWidth();\n srcH = src.outerHeight();\n\n tgtW = tgt.outerWidth();\n tgtH = tgt.outerHeight();\n\n srcShape = r.nodeShapes[ this.getNodeShape(src) ];\n tgtShape = r.nodeShapes[ this.getNodeShape(tgt) ];\n\n badBezier = false;\n\n\n if( (pairEdges.length > 1 && src !== tgt) || pairEdges.hasUnbundled ){\n\n // pt outside src shape to calc distance/displacement from src to tgt\n var srcOutside = srcShape.intersectLine(\n srcPos.x,\n srcPos.y,\n srcW,\n srcH,\n tgtPos.x,\n tgtPos.y,\n 0\n );\n\n // pt outside tgt shape to calc distance/displacement from src to tgt\n var tgtOutside = tgtShape.intersectLine(\n tgtPos.x,\n tgtPos.y,\n tgtW,\n tgtH,\n srcPos.x,\n srcPos.y,\n 0\n );\n\n var midptSrcPts = {\n x1: srcOutside[0],\n x2: tgtOutside[0],\n y1: srcOutside[1],\n y2: tgtOutside[1]\n };\n\n var dy = ( tgtOutside[1] - srcOutside[1] );\n var dx = ( tgtOutside[0] - srcOutside[0] );\n var l = Math.sqrt( dx*dx + dy*dy );\n\n var vector = {\n x: dx,\n y: dy\n };\n\n var vectorNorm = {\n x: vector.x/l,\n y: vector.y/l\n };\n vectorNormInverse = {\n x: -vectorNorm.y,\n y: vectorNorm.x\n };\n\n\n // if src intersection is inside tgt or tgt intersection is inside src, then no ctrl pts to draw\n if(\n tgtShape.checkPoint( srcOutside[0], srcOutside[1], 0, tgtW, tgtH, tgtPos.x, tgtPos.y ) ||\n srcShape.checkPoint( tgtOutside[0], tgtOutside[1], 0, srcW, srcH, srcPos.x, srcPos.y )\n ){\n vectorNormInverse = {};\n badBezier = true;\n }\n\n }\n\n var edge;\n var edge_p;\n var rs;\n\n for (var i = 0; i < pairEdges.length; i++) {\n edge = pairEdges[i];\n edge_p = edge._private;\n rs = edge_p.rscratch;\n\n var edgeIndex1 = rs.lastEdgeIndex;\n var edgeIndex2 = i;\n\n var numEdges1 = rs.lastNumEdges;\n var numEdges2 = pairEdges.length;\n\n var eStyle = edge_p.style;\n var style = eStyle;\n var curveStyle = eStyle['curve-style'].value;\n var ctrlptDists = eStyle['control-point-distances'];\n var ctrlptWs = eStyle['control-point-weights'];\n var bezierN = ctrlptDists && ctrlptWs ? Math.min( ctrlptDists.value.length, ctrlptWs.value.length ) : 1;\n var stepSize = eStyle['control-point-step-size'].pfValue;\n var ctrlptDist = ctrlptDists !== undefined ? ctrlptDists.pfValue[0] : undefined;\n var ctrlptWeight = ctrlptWs.value[0];\n var edgeIsUnbundled = curveStyle === 'unbundled-bezier' || curveStyle === 'segments';\n\n var swappedDirection = edge_p.source !== src;\n\n if( swappedDirection && edgeIsUnbundled ){\n ctrlptDist *= -1;\n }\n\n var srcX1 = rs.lastSrcCtlPtX;\n var srcX2 = srcPos.x;\n var srcY1 = rs.lastSrcCtlPtY;\n var srcY2 = srcPos.y;\n var srcW1 = rs.lastSrcCtlPtW;\n var srcW2 = src.outerWidth();\n var srcH1 = rs.lastSrcCtlPtH;\n var srcH2 = src.outerHeight();\n\n var tgtX1 = rs.lastTgtCtlPtX;\n var tgtX2 = tgtPos.x;\n var tgtY1 = rs.lastTgtCtlPtY;\n var tgtY2 = tgtPos.y;\n var tgtW1 = rs.lastTgtCtlPtW;\n var tgtW2 = tgt.outerWidth();\n var tgtH1 = rs.lastTgtCtlPtH;\n var tgtH2 = tgt.outerHeight();\n\n var width1 = rs.lastW;\n var width2 = eStyle['control-point-step-size'].pfValue;\n\n if( badBezier ){\n rs.badBezier = true;\n } else {\n rs.badBezier = false;\n }\n\n if( srcX1 === srcX2 && srcY1 === srcY2 && srcW1 === srcW2 && srcH1 === srcH2\n && tgtX1 === tgtX2 && tgtY1 === tgtY2 && tgtW1 === tgtW2 && tgtH1 === tgtH2\n && width1 === width2\n && ((edgeIndex1 === edgeIndex2 && numEdges1 === numEdges2) || edgeIsUnbundled) ){\n // console.log('edge ctrl pt cache HIT')\n continue; // then the control points haven't changed and we can skip calculating them\n } else {\n rs.lastSrcCtlPtX = srcX2;\n rs.lastSrcCtlPtY = srcY2;\n rs.lastSrcCtlPtW = srcW2;\n rs.lastSrcCtlPtH = srcH2;\n rs.lastTgtCtlPtX = tgtX2;\n rs.lastTgtCtlPtY = tgtY2;\n rs.lastTgtCtlPtW = tgtW2;\n rs.lastTgtCtlPtH = tgtH2;\n rs.lastEdgeIndex = edgeIndex2;\n rs.lastNumEdges = numEdges2;\n rs.lastWidth = width2;\n // console.log('edge ctrl pt cache MISS')\n }\n\n if( src === tgt ){\n // Self-edge\n\n rs.edgeType = 'self';\n\n var j = i;\n var loopDist = stepSize;\n\n if( edgeIsUnbundled ){\n j = 0;\n loopDist = ctrlptDist;\n }\n\n rs.ctrlpts = [\n srcPos.x,\n srcPos.y - (1 + Math.pow(srcH, 1.12) / 100) * loopDist * (j / 3 + 1),\n\n srcPos.x - (1 + Math.pow(srcW, 1.12) / 100) * loopDist * (j / 3 + 1),\n srcPos.y\n ];\n\n } else if(\n hasCompounds &&\n ( src.isParent() || src.isChild() || tgt.isParent() || tgt.isChild() ) &&\n ( src.parents().anySame(tgt) || tgt.parents().anySame(src) )\n ){\n // Compound edge\n\n rs.edgeType = 'compound';\n\n // because the line approximation doesn't apply for compound beziers\n // (loop/self edges are already elided b/c of cheap src==tgt check)\n rs.badBezier = false;\n\n var j = i;\n var loopDist = stepSize;\n\n if( edgeIsUnbundled ){\n j = 0;\n loopDist = ctrlptDist;\n }\n\n var loopW = 50;\n\n var loopaPos = {\n x: srcPos.x - srcW/2,\n y: srcPos.y - srcH/2\n };\n\n var loopbPos = {\n x: tgtPos.x - tgtW/2,\n y: tgtPos.y - tgtH/2\n };\n\n var loopPos = {\n x: Math.min( loopaPos.x, loopbPos.x ),\n y: Math.min( loopaPos.y, loopbPos.y )\n };\n\n // avoids cases with impossible beziers\n var minCompoundStretch = 0.5;\n var compoundStretchA = Math.max( minCompoundStretch, Math.log(srcW * 0.01) );\n var compoundStretchB = Math.max( minCompoundStretch, Math.log(tgtW * 0.01) );\n\n rs.ctrlpts = [\n loopPos.x,\n loopPos.y - (1 + Math.pow(loopW, 1.12) / 100) * loopDist * (j / 3 + 1) * compoundStretchA,\n\n loopPos.x - (1 + Math.pow(loopW, 1.12) / 100) * loopDist * (j / 3 + 1) * compoundStretchB,\n loopPos.y\n ];\n\n } else if( curveStyle === 'segments' ){\n // Segments (multiple straight lines)\n\n rs.edgeType = 'segments';\n rs.segpts = [];\n\n var segmentWs = eStyle['segment-weights'].pfValue;\n var segmentDs = eStyle['segment-distances'].pfValue;\n var segmentsN = Math.min( segmentWs.length, segmentDs.length );\n\n for( var s = 0; s < segmentsN; s++ ){\n var w = segmentWs[s];\n var d = segmentDs[s];\n\n // d = swappedDirection ? -d : d;\n //\n // d = Math.abs(d);\n\n // var w1 = !swappedDirection ? (1 - w) : w;\n // var w2 = !swappedDirection ? w : (1 - w);\n\n var w1 = (1 - w);\n var w2 = w;\n\n var adjustedMidpt = {\n x: midptSrcPts.x1 * w1 + midptSrcPts.x2 * w2,\n y: midptSrcPts.y1 * w1 + midptSrcPts.y2 * w2\n };\n\n rs.segpts.push(\n adjustedMidpt.x + vectorNormInverse.x * d,\n adjustedMidpt.y + vectorNormInverse.y * d\n );\n }\n\n // Straight edge\n } else if (\n pairEdges.length % 2 === 1\n && i === Math.floor(pairEdges.length / 2)\n && !edgeIsUnbundled\n ){\n\n rs.edgeType = 'straight';\n\n } else {\n // (Multi)bezier\n\n var multi = edgeIsUnbundled;\n\n rs.edgeType = multi ? 'multibezier' : 'bezier';\n rs.ctrlpts = [];\n\n for( var b = 0; b < bezierN; b++ ){\n var normctrlptDist = (0.5 - pairEdges.length / 2 + i) * stepSize;\n var manctrlptDist;\n var sign = math.signum( normctrlptDist );\n\n if( multi ){\n ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[b] : stepSize; // fall back on step size\n ctrlptWeight = ctrlptWs.value[b];\n }\n\n if( edgeIsUnbundled ){ // multi or single unbundled\n manctrlptDist = ctrlptDist;\n } else {\n manctrlptDist = ctrlptDist !== undefined ? sign * ctrlptDist : undefined;\n }\n\n var distanceFromMidpoint = manctrlptDist !== undefined ? manctrlptDist : normctrlptDist;\n\n var w1 = !swappedDirection || edgeIsUnbundled ? (1 - ctrlptWeight) : ctrlptWeight;\n var w2 = !swappedDirection || edgeIsUnbundled ? ctrlptWeight : (1 - ctrlptWeight);\n\n var adjustedMidpt = {\n x: midptSrcPts.x1 * w1 + midptSrcPts.x2 * w2,\n y: midptSrcPts.y1 * w1 + midptSrcPts.y2 * w2\n };\n\n rs.ctrlpts.push(\n adjustedMidpt.x + vectorNormInverse.x * distanceFromMidpoint,\n adjustedMidpt.y + vectorNormInverse.y * distanceFromMidpoint\n );\n }\n\n }\n\n // find endpts for edge\n this.findEndpoints( edge );\n\n var badStart = !is.number( rs.startX ) || !is.number( rs.startY );\n var badAStart = !is.number( rs.arrowStartX ) || !is.number( rs.arrowStartY );\n var badEnd = !is.number( rs.endX ) || !is.number( rs.endY );\n var badAEnd = !is.number( rs.arrowEndX ) || !is.number( rs.arrowEndY );\n\n var minCpADistFactor = 3;\n var arrowW = this.getArrowWidth( eStyle['width'].pfValue ) * this.arrowShapeHeight;\n var minCpADist = minCpADistFactor * arrowW;\n\n if( rs.edgeType === 'bezier' ){\n var startACpDist = math.distance( { x: rs.ctrlpts[0], y: rs.ctrlpts[1] }, { x: rs.startX, y: rs.startY } );\n var closeStartACp = startACpDist < minCpADist;\n var endACpDist = math.distance( { x: rs.ctrlpts[0], y: rs.ctrlpts[1] }, { x: rs.endX, y: rs.endY } );\n var closeEndACp = endACpDist < minCpADist;\n\n var overlapping = false;\n\n if( badStart || badAStart || closeStartACp ){\n overlapping = true;\n\n // project control point along line from src centre to outside the src shape\n // (otherwise intersection will yield nothing)\n var cpD = { // delta\n x: rs.ctrlpts[0] - srcPos.x,\n y: rs.ctrlpts[1] - srcPos.y\n };\n var cpL = Math.sqrt( cpD.x*cpD.x + cpD.y*cpD.y ); // length of line\n var cpM = { // normalised delta\n x: cpD.x / cpL,\n y: cpD.y / cpL\n };\n var radius = Math.max(srcW, srcH);\n var cpProj = { // *2 radius guarantees outside shape\n x: rs.ctrlpts[0] + cpM.x * 2 * radius,\n y: rs.ctrlpts[1] + cpM.y * 2 * radius\n };\n\n var srcCtrlPtIntn = srcShape.intersectLine(\n srcPos.x,\n srcPos.y,\n srcW,\n srcH,\n cpProj.x,\n cpProj.y,\n 0\n );\n\n if( closeStartACp ){\n rs.ctrlpts[0] = rs.ctrlpts[0] + cpM.x * (minCpADist - startACpDist);\n rs.ctrlpts[1] = rs.ctrlpts[1] + cpM.y * (minCpADist - startACpDist);\n } else {\n rs.ctrlpts[0] = srcCtrlPtIntn[0] + cpM.x * minCpADist;\n rs.ctrlpts[1] = srcCtrlPtIntn[1] + cpM.y * minCpADist;\n }\n }\n\n if( badEnd || badAEnd || closeEndACp ){\n overlapping = true;\n\n // project control point along line from tgt centre to outside the tgt shape\n // (otherwise intersection will yield nothing)\n var cpD = { // delta\n x: rs.ctrlpts[0] - tgtPos.x,\n y: rs.ctrlpts[1] - tgtPos.y\n };\n var cpL = Math.sqrt( cpD.x*cpD.x + cpD.y*cpD.y ); // length of line\n var cpM = { // normalised delta\n x: cpD.x / cpL,\n y: cpD.y / cpL\n };\n var radius = Math.max(srcW, srcH);\n var cpProj = { // *2 radius guarantees outside shape\n x: rs.ctrlpts[0] + cpM.x * 2 * radius,\n y: rs.ctrlpts[1] + cpM.y * 2 * radius\n };\n\n var tgtCtrlPtIntn = tgtShape.intersectLine(\n tgtPos.x,\n tgtPos.y,\n tgtW,\n tgtH,\n cpProj.x,\n cpProj.y,\n 0\n );\n\n if( closeEndACp ){\n rs.ctrlpts[0] = rs.ctrlpts[0] + cpM.x * (minCpADist - endACpDist);\n rs.ctrlpts[1] = rs.ctrlpts[1] + cpM.y * (minCpADist - endACpDist);\n } else {\n rs.ctrlpts[0] = tgtCtrlPtIntn[0] + cpM.x * minCpADist;\n rs.ctrlpts[1] = tgtCtrlPtIntn[1] + cpM.y * minCpADist;\n }\n\n }\n\n if( overlapping ){\n // recalc endpts\n this.findEndpoints( edge );\n }\n\n }\n\n if( rs.edgeType === 'multibezier' || rs.edgeType === 'bezier' || rs.edgeType === 'self' || rs.edgeType === 'compound' ){\n rs.allpts = [];\n\n rs.allpts.push( rs.startX, rs.startY );\n\n for( var b = 0; b+1 < rs.ctrlpts.length; b += 2 ){\n // ctrl pt itself\n rs.allpts.push( rs.ctrlpts[b], rs.ctrlpts[b+1] );\n\n // the midpt between ctrlpts as intermediate destination pts\n if( b + 3 < rs.ctrlpts.length ){\n rs.allpts.push( (rs.ctrlpts[b] + rs.ctrlpts[b+2])/2, (rs.ctrlpts[b+1] + rs.ctrlpts[b+3])/2 );\n }\n }\n\n rs.allpts.push( rs.endX, rs.endY );\n\n var m, mt;\n if( rs.edgeType === 'bezier' ){\n rs.midX = math.qbezierAt( rs.arrowStartX, rs.ctrlpts[0], rs.arrowEndX, 0.5 );\n rs.midY = math.qbezierAt( rs.arrowStartY, rs.ctrlpts[1], rs.arrowEndY, 0.5 );\n } else if( rs.ctrlpts.length/2 % 2 === 0 ){\n m = rs.allpts.length/2 - 1;\n\n rs.midX = rs.allpts[m];\n rs.midY = rs.allpts[m+1];\n } else {\n m = rs.allpts.length/2 - 3;\n mt = 0.5;\n\n rs.midX = math.qbezierAt( rs.allpts[m], rs.allpts[m+2], rs.allpts[m+4], mt );\n rs.midY = math.qbezierAt( rs.allpts[m+1], rs.allpts[m+3], rs.allpts[m+5], mt );\n }\n\n } else if( rs.edgeType === 'straight' ){\n // need to calc these after endpts\n rs.allpts = [ rs.startX, rs.startY, rs.endX, rs.endY ];\n\n // default midpt for labels etc\n rs.midX = ( rs.arrowStartX + rs.arrowEndX )/2;\n rs.midY = ( rs.arrowStartY + rs.arrowEndY )/2;\n\n } else if( rs.edgeType === 'segments' ){\n rs.allpts = [];\n rs.allpts.push( rs.startX, rs.startY );\n rs.allpts.push.apply( rs.allpts, rs.segpts );\n rs.allpts.push( rs.endX, rs.endY );\n\n if( rs.segpts.length % 4 === 0 ){\n var i2 = rs.segpts.length / 2;\n var i1 = i2 - 2;\n\n rs.midX = ( rs.segpts[i1] + rs.segpts[i2] ) / 2;\n rs.midY = ( rs.segpts[i1+1] + rs.segpts[i2+1] ) / 2;\n } else {\n var i1 = rs.segpts.length / 2 - 1;\n\n rs.midX = rs.segpts[i1];\n rs.midY = rs.segpts[i1+1];\n }\n\n\n }\n\n this.projectLines( edge );\n this.calculateArrowAngles( edge );\n this.recalculateEdgeLabelProjection( edge );\n\n }\n }\n\n for( var i = 0; i < haystackEdges.length; i++ ){\n var edge = haystackEdges[i];\n var _p = edge._private;\n var style = _p.style;\n var rscratch = _p.rscratch;\n var rs = rscratch;\n\n if( !rscratch.haystack ){\n var angle = Math.random() * 2 * Math.PI;\n\n rscratch.source = {\n x: Math.cos(angle),\n y: Math.sin(angle)\n };\n\n var angle = Math.random() * 2 * Math.PI;\n\n rscratch.target = {\n x: Math.cos(angle),\n y: Math.sin(angle)\n };\n\n }\n\n var src = _p.source;\n var tgt = _p.target;\n var srcPos = src._private.position;\n var tgtPos = tgt._private.position;\n var srcW = src.width();\n var tgtW = tgt.width();\n var srcH = src.height();\n var tgtH = tgt.height();\n var radius = style['haystack-radius'].value;\n var halfRadius = radius/2; // b/c have to half width/height\n\n rs.haystackPts = rs.allpts = [\n rs.source.x * srcW * halfRadius + srcPos.x,\n rs.source.y * srcH * halfRadius + srcPos.y,\n rs.target.x * tgtW * halfRadius + tgtPos.x,\n rs.target.y * tgtH * halfRadius + tgtPos.y\n ];\n\n rs.midX = (rs.allpts[0] + rs.allpts[2])/2;\n rs.midY = (rs.allpts[1] + rs.allpts[3])/2;\n\n // always override as haystack in case set to different type previously\n rscratch.edgeType = 'haystack';\n rscratch.haystack = true;\n\n this.projectLines( edge );\n this.calculateArrowAngles( edge );\n this.recalculateEdgeLabelProjection( edge );\n }\n\n for( var i = 0 ; i < autorotateEdges.length; i++ ){\n var edge = autorotateEdges[i];\n var rs = edge._private.rscratch;\n\n rs.labelAngle = Math.atan( rs.midDispY / rs.midDispX );\n }\n\n return hashTable;\n};\n\nvar getAngleFromDisp = function( dispX, dispY ){\n return Math.atan2( dispY, dispX ) - Math.PI/2;\n};\n\nBRp.calculateArrowAngles = function( edge ){\n var rs = edge._private.rscratch;\n var isHaystack = rs.edgeType === 'haystack';\n var isMultibezier = rs.edgeType === 'multibezier';\n var isSegments = rs.edgeType === 'segments';\n var isCompound = rs.edgeType === 'compound';\n var isSelf = rs.edgeType === 'self';\n\n // Displacement gives direction for arrowhead orientation\n var dispX, dispY;\n var startX, startY, endX, endY;\n\n var srcPos = edge.source().position();\n var tgtPos = edge.target().position();\n\n if( isHaystack ){\n startX = rs.haystackPts[0];\n startY = rs.haystackPts[1];\n endX = rs.haystackPts[2];\n endY = rs.haystackPts[3];\n } else {\n startX = rs.arrowStartX;\n startY = rs.arrowStartY;\n endX = rs.arrowEndX;\n endY = rs.arrowEndY;\n }\n\n // source\n //\n\n dispX = srcPos.x - startX;\n dispY = srcPos.y - startY;\n\n rs.srcArrowAngle = getAngleFromDisp( dispX, dispY );\n\n // mid target\n //\n\n var midX = rs.midX;\n var midY = rs.midY;\n\n if( isHaystack ){\n midX = ( startX + endX )/2;\n midY = ( startY + endY )/2;\n }\n\n dispX = endX - startX;\n dispY = endY - startY;\n\n if( isSelf ){\n dispX = -1;\n dispY = 1;\n } else if( isSegments ){\n var pts = rs.allpts;\n\n if( pts.length / 2 % 2 === 0 ){\n var i2 = pts.length / 2;\n var i1 = i2 - 2;\n\n dispX = ( pts[i2] - pts[i1] );\n dispY = ( pts[i2+1] - pts[i1+1] );\n } else {\n var i2 = pts.length / 2 - 1;\n var i1 = i2 - 2;\n var i3 = i2 + 2;\n\n dispX = ( pts[i2] - pts[i1] );\n dispY = ( pts[i2+1] - pts[i1+1] );\n }\n } else if( isMultibezier || isCompound ){\n var pts = rs.allpts;\n var cpts = rs.ctrlpts;\n var bp0x, bp0y;\n var bp1x, bp1y;\n\n if( cpts.length / 2 % 2 === 0 ){\n var p0 = pts.length / 2 - 1; // startpt\n var ic = p0 + 2;\n var p1 = ic + 2;\n\n bp0x = math.qbezierAt( pts[p0], pts[ic], pts[p1], 0.0 );\n bp0y = math.qbezierAt( pts[p0+1], pts[ic+1], pts[p1+1], 0.0 );\n\n bp1x = math.qbezierAt( pts[p0], pts[ic], pts[p1], 0.0001 );\n bp1y = math.qbezierAt( pts[p0+1], pts[ic+1], pts[p1+1], 0.0001 );\n } else {\n var ic = pts.length / 2 - 1; // ctrpt\n var p0 = ic - 2; // startpt\n var p1 = ic + 2; // endpt\n\n bp0x = math.qbezierAt( pts[p0], pts[ic], pts[p1], 0.4999 );\n bp0y = math.qbezierAt( pts[p0+1], pts[ic+1], pts[p1+1], 0.4999 );\n\n bp1x = math.qbezierAt( pts[p0], pts[ic], pts[p1], 0.5 );\n bp1y = math.qbezierAt( pts[p0+1], pts[ic+1], pts[p1+1], 0.5 );\n }\n\n dispX = ( bp1x - bp0x );\n dispY = ( bp1y - bp0y );\n }\n\n rs.midtgtArrowAngle = getAngleFromDisp( dispX, dispY );\n\n rs.midDispX = dispX;\n rs.midDispY = dispY;\n\n // mid source\n //\n\n dispX *= -1;\n dispY *= -1;\n\n if( isSegments ){\n var pts = rs.allpts;\n\n if( pts.length / 2 % 2 === 0 ){\n // already ok\n } else {\n var i2 = pts.length / 2 - 1;\n var i3 = i2 + 2;\n\n dispX = -( pts[i3] - pts[i2] );\n dispY = -( pts[i3+1] - pts[i2+1] );\n }\n }\n\n rs.midsrcArrowAngle = getAngleFromDisp( dispX, dispY );\n\n // target\n //\n\n dispX = tgtPos.x - endX;\n dispY = tgtPos.y - endY;\n\n rs.tgtArrowAngle = getAngleFromDisp( dispX, dispY );\n};\n\n\nBRp.findEndpoints = function( edge ){\n var r = this;\n var intersect;\n\n var source = edge.source()[0];\n var target = edge.target()[0];\n\n var src_p = source._private;\n var tgt_p = target._private;\n\n var srcPos = src_p.position;\n var tgtPos = tgt_p.position;\n\n var tgtArShape = edge._private.style['target-arrow-shape'].value;\n var srcArShape = edge._private.style['source-arrow-shape'].value;\n\n var rs = edge._private.rscratch;\n\n var et = rs.edgeType;\n var bezier = et === 'bezier' || et === 'multibezier' || et === 'self' || et === 'compound';\n var multi = et !== 'bezier';\n var lines = et === 'straight' || et === 'segments';\n var segments = et === 'segments';\n\n var p1, p2;\n\n if( bezier ){\n var cpStart = [ rs.ctrlpts[0], rs.ctrlpts[1] ];\n var cpEnd = multi ? [ rs.ctrlpts[rs.ctrlpts.length - 2], rs.ctrlpts[rs.ctrlpts.length - 1] ] : cpStart;\n\n p1 = cpEnd;\n p2 = cpStart;\n } else if( lines ){\n var srcArrowFromPt = !segments ? [ tgtPos.x, tgtPos.y ] : rs.segpts.slice( 0, 2 );\n var tgtArrowFromPt = !segments ? [ srcPos.x, srcPos.y ] : rs.segpts.slice( rs.segpts.length - 2 );\n\n p1 = tgtArrowFromPt;\n p2 = srcArrowFromPt;\n }\n\n intersect = r.nodeShapes[this.getNodeShape(target)].intersectLine(\n tgtPos.x,\n tgtPos.y,\n target.outerWidth(),\n target.outerHeight(),\n p1[0],\n p1[1],\n 0\n );\n\n var arrowEnd = math.shortenIntersection(intersect, p1,\n r.arrowShapes[tgtArShape].spacing(edge));\n var edgeEnd = math.shortenIntersection(intersect, p1,\n r.arrowShapes[tgtArShape].gap(edge));\n\n rs.endX = edgeEnd[0];\n rs.endY = edgeEnd[1];\n\n rs.arrowEndX = arrowEnd[0];\n rs.arrowEndY = arrowEnd[1];\n\n intersect = r.nodeShapes[this.getNodeShape(source)].intersectLine(\n srcPos.x,\n srcPos.y,\n source.outerWidth(),\n source.outerHeight(),\n p2[0],\n p2[1],\n 0\n );\n\n var arrowStart = math.shortenIntersection(\n intersect, p2,\n r.arrowShapes[srcArShape].spacing(edge)\n );\n var edgeStart = math.shortenIntersection(\n intersect, p2,\n r.arrowShapes[srcArShape].gap(edge)\n );\n\n rs.startX = edgeStart[0];\n rs.startY = edgeStart[1];\n\n rs.arrowStartX = arrowStart[0];\n rs.arrowStartY = arrowStart[1];\n\n if( lines ){\n if( !is.number(rs.startX) || !is.number(rs.startY) || !is.number(rs.endX) || !is.number(rs.endY) ){\n rs.badLine = true;\n } else {\n rs.badLine = false;\n }\n }\n};\n\nBRp.getArrowWidth = BRp.getArrowHeight = function(edgeWidth) {\n var cache = this.arrowWidthCache = this.arrowWidthCache || {};\n\n var cachedVal = cache[edgeWidth];\n if( cachedVal ){\n return cachedVal;\n }\n\n cachedVal = Math.max(Math.pow(edgeWidth * 13.37, 0.9), 29);\n cache[edgeWidth] = cachedVal;\n\n return cachedVal;\n};\n\nmodule.exports = BRp;\n","'use strict';\n\nvar BRp = {};\n\nBRp.getCachedImage = function(url, onLoad) {\n var r = this;\n var imageCache = r.imageCache = r.imageCache || {};\n\n if( imageCache[url] && imageCache[url].image ){\n return imageCache[url].image;\n }\n\n var cache = imageCache[url] = imageCache[url] || {};\n\n var image = cache.image = new Image();\n image.addEventListener('load', onLoad);\n image.src = url;\n\n return image;\n};\n\nmodule.exports = BRp;\n","'use strict';\n\nvar is = require('../../../is');\nvar util = require('../../../util');\n\nvar BaseRenderer = function(){};\nvar BR = BaseRenderer;\nvar BRp = BR.prototype;\n\nBRp.clientFunctions = [ 'redrawHint', 'render', 'renderTo', 'matchCanvasSize', 'nodeShapeImpl', 'arrowShapeImpl' ];\n\nBRp.init = function( options ){\n var r = this;\n\n r.options = options;\n\n r.cy = options.cy;\n\n r.container = options.cy.container();\n\n r.selection = [undefined, undefined, undefined, undefined, 0]; // Coordinates for selection box, plus enabled flag\n\n //--Pointer-related data\n r.hoverData = {down: null, last: null,\n downTime: null, triggerMode: null,\n dragging: false,\n initialPan: [null, null], capture: false};\n\n r.dragData = {possibleDragElements: []};\n\n r.touchData = {\n start: null, capture: false,\n\n // These 3 fields related to tap, taphold events\n startPosition: [null, null, null, null, null, null],\n singleTouchStartTime: null,\n singleTouchMoved: true,\n\n now: [null, null, null, null, null, null],\n earlier: [null, null, null, null, null, null]\n };\n\n r.redraws = 0;\n r.showFps = options.showFps;\n\n r.hideEdgesOnViewport = options.hideEdgesOnViewport;\n r.hideLabelsOnViewport = options.hideLabelsOnViewport;\n r.textureOnViewport = options.textureOnViewport;\n r.wheelSensitivity = options.wheelSensitivity;\n r.motionBlurEnabled = options.motionBlur; // on by default\n r.forcedPixelRatio = options.pixelRatio;\n r.motionBlur = true; // for initial kick off\n r.motionBlurOpacity = options.motionBlurOpacity;\n r.motionBlurTransparency = 1 - r.motionBlurOpacity;\n r.motionBlurPxRatio = 1;\n r.mbPxRBlurry = 1; //0.8;\n r.minMbLowQualFrames = 4;\n r.fullQualityMb = false;\n r.clearedForMotionBlur = [];\n r.desktopTapThreshold = options.desktopTapThreshold;\n r.desktopTapThreshold2 = options.desktopTapThreshold * options.desktopTapThreshold;\n r.touchTapThreshold = options.touchTapThreshold;\n r.touchTapThreshold2 = options.touchTapThreshold * options.touchTapThreshold;\n r.tapholdDuration = 500;\n\n r.bindings = [];\n\n r.registerNodeShapes();\n r.registerArrowShapes();\n r.load();\n};\n\nBRp.notify = function(params) {\n var types;\n var r = this;\n\n if( is.array( params.type ) ){\n types = params.type;\n\n } else {\n types = [ params.type ];\n }\n\n for( var i = 0; i < types.length; i++ ){\n var type = types[i];\n\n switch( type ){\n case 'destroy':\n r.destroy();\n return;\n\n case 'add':\n case 'remove':\n case 'load':\n r.updateElementsCache();\n break;\n\n case 'viewport':\n r.redrawHint('select', true);\n break;\n\n case 'style':\n r.updateCachedZSortedEles();\n break;\n }\n\n if( type === 'load' || type === 'resize' ){\n r.invalidateContainerClientCoordsCache();\n r.matchCanvasSize(r.container);\n }\n } // for\n\n r.redrawHint('eles', true);\n r.redrawHint('drag', true);\n\n this.startRenderLoop();\n\n this.redraw();\n};\n\nBRp.destroy = function(){\n this.destroyed = true;\n\n this.cy.stopAnimationLoop();\n\n for( var i = 0; i < this.bindings.length; i++ ){\n var binding = this.bindings[i];\n var b = binding;\n\n b.target.removeEventListener(b.event, b.handler, b.useCapture);\n }\n\n if( this.removeObserver ){\n this.removeObserver.disconnect();\n }\n\n if( this.labelCalcDiv ){\n try{\n document.body.removeChild(this.labelCalcDiv);\n } catch(e){\n // ie10 issue #1014\n }\n }\n};\n\n[\n require('./arrow-shapes'),\n require('./cached-eles'),\n require('./coord-ele-math'),\n require('./images'),\n require('./load-listeners'),\n require('./node-shapes'),\n require('./redraw')\n].forEach(function( props ){\n util.extend( BRp, props );\n});\n\nmodule.exports = BR;\n","'use strict';\n\nvar is = require('../../../is');\nvar util = require('../../../util');\nvar Event = require('../../../event');\nvar Collection = require('../../../collection');\n\nvar BRp = {};\n\nBRp.registerBinding = function(target, event, handler, useCapture){\n this.bindings.push({\n target: target,\n event: event,\n handler: handler,\n useCapture: useCapture\n });\n\n target.addEventListener(event, handler, useCapture);\n};\n\nBRp.nodeIsDraggable = function(node) {\n if (node._private.style['opacity'].value !== 0\n && node._private.style['visibility'].value == 'visible'\n && node._private.style['display'].value == 'element'\n && !node.locked()\n && node.grabbable() ) {\n\n return true;\n }\n\n return false;\n};\n\nBRp.load = function() {\n var r = this;\n\n var triggerEvents = function( target, names, e, props ){\n if( target == null ){\n target = r.cy;\n }\n\n for( var i = 0; i < names.length; i++ ){\n var name = names[i];\n\n var event = Event( e, util.extend({ type: name }, props) );\n target.trigger( event );\n }\n };\n\n var isMultSelKeyDown = function( e ){\n return e.shiftKey || e.metaKey || e.ctrlKey; // maybe e.altKey\n };\n\n var getDragListIds = function(opts){\n var listHasId;\n\n if( opts.addToList && r.cy.hasCompoundNodes() ){ // only needed for compound graphs\n if( !opts.addToList.hasId ){ // build ids lookup if doesn't already exist\n opts.addToList.hasId = {};\n\n for( var i = 0; i < opts.addToList.length; i++ ){\n var ele = opts.addToList[i];\n\n opts.addToList.hasId[ ele.id() ] = true;\n }\n }\n\n listHasId = opts.addToList.hasId;\n }\n\n return listHasId || {};\n };\n\n // helper function to determine which child nodes and inner edges\n // of a compound node to be dragged as well as the grabbed and selected nodes\n var addDescendantsToDrag = function(node, opts){\n if( !node._private.cy.hasCompoundNodes() ){\n return;\n }\n\n if( opts.inDragLayer == null && opts.addToList == null ){ return; } // nothing to do\n\n var listHasId = getDragListIds( opts );\n\n var innerNodes = node.descendants();\n\n for( var i = 0; i < innerNodes.size(); i++ ){\n var iNode = innerNodes[i];\n var _p = iNode._private;\n\n if( opts.inDragLayer ){\n _p.rscratch.inDragLayer = true;\n }\n\n if( opts.addToList && !listHasId[ iNode.id() ] ){\n opts.addToList.push( iNode );\n listHasId[ iNode.id() ] = true;\n\n _p.grabbed = true;\n }\n\n var edges = _p.edges;\n for( var j = 0; opts.inDragLayer && j < edges.length; j++ ){\n edges[j]._private.rscratch.inDragLayer = true;\n }\n }\n };\n\n // adds the given nodes, and its edges to the drag layer\n var addNodeToDrag = function(node, opts){\n\n var _p = node._private;\n var listHasId = getDragListIds( opts );\n\n if( opts.inDragLayer ){\n _p.rscratch.inDragLayer = true;\n }\n\n if( opts.addToList && !listHasId[ node.id() ] ){\n opts.addToList.push( node );\n listHasId[ node.id() ] = true;\n\n _p.grabbed = true;\n }\n\n var edges = _p.edges;\n for( var i = 0; opts.inDragLayer && i < edges.length; i++ ){\n edges[i]._private.rscratch.inDragLayer = true;\n }\n\n addDescendantsToDrag( node, opts ); // always add to drag\n\n // also add nodes and edges related to the topmost ancestor\n updateAncestorsInDragLayer( node, {\n inDragLayer: opts.inDragLayer\n } );\n };\n\n var freeDraggedElements = function( draggedElements ){\n if( !draggedElements ){ return; }\n\n for (var i=0; i < draggedElements.length; i++) {\n\n var dEi_p = draggedElements[i]._private;\n\n if(dEi_p.group === 'nodes') {\n dEi_p.rscratch.inDragLayer = false;\n dEi_p.grabbed = false;\n\n var sEdges = dEi_p.edges;\n for( var j = 0; j < sEdges.length; j++ ){ sEdges[j]._private.rscratch.inDragLayer = false; }\n\n // for compound nodes, also remove related nodes and edges from the drag layer\n updateAncestorsInDragLayer(draggedElements[i], { inDragLayer: false });\n\n } else if( dEi_p.group === 'edges' ){\n dEi_p.rscratch.inDragLayer = false;\n }\n\n }\n };\n\n // helper function to determine which ancestor nodes and edges should go\n // to the drag layer (or should be removed from drag layer).\n var updateAncestorsInDragLayer = function(node, opts) {\n\n if( opts.inDragLayer == null && opts.addToList == null ){ return; } // nothing to do\n\n // find top-level parent\n var parent = node;\n\n if( !node._private.cy.hasCompoundNodes() ){\n return;\n }\n\n while( parent.parent().nonempty() ){\n parent = parent.parent()[0];\n }\n\n // no parent node: no nodes to add to the drag layer\n if( parent == node ){\n return;\n }\n\n var nodes = parent.descendants()\n .merge( parent )\n .unmerge( node )\n .unmerge( node.descendants() )\n ;\n\n var edges = nodes.connectedEdges();\n\n var listHasId = getDragListIds( opts );\n\n for( var i = 0; i < nodes.size(); i++ ){\n if( opts.inDragLayer !== undefined ){\n nodes[i]._private.rscratch.inDragLayer = opts.inDragLayer;\n }\n\n if( opts.addToList && !listHasId[ nodes[i].id() ] ){\n opts.addToList.push( nodes[i] );\n listHasId[ nodes[i].id() ] = true;\n\n nodes[i]._private.grabbed = true;\n }\n }\n\n for( var j = 0; opts.inDragLayer !== undefined && j < edges.length; j++ ) {\n edges[j]._private.rscratch.inDragLayer = opts.inDragLayer;\n }\n };\n\n if( typeof MutationObserver !== 'undefined' ){\n r.removeObserver = new MutationObserver(function( mutns ){\n for( var i = 0; i < mutns.length; i++ ){\n var mutn = mutns[i];\n var rNodes = mutn.removedNodes;\n\n if( rNodes ){ for( var j = 0; j < rNodes.length; j++ ){\n var rNode = rNodes[j];\n\n if( rNode === r.container ){\n r.destroy();\n break;\n }\n } }\n }\n });\n\n if( r.container.parentNode ){\n r.removeObserver.observe( r.container.parentNode, { childList: true } );\n }\n } else {\n r.registerBinding(r.container, 'DOMNodeRemoved', function(e){\n r.destroy();\n });\n }\n\n\n\n // auto resize\n r.registerBinding(window, 'resize', util.debounce( function(e) {\n r.invalidateContainerClientCoordsCache();\n\n r.matchCanvasSize(r.container);\n r.redrawHint('eles', true);\n r.redraw();\n }, 100 ) );\n\n var invalCtnrBBOnScroll = function(domEle){\n r.registerBinding(domEle, 'scroll', function(e){\n r.invalidateContainerClientCoordsCache();\n } );\n };\n\n var bbCtnr = r.cy.container();\n\n for( ;; ){\n\n invalCtnrBBOnScroll( bbCtnr );\n\n if( bbCtnr.parentNode ){\n bbCtnr = bbCtnr.parentNode;\n } else {\n break;\n }\n\n }\n\n // stop right click menu from appearing on cy\n r.registerBinding(r.container, 'contextmenu', function(e){\n e.preventDefault();\n });\n\n var inBoxSelection = function(){\n return r.selection[4] !== 0;\n };\n\n // Primary key\n r.registerBinding(r.container, 'mousedown', function(e) {\n e.preventDefault();\n r.hoverData.capture = true;\n r.hoverData.which = e.which;\n\n var cy = r.cy;\n var pos = r.projectIntoViewport(e.clientX, e.clientY);\n var select = r.selection;\n var near = r.findNearestElement(pos[0], pos[1], true, false);\n var draggedElements = r.dragData.possibleDragElements;\n\n r.hoverData.mdownPos = pos;\n\n var checkForTaphold = function(){\n r.hoverData.tapholdCancelled = false;\n\n clearTimeout( r.hoverData.tapholdTimeout );\n\n r.hoverData.tapholdTimeout = setTimeout(function(){\n\n if( r.hoverData.tapholdCancelled ){\n return;\n } else {\n var ele = r.hoverData.down;\n\n if( ele ){\n ele.trigger( Event(e, {\n type: 'taphold',\n cyPosition: { x: pos[0], y: pos[1] }\n }) );\n } else {\n cy.trigger( Event(e, {\n type: 'taphold',\n cyPosition: { x: pos[0], y: pos[1] }\n }) );\n }\n }\n\n }, r.tapholdDuration);\n };\n\n // Right click button\n if( e.which == 3 ){\n\n r.hoverData.cxtStarted = true;\n\n var cxtEvt = Event(e, {\n type: 'cxttapstart',\n cyPosition: { x: pos[0], y: pos[1] }\n });\n\n if( near ){\n near.activate();\n near.trigger( cxtEvt );\n\n r.hoverData.down = near;\n } else {\n cy.trigger( cxtEvt );\n }\n\n r.hoverData.downTime = (new Date()).getTime();\n r.hoverData.cxtDragged = false;\n\n // Primary button\n } else if (e.which == 1) {\n\n if( near ){\n near.activate();\n }\n\n // Element dragging\n {\n // If something is under the cursor and it is draggable, prepare to grab it\n if (near != null) {\n\n if( r.nodeIsDraggable(near) ){\n\n var grabEvent = Event(e, {\n type: 'grab',\n cyPosition: { x: pos[0], y: pos[1] }\n });\n\n if ( near.isNode() && !near.selected() ){\n\n draggedElements = r.dragData.possibleDragElements = [];\n addNodeToDrag( near, { addToList: draggedElements } );\n\n near.trigger(grabEvent);\n\n } else if ( near.isNode() && near.selected() ){\n draggedElements = r.dragData.possibleDragElements = [ ];\n\n var selectedNodes = cy.$(function(){ return this.isNode() && this.selected(); });\n\n for( var i = 0; i < selectedNodes.length; i++ ){\n\n // Only add this selected node to drag if it is draggable, eg. has nonzero opacity\n if( r.nodeIsDraggable( selectedNodes[i] ) ){\n addNodeToDrag( selectedNodes[i], { addToList: draggedElements } );\n }\n }\n\n near.trigger( grabEvent );\n }\n\n r.redrawHint('eles', true);\n r.redrawHint('drag', true);\n\n }\n\n }\n\n r.hoverData.down = near;\n r.hoverData.downTime = (new Date()).getTime();\n }\n\n triggerEvents( near, ['mousedown', 'tapstart', 'vmousedown'], e, {\n cyPosition: { x: pos[0], y: pos[1] }\n } );\n\n if ( near == null ) {\n select[4] = 1;\n\n r.data.bgActivePosistion = {\n x: pos[0],\n y: pos[1]\n };\n\n r.redrawHint('select', true);\n\n r.redraw();\n } else if( near.isEdge() ){\n select[4] = 1; // for future pan\n }\n\n checkForTaphold();\n\n }\n\n // Initialize selection box coordinates\n select[0] = select[2] = pos[0];\n select[1] = select[3] = pos[1];\n\n }, false);\n\n r.registerBinding(window, 'mousemove', function(e) {\n var preventDefault = false;\n var capture = r.hoverData.capture;\n\n // save cycles if mouse events aren't to be captured\n if ( !capture ){\n var containerPageCoords = r.findContainerClientCoords();\n\n if (e.clientX > containerPageCoords[0] && e.clientX < containerPageCoords[0] + r.canvasWidth\n && e.clientY > containerPageCoords[1] && e.clientY < containerPageCoords[1] + r.canvasHeight\n ) {\n // inside container bounds so OK\n } else {\n return;\n }\n\n var cyContainer = r.container;\n var target = e.target;\n var tParent = target.parentNode;\n var containerIsTarget = false;\n\n while( tParent ){\n if( tParent === cyContainer ){\n containerIsTarget = true;\n break;\n }\n\n tParent = tParent.parentNode;\n }\n\n if( !containerIsTarget ){ return; } // if target is outisde cy container, then this event is not for us\n }\n\n var cy = r.cy;\n var zoom = cy.zoom();\n var pos = r.projectIntoViewport(e.clientX, e.clientY);\n var select = r.selection;\n\n var near = null;\n if( !r.hoverData.draggingEles ){\n near = r.findNearestElement(pos[0], pos[1], true, false);\n }\n var last = r.hoverData.last;\n var down = r.hoverData.down;\n\n var disp = [pos[0] - select[2], pos[1] - select[3]];\n\n var draggedElements = r.dragData.possibleDragElements;\n\n var dx = select[2] - select[0];\n var dx2 = dx * dx;\n var dy = select[3] - select[1];\n var dy2 = dy * dy;\n var dist2 = dx2 + dy2;\n var rdist2 = dist2 * zoom * zoom;\n\n var multSelKeyDown = isMultSelKeyDown( e );\n\n r.hoverData.tapholdCancelled = true;\n\n var updateDragDelta = function(){\n var dragDelta = r.hoverData.dragDelta = r.hoverData.dragDelta || [];\n\n if( dragDelta.length === 0 ){\n dragDelta.push( disp[0] );\n dragDelta.push( disp[1] );\n } else {\n dragDelta[0] += disp[0];\n dragDelta[1] += disp[1];\n }\n };\n\n\n preventDefault = true;\n\n triggerEvents( near, ['mousemove', 'vmousemove', 'tapdrag'], e, {\n cyPosition: { x: pos[0], y: pos[1] }\n } );\n\n // trigger context drag if rmouse down\n if( r.hoverData.which === 3 ){\n var cxtEvt = Event(e, {\n type: 'cxtdrag',\n cyPosition: { x: pos[0], y: pos[1] }\n });\n\n if( down ){\n down.trigger( cxtEvt );\n } else {\n cy.trigger( cxtEvt );\n }\n\n r.hoverData.cxtDragged = true;\n\n if( !r.hoverData.cxtOver || near !== r.hoverData.cxtOver ){\n\n if( r.hoverData.cxtOver ){\n r.hoverData.cxtOver.trigger( Event(e, {\n type: 'cxtdragout',\n cyPosition: { x: pos[0], y: pos[1] }\n }) );\n }\n\n r.hoverData.cxtOver = near;\n\n if( near ){\n near.trigger( Event(e, {\n type: 'cxtdragover',\n cyPosition: { x: pos[0], y: pos[1] }\n }) );\n }\n\n }\n\n // Check if we are drag panning the entire graph\n } else if (r.hoverData.dragging) {\n preventDefault = true;\n\n if( cy.panningEnabled() && cy.userPanningEnabled() ){\n var deltaP;\n\n if( r.hoverData.justStartedPan ){\n var mdPos = r.hoverData.mdownPos;\n\n deltaP = {\n x: ( pos[0] - mdPos[0] ) * zoom,\n y: ( pos[1] - mdPos[1] ) * zoom\n };\n\n r.hoverData.justStartedPan = false;\n\n } else {\n deltaP = {\n x: disp[0] * zoom,\n y: disp[1] * zoom\n };\n\n }\n\n cy.panBy( deltaP );\n\n r.hoverData.dragged = true;\n }\n\n // Needs reproject due to pan changing viewport\n pos = r.projectIntoViewport(e.clientX, e.clientY);\n\n // Checks primary button down & out of time & mouse not moved much\n } else if(\n select[4] == 1 && (down == null || down.isEdge())\n ){\n\n if( !r.hoverData.dragging && cy.boxSelectionEnabled() && ( multSelKeyDown || !cy.panningEnabled() || !cy.userPanningEnabled() ) ){\n r.data.bgActivePosistion = undefined;\n r.hoverData.selecting = true;\n\n r.redrawHint('select', true);\n r.redraw();\n\n } else if( !r.hoverData.selecting && cy.panningEnabled() && cy.userPanningEnabled() ){\n r.hoverData.dragging = true;\n r.hoverData.justStartedPan = true;\n select[4] = 0;\n\n r.data.bgActivePosistion = {\n x: pos[0],\n y: pos[1]\n };\n\n r.redrawHint('select', true);\n r.redraw();\n }\n\n if( down && down.isEdge() && down.active() ){ down.unactivate(); }\n\n } else {\n if( down && down.isEdge() && down.active() ){ down.unactivate(); }\n\n if (near != last) {\n\n if (last) {\n triggerEvents( last, ['mouseout', 'tapdragout'], e, {\n cyPosition: { x: pos[0], y: pos[1] }\n } );\n }\n\n if (near) {\n triggerEvents( near, ['mouseover', 'tapdragover'], e, {\n cyPosition: { x: pos[0], y: pos[1] }\n } );\n }\n\n r.hoverData.last = near;\n }\n\n if( down && down.isNode() && r.nodeIsDraggable(down) ){\n\n if( rdist2 >= r.desktopTapThreshold2 ){ // then drag\n\n var justStartedDrag = !r.dragData.didDrag;\n\n if( justStartedDrag ) {\n r.redrawHint('eles', true);\n }\n\n r.dragData.didDrag = true; // indicate that we actually did drag the node\n\n var toTrigger = [];\n\n for( var i = 0; i < draggedElements.length; i++ ){\n var dEle = draggedElements[i];\n\n // now, add the elements to the drag layer if not done already\n if( !r.hoverData.draggingEles ){\n addNodeToDrag( dEle, { inDragLayer: true } );\n }\n\n // Locked nodes not draggable, as well as non-visible nodes\n if( dEle.isNode() && r.nodeIsDraggable(dEle) && dEle.grabbed() ){\n var dPos = dEle._private.position;\n\n toTrigger.push( dEle );\n\n if( is.number(disp[0]) && is.number(disp[1]) ){\n var updatePos = !dEle.isParent();\n\n if( updatePos ){\n dPos.x += disp[0];\n dPos.y += disp[1];\n }\n\n if( justStartedDrag ){\n var dragDelta = r.hoverData.dragDelta;\n\n if( updatePos && is.number(dragDelta[0]) && is.number(dragDelta[1]) ){\n dPos.x += dragDelta[0];\n dPos.y += dragDelta[1];\n }\n }\n }\n\n }\n }\n\n r.hoverData.draggingEles = true;\n\n var tcol = (Collection(cy, toTrigger));\n\n tcol.updateCompoundBounds();\n tcol.trigger('position drag');\n\n r.redrawHint('drag', true);\n r.redraw();\n\n } else { // otherwise save drag delta for when we actually start dragging so the relative grab pos is constant\n updateDragDelta();\n }\n }\n\n // prevent the dragging from triggering text selection on the page\n preventDefault = true;\n }\n\n select[2] = pos[0]; select[3] = pos[1];\n\n if( preventDefault ){\n if(e.stopPropagation) e.stopPropagation();\n if(e.preventDefault) e.preventDefault();\n return false;\n }\n }, false);\n\n r.registerBinding(window, 'mouseup', function(e) {\n var capture = r.hoverData.capture;\n if (!capture) { return; }\n r.hoverData.capture = false;\n\n var cy = r.cy; var pos = r.projectIntoViewport(e.clientX, e.clientY); var select = r.selection;\n var near = r.findNearestElement(pos[0], pos[1], true, false);\n var draggedElements = r.dragData.possibleDragElements; var down = r.hoverData.down;\n var multSelKeyDown = isMultSelKeyDown( e );\n\n if( r.data.bgActivePosistion ){\n r.redrawHint('select', true);\n r.redraw();\n }\n\n r.hoverData.tapholdCancelled = true;\n\n r.data.bgActivePosistion = undefined; // not active bg now\n\n if( down ){\n down.unactivate();\n }\n\n if( r.hoverData.which === 3 ){\n var cxtEvt = Event(e, {\n type: 'cxttapend',\n cyPosition: { x: pos[0], y: pos[1] }\n });\n\n if( down ){\n down.trigger( cxtEvt );\n } else {\n cy.trigger( cxtEvt );\n }\n\n if( !r.hoverData.cxtDragged ){\n var cxtTap = Event(e, {\n type: 'cxttap',\n cyPosition: { x: pos[0], y: pos[1] }\n });\n\n if( down ){\n down.trigger( cxtTap );\n } else {\n cy.trigger( cxtTap );\n }\n }\n\n r.hoverData.cxtDragged = false;\n r.hoverData.which = null;\n\n } else if( r.hoverData.which === 1 ) {\n\n // Deselect all elements if nothing is currently under the mouse cursor and we aren't dragging something\n if ( (down == null) // not mousedown on node\n && !r.dragData.didDrag // didn't move the node around\n && !r.hoverData.selecting // not box selection\n && !r.hoverData.dragged // didn't pan\n && !isMultSelKeyDown( e )\n ) {\n\n cy.$(function(){\n return this.selected();\n }).unselect();\n\n if (draggedElements.length > 0) {\n r.redrawHint('eles', true);\n }\n\n r.dragData.possibleDragElements = draggedElements = [];\n }\n\n triggerEvents( near, ['mouseup', 'tapend', 'vmouseup'], e, {\n cyPosition: { x: pos[0], y: pos[1] }\n } );\n\n if(\n !r.dragData.didDrag // didn't move a node around\n && !r.hoverData.dragged // didn't pan\n ){\n triggerEvents( near, ['click', 'tap', 'vclick'], e, {\n cyPosition: { x: pos[0], y: pos[1] }\n } );\n }\n\n // Single selection\n if( near == down && !r.dragData.didDrag && !r.hoverData.selecting ){\n if( near != null && near._private.selectable ){\n\n if( r.hoverData.dragging ){\n // if panning, don't change selection state\n } else if( cy.selectionType() === 'additive' || multSelKeyDown ){\n if( near.selected() ){\n near.unselect();\n } else {\n near.select();\n }\n } else {\n if( !multSelKeyDown ){\n cy.$(':selected').unmerge( near ).unselect();\n near.select();\n }\n }\n\n r.redrawHint('eles', true);\n }\n }\n\n if ( r.hoverData.selecting ) {\n var newlySelected = [];\n var box = r.getAllInBox( select[0], select[1], select[2], select[3] );\n\n r.redrawHint('select', true);\n\n if( box.length > 0 ) {\n r.redrawHint('eles', true);\n }\n\n for( var i = 0; i < box.length; i++ ){\n if( box[i]._private.selectable ){\n newlySelected.push( box[i] );\n }\n }\n\n var newlySelCol = Collection( cy, newlySelected );\n\n if( cy.selectionType() === 'additive' ){\n newlySelCol.select();\n } else {\n if( !multSelKeyDown ){\n cy.$(':selected').unmerge( newlySelCol ).unselect();\n }\n\n newlySelCol.select();\n }\n\n // always need redraw in case eles unselectable\n r.redraw();\n\n }\n\n // Cancel drag pan\n if( r.hoverData.dragging ){\n r.hoverData.dragging = false;\n\n r.redrawHint('select', true);\n r.redrawHint('eles', true);\n\n r.redraw();\n }\n\n if (!select[4]) {\n\n\n r.redrawHint('drag', true);\n r.redrawHint('eles', true);\n\n freeDraggedElements( draggedElements );\n\n if( down ){ down.trigger('free'); }\n }\n\n } // else not right mouse\n\n select[4] = 0; r.hoverData.down = null;\n\n r.hoverData.cxtStarted = false;\n r.hoverData.draggingEles = false;\n r.hoverData.selecting = false;\n r.dragData.didDrag = false;\n r.hoverData.dragged = false;\n r.hoverData.dragDelta = [];\n\n }, false);\n\n var wheelHandler = function(e) {\n\n\n if( r.scrollingPage ){ return; } // while scrolling, ignore wheel-to-zoom\n\n var cy = r.cy;\n var pos = r.projectIntoViewport(e.clientX, e.clientY);\n var rpos = [pos[0] * cy.zoom() + cy.pan().x,\n pos[1] * cy.zoom() + cy.pan().y];\n\n if( r.hoverData.draggingEles || r.hoverData.dragging || r.hoverData.cxtStarted || inBoxSelection() ){ // if pan dragging or cxt dragging, wheel movements make no zoom\n e.preventDefault();\n return;\n }\n\n if( cy.panningEnabled() && cy.userPanningEnabled() && cy.zoomingEnabled() && cy.userZoomingEnabled() ){\n e.preventDefault();\n\n r.data.wheelZooming = true;\n clearTimeout( r.data.wheelTimeout );\n r.data.wheelTimeout = setTimeout(function(){\n r.data.wheelZooming = false;\n\n r.redrawHint('eles', true);\n r.redraw();\n }, 150);\n\n var diff = e.deltaY / -250 || e.wheelDeltaY / 1000 || e.wheelDelta / 1000;\n diff = diff * r.wheelSensitivity;\n\n var needsWheelFix = e.deltaMode === 1;\n if( needsWheelFix ){ // fixes slow wheel events on ff/linux and ff/windows\n diff *= 33;\n }\n\n cy.zoom({\n level: cy.zoom() * Math.pow(10, diff),\n renderedPosition: { x: rpos[0], y: rpos[1] }\n });\n }\n\n };\n\n // Functions to help with whether mouse wheel should trigger zooming\n // --\n r.registerBinding(r.container, 'wheel', wheelHandler, true);\n\n // disable nonstandard wheel events\n // r.registerBinding(r.container, 'mousewheel', wheelHandler, true);\n // r.registerBinding(r.container, 'DOMMouseScroll', wheelHandler, true);\n // r.registerBinding(r.container, 'MozMousePixelScroll', wheelHandler, true); // older firefox\n\n r.registerBinding(window, 'scroll', function(e){\n r.scrollingPage = true;\n\n clearTimeout( r.scrollingPageTimeout );\n r.scrollingPageTimeout = setTimeout(function(){\n r.scrollingPage = false;\n }, 250);\n }, true);\n\n // Functions to help with handling mouseout/mouseover on the Cytoscape container\n // Handle mouseout on Cytoscape container\n r.registerBinding(r.container, 'mouseout', function(e) {\n var pos = r.projectIntoViewport(e.clientX, e.clientY);\n\n r.cy.trigger(Event(e, {\n type: 'mouseout',\n cyPosition: { x: pos[0], y: pos[1] }\n }));\n }, false);\n\n r.registerBinding(r.container, 'mouseover', function(e) {\n var pos = r.projectIntoViewport(e.clientX, e.clientY);\n\n r.cy.trigger(Event(e, {\n type: 'mouseover',\n cyPosition: { x: pos[0], y: pos[1] }\n }));\n }, false);\n\n var f1x1, f1y1, f2x1, f2y1; // starting points for pinch-to-zoom\n var distance1, distance1Sq; // initial distance between finger 1 and finger 2 for pinch-to-zoom\n var center1, modelCenter1; // center point on start pinch to zoom\n var offsetLeft, offsetTop;\n var containerWidth, containerHeight;\n var twoFingersStartInside;\n\n var distance = function(x1, y1, x2, y2){\n return Math.sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) );\n };\n\n var distanceSq = function(x1, y1, x2, y2){\n return (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1);\n };\n\n var touchstartHandler;\n r.registerBinding(r.container, 'touchstart', touchstartHandler = function(e) {\n r.touchData.capture = true;\n r.data.bgActivePosistion = undefined;\n\n var cy = r.cy;\n var nodes = r.getCachedNodes();\n var edges = r.getCachedEdges();\n var now = r.touchData.now;\n var earlier = r.touchData.earlier;\n\n if (e.touches[0]) { var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY); now[0] = pos[0]; now[1] = pos[1]; }\n if (e.touches[1]) { var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY); now[2] = pos[0]; now[3] = pos[1]; }\n if (e.touches[2]) { var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY); now[4] = pos[0]; now[5] = pos[1]; }\n\n\n // record starting points for pinch-to-zoom\n if( e.touches[1] ){\n\n // anything in the set of dragged eles should be released\n var release = function( eles ){\n for( var i = 0; i < eles.length; i++ ){\n eles[i]._private.grabbed = false;\n eles[i]._private.rscratch.inDragLayer = false;\n if( eles[i].active() ){ eles[i].unactivate(); }\n }\n };\n release(nodes);\n release(edges);\n\n var offsets = r.findContainerClientCoords();\n offsetLeft = offsets[0];\n offsetTop = offsets[1];\n containerWidth = offsets[2];\n containerHeight = offsets[3];\n\n f1x1 = e.touches[0].clientX - offsetLeft;\n f1y1 = e.touches[0].clientY - offsetTop;\n\n f2x1 = e.touches[1].clientX - offsetLeft;\n f2y1 = e.touches[1].clientY - offsetTop;\n\n twoFingersStartInside =\n 0 <= f1x1 && f1x1 <= containerWidth\n && 0 <= f2x1 && f2x1 <= containerWidth\n && 0 <= f1y1 && f1y1 <= containerHeight\n && 0 <= f2y1 && f2y1 <= containerHeight\n ;\n\n var pan = cy.pan();\n var zoom = cy.zoom();\n\n distance1 = distance( f1x1, f1y1, f2x1, f2y1 );\n distance1Sq = distanceSq( f1x1, f1y1, f2x1, f2y1 );\n center1 = [ (f1x1 + f2x1)/2, (f1y1 + f2y1)/2 ];\n modelCenter1 = [\n (center1[0] - pan.x) / zoom,\n (center1[1] - pan.y) / zoom\n ];\n\n // consider context tap\n var cxtDistThreshold = 200;\n var cxtDistThresholdSq = cxtDistThreshold * cxtDistThreshold;\n if( distance1Sq < cxtDistThresholdSq && !e.touches[2] ){\n\n var near1 = r.findNearestElement(now[0], now[1], true, true);\n var near2 = r.findNearestElement(now[2], now[3], true, true);\n\n if( near1 && near1.isNode() ){\n near1.activate().trigger( Event(e, {\n type: 'cxttapstart',\n cyPosition: { x: now[0], y: now[1] }\n }) );\n r.touchData.start = near1;\n\n } else if( near2 && near2.isNode() ){\n near2.activate().trigger( Event(e, {\n type: 'cxttapstart',\n cyPosition: { x: now[0], y: now[1] }\n }) );\n r.touchData.start = near2;\n\n } else {\n cy.trigger( Event(e, {\n type: 'cxttapstart',\n cyPosition: { x: now[0], y: now[1] }\n }) );\n r.touchData.start = null;\n }\n\n if( r.touchData.start ){ r.touchData.start._private.grabbed = false; }\n r.touchData.cxt = true;\n r.touchData.cxtDragged = false;\n r.data.bgActivePosistion = undefined;\n\n r.redraw();\n return;\n\n }\n\n }\n\n if (e.touches[2]) {\n\n } else if (e.touches[1]) {\n\n } else if (e.touches[0]) {\n var near = r.findNearestElement(now[0], now[1], true, true);\n\n if (near != null) {\n near.activate();\n\n r.touchData.start = near;\n\n if( near.isNode() && r.nodeIsDraggable(near) ){\n\n var draggedEles = r.dragData.touchDragEles = [];\n\n r.redrawHint('eles', true);\n r.redrawHint('drag', true);\n\n if( near.selected() ){\n // reset drag elements, since near will be added again\n\n var selectedNodes = cy.$(function(){\n return this.isNode() && this.selected();\n });\n\n for( var k = 0; k < selectedNodes.length; k++ ){\n var selectedNode = selectedNodes[k];\n\n if( r.nodeIsDraggable(selectedNode) ){\n addNodeToDrag( selectedNode, { addToList: draggedEles } );\n }\n }\n } else {\n addNodeToDrag( near, { addToList: draggedEles } );\n }\n\n near.trigger( Event(e, {\n type: 'grab',\n cyPosition: { x: now[0], y: now[1] }\n }) );\n }\n }\n\n triggerEvents( near, ['touchstart', 'tapstart', 'vmousedown'], e, {\n cyPosition: { x: now[0], y: now[1] }\n } );\n\n if (near == null) {\n r.data.bgActivePosistion = {\n x: pos[0],\n y: pos[1]\n };\n\n r.redrawHint('select', true);\n r.redraw();\n }\n\n\n // Tap, taphold\n // -----\n\n for (var i=0; i= factorThresholdSq || distance2Sq >= distThresholdSq ){\n r.touchData.cxt = false;\n if( r.touchData.start ){ r.touchData.start.unactivate(); r.touchData.start = null; }\n r.data.bgActivePosistion = undefined;\n r.redrawHint('select', true);\n\n var cxtEvt = Event(e, {\n type: 'cxttapend',\n cyPosition: { x: now[0], y: now[1] }\n });\n if( r.touchData.start ){\n r.touchData.start.trigger( cxtEvt );\n } else {\n cy.trigger( cxtEvt );\n }\n }\n\n }\n\n // context swipe\n if( capture && r.touchData.cxt ){\n var cxtEvt = Event(e, {\n type: 'cxtdrag',\n cyPosition: { x: now[0], y: now[1] }\n });\n r.data.bgActivePosistion = undefined;\n r.redrawHint('select', true);\n\n if( r.touchData.start ){\n r.touchData.start.trigger( cxtEvt );\n } else {\n cy.trigger( cxtEvt );\n }\n\n if( r.touchData.start ){ r.touchData.start._private.grabbed = false; }\n r.touchData.cxtDragged = true;\n\n var near = r.findNearestElement(now[0], now[1], true, true);\n\n if( !r.touchData.cxtOver || near !== r.touchData.cxtOver ){\n\n if( r.touchData.cxtOver ){\n r.touchData.cxtOver.trigger( Event(e, {\n type: 'cxtdragout',\n cyPosition: { x: now[0], y: now[1] }\n }) );\n }\n\n r.touchData.cxtOver = near;\n\n if( near ){\n near.trigger( Event(e, {\n type: 'cxtdragover',\n cyPosition: { x: now[0], y: now[1] }\n }) );\n\n }\n\n }\n\n // box selection\n } else if( capture && e.touches[2] && cy.boxSelectionEnabled() ){\n e.preventDefault();\n\n r.data.bgActivePosistion = undefined;\n\n this.lastThreeTouch = +new Date();\n r.touchData.selecting = true;\n\n r.redrawHint('select', true);\n\n if( !select || select.length === 0 || select[0] === undefined ){\n select[0] = (now[0] + now[2] + now[4])/3;\n select[1] = (now[1] + now[3] + now[5])/3;\n select[2] = (now[0] + now[2] + now[4])/3 + 1;\n select[3] = (now[1] + now[3] + now[5])/3 + 1;\n } else {\n select[2] = (now[0] + now[2] + now[4])/3;\n select[3] = (now[1] + now[3] + now[5])/3;\n }\n\n select[4] = 1;\n r.touchData.selecting = true;\n\n r.redraw();\n\n // pinch to zoom\n } else if ( capture && e.touches[1] && cy.zoomingEnabled() && cy.panningEnabled() && cy.userZoomingEnabled() && cy.userPanningEnabled() ) { // two fingers => pinch to zoom\n e.preventDefault();\n\n r.data.bgActivePosistion = undefined;\n r.redrawHint('select', true);\n\n var draggedEles = r.dragData.touchDragEles;\n if( draggedEles ){\n r.redrawHint('drag', true);\n\n for( var i = 0; i < draggedEles.length; i++ ){\n draggedEles[i]._private.grabbed = false;\n draggedEles[i]._private.rscratch.inDragLayer = false;\n }\n }\n\n // (x2, y2) for fingers 1 and 2\n var f1x2 = e.touches[0].clientX - offsetLeft, f1y2 = e.touches[0].clientY - offsetTop;\n var f2x2 = e.touches[1].clientX - offsetLeft, f2y2 = e.touches[1].clientY - offsetTop;\n\n\n var distance2 = distance( f1x2, f1y2, f2x2, f2y2 );\n // var distance2Sq = distanceSq( f1x2, f1y2, f2x2, f2y2 );\n // var factor = Math.sqrt( distance2Sq ) / Math.sqrt( distance1Sq );\n var factor = distance2 / distance1;\n\n if( factor != 1 && twoFingersStartInside){\n // delta finger1\n var df1x = f1x2 - f1x1;\n var df1y = f1y2 - f1y1;\n\n // delta finger 2\n var df2x = f2x2 - f2x1;\n var df2y = f2y2 - f2y1;\n\n // translation is the normalised vector of the two fingers movement\n // i.e. so pinching cancels out and moving together pans\n var tx = (df1x + df2x)/2;\n var ty = (df1y + df2y)/2;\n\n // adjust factor by the speed multiplier\n // var speed = 1.5;\n // if( factor > 1 ){\n // factor = (factor - 1) * speed + 1;\n // } else {\n // factor = 1 - (1 - factor) * speed;\n // }\n\n // now calculate the zoom\n var zoom1 = cy.zoom();\n var zoom2 = zoom1 * factor;\n var pan1 = cy.pan();\n\n // the model center point converted to the current rendered pos\n var ctrx = modelCenter1[0] * zoom1 + pan1.x;\n var ctry = modelCenter1[1] * zoom1 + pan1.y;\n\n var pan2 = {\n x: -zoom2/zoom1 * (ctrx - pan1.x - tx) + ctrx,\n y: -zoom2/zoom1 * (ctry - pan1.y - ty) + ctry\n };\n\n // remove dragged eles\n if( r.touchData.start ){\n var draggedEles = r.dragData.touchDragEles;\n\n if( draggedEles ){ for( var i = 0; i < draggedEles.length; i++ ){\n var dEi_p = draggedEles[i]._private;\n\n dEi_p.grabbed = false;\n dEi_p.rscratch.inDragLayer = false;\n } }\n\n var start_p = r.touchData.start._private;\n start_p.active = false;\n start_p.grabbed = false;\n start_p.rscratch.inDragLayer = false;\n\n r.redrawHint('drag', true);\n\n r.touchData.start\n .trigger('free')\n .trigger('unactivate')\n ;\n }\n\n cy.viewport({\n zoom: zoom2,\n pan: pan2,\n cancelOnFailedZoom: true\n });\n\n distance1 = distance2;\n f1x1 = f1x2;\n f1y1 = f1y2;\n f2x1 = f2x2;\n f2y1 = f2y2;\n\n r.pinching = true;\n }\n\n // Re-project\n if (e.touches[0]) { var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY); now[0] = pos[0]; now[1] = pos[1]; }\n if (e.touches[1]) { var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY); now[2] = pos[0]; now[3] = pos[1]; }\n if (e.touches[2]) { var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY); now[4] = pos[0]; now[5] = pos[1]; }\n\n } else if (e.touches[0]) {\n var start = r.touchData.start;\n var last = r.touchData.last;\n var near = near || r.findNearestElement(now[0], now[1], true, true);\n\n if( start != null ){\n e.preventDefault();\n }\n\n // dragging nodes\n if( start != null && start._private.group == 'nodes' && r.nodeIsDraggable(start) ){\n\n if( rdist2 >= r.touchTapThreshold2 ){ // then dragging can happen\n var draggedEles = r.dragData.touchDragEles;\n var justStartedDrag = !r.dragData.didDrag;\n\n for( var k = 0; k < draggedEles.length; k++ ){\n var draggedEle = draggedEles[k];\n\n if( justStartedDrag ){\n addNodeToDrag( draggedEle, { inDragLayer: true } );\n }\n\n if( r.nodeIsDraggable(draggedEle) && draggedEle.isNode() && draggedEle.grabbed() ){\n r.dragData.didDrag = true;\n var dPos = draggedEle._private.position;\n var updatePos = !draggedEle.isParent();\n\n if( updatePos && is.number(disp[0]) && is.number(disp[1]) ){\n dPos.x += disp[0];\n dPos.y += disp[1];\n }\n\n if( justStartedDrag ){\n r.redrawHint('eles', true);\n\n var dragDelta = r.touchData.dragDelta;\n\n if( updatePos && is.number(dragDelta[0]) && is.number(dragDelta[1]) ){\n dPos.x += dragDelta[0];\n dPos.y += dragDelta[1];\n }\n\n }\n }\n }\n\n var tcol = Collection(cy, draggedEles);\n\n tcol.updateCompoundBounds();\n tcol.trigger('position drag');\n\n r.hoverData.draggingEles = true;\n\n r.redrawHint('drag', true);\n\n if(\n r.touchData.startPosition[0] == earlier[0]\n && r.touchData.startPosition[1] == earlier[1]\n ){\n\n r.redrawHint('eles', true);\n }\n\n r.redraw();\n } else { // otherise keep track of drag delta for later\n var dragDelta = r.touchData.dragDelta = r.touchData.dragDelta || [];\n\n if( dragDelta.length === 0 ){\n dragDelta.push( disp[0] );\n dragDelta.push( disp[1] );\n } else {\n dragDelta[0] += disp[0];\n dragDelta[1] += disp[1];\n }\n }\n }\n\n // touchmove\n {\n triggerEvents( (start || near), ['touchmove', 'tapdrag', 'vmousemove'], e, {\n cyPosition: { x: now[0], y: now[1] }\n } );\n\n if (near != last) {\n if (last) { last.trigger(Event(e, { type: 'tapdragout', cyPosition: { x: now[0], y: now[1] } })); }\n if (near) { near.trigger(Event(e, { type: 'tapdragover', cyPosition: { x: now[0], y: now[1] } })); }\n }\n\n r.touchData.last = near;\n }\n\n // check to cancel taphold\n for (var i=0;i r.touchTapThreshold2 ){\n\n r.touchData.singleTouchMoved = true;\n }\n }\n\n // panning\n if(\n capture\n && ( start == null || start.isEdge() )\n && cy.panningEnabled() && cy.userPanningEnabled()\n ){\n\n e.preventDefault();\n\n if( r.swipePanning ){\n cy.panBy({\n x: disp[0] * zoom,\n y: disp[1] * zoom\n });\n\n } else if( rdist2 >= r.touchTapThreshold2 ){\n r.swipePanning = true;\n\n cy.panBy({\n x: dx * zoom,\n y: dy * zoom\n });\n\n if( start ){\n start.unactivate();\n\n if( !r.data.bgActivePosistion ){\n r.data.bgActivePosistion = {\n x: now[0],\n y: now[1]\n };\n }\n\n r.redrawHint('select', true);\n\n r.touchData.start = null;\n }\n }\n\n // Re-project\n var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);\n now[0] = pos[0]; now[1] = pos[1];\n }\n }\n\n for (var j=0; j 0 ) {\n r.redrawHint('eles', true);\n } else {\n r.redraw();\n }\n }\n\n var updateStartStyle = false;\n\n if( start != null ){\n start._private.active = false;\n updateStartStyle = true;\n start.unactivate();\n }\n\n if (e.touches[2]) {\n r.data.bgActivePosistion = undefined;\n r.redrawHint('select', true);\n } else if (e.touches[1]) {\n\n } else if (e.touches[0]) {\n\n // Last touch released\n } else if (!e.touches[0]) {\n\n r.data.bgActivePosistion = undefined;\n r.redrawHint('select', true);\n\n var draggedEles = r.dragData.touchDragEles;\n\n if (start != null ) {\n\n var startWasGrabbed = start._private.grabbed;\n\n freeDraggedElements( draggedEles );\n\n r.redrawHint('drag', true);\n r.redrawHint('eles', true);\n\n if( startWasGrabbed ){\n start.trigger('free');\n }\n\n triggerEvents( start, ['touchend', 'tapend', 'vmouseup'], e, {\n cyPosition: { x: now[0], y: now[1] }\n } );\n\n start.unactivate();\n\n r.touchData.start = null;\n\n } else {\n var near = r.findNearestElement(now[0], now[1], true, true);\n\n triggerEvents( near, ['touchend', 'tapend', 'vmouseup'], e, {\n cyPosition: { x: now[0], y: now[1] }\n } );\n\n }\n\n var dx = r.touchData.startPosition[0] - now[0];\n var dx2 = dx * dx;\n var dy = r.touchData.startPosition[1] - now[1];\n var dy2 = dy * dy;\n var dist2 = dx2 + dy2;\n var rdist2 = dist2 * zoom * zoom;\n\n // Prepare to select the currently touched node, only if it hasn't been dragged past a certain distance\n if (start != null\n && !r.dragData.didDrag // didn't drag nodes around\n && start._private.selectable\n && rdist2 < r.touchTapThreshold2\n && !r.pinching // pinch to zoom should not affect selection\n ) {\n\n if( cy.selectionType() === 'single' ){\n cy.$(':selected').unmerge( start ).unselect();\n start.select();\n } else {\n if( start.selected() ){\n start.unselect();\n } else {\n start.select();\n }\n }\n\n updateStartStyle = true;\n\n\n r.redrawHint('eles', true);\n }\n\n // Tap event, roughly same as mouse click event for touch\n if( !r.touchData.singleTouchMoved ){\n triggerEvents( start, ['tap', 'vclick'], e, {\n cyPosition: { x: now[0], y: now[1] }\n } );\n }\n\n r.touchData.singleTouchMoved = true;\n }\n\n for( var j = 0; j < now.length; j++ ){ earlier[j] = now[j]; }\n\n r.dragData.didDrag = false; // reset for next mousedown\n\n if( e.touches.length === 0 ){\n r.touchData.dragDelta = [];\n }\n\n if( updateStartStyle && start ){\n start.updateStyle(false);\n }\n\n if( e.touches.length < 2 ){\n r.pinching = false;\n r.redrawHint('eles', true);\n r.redraw();\n }\n\n //r.redraw();\n\n }, false);\n\n // fallback compatibility layer for ms pointer events\n if( typeof TouchEvent === 'undefined' ){\n\n var pointers = [];\n\n var makeTouch = function( e ){\n return {\n clientX: e.clientX,\n clientY: e.clientY,\n force: 1,\n identifier: e.pointerId,\n pageX: e.pageX,\n pageY: e.pageY,\n radiusX: e.width/2,\n radiusY: e.height/2,\n screenX: e.screenX,\n screenY: e.screenY,\n target: e.target\n };\n };\n\n var makePointer = function( e ){\n return {\n event: e,\n touch: makeTouch(e)\n };\n };\n\n var addPointer = function( e ){\n pointers.push( makePointer(e) );\n };\n\n var removePointer = function( e ){\n for( var i = 0; i < pointers.length; i++ ){\n var p = pointers[i];\n\n if( p.event.pointerId === e.pointerId ){\n pointers.splice( i, 1 );\n return;\n }\n }\n };\n\n var updatePointer = function( e ){\n var p = pointers.filter(function( p ){\n return p.event.pointerId === e.pointerId;\n })[0];\n\n p.event = e;\n p.touch = makeTouch(e);\n };\n\n var addTouchesToEvent = function( e ){\n e.touches = pointers.map(function( p ){\n return p.touch;\n });\n };\n\n var pointerIsMouse = function( e ){\n return e.pointerType === 'mouse' || e.pointerType === 4;\n };\n\n r.registerBinding(r.container, 'pointerdown', function(e){\n if( pointerIsMouse(e) ){ return; } // mouse already handled\n\n e.preventDefault();\n\n addPointer( e );\n\n addTouchesToEvent( e );\n touchstartHandler( e );\n });\n\n r.registerBinding(r.container, 'pointerup', function(e){\n if( pointerIsMouse(e) ){ return; } // mouse already handled\n\n removePointer( e );\n\n addTouchesToEvent( e );\n touchendHandler( e );\n });\n\n r.registerBinding(r.container, 'pointercancel', function(e){\n if( pointerIsMouse(e) ){ return; } // mouse already handled\n\n removePointer( e );\n\n addTouchesToEvent( e );\n touchcancelHandler( e );\n });\n\n r.registerBinding(r.container, 'pointermove', function(e){\n if( pointerIsMouse(e) ){ return; } // mouse already handled\n\n e.preventDefault();\n\n updatePointer( e );\n\n addTouchesToEvent( e );\n touchmoveHandler( e );\n });\n\n }\n};\n\nmodule.exports = BRp;\n","'use strict';\n\nvar math = require('../../../math');\n\nvar BRp = {};\n\nBRp.registerNodeShapes = function(){\n var nodeShapes = this.nodeShapes = {};\n var renderer = this;\n\n nodeShapes['ellipse'] = {\n name: 'ellipse',\n\n draw: function( context, centerX, centerY, width, height ){\n renderer.nodeShapeImpl( this.name )( context, centerX, centerY, width, height );\n },\n\n intersectLine: function( nodeX, nodeY, width, height, x, y, padding ){\n return math.intersectLineEllipse(\n x, y,\n nodeX,\n nodeY,\n width / 2 + padding,\n height / 2 + padding)\n ;\n },\n\n checkPoint: function( x, y, padding, width, height, centerX, centerY ){\n x -= centerX;\n y -= centerY;\n\n x /= (width / 2 + padding);\n y /= (height / 2 + padding);\n\n return x*x + y*y <= 1;\n }\n };\n\n function generatePolygon( name, points ){\n return ( nodeShapes[name] = {\n name: name,\n\n points: points,\n\n draw: function( context, centerX, centerY, width, height ){\n renderer.nodeShapeImpl('polygon')( context, centerX, centerY, width, height, this.points );\n },\n\n intersectLine: function( nodeX, nodeY, width, height, x, y, padding ){\n return math.polygonIntersectLine(\n x, y,\n this.points,\n nodeX,\n nodeY,\n width / 2, height / 2,\n padding)\n ;\n },\n\n checkPoint: function( x, y, padding, width, height, centerX, centerY ){\n return math.pointInsidePolygon(x, y, nodeShapes[name].points,\n centerX, centerY, width, height, [0, -1], padding)\n ;\n }\n } );\n }\n\n generatePolygon( 'triangle', math.generateUnitNgonPointsFitToSquare(3, 0) );\n\n generatePolygon( 'square', math.generateUnitNgonPointsFitToSquare(4, 0) );\n nodeShapes['rectangle'] = nodeShapes['square'];\n\n nodeShapes['roundrectangle'] = {\n name: 'roundrectangle',\n\n points: math.generateUnitNgonPointsFitToSquare(4, 0),\n\n draw: function( context, centerX, centerY, width, height ){\n renderer.nodeShapeImpl( this.name )( context, centerX, centerY, width, height );\n },\n\n intersectLine: function( nodeX, nodeY, width, height, x, y, padding ){\n return math.roundRectangleIntersectLine(\n x, y,\n nodeX,\n nodeY,\n width, height,\n padding)\n ;\n },\n\n // Looks like the width passed into this function is actually the total width / 2\n checkPoint: function(\n x, y, padding, width, height, centerX, centerY ){\n\n var cornerRadius = math.getRoundRectangleRadius(width, height);\n\n // Check hBox\n if (math.pointInsidePolygon(x, y, this.points,\n centerX, centerY, width, height - 2 * cornerRadius, [0, -1], padding) ){\n return true;\n }\n\n // Check vBox\n if (math.pointInsidePolygon(x, y, this.points,\n centerX, centerY, width - 2 * cornerRadius, height, [0, -1], padding) ){\n return true;\n }\n\n var checkInEllipse = function( x, y, centerX, centerY, width, height, padding ){\n x -= centerX;\n y -= centerY;\n\n x /= (width / 2 + padding);\n y /= (height / 2 + padding);\n\n return (x*x + y*y <= 1);\n };\n\n\n // Check top left quarter circle\n if (checkInEllipse(x, y,\n centerX - width / 2 + cornerRadius,\n centerY - height / 2 + cornerRadius,\n cornerRadius * 2, cornerRadius * 2, padding) ){\n\n return true;\n }\n\n // Check top right quarter circle\n if (checkInEllipse(x, y,\n centerX + width / 2 - cornerRadius,\n centerY - height / 2 + cornerRadius,\n cornerRadius * 2, cornerRadius * 2, padding) ){\n\n return true;\n }\n\n // Check bottom right quarter circle\n if (checkInEllipse(x, y,\n centerX + width / 2 - cornerRadius,\n centerY + height / 2 - cornerRadius,\n cornerRadius * 2, cornerRadius * 2, padding) ){\n\n return true;\n }\n\n // Check bottom left quarter circle\n if (checkInEllipse(x, y,\n centerX - width / 2 + cornerRadius,\n centerY + height / 2 - cornerRadius,\n cornerRadius * 2, cornerRadius * 2, padding) ){\n\n return true;\n }\n\n return false;\n }\n };\n\n generatePolygon( 'diamond', [\n 0, 1,\n 1, 0,\n 0, -1,\n -1, 0\n ] );\n\n generatePolygon( 'pentagon', math.generateUnitNgonPointsFitToSquare(5, 0) );\n\n generatePolygon( 'hexagon', math.generateUnitNgonPointsFitToSquare(6, 0) );\n\n generatePolygon( 'heptagon', math.generateUnitNgonPointsFitToSquare(7, 0) );\n\n generatePolygon( 'octagon', math.generateUnitNgonPointsFitToSquare(8, 0) );\n\n var star5Points = new Array(20);\n {\n var outerPoints = math.generateUnitNgonPoints(5, 0);\n var innerPoints = math.generateUnitNgonPoints(5, Math.PI / 5);\n\n // Outer radius is 1; inner radius of star is smaller\n var innerRadius = 0.5 * (3 - Math.sqrt(5));\n innerRadius *= 1.57;\n\n for (var i=0;i redrawLimit ? minRedrawLimit : redrawLimit;\n redrawLimit = redrawLimit < maxRedrawLimit ? redrawLimit : maxRedrawLimit;\n\n if( r.lastDrawTime === undefined ){ r.lastDrawTime = 0; }\n\n var nowTime = Date.now();\n var timeElapsed = nowTime - r.lastDrawTime;\n var callAfterLimit = timeElapsed >= redrawLimit;\n\n if( !forcedContext ){\n if( !callAfterLimit || r.currentlyDrawing ){\n r.skipFrame = true;\n return;\n }\n }\n\n r.requestedFrame = true;\n r.currentlyDrawing = true;\n r.renderOptions = options;\n};\n\nBRp.startRenderLoop = function(){\n var r = this;\n\n var renderFn = function(){\n if( r.destroyed ){ return; }\n\n if( r.requestedFrame && !r.skipFrame ){\n var startTime = util.performanceNow();\n\n r.render( r.renderOptions );\n\n var endTime = r.lastRedrawTime = util.performanceNow();\n\n if( r.averageRedrawTime === undefined ){\n r.averageRedrawTime = endTime - startTime;\n }\n\n if( r.redrawCount === undefined ){\n r.redrawCount = 0;\n }\n\n r.redrawCount++;\n\n if( r.redrawTotalTime === undefined ){\n r.redrawTotalTime = 0;\n }\n\n var duration = endTime - startTime;\n\n r.redrawTotalTime += duration;\n r.lastRedrawTime = duration;\n\n // use a weighted average with a bias from the previous average so we don't spike so easily\n r.averageRedrawTime = r.averageRedrawTime/2 + duration/2;\n\n r.requestedFrame = false;\n }\n\n r.skipFrame = false;\n\n util.requestAnimationFrame( renderFn );\n };\n\n util.requestAnimationFrame( renderFn );\n\n};\n\nmodule.exports = BRp;\n","'use strict';\n\nvar CRp = {};\n\nvar impl;\n\nCRp.arrowShapeImpl = function( name ){\n return ( impl || (impl = {\n 'polygon': function( context, points ){\n for( var i = 0; i < points.length; i++ ){\n var pt = points[i];\n\n context.lineTo( pt.x, pt.y );\n }\n },\n\n 'triangle-backcurve': function( context, points, controlPoint ){\n var firstPt;\n\n for( var i = 0; i < points.length; i++ ){\n var pt = points[i];\n\n if( i === 0 ){\n firstPt = pt;\n }\n\n context.lineTo( pt.x, pt.y );\n }\n\n context.quadraticCurveTo( controlPoint.x, controlPoint.y, firstPt.x, firstPt.y );\n },\n\n 'triangle-tee': function( context, trianglePoints, teePoints ){\n var triPts = trianglePoints;\n for( var i = 0; i < triPts.length; i++ ){\n var pt = triPts[i];\n\n context.lineTo( pt.x, pt.y );\n }\n\n var teePts = teePoints;\n var firstTeePt = teePoints[0];\n context.moveTo( firstTeePt.x, firstTeePt.y );\n\n for( var i = 0; i < teePts.length; i++ ){\n var pt = teePts[i];\n\n context.lineTo( pt.x, pt.y );\n }\n },\n\n 'circle': function( context, rx, ry, r ){\n context.arc(rx, ry, r, 0, Math.PI * 2, false);\n }\n }) )[ name ];\n};\n\nmodule.exports = CRp;\n","'use strict';\n\nvar CRp = {};\n\nCRp.drawEdge = function(context, edge, drawOverlayInstead) {\n var rs = edge._private.rscratch;\n var usePaths = this.usePaths();\n\n // if bezier ctrl pts can not be calculated, then die\n if( rs.badBezier || rs.badLine || isNaN( rs.allpts[0] ) ){ // iNaN in case edge is impossible and browser bugs (e.g. safari)\n return;\n }\n\n var style = edge._private.style;\n\n // Edge line width\n if (style['width'].pfValue <= 0) {\n return;\n }\n\n var overlayPadding = style['overlay-padding'].pfValue;\n var overlayOpacity = style['overlay-opacity'].value;\n var overlayColor = style['overlay-color'].value;\n\n // Edge color & opacity\n if( drawOverlayInstead ){\n\n if( overlayOpacity === 0 ){ // exit early if no overlay\n return;\n }\n\n this.strokeStyle(context, overlayColor[0], overlayColor[1], overlayColor[2], overlayOpacity);\n context.lineCap = 'round';\n\n if( rs.edgeType == 'self' && !usePaths ){\n context.lineCap = 'butt';\n }\n\n } else {\n var lineColor = style['line-color'].value;\n\n this.strokeStyle(context, lineColor[0], lineColor[1], lineColor[2], style.opacity.value);\n\n context.lineCap = 'butt';\n }\n\n var edgeWidth = style['width'].pfValue + (drawOverlayInstead ? 2 * overlayPadding : 0);\n var lineStyle = drawOverlayInstead ? 'solid' : style['line-style'].value;\n context.lineWidth = edgeWidth;\n\n var shadowBlur = style['shadow-blur'].pfValue;\n var shadowOpacity = style['shadow-opacity'].value;\n var shadowColor = style['shadow-color'].value;\n var shadowOffsetX = style['shadow-offset-x'].pfValue;\n var shadowOffsetY = style['shadow-offset-y'].pfValue;\n\n this.shadowStyle(context, shadowColor, drawOverlayInstead ? 0 : shadowOpacity, shadowBlur, shadowOffsetX, shadowOffsetY);\n\n this.drawEdgePath(\n edge,\n context,\n rs.allpts,\n lineStyle,\n edgeWidth\n );\n\n this.drawArrowheads(context, edge, drawOverlayInstead);\n\n this.shadowStyle(context, 'transparent', 0); // reset for next guy\n\n};\n\n\nCRp.drawEdgePath = function(edge, context, pts, type, width) {\n var rs = edge._private.rscratch;\n var canvasCxt = context;\n var path;\n var pathCacheHit = false;\n var usePaths = this.usePaths();\n\n if( usePaths ){\n var pathCacheKey = pts.join('$');\n var keyMatches = rs.pathCacheKey && rs.pathCacheKey === pathCacheKey;\n\n if( keyMatches ){\n path = context = rs.pathCache;\n pathCacheHit = true;\n } else {\n path = context = new Path2D();\n rs.pathCacheKey = pathCacheKey;\n rs.pathCache = path;\n }\n }\n\n if( canvasCxt.setLineDash ){ // for very outofdate browsers\n switch( type ){\n case 'dotted':\n canvasCxt.setLineDash([ 1, 1 ]);\n break;\n\n case 'dashed':\n canvasCxt.setLineDash([ 6, 3 ]);\n break;\n\n case 'solid':\n canvasCxt.setLineDash([ ]);\n break;\n }\n }\n\n if( !pathCacheHit ){\n if( context.beginPath ){ context.beginPath(); }\n context.moveTo( pts[0], pts[1] );\n\n switch( rs.edgeType ){\n case 'bezier':\n case 'self':\n case 'compound':\n case 'multibezier':\n if( !rs.badBezier ){\n for( var i = 2; i + 3 < pts.length; i += 4 ){\n context.quadraticCurveTo( pts[i], pts[i+1], pts[i+2], pts[i+3] );\n }\n }\n break;\n\n case 'straight':\n case 'segments':\n case 'haystack':\n if( !rs.badLine ){\n for( var i = 2; i + 1 < pts.length; i += 2 ){\n context.lineTo( pts[i], pts[i+1] );\n }\n }\n break;\n }\n }\n\n context = canvasCxt;\n if( usePaths ){\n context.stroke( path );\n } else {\n context.stroke();\n }\n\n // reset any line dashes\n if( context.setLineDash ){ // for very outofdate browsers\n context.setLineDash([ ]);\n }\n\n};\n\nCRp.drawArrowheads = function(context, edge, drawOverlayInstead) {\n if( drawOverlayInstead ){ return; } // don't do anything for overlays\n\n var rs = edge._private.rscratch;\n var isHaystack = rs.edgeType === 'haystack';\n\n if( !isHaystack ){\n this.drawArrowhead( context, edge, 'source', rs.arrowStartX, rs.arrowStartY, rs.srcArrowAngle );\n }\n\n this.drawArrowhead( context, edge, 'mid-target', rs.midX, rs.midY, rs.midtgtArrowAngle );\n\n this.drawArrowhead( context, edge, 'mid-source', rs.midX, rs.midY, rs.midsrcArrowAngle );\n\n if( !isHaystack ){\n this.drawArrowhead( context, edge, 'target', rs.arrowEndX, rs.arrowEndY, rs.tgtArrowAngle );\n }\n};\n\nCRp.drawArrowhead = function( context, edge, prefix, x, y, angle ){\n if( isNaN(x) || x == null || isNaN(y) || y == null || isNaN(angle) || angle == null ){ return; }\n\n var self = this;\n var style = edge._private.style;\n var arrowShape = style[prefix + '-arrow-shape'].value;\n\n if( arrowShape === 'none' ){\n return;\n }\n\n var gco = context.globalCompositeOperation;\n\n var arrowClearFill = style[prefix + '-arrow-fill'].value === 'hollow' ? 'both' : 'filled';\n var arrowFill = style[prefix + '-arrow-fill'].value;\n\n if( arrowShape === 'half-triangle-overshot' ){\n arrowFill = 'hollow';\n arrowClearFill = 'hollow';\n }\n\n if( style.opacity.value !== 1 || arrowFill === 'hollow' ){ // then extra clear is needed\n context.globalCompositeOperation = 'destination-out';\n\n self.fillStyle(context, 255, 255, 255, 1);\n self.strokeStyle(context, 255, 255, 255, 1);\n\n self.drawArrowShape( edge, prefix, context,\n arrowClearFill, style['width'].pfValue, style[prefix + '-arrow-shape'].value,\n x, y, angle\n );\n\n context.globalCompositeOperation = gco;\n } // otherwise, the opaque arrow clears it for free :)\n\n var color = style[prefix + '-arrow-color'].value;\n self.fillStyle(context, color[0], color[1], color[2], style.opacity.value);\n self.strokeStyle(context, color[0], color[1], color[2], style.opacity.value);\n\n self.drawArrowShape( edge, prefix, context,\n arrowFill, style['width'].pfValue, style[prefix + '-arrow-shape'].value,\n x, y, angle\n );\n};\n\nCRp.drawArrowShape = function(edge, arrowType, context, fill, edgeWidth, shape, x, y, angle) {\n var r = this;\n var usePaths = this.usePaths();\n var rs = edge._private.rscratch;\n var pathCacheHit = false;\n var path;\n var canvasContext = context;\n var translation = { x: x, y: y };\n var size = this.getArrowWidth( edgeWidth );\n var shapeImpl = r.arrowShapes[shape];\n\n if( usePaths ){\n var pathCacheKey = size + '$' + shape + '$' + angle + '$' + x + '$' + y;\n rs.arrowPathCacheKey = rs.arrowPathCacheKey || {};\n rs.arrowPathCache = rs.arrowPathCache || {};\n\n var alreadyCached = rs.arrowPathCacheKey[arrowType] === pathCacheKey;\n if( alreadyCached ){\n path = context = rs.arrowPathCache[arrowType];\n pathCacheHit = true;\n } else {\n path = context = new Path2D();\n rs.arrowPathCacheKey[arrowType] = pathCacheKey;\n rs.arrowPathCache[arrowType] = path;\n }\n }\n\n if( context.beginPath ){ context.beginPath(); }\n\n if( !pathCacheHit ){\n shapeImpl.draw(context, size, angle, translation);\n }\n\n if( !shapeImpl.leavePathOpen && context.closePath ){\n context.closePath();\n }\n\n context = canvasContext;\n\n if( fill === 'filled' || fill === 'both' ){\n if( usePaths ){\n context.fill( path );\n } else {\n context.fill();\n }\n }\n\n if( fill === 'hollow' || fill === 'both' ){\n context.lineWidth = ( shapeImpl.matchEdgeWidth ? edgeWidth : 1 );\n context.lineJoin = 'miter';\n\n if( usePaths ){\n context.stroke( path );\n } else {\n context.stroke();\n }\n\n }\n};\n\nmodule.exports = CRp;\n","'use strict';\n\nvar CRp = {};\n\nCRp.safeDrawImage = function( context, img, ix, iy, iw, ih, x, y, w, h ){\n var r = this;\n\n try {\n context.drawImage( img, ix, iy, iw, ih, x, y, w, h );\n } catch(e){\n r.data.canvasNeedsRedraw[r.NODE] = true;\n r.data.canvasNeedsRedraw[r.DRAG] = true;\n\n r.drawingImage = true;\n\n r.redraw();\n }\n};\n\nCRp.drawInscribedImage = function(context, img, node) {\n var r = this;\n var nodeX = node._private.position.x;\n var nodeY = node._private.position.y;\n var style = node._private.style;\n var fit = style['background-fit'].value;\n var xPos = style['background-position-x'];\n var yPos = style['background-position-y'];\n var repeat = style['background-repeat'].value;\n var nodeW = node.width();\n var nodeH = node.height();\n var rs = node._private.rscratch;\n var clip = style['background-clip'].value;\n var shouldClip = clip === 'node';\n var imgOpacity = style['background-image-opacity'].value;\n\n var imgW = img.width || img.cachedW;\n var imgH = img.height || img.cachedH;\n\n // workaround for broken browsers like ie\n if( null == imgW || null == imgH ){\n document.body.appendChild( img );\n\n imgW = img.cachedW = img.width || img.offsetWidth;\n imgH = img.cachedH = img.height || img.offsetHeight;\n\n document.body.removeChild( img );\n }\n\n var w = imgW;\n var h = imgH;\n\n var bgW = style['background-width'];\n if( bgW.value !== 'auto' ){\n if( bgW.units === '%' ){\n w = bgW.value/100 * nodeW;\n } else {\n w = bgW.pfValue;\n }\n }\n\n var bgH = style['background-height'];\n if( bgH.value !== 'auto' ){\n if( bgH.units === '%' ){\n h = bgH.value/100 * nodeH;\n } else {\n h = bgH.pfValue;\n }\n }\n\n if( w === 0 || h === 0 ){\n return; // no point in drawing empty image (and chrome is broken in this case)\n }\n\n if( fit === 'contain' ){\n var scale = Math.min( nodeW/w, nodeH/h );\n\n w *= scale;\n h *= scale;\n\n } else if( fit === 'cover' ){\n var scale = Math.max( nodeW/w, nodeH/h );\n\n w *= scale;\n h *= scale;\n }\n\n var x = (nodeX - nodeW/2); // left\n if( xPos.units === '%' ){\n x += (nodeW - w) * xPos.value/100;\n } else {\n x += xPos.pfValue;\n }\n\n var y = (nodeY - nodeH/2); // top\n if( yPos.units === '%' ){\n y += (nodeH - h) * yPos.value/100;\n } else {\n y += yPos.pfValue;\n }\n\n if( rs.pathCache ){\n x -= nodeX;\n y -= nodeY;\n\n nodeX = 0;\n nodeY = 0;\n }\n\n var gAlpha = context.globalAlpha;\n\n context.globalAlpha = imgOpacity;\n\n if( repeat === 'no-repeat' ){\n\n if( shouldClip ){\n context.save();\n\n if( rs.pathCache ){\n context.clip( rs.pathCache );\n } else {\n r.nodeShapes[r.getNodeShape(node)].draw(\n context,\n nodeX, nodeY,\n nodeW, nodeH);\n\n context.clip();\n }\n }\n\n r.safeDrawImage( context, img, 0, 0, imgW, imgH, x, y, w, h );\n\n if( shouldClip ){\n context.restore();\n }\n } else {\n var pattern = context.createPattern( img, repeat );\n context.fillStyle = pattern;\n\n r.nodeShapes[r.getNodeShape(node)].draw(\n context,\n nodeX, nodeY,\n nodeW, nodeH);\n\n context.translate(x, y);\n context.fill();\n context.translate(-x, -y);\n }\n\n context.globalAlpha = gAlpha;\n\n};\n\nmodule.exports = CRp;\n","'use strict';\n\nvar is = require('../../../is');\n\nvar CRp = {};\n\n// Draw edge text\nCRp.drawEdgeText = function(context, edge) {\n var text = edge._private.style['label'].strValue;\n\n if( !text || text.match(/^\\s+$/) ){\n return;\n }\n\n if( this.hideEdgesOnViewport && (this.dragData.didDrag || this.pinching || this.hoverData.dragging || this.data.wheel || this.swipePanning) ){ return; } // save cycles on pinching\n\n var computedSize = edge._private.style['font-size'].pfValue * edge.cy().zoom();\n var minSize = edge._private.style['min-zoomed-font-size'].pfValue;\n\n if( computedSize < minSize ){\n return;\n }\n\n // Calculate text draw position\n\n context.textAlign = 'center';\n context.textBaseline = 'middle';\n\n var rs = edge._private.rscratch;\n if( !is.number( rs.labelX ) || !is.number( rs.labelY ) ){ return; } // no pos => label can't be rendered\n\n var style = edge._private.style;\n var autorotate = style['edge-text-rotation'].strValue === 'autorotate';\n var theta;\n\n if( autorotate ){\n theta = rs.labelAngle;\n\n context.translate(rs.labelX, rs.labelY);\n context.rotate(theta);\n\n this.drawText(context, edge, 0, 0);\n\n context.rotate(-theta);\n context.translate(-rs.labelX, -rs.labelY);\n } else {\n this.drawText(context, edge, rs.labelX, rs.labelY);\n }\n\n};\n\n// Draw node text\nCRp.drawNodeText = function(context, node) {\n var text = node._private.style['label'].strValue;\n\n if ( !text || text.match(/^\\s+$/) ) {\n return;\n }\n\n var computedSize = node._private.style['font-size'].pfValue * node.cy().zoom();\n var minSize = node._private.style['min-zoomed-font-size'].pfValue;\n\n if( computedSize < minSize ){\n return;\n }\n\n // this.recalculateNodeLabelProjection( node );\n\n var textHalign = node._private.style['text-halign'].strValue;\n var textValign = node._private.style['text-valign'].strValue;\n var rs = node._private.rscratch;\n if( !is.number( rs.labelX ) || !is.number( rs.labelY ) ){ return; } // no pos => label can't be rendered\n\n switch( textHalign ){\n case 'left':\n context.textAlign = 'right';\n break;\n\n case 'right':\n context.textAlign = 'left';\n break;\n\n default: // e.g. center\n context.textAlign = 'center';\n }\n\n switch( textValign ){\n case 'top':\n context.textBaseline = 'bottom';\n break;\n\n case 'bottom':\n context.textBaseline = 'top';\n break;\n\n default: // e.g. center\n context.textBaseline = 'middle';\n }\n\n this.drawText(context, node, rs.labelX, rs.labelY);\n};\n\nCRp.getFontCache = function(context){\n var cache;\n\n this.fontCaches = this.fontCaches || [];\n\n for( var i = 0; i < this.fontCaches.length; i++ ){\n cache = this.fontCaches[i];\n\n if( cache.context === context ){\n return cache;\n }\n }\n\n cache = {\n context: context\n };\n this.fontCaches.push(cache);\n\n return cache;\n};\n\n// set up canvas context with font\n// returns transformed text string\nCRp.setupTextStyle = function( context, element ){\n // Font style\n var parentOpacity = element.effectiveOpacity();\n var style = element._private.style;\n var labelStyle = style['font-style'].strValue;\n var labelSize = style['font-size'].pfValue + 'px';\n var labelFamily = style['font-family'].strValue;\n var labelWeight = style['font-weight'].strValue;\n var opacity = style['text-opacity'].value * style['opacity'].value * parentOpacity;\n var outlineOpacity = style['text-outline-opacity'].value * opacity;\n var color = style['color'].value;\n var outlineColor = style['text-outline-color'].value;\n var shadowBlur = style['text-shadow-blur'].pfValue;\n var shadowOpacity = style['text-shadow-opacity'].value;\n var shadowColor = style['text-shadow-color'].value;\n var shadowOffsetX = style['text-shadow-offset-x'].pfValue;\n var shadowOffsetY = style['text-shadow-offset-y'].pfValue;\n\n var fontCacheKey = element._private.fontKey;\n var cache = this.getFontCache(context);\n\n if( cache.key !== fontCacheKey ){\n context.font = labelStyle + ' ' + labelWeight + ' ' + labelSize + ' ' + labelFamily;\n\n cache.key = fontCacheKey;\n }\n\n var text = this.getLabelText( element );\n\n // Calculate text draw position based on text alignment\n\n // so text outlines aren't jagged\n context.lineJoin = 'round';\n\n this.fillStyle(context, color[0], color[1], color[2], opacity);\n\n this.strokeStyle(context, outlineColor[0], outlineColor[1], outlineColor[2], outlineOpacity);\n\n this.shadowStyle(context, shadowColor, shadowOpacity, shadowBlur, shadowOffsetX, shadowOffsetY);\n\n return text;\n};\n\nfunction roundRect(ctx, x, y, width, height, radius) {\n var radius = radius || 5;\n ctx.beginPath();\n ctx.moveTo(x + radius, y);\n ctx.lineTo(x + width - radius, y);\n ctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n ctx.lineTo(x + width, y + height - radius);\n ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n ctx.lineTo(x + radius, y + height);\n ctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n ctx.lineTo(x, y + radius);\n ctx.quadraticCurveTo(x, y, x + radius, y);\n ctx.closePath();\n ctx.fill();\n}\n\n// Draw text\nCRp.drawText = function(context, element, textX, textY) {\n var _p = element._private;\n var style = _p.style;\n var rstyle = _p.rstyle;\n var rscratch = _p.rscratch;\n var parentOpacity = element.effectiveOpacity();\n if( parentOpacity === 0 || style['text-opacity'].value === 0){ return; }\n\n var text = this.setupTextStyle( context, element );\n var halign = style['text-halign'].value;\n var valign = style['text-valign'].value;\n\n if( element.isEdge() ){\n halign = 'center';\n valign = 'center';\n }\n\n if( element.isNode() ){\n var pLeft = style['padding-left'].pfValue;\n var pRight = style['padding-right'].pfValue;\n var pTop = style['padding-top'].pfValue;\n var pBottom = style['padding-bottom'].pfValue;\n\n textX += pLeft/2;\n textX -= pRight/2;\n\n textY += pTop/2;\n textY -= pBottom/2;\n }\n\n if ( text != null && !isNaN(textX) && !isNaN(textY)) {\n var backgroundOpacity = style['text-background-opacity'].value;\n var borderOpacity = style['text-border-opacity'].value;\n var textBorderWidth = style['text-border-width'].pfValue;\n\n if( backgroundOpacity > 0 || (textBorderWidth > 0 && borderOpacity > 0) ){\n var margin = 4 + textBorderWidth/2;\n\n if (element.isNode()) {\n //Move textX, textY to include the background margins\n if (valign === 'top') {\n textY -= margin;\n } else if (valign === 'bottom') {\n textY += margin;\n }\n if (halign === 'left') {\n textX -= margin;\n } else if (halign === 'right') {\n textX += margin;\n }\n }\n\n var bgWidth = rstyle.labelWidth;\n var bgHeight = rstyle.labelHeight;\n var bgX = textX;\n\n if (halign) {\n if (halign == 'center') {\n bgX = bgX - bgWidth / 2;\n } else if (halign == 'left') {\n bgX = bgX- bgWidth;\n }\n }\n\n var bgY = textY;\n\n if (element.isNode()) {\n if (valign == 'top') {\n bgY = bgY - bgHeight;\n } else if (valign == 'center') {\n bgY = bgY- bgHeight / 2;\n }\n } else {\n bgY = bgY - bgHeight / 2;\n }\n\n if (style['edge-text-rotation'].strValue === 'autorotate') {\n textY = 0;\n bgWidth += 4;\n bgX = textX - bgWidth / 2;\n bgY = textY - bgHeight / 2;\n } else {\n // Adjust with border width & margin\n bgX -= margin;\n bgY -= margin;\n bgHeight += margin*2;\n bgWidth += margin*2;\n }\n\n if( backgroundOpacity > 0 ){\n var textFill = context.fillStyle;\n var textBackgroundColor = style['text-background-color'].value;\n\n context.fillStyle = 'rgba(' + textBackgroundColor[0] + ',' + textBackgroundColor[1] + ',' + textBackgroundColor[2] + ',' + backgroundOpacity * parentOpacity + ')';\n var styleShape = style['text-background-shape'].strValue;\n if (styleShape == 'roundrectangle') {\n roundRect(context, bgX, bgY, bgWidth, bgHeight, 2);\n } else {\n context.fillRect(bgX,bgY,bgWidth,bgHeight);\n }\n context.fillStyle = textFill;\n }\n\n if( textBorderWidth > 0 && borderOpacity > 0 ){\n var textStroke = context.strokeStyle;\n var textLineWidth = context.lineWidth;\n var textBorderColor = style['text-border-color'].value;\n var textBorderStyle = style['text-border-style'].value;\n\n context.strokeStyle = 'rgba(' + textBorderColor[0] + ',' + textBorderColor[1] + ',' + textBorderColor[2] + ',' + borderOpacity * parentOpacity + ')';\n context.lineWidth = textBorderWidth;\n\n if( context.setLineDash ){ // for very outofdate browsers\n switch( textBorderStyle ){\n case 'dotted':\n context.setLineDash([ 1, 1 ]);\n break;\n case 'dashed':\n context.setLineDash([ 4, 2 ]);\n break;\n case 'double':\n context.lineWidth = textBorderWidth/4; // 50% reserved for white between the two borders\n context.setLineDash([ ]);\n break;\n case 'solid':\n context.setLineDash([ ]);\n break;\n }\n }\n\n context.strokeRect(bgX,bgY,bgWidth,bgHeight);\n\n if( textBorderStyle === 'double' ){\n var whiteWidth = textBorderWidth/2;\n\n context.strokeRect(bgX+whiteWidth,bgY+whiteWidth,bgWidth-whiteWidth*2,bgHeight-whiteWidth*2);\n }\n\n if( context.setLineDash ){ // for very outofdate browsers\n context.setLineDash([ ]);\n }\n context.lineWidth = textLineWidth;\n context.strokeStyle = textStroke;\n }\n\n }\n\n var lineWidth = 2 * style['text-outline-width'].pfValue; // *2 b/c the stroke is drawn centred on the middle\n\n if( lineWidth > 0 ){\n context.lineWidth = lineWidth;\n }\n\n if( style['text-wrap'].value === 'wrap' ){\n var lines = rscratch.labelWrapCachedLines;\n var lineHeight = rstyle.labelHeight / lines.length;\n\n switch( valign ){\n case 'top':\n textY -= (lines.length - 1) * lineHeight;\n break;\n\n case 'bottom':\n // nothing required\n break;\n\n default:\n case 'center':\n textY -= (lines.length - 1) * lineHeight / 2;\n }\n\n for( var l = 0; l < lines.length; l++ ){\n if( lineWidth > 0 ){\n context.strokeText( lines[l], textX, textY );\n }\n\n context.fillText( lines[l], textX, textY );\n\n textY += lineHeight;\n }\n\n } else {\n if( lineWidth > 0 ){\n context.strokeText( text, textX, textY );\n }\n\n context.fillText( text, textX, textY );\n }\n\n\n this.shadowStyle(context, 'transparent', 0); // reset for next guy\n }\n};\n\n\nmodule.exports = CRp;\n","'use strict';\n\nvar is = require('../../../is');\n\nvar CRp = {};\n\n// Draw node\nCRp.drawNode = function(context, node, drawOverlayInstead) {\n\n var r = this;\n var nodeWidth, nodeHeight;\n var style = node._private.style;\n var rs = node._private.rscratch;\n var _p = node._private;\n var pos = _p.position;\n\n if( !is.number(pos.x) || !is.number(pos.y) ){\n return; // can't draw node with undefined position\n }\n\n var usePaths = this.usePaths();\n var canvasContext = context;\n var path;\n var pathCacheHit = false;\n\n var overlayPadding = style['overlay-padding'].pfValue;\n var overlayOpacity = style['overlay-opacity'].value;\n var overlayColor = style['overlay-color'].value;\n\n if( drawOverlayInstead && overlayOpacity === 0 ){ // exit early if drawing overlay but none to draw\n return;\n }\n\n var parentOpacity = node.effectiveOpacity();\n if( parentOpacity === 0 ){ return; }\n\n nodeWidth = node.width() + style['padding-left'].pfValue + style['padding-right'].pfValue;\n nodeHeight = node.height() + style['padding-top'].pfValue + style['padding-bottom'].pfValue;\n\n context.lineWidth = style['border-width'].pfValue;\n\n if( drawOverlayInstead === undefined || !drawOverlayInstead ){\n\n var url = style['background-image'].value[2] ||\n style['background-image'].value[1];\n var image;\n\n if (url !== undefined) {\n\n // get image, and if not loaded then ask to redraw when later loaded\n image = this.getCachedImage(url, function(){\n r.data.canvasNeedsRedraw[r.NODE] = true;\n r.data.canvasNeedsRedraw[r.DRAG] = true;\n\n r.drawingImage = true;\n\n r.redraw();\n });\n\n var prevBging = _p.backgrounding;\n _p.backgrounding = !image.complete;\n\n if( prevBging !== _p.backgrounding ){ // update style b/c :backgrounding state changed\n node.updateStyle( false );\n }\n }\n\n // Node color & opacity\n\n var bgColor = style['background-color'].value;\n var borderColor = style['border-color'].value;\n var borderStyle = style['border-style'].value;\n\n this.fillStyle(context, bgColor[0], bgColor[1], bgColor[2], style['background-opacity'].value * parentOpacity);\n\n this.strokeStyle(context, borderColor[0], borderColor[1], borderColor[2], style['border-opacity'].value * parentOpacity);\n\n var shadowBlur = style['shadow-blur'].pfValue;\n var shadowOpacity = style['shadow-opacity'].value;\n var shadowColor = style['shadow-color'].value;\n var shadowOffsetX = style['shadow-offset-x'].pfValue;\n var shadowOffsetY = style['shadow-offset-y'].pfValue;\n\n this.shadowStyle(context, shadowColor, shadowOpacity, shadowBlur, shadowOffsetX, shadowOffsetY);\n\n context.lineJoin = 'miter'; // so borders are square with the node shape\n\n if( context.setLineDash ){ // for very outofdate browsers\n switch( borderStyle ){\n case 'dotted':\n context.setLineDash([ 1, 1 ]);\n break;\n\n case 'dashed':\n context.setLineDash([ 4, 2 ]);\n break;\n\n case 'solid':\n case 'double':\n context.setLineDash([ ]);\n break;\n }\n }\n\n\n var styleShape = style['shape'].strValue;\n\n if( usePaths ){\n var pathCacheKey = styleShape + '$' + nodeWidth +'$' + nodeHeight;\n\n context.translate( pos.x, pos.y );\n\n if( rs.pathCacheKey === pathCacheKey ){\n path = context = rs.pathCache;\n pathCacheHit = true;\n } else {\n path = context = new Path2D();\n rs.pathCacheKey = pathCacheKey;\n rs.pathCache = path;\n }\n }\n\n if( !pathCacheHit ){\n\n var npos = pos;\n\n if( usePaths ){\n npos = {\n x: 0,\n y: 0\n };\n }\n\n r.nodeShapes[this.getNodeShape(node)].draw(\n context,\n npos.x,\n npos.y,\n nodeWidth,\n nodeHeight);\n }\n\n context = canvasContext;\n\n if( usePaths ){\n context.fill( path );\n } else {\n context.fill();\n }\n\n this.shadowStyle(context, 'transparent', 0); // reset for next guy\n\n if (url !== undefined) {\n if( image.complete ){\n this.drawInscribedImage(context, image, node);\n }\n }\n\n var darkness = style['background-blacken'].value;\n var borderWidth = style['border-width'].pfValue;\n\n if( this.hasPie(node) ){\n this.drawPie( context, node, parentOpacity );\n\n // redraw path for blacken and border\n if( darkness !== 0 || borderWidth !== 0 ){\n\n if( !usePaths ){\n r.nodeShapes[this.getNodeShape(node)].draw(\n context,\n pos.x,\n pos.y,\n nodeWidth,\n nodeHeight);\n }\n }\n }\n\n if( darkness > 0 ){\n this.fillStyle(context, 0, 0, 0, darkness);\n\n if( usePaths ){\n context.fill( path );\n } else {\n context.fill();\n }\n\n } else if( darkness < 0 ){\n this.fillStyle(context, 255, 255, 255, -darkness);\n\n if( usePaths ){\n context.fill( path );\n } else {\n context.fill();\n }\n }\n\n // Border width, draw border\n if (borderWidth > 0) {\n\n if( usePaths ){\n context.stroke( path );\n } else {\n context.stroke();\n }\n\n if( borderStyle === 'double' ){\n context.lineWidth = style['border-width'].pfValue/3;\n\n var gco = context.globalCompositeOperation;\n context.globalCompositeOperation = 'destination-out';\n\n if( usePaths ){\n context.stroke( path );\n } else {\n context.stroke();\n }\n\n context.globalCompositeOperation = gco;\n }\n\n }\n\n if( usePaths ){\n context.translate( -pos.x, -pos.y );\n }\n\n // reset in case we changed the border style\n if( context.setLineDash ){ // for very outofdate browsers\n context.setLineDash([ ]);\n }\n\n // draw the overlay\n } else {\n\n if( overlayOpacity > 0 ){\n this.fillStyle(context, overlayColor[0], overlayColor[1], overlayColor[2], overlayOpacity);\n\n r.nodeShapes['roundrectangle'].draw(\n context,\n node._private.position.x,\n node._private.position.y,\n nodeWidth + overlayPadding * 2,\n nodeHeight + overlayPadding * 2\n );\n\n context.fill();\n }\n }\n\n};\n\n// does the node have at least one pie piece?\nCRp.hasPie = function(node){\n node = node[0]; // ensure ele ref\n\n return node._private.hasPie;\n};\n\nCRp.drawPie = function( context, node, nodeOpacity ){\n node = node[0]; // ensure ele ref\n\n var _p = node._private;\n var cyStyle = node.cy().style();\n var style = _p.style;\n var pieSize = style['pie-size'];\n var nodeW = node.width();\n var nodeH = node.height();\n var x = _p.position.x;\n var y = _p.position.y;\n var radius = Math.min( nodeW, nodeH ) / 2; // must fit in node\n var lastPercent = 0; // what % to continue drawing pie slices from on [0, 1]\n var usePaths = this.usePaths();\n\n if( usePaths ){\n x = 0;\n y = 0;\n }\n\n if( pieSize.units === '%' ){\n radius = radius * pieSize.value / 100;\n } else if( pieSize.pfValue !== undefined ){\n radius = pieSize.pfValue / 2;\n }\n\n for( var i = 1; i <= cyStyle.pieBackgroundN; i++ ){ // 1..N\n var size = style['pie-' + i + '-background-size'].value;\n var color = style['pie-' + i + '-background-color'].value;\n var opacity = style['pie-' + i + '-background-opacity'].value * nodeOpacity;\n var percent = size / 100; // map integer range [0, 100] to [0, 1]\n\n // percent can't push beyond 1\n if( percent + lastPercent > 1 ){\n percent = 1 - lastPercent;\n }\n\n var angleStart = 1.5 * Math.PI + 2 * Math.PI * lastPercent; // start at 12 o'clock and go clockwise\n var angleDelta = 2 * Math.PI * percent;\n var angleEnd = angleStart + angleDelta;\n\n // ignore if\n // - zero size\n // - we're already beyond the full circle\n // - adding the current slice would go beyond the full circle\n if( size === 0 || lastPercent >= 1 || lastPercent + percent > 1 ){\n continue;\n }\n\n context.beginPath();\n context.moveTo(x, y);\n context.arc( x, y, radius, angleStart, angleEnd );\n context.closePath();\n\n this.fillStyle(context, color[0], color[1], color[2], opacity);\n\n context.fill();\n\n lastPercent += percent;\n }\n\n};\n\n\nmodule.exports = CRp;\n","'use strict';\n\nvar CRp = {};\n\nvar util = require('../../../util');\nvar math = require('../../../math');\n\nvar motionBlurDelay = 100;\n\n// var isFirefox = typeof InstallTrigger !== 'undefined';\n\nCRp.getPixelRatio = function(){\n var context = this.data.contexts[0];\n\n if( this.forcedPixelRatio != null ){\n return this.forcedPixelRatio;\n }\n\n var backingStore = context.backingStorePixelRatio ||\n context.webkitBackingStorePixelRatio ||\n context.mozBackingStorePixelRatio ||\n context.msBackingStorePixelRatio ||\n context.oBackingStorePixelRatio ||\n context.backingStorePixelRatio || 1;\n\n return (window.devicePixelRatio || 1) / backingStore;\n};\n\nCRp.paintCache = function(context){\n var caches = this.paintCaches = this.paintCaches || [];\n var needToCreateCache = true;\n var cache;\n\n for(var i = 0; i < caches.length; i++ ){\n cache = caches[i];\n\n if( cache.context === context ){\n needToCreateCache = false;\n break;\n }\n }\n\n if( needToCreateCache ){\n cache = {\n context: context\n };\n caches.push( cache );\n }\n\n return cache;\n};\n\nCRp.fillStyle = function(context, r, g, b, a){\n context.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n\n // turn off for now, seems context does its own caching\n\n // var cache = this.paintCache(context);\n\n // var fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n\n // if( cache.fillStyle !== fillStyle ){\n // context.fillStyle = cache.fillStyle = fillStyle;\n // }\n};\n\nCRp.strokeStyle = function(context, r, g, b, a){\n context.strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n\n // turn off for now, seems context does its own caching\n\n // var cache = this.paintCache(context);\n\n // var strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n\n // if( cache.strokeStyle !== strokeStyle ){\n // context.strokeStyle = cache.strokeStyle = strokeStyle;\n // }\n};\n\nCRp.shadowStyle = function(context, color, opacity, blur, offsetX, offsetY){\n var zoom = this.cy.zoom();\n\n var cache = this.paintCache(context);\n\n // don't make expensive changes to the shadow style if it's not used\n if( cache.shadowOpacity === 0 && opacity === 0 ){\n return;\n }\n\n cache.shadowOpacity = opacity;\n\n if (opacity > 0) {\n context.shadowBlur = blur * zoom;\n context.shadowColor = \"rgba(\" + color[0] + \",\" + color[1] + \",\" + color[2] + \",\" + opacity + \")\";\n context.shadowOffsetX = offsetX * zoom;\n context.shadowOffsetY = offsetY * zoom;\n } else {\n context.shadowBlur = 0;\n context.shadowColor = \"transparent\";\n }\n};\n\n// Resize canvas\nCRp.matchCanvasSize = function(container) {\n var r = this;\n var data = r.data;\n var width = container.clientWidth;\n var height = container.clientHeight;\n var pixelRatio = r.getPixelRatio();\n var mbPxRatio = r.motionBlurPxRatio;\n\n if(\n container === r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_NODE] ||\n container === r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_DRAG]\n ){\n pixelRatio = mbPxRatio;\n }\n\n var canvasWidth = width * pixelRatio;\n var canvasHeight = height * pixelRatio;\n var canvas;\n\n if( canvasWidth === r.canvasWidth && canvasHeight === r.canvasHeight ){\n return; // save cycles if same\n }\n\n r.fontCaches = null; // resizing resets the style\n\n var canvasContainer = data.canvasContainer;\n canvasContainer.style.width = width + 'px';\n canvasContainer.style.height = height + 'px';\n\n for (var i = 0; i < r.CANVAS_LAYERS; i++) {\n\n canvas = data.canvases[i];\n\n if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) {\n\n canvas.width = canvasWidth;\n canvas.height = canvasHeight;\n\n canvas.style.width = width + 'px';\n canvas.style.height = height + 'px';\n }\n }\n\n for (var i = 0; i < r.BUFFER_COUNT; i++) {\n\n canvas = data.bufferCanvases[i];\n\n if (canvas.width !== canvasWidth || canvas.height !== canvasHeight) {\n\n canvas.width = canvasWidth;\n canvas.height = canvasHeight;\n\n canvas.style.width = width + 'px';\n canvas.style.height = height + 'px';\n }\n }\n\n r.textureMult = 1;\n if( pixelRatio <= 1 ){\n canvas = data.bufferCanvases[ r.TEXTURE_BUFFER ];\n\n r.textureMult = 2;\n canvas.width = canvasWidth * r.textureMult;\n canvas.height = canvasHeight * r.textureMult;\n }\n\n r.canvasWidth = canvasWidth;\n r.canvasHeight = canvasHeight;\n\n};\n\nCRp.renderTo = function( cxt, zoom, pan, pxRatio ){\n this.render({\n forcedContext: cxt,\n forcedZoom: zoom,\n forcedPan: pan,\n drawAllLayers: true,\n forcedPxRatio: pxRatio\n });\n};\n\nCRp.render = function( options ) {\n options = options || util.staticEmptyObject();\n\n var forcedContext = options.forcedContext;\n var drawAllLayers = options.drawAllLayers;\n var drawOnlyNodeLayer = options.drawOnlyNodeLayer;\n var forcedZoom = options.forcedZoom;\n var forcedPan = options.forcedPan;\n var r = this;\n var pixelRatio = options.forcedPxRatio === undefined ? this.getPixelRatio() : options.forcedPxRatio;\n var cy = r.cy; var data = r.data;\n var needDraw = data.canvasNeedsRedraw;\n var textureDraw = r.textureOnViewport && !forcedContext && (r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming);\n var motionBlur = options.motionBlur !== undefined ? options.motionBlur : r.motionBlur;\n var mbPxRatio = r.motionBlurPxRatio;\n var hasCompoundNodes = cy.hasCompoundNodes();\n var inNodeDragGesture = r.hoverData.draggingEles;\n var inBoxSelection = r.hoverData.selecting || r.touchData.selecting ? true : false;\n motionBlur = motionBlur && !forcedContext && r.motionBlurEnabled && !inBoxSelection;\n var motionBlurFadeEffect = motionBlur;\n\n if( !forcedContext && r.motionBlurTimeout ){\n clearTimeout( r.motionBlurTimeout );\n }\n\n if( motionBlur ){\n if( r.mbFrames == null ){\n r.mbFrames = 0;\n }\n\n if( !r.drawingImage ){ // image loading frames don't count towards motion blur blurry frames\n r.mbFrames++;\n }\n\n if( r.mbFrames < 3 ){ // need several frames before even high quality motionblur\n motionBlurFadeEffect = false;\n }\n\n // go to lower quality blurry frames when several m/b frames have been rendered (avoids flashing)\n if( r.mbFrames > r.minMbLowQualFrames ){\n //r.fullQualityMb = false;\n r.motionBlurPxRatio = r.mbPxRBlurry;\n }\n }\n\n if( r.clearingMotionBlur ){\n r.motionBlurPxRatio = 1;\n }\n\n // b/c drawToContext() may be async w.r.t. redraw(), keep track of last texture frame\n // because a rogue async texture frame would clear needDraw\n if( r.textureDrawLastFrame && !textureDraw ){\n needDraw[r.NODE] = true;\n needDraw[r.SELECT_BOX] = true;\n }\n\n var edges = r.getCachedEdges();\n var coreStyle = cy.style()._private.coreStyle;\n\n var zoom = cy.zoom();\n var effectiveZoom = forcedZoom !== undefined ? forcedZoom : zoom;\n var pan = cy.pan();\n var effectivePan = {\n x: pan.x,\n y: pan.y\n };\n\n var vp = {\n zoom: zoom,\n pan: {\n x: pan.x,\n y: pan.y\n }\n };\n var prevVp = r.prevViewport;\n var viewportIsDiff = prevVp === undefined || vp.zoom !== prevVp.zoom || vp.pan.x !== prevVp.pan.x || vp.pan.y !== prevVp.pan.y;\n\n // we want the low quality motionblur only when the viewport is being manipulated etc (where it's not noticed)\n if( !viewportIsDiff && !(inNodeDragGesture && !hasCompoundNodes) ){\n r.motionBlurPxRatio = 1;\n }\n\n if( forcedPan ){\n effectivePan = forcedPan;\n }\n\n // apply pixel ratio\n\n effectiveZoom *= pixelRatio;\n effectivePan.x *= pixelRatio;\n effectivePan.y *= pixelRatio;\n\n var eles = {\n drag: {\n nodes: [],\n edges: [],\n eles: []\n },\n nondrag: {\n nodes: [],\n edges: [],\n eles: []\n }\n };\n\n function mbclear( context, x, y, w, h ){\n var gco = context.globalCompositeOperation;\n\n context.globalCompositeOperation = 'destination-out';\n r.fillStyle( context, 255, 255, 255, r.motionBlurTransparency );\n context.fillRect(x, y, w, h);\n\n context.globalCompositeOperation = gco;\n }\n\n function setContextTransform(context, clear){\n var ePan, eZoom, w, h;\n\n if( !r.clearingMotionBlur && (context === data.bufferContexts[r.MOTIONBLUR_BUFFER_NODE] || context === data.bufferContexts[r.MOTIONBLUR_BUFFER_DRAG]) ){\n ePan = {\n x: pan.x * mbPxRatio,\n y: pan.y * mbPxRatio\n };\n\n eZoom = zoom * mbPxRatio;\n\n w = r.canvasWidth * mbPxRatio;\n h = r.canvasHeight * mbPxRatio;\n } else {\n ePan = effectivePan;\n eZoom = effectiveZoom;\n\n w = r.canvasWidth;\n h = r.canvasHeight;\n }\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n\n if( clear === 'motionBlur' ){\n mbclear(context, 0, 0, w, h);\n } else if( !forcedContext && (clear === undefined || clear) ){\n context.clearRect(0, 0, w, h);\n }\n\n if( !drawAllLayers ){\n context.translate( ePan.x, ePan.y );\n context.scale( eZoom, eZoom );\n }\n if( forcedPan ){\n context.translate( forcedPan.x, forcedPan.y );\n }\n if( forcedZoom ){\n context.scale( forcedZoom, forcedZoom );\n }\n }\n\n if( !textureDraw ){\n r.textureDrawLastFrame = false;\n }\n\n if( textureDraw ){\n r.textureDrawLastFrame = true;\n\n var bb;\n\n if( !r.textureCache ){\n r.textureCache = {};\n\n bb = r.textureCache.bb = cy.elements().boundingBox();\n\n r.textureCache.texture = r.data.bufferCanvases[ r.TEXTURE_BUFFER ];\n\n var cxt = r.data.bufferContexts[ r.TEXTURE_BUFFER ];\n\n cxt.setTransform(1, 0, 0, 1, 0, 0);\n cxt.clearRect(0, 0, r.canvasWidth * r.textureMult, r.canvasHeight * r.textureMult);\n\n r.render({\n forcedContext: cxt,\n drawOnlyNodeLayer: true,\n forcedPxRatio: pixelRatio * r.textureMult\n });\n\n var vp = r.textureCache.viewport = {\n zoom: cy.zoom(),\n pan: cy.pan(),\n width: r.canvasWidth,\n height: r.canvasHeight\n };\n\n vp.mpan = {\n x: (0 - vp.pan.x)/vp.zoom,\n y: (0 - vp.pan.y)/vp.zoom\n };\n }\n\n needDraw[r.DRAG] = false;\n needDraw[r.NODE] = false;\n\n var context = data.contexts[r.NODE];\n\n var texture = r.textureCache.texture;\n var vp = r.textureCache.viewport;\n bb = r.textureCache.bb;\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n\n if( motionBlur ){\n mbclear(context, 0, 0, vp.width, vp.height);\n } else {\n context.clearRect(0, 0, vp.width, vp.height);\n }\n\n var outsideBgColor = coreStyle['outside-texture-bg-color'].value;\n var outsideBgOpacity = coreStyle['outside-texture-bg-opacity'].value;\n r.fillStyle( context, outsideBgColor[0], outsideBgColor[1], outsideBgColor[2], outsideBgOpacity );\n context.fillRect( 0, 0, vp.width, vp.height );\n\n var zoom = cy.zoom();\n\n setContextTransform( context, false );\n\n context.clearRect( vp.mpan.x, vp.mpan.y, vp.width/vp.zoom/pixelRatio, vp.height/vp.zoom/pixelRatio );\n context.drawImage( texture, vp.mpan.x, vp.mpan.y, vp.width/vp.zoom/pixelRatio, vp.height/vp.zoom/pixelRatio );\n\n } else if( r.textureOnViewport && !forcedContext ){ // clear the cache since we don't need it\n r.textureCache = null;\n }\n\n var vpManip = (r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming || r.hoverData.draggingEles);\n var hideEdges = r.hideEdgesOnViewport && vpManip;\n var hideLabels = r.hideLabelsOnViewport && vpManip;\n\n if (needDraw[r.DRAG] || needDraw[r.NODE] || drawAllLayers || drawOnlyNodeLayer) {\n if( hideEdges ){\n } else {\n r.findEdgeControlPoints(edges);\n }\n\n var zEles = r.getCachedZSortedEles();\n var extent = cy.extent();\n\n for (var i = 0; i < zEles.length; i++) {\n var ele = zEles[i];\n var list;\n var bb = forcedContext ? null : ele.boundingBox();\n var insideExtent = forcedContext ? true : math.boundingBoxesIntersect( extent, bb );\n\n if( !insideExtent ){ continue; } // no need to render\n\n if ( ele._private.rscratch.inDragLayer ) {\n list = eles.drag;\n } else {\n list = eles.nondrag;\n }\n\n list.eles.push( ele );\n }\n\n }\n\n\n function drawElements( list, context ){\n var eles = list.eles;\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n\n if( ele.isNode() ){\n r.drawNode(context, ele);\n\n if( !hideLabels ){\n r.drawNodeText(context, ele);\n }\n\n r.drawNode(context, ele, true);\n } else if( !hideEdges ) {\n r.drawEdge(context, ele);\n\n if( !hideLabels ){\n r.drawEdgeText(context, ele);\n }\n\n r.drawEdge(context, ele, true);\n }\n\n\n }\n\n }\n\n var needMbClear = [];\n\n needMbClear[r.NODE] = !needDraw[r.NODE] && motionBlur && !r.clearedForMotionBlur[r.NODE] || r.clearingMotionBlur;\n if( needMbClear[r.NODE] ){ r.clearedForMotionBlur[r.NODE] = true; }\n\n needMbClear[r.DRAG] = !needDraw[r.DRAG] && motionBlur && !r.clearedForMotionBlur[r.DRAG] || r.clearingMotionBlur;\n if( needMbClear[r.DRAG] ){ r.clearedForMotionBlur[r.DRAG] = true; }\n\n if( needDraw[r.NODE] || drawAllLayers || drawOnlyNodeLayer || needMbClear[r.NODE] ){\n var useBuffer = motionBlur && !needMbClear[r.NODE] && mbPxRatio !== 1;\n var context = forcedContext || ( useBuffer ? r.data.bufferContexts[ r.MOTIONBLUR_BUFFER_NODE ] : data.contexts[r.NODE] );\n var clear = motionBlur && !useBuffer ? 'motionBlur' : undefined;\n\n setContextTransform( context, clear );\n drawElements(eles.nondrag, context);\n\n if( !drawAllLayers && !motionBlur ){\n needDraw[r.NODE] = false;\n }\n }\n\n if ( !drawOnlyNodeLayer && (needDraw[r.DRAG] || drawAllLayers || needMbClear[r.DRAG]) ) {\n var useBuffer = motionBlur && !needMbClear[r.DRAG] && mbPxRatio !== 1;\n var context = forcedContext || ( useBuffer ? r.data.bufferContexts[ r.MOTIONBLUR_BUFFER_DRAG ] : data.contexts[r.DRAG] );\n\n setContextTransform( context, motionBlur && !useBuffer ? 'motionBlur' : undefined );\n drawElements(eles.drag, context);\n\n if( !drawAllLayers && !motionBlur ){\n needDraw[r.DRAG] = false;\n }\n }\n\n if( r.showFps || (!drawOnlyNodeLayer && (needDraw[r.SELECT_BOX] && !drawAllLayers)) ) {\n var context = forcedContext || data.contexts[r.SELECT_BOX];\n\n setContextTransform( context );\n\n if( r.selection[4] == 1 && ( r.hoverData.selecting || r.touchData.selecting ) ){\n var zoom = r.cy.zoom();\n var borderWidth = coreStyle['selection-box-border-width'].value / zoom;\n\n context.lineWidth = borderWidth;\n context.fillStyle = \"rgba(\"\n + coreStyle['selection-box-color'].value[0] + \",\"\n + coreStyle['selection-box-color'].value[1] + \",\"\n + coreStyle['selection-box-color'].value[2] + \",\"\n + coreStyle['selection-box-opacity'].value + \")\";\n\n context.fillRect(\n r.selection[0],\n r.selection[1],\n r.selection[2] - r.selection[0],\n r.selection[3] - r.selection[1]);\n\n if (borderWidth > 0) {\n context.strokeStyle = \"rgba(\"\n + coreStyle['selection-box-border-color'].value[0] + \",\"\n + coreStyle['selection-box-border-color'].value[1] + \",\"\n + coreStyle['selection-box-border-color'].value[2] + \",\"\n + coreStyle['selection-box-opacity'].value + \")\";\n\n context.strokeRect(\n r.selection[0],\n r.selection[1],\n r.selection[2] - r.selection[0],\n r.selection[3] - r.selection[1]);\n }\n }\n\n if( data.bgActivePosistion && !r.hoverData.selecting ){\n var zoom = r.cy.zoom();\n var pos = data.bgActivePosistion;\n\n context.fillStyle = \"rgba(\"\n + coreStyle['active-bg-color'].value[0] + \",\"\n + coreStyle['active-bg-color'].value[1] + \",\"\n + coreStyle['active-bg-color'].value[2] + \",\"\n + coreStyle['active-bg-opacity'].value + \")\";\n\n context.beginPath();\n context.arc(pos.x, pos.y, coreStyle['active-bg-size'].pfValue / zoom, 0, 2 * Math.PI);\n context.fill();\n }\n\n var timeToRender = r.lastRedrawTime;\n if( r.showFps && timeToRender ){\n timeToRender = Math.round( timeToRender );\n var fps = Math.round(1000/timeToRender);\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n\n context.fillStyle = 'rgba(255, 0, 0, 0.75)';\n context.strokeStyle = 'rgba(255, 0, 0, 0.75)';\n context.lineWidth = 1;\n context.fillText( '1 frame = ' + timeToRender + ' ms = ' + fps + ' fps', 0, 20);\n\n var maxFps = 60;\n context.strokeRect(0, 30, 250, 20);\n context.fillRect(0, 30, 250 * Math.min(fps/maxFps, 1), 20);\n }\n\n if( !drawAllLayers ){\n needDraw[r.SELECT_BOX] = false;\n }\n }\n\n // motionblur: blit rendered blurry frames\n if( motionBlur && mbPxRatio !== 1 ){\n var cxtNode = data.contexts[r.NODE];\n var txtNode = r.data.bufferCanvases[ r.MOTIONBLUR_BUFFER_NODE ];\n\n var cxtDrag = data.contexts[r.DRAG];\n var txtDrag = r.data.bufferCanvases[ r.MOTIONBLUR_BUFFER_DRAG ];\n\n var drawMotionBlur = function( cxt, txt, needClear ){\n cxt.setTransform(1, 0, 0, 1, 0, 0);\n\n if( needClear || !motionBlurFadeEffect ){\n cxt.clearRect( 0, 0, r.canvasWidth, r.canvasHeight );\n } else {\n mbclear( cxt, 0, 0, r.canvasWidth, r.canvasHeight );\n }\n\n var pxr = mbPxRatio;\n\n cxt.drawImage(\n txt, // img\n 0, 0, // sx, sy\n r.canvasWidth * pxr, r.canvasHeight * pxr, // sw, sh\n 0, 0, // x, y\n r.canvasWidth, r.canvasHeight // w, h\n );\n };\n\n if( needDraw[r.NODE] || needMbClear[r.NODE] ){\n drawMotionBlur( cxtNode, txtNode, needMbClear[r.NODE] );\n needDraw[r.NODE] = false;\n }\n\n if( needDraw[r.DRAG] || needMbClear[r.DRAG] ){\n drawMotionBlur( cxtDrag, txtDrag, needMbClear[r.DRAG] );\n needDraw[r.DRAG] = false;\n }\n }\n\n r.currentlyDrawing = false;\n\n r.prevViewport = vp;\n\n if( r.clearingMotionBlur ){\n r.clearingMotionBlur = false;\n r.motionBlurCleared = true;\n r.motionBlur = true;\n }\n\n if( motionBlur ){\n r.motionBlurTimeout = setTimeout(function(){\n r.motionBlurTimeout = null;\n\n r.clearedForMotionBlur[r.NODE] = false;\n r.clearedForMotionBlur[r.DRAG] = false;\n r.motionBlur = false;\n r.clearingMotionBlur = !textureDraw;\n r.mbFrames = 0;\n\n needDraw[r.NODE] = true;\n needDraw[r.DRAG] = true;\n\n r.redraw();\n }, motionBlurDelay);\n }\n\n r.drawingImage = false;\n\n\n if( !forcedContext && !r.initrender ){\n r.initrender = true;\n cy.trigger('initrender');\n }\n\n if( !forcedContext ){\n cy.triggerOnRender();\n }\n\n};\n\nmodule.exports = CRp;\n","'use strict';\n\n var math = require('../../../math');\n\n var CRp = {};\n\n // @O Polygon drawing\n CRp.drawPolygonPath = function(\n context, x, y, width, height, points) {\n\n var halfW = width / 2;\n var halfH = height / 2;\n\n if( context.beginPath ){ context.beginPath(); }\n\n context.moveTo( x + halfW * points[0], y + halfH * points[1] );\n\n for (var i = 1; i < points.length / 2; i++) {\n context.lineTo( x + halfW * points[i * 2], y + halfH * points[i * 2 + 1] );\n }\n\n context.closePath();\n };\n\n // Round rectangle drawing\n CRp.drawRoundRectanglePath = function(\n context, x, y, width, height, radius) {\n\n var halfWidth = width / 2;\n var halfHeight = height / 2;\n var cornerRadius = math.getRoundRectangleRadius(width, height);\n\n if( context.beginPath ){ context.beginPath(); }\n\n // Start at top middle\n context.moveTo(x, y - halfHeight);\n // Arc from middle top to right side\n context.arcTo(x + halfWidth, y - halfHeight, x + halfWidth, y, cornerRadius);\n // Arc from right side to bottom\n context.arcTo(x + halfWidth, y + halfHeight, x, y + halfHeight, cornerRadius);\n // Arc from bottom to left side\n context.arcTo(x - halfWidth, y + halfHeight, x - halfWidth, y, cornerRadius);\n // Arc from left side to topBorder\n context.arcTo(x - halfWidth, y - halfHeight, x, y - halfHeight, cornerRadius);\n // Join line\n context.lineTo(x, y - halfHeight);\n\n\n context.closePath();\n };\n\n var sin0 = Math.sin(0);\n var cos0 = Math.cos(0);\n\n var sin = {};\n var cos = {};\n\n var ellipseStepSize = Math.PI / 40;\n\n for (var i = 0 * Math.PI; i < 2 * Math.PI; i += ellipseStepSize ) {\n sin[i] = Math.sin(i);\n cos[i] = Math.cos(i);\n }\n\n CRp.drawEllipsePath = function(context, centerX, centerY, width, height){\n if( context.beginPath ){ context.beginPath(); }\n\n if( context.ellipse ){\n context.ellipse( centerX, centerY, width/2, height/2, 0, 0, 2*Math.PI );\n } else {\n var xPos, yPos;\n var rw = width/2;\n var rh = height/2;\n for (var i = 0 * Math.PI; i < 2 * Math.PI; i += ellipseStepSize ) {\n xPos = centerX - (rw * sin[i]) * sin0 + (rw * cos[i]) * cos0;\n yPos = centerY + (rh * cos[i]) * sin0 + (rh * sin[i]) * cos0;\n\n if (i === 0) {\n context.moveTo(xPos, yPos);\n } else {\n context.lineTo(xPos, yPos);\n }\n }\n }\n\n context.closePath();\n };\n\nmodule.exports = CRp;\n","'use strict';\n\nvar is = require('../../../is');\n\nvar CRp = {};\n\nCRp.createBuffer = function(w, h) {\n var buffer = document.createElement('canvas');\n buffer.width = w;\n buffer.height = h;\n\n return [buffer, buffer.getContext('2d')];\n};\n\nCRp.bufferCanvasImage = function( options ){\n var cy = this.cy;\n var bb = cy.elements().boundingBox();\n var width = options.full ? Math.ceil(bb.w) : this.container.clientWidth;\n var height = options.full ? Math.ceil(bb.h) : this.container.clientHeight;\n var scale = 1;\n\n if( options.scale !== undefined ){\n width *= options.scale;\n height *= options.scale;\n\n scale = options.scale;\n } else if( is.number(options.maxWidth) || is.number(options.maxHeight) ){\n var maxScaleW = Infinity;\n var maxScaleH = Infinity;\n\n if( is.number(options.maxWidth) ){\n maxScaleW = scale * options.maxWidth / width;\n }\n\n if( is.number(options.maxHeight) ){\n maxScaleH = scale * options.maxHeight / height;\n }\n\n scale = Math.min( maxScaleW, maxScaleH );\n\n width *= scale;\n height *= scale;\n }\n\n var buffCanvas = document.createElement('canvas');\n\n buffCanvas.width = width;\n buffCanvas.height = height;\n\n buffCanvas.style.width = width + 'px';\n buffCanvas.style.height = height + 'px';\n\n var buffCxt = buffCanvas.getContext('2d');\n\n // Rasterize the layers, but only if container has nonzero size\n if (width > 0 && height > 0) {\n\n buffCxt.clearRect( 0, 0, width, height );\n\n if( options.bg ){\n buffCxt.fillStyle = options.bg;\n buffCxt.rect( 0, 0, width, height );\n buffCxt.fill();\n }\n\n buffCxt.globalCompositeOperation = 'source-over';\n\n if( options.full ){ // draw the full bounds of the graph\n this.render({\n forcedContext: buffCxt,\n drawAllLayers: true,\n forcedZoom: scale,\n forcedPan: { x: -bb.x1*scale, y: -bb.y1*scale },\n forcedPxRatio: 1\n });\n } else { // draw the current view\n var cyPan = cy.pan();\n var pan = {\n x: cyPan.x * scale,\n y: cyPan.y * scale\n };\n var zoom = cy.zoom() * scale;\n\n this.render({\n forcedContext: buffCxt,\n drawAllLayers: true,\n forcedZoom: zoom,\n forcedPan: pan,\n forcedPxRatio: 1\n });\n }\n }\n\n return buffCanvas;\n};\n\nCRp.png = function( options ){\n return this.bufferCanvasImage( options ).toDataURL('image/png');\n};\n\nCRp.jpg = function( options ){\n return this.bufferCanvasImage( options ).toDataURL('image/jpeg');\n};\n\nmodule.exports = CRp;\n","/*\nThe canvas renderer was written by Yue Dong.\n\nModifications tracked on Github.\n*/\n\n'use strict';\n\nvar util = require('../../../util');\nvar is = require('../../../is');\n\nvar CR = CanvasRenderer;\nvar CRp = CanvasRenderer.prototype;\n\nCRp.CANVAS_LAYERS = 3;\n//\nCRp.SELECT_BOX = 0;\nCRp.DRAG = 1;\nCRp.NODE = 2;\n\nCRp.BUFFER_COUNT = 3;\n//\nCRp.TEXTURE_BUFFER = 0;\nCRp.MOTIONBLUR_BUFFER_NODE = 1;\nCRp.MOTIONBLUR_BUFFER_DRAG = 2;\n\nfunction CanvasRenderer(options) {\n var r = this;\n\n r.data = {\n canvases: new Array(CRp.CANVAS_LAYERS),\n contexts: new Array(CRp.CANVAS_LAYERS),\n canvasNeedsRedraw: new Array(CRp.CANVAS_LAYERS),\n\n bufferCanvases: new Array(CRp.BUFFER_COUNT),\n bufferContexts: new Array(CRp.CANVAS_LAYERS)\n };\n\n r.data.canvasContainer = document.createElement('div');\n var containerStyle = r.data.canvasContainer.style;\n r.data.canvasContainer.setAttribute('style', '-webkit-tap-highlight-color: rgba(0,0,0,0);');\n containerStyle.position = 'relative';\n containerStyle.zIndex = '0';\n containerStyle.overflow = 'hidden';\n\n var container = options.cy.container();\n container.appendChild( r.data.canvasContainer );\n container.setAttribute('style', ( container.getAttribute('style') || '' ) + '-webkit-tap-highlight-color: rgba(0,0,0,0);');\n\n for (var i = 0; i < CRp.CANVAS_LAYERS; i++) {\n var canvas = r.data.canvases[i] = document.createElement('canvas');\n r.data.contexts[i] = canvas.getContext('2d');\n canvas.setAttribute( 'style', '-webkit-user-select: none; -moz-user-select: -moz-none; user-select: none; -webkit-tap-highlight-color: rgba(0,0,0,0); outline-style: none;' + ( is.ms() ? ' -ms-touch-action: none; touch-action: none; ' : '' ) );\n canvas.style.position = 'absolute';\n canvas.setAttribute('data-id', 'layer' + i);\n canvas.style.zIndex = String(CRp.CANVAS_LAYERS - i);\n r.data.canvasContainer.appendChild(canvas);\n\n r.data.canvasNeedsRedraw[i] = false;\n }\n r.data.topCanvas = r.data.canvases[0];\n\n r.data.canvases[CRp.NODE].setAttribute('data-id', 'layer' + CRp.NODE + '-node');\n r.data.canvases[CRp.SELECT_BOX].setAttribute('data-id', 'layer' + CRp.SELECT_BOX + '-selectbox');\n r.data.canvases[CRp.DRAG].setAttribute('data-id', 'layer' + CRp.DRAG + '-drag');\n\n for (var i = 0; i < CRp.BUFFER_COUNT; i++) {\n r.data.bufferCanvases[i] = document.createElement('canvas');\n r.data.bufferContexts[i] = r.data.bufferCanvases[i].getContext('2d');\n r.data.bufferCanvases[i].style.position = 'absolute';\n r.data.bufferCanvases[i].setAttribute('data-id', 'buffer' + i);\n r.data.bufferCanvases[i].style.zIndex = String(-i - 1);\n r.data.bufferCanvases[i].style.visibility = 'hidden';\n //r.data.canvasContainer.appendChild(r.data.bufferCanvases[i]);\n }\n\n r.pathsEnabled = true;\n}\n\nCRp.redrawHint = function( group, bool ){\n var r = this;\n\n switch( group ){\n case 'eles':\n r.data.canvasNeedsRedraw[ CRp.NODE ] = bool;\n break;\n case 'drag':\n r.data.canvasNeedsRedraw[ CRp.DRAG ] = bool;\n break;\n case 'select':\n r.data.canvasNeedsRedraw[ CRp.SELECT_BOX ] = bool;\n break;\n }\n};\n\n// whether to use Path2D caching for drawing\nvar pathsImpld = typeof Path2D !== 'undefined';\n\nCRp.path2dEnabled = function( on ){\n if( on === undefined ){\n return this.pathsEnabled;\n }\n\n this.pathsEnabled = on ? true : false;\n};\n\nCRp.usePaths = function(){\n return pathsImpld && this.pathsEnabled;\n};\n\n[\n require('./arrow-shapes'),\n require('./drawing-edges'),\n require('./drawing-images'),\n require('./drawing-label-text'),\n require('./drawing-nodes'),\n require('./drawing-redraw'),\n require('./drawing-shapes'),\n require('./export-image'),\n require('./node-shapes')\n].forEach(function( props ){\n util.extend( CRp, props );\n});\n\nmodule.exports = CR;\n","'use strict';\n\nvar CRp = {};\n\nvar impl;\n\nCRp.nodeShapeImpl = function( name ){\n var self = this;\n\n return ( impl || (impl = {\n 'ellipse': function( context, centerX, centerY, width, height ){\n self.drawEllipsePath( context, centerX, centerY, width, height );\n },\n\n 'polygon': function( context, centerX, centerY, width, height, points ){\n self.drawPolygonPath( context, centerX, centerY, width, height, points );\n },\n\n 'roundrectangle': function( context, centerX, centerY, width, height ){\n self.drawRoundRectanglePath( context, centerX, centerY, width, height, 10 );\n }\n }) )[ name ];\n};\n\nmodule.exports = CRp;\n","'use strict';\n\nmodule.exports = [\n { name: 'null', impl: require('./null') },\n { name: 'base', impl: require('./base') },\n { name: 'canvas', impl: require('./canvas') }\n];\n","'use strict';\n\nfunction NullRenderer(options){\n this.options = options;\n this.notifications = 0; // for testing\n}\n\nvar noop = function(){};\n\nNullRenderer.prototype = {\n recalculateRenderedStyle: noop,\n notify: function(){ this.notifications++; },\n init: noop\n};\n\nmodule.exports = NullRenderer;\n","'use strict';\n\nvar is = require('./is');\nvar util = require('./util');\nvar Thread = require('./thread');\nvar Promise = require('./promise');\nvar define = require('./define');\n\nvar Fabric = function( N ){\n if( !(this instanceof Fabric) ){\n return new Fabric( N );\n }\n\n this._private = {\n pass: []\n };\n\n var defN = 4;\n\n if( is.number(N) ){\n // then use the specified number of threads\n } if( typeof navigator !== 'undefined' && navigator.hardwareConcurrency != null ){\n N = navigator.hardwareConcurrency;\n } else {\n try{\n N = require('os').cpus().length;\n } catch( err ){\n N = defN;\n }\n } // TODO could use an estimation here but would the additional expense be worth it?\n\n for( var i = 0; i < N; i++ ){\n this[i] = new Thread();\n }\n\n this.length = N;\n};\n\nvar fabfn = Fabric.prototype; // short alias\n\nutil.extend(fabfn, {\n\n instanceString: function(){ return 'fabric'; },\n\n // require fn in all threads\n require: function( fn, as ){\n for( var i = 0; i < this.length; i++ ){\n var thread = this[i];\n\n thread.require( fn, as );\n }\n\n return this;\n },\n\n // get a random thread\n random: function(){\n var i = Math.round( (this.length - 1) * Math.random() );\n var thread = this[i];\n\n return thread;\n },\n\n // run on random thread\n run: function( fn ){\n var pass = this._private.pass.shift();\n\n return this.random().pass( pass ).run( fn );\n },\n\n // sends a random thread a message\n message: function( m ){\n return this.random().message( m );\n },\n\n // send all threads a message\n broadcast: function( m ){\n for( var i = 0; i < this.length; i++ ){\n var thread = this[i];\n\n thread.message( m );\n }\n\n return this; // chaining\n },\n\n // stop all threads\n stop: function(){\n for( var i = 0; i < this.length; i++ ){\n var thread = this[i];\n\n thread.stop();\n }\n\n return this; // chaining\n },\n\n // pass data to be used with .spread() etc.\n pass: function( data ){\n var pass = this._private.pass;\n\n if( is.array(data) ){\n pass.push( data );\n } else {\n throw 'Only arrays may be used with fabric.pass()';\n }\n\n return this; // chaining\n },\n\n spreadSize: function(){\n var subsize = Math.ceil( this._private.pass[0].length / this.length );\n\n subsize = Math.max( 1, subsize ); // don't pass less than one ele to each thread\n\n return subsize;\n },\n\n // split the data into slices to spread the data equally among threads\n spread: function( fn ){\n var self = this;\n var _p = self._private;\n var subsize = self.spreadSize(); // number of pass eles to handle in each thread\n var pass = _p.pass.shift().concat([]); // keep a copy\n var runPs = [];\n\n for( var i = 0; i < this.length; i++ ){\n var thread = this[i];\n var slice = pass.splice( 0, subsize );\n\n var runP = thread.pass( slice ).run( fn );\n\n runPs.push( runP );\n\n var doneEarly = pass.length === 0;\n if( doneEarly ){ break; }\n }\n\n return Promise.all( runPs ).then(function( thens ){\n var postpass = [];\n var p = 0;\n\n // fill postpass with the total result joined from all threads\n for( var i = 0; i < thens.length; i++ ){\n var then = thens[i]; // array result from thread i\n\n for( var j = 0; j < then.length; j++ ){\n var t = then[j]; // array element\n\n postpass[ p++ ] = t;\n }\n }\n\n return postpass;\n });\n },\n\n // parallel version of array.map()\n map: function( fn ){\n var self = this;\n\n self.require( fn, '_$_$_fabmap' );\n\n return self.spread(function( split ){\n var mapped = [];\n var origResolve = resolve; // jshint ignore:line\n\n resolve = function( val ){ // jshint ignore:line\n mapped.push( val );\n };\n\n for( var i = 0; i < split.length; i++ ){\n var oldLen = mapped.length;\n var ret = _$_$_fabmap( split[i] ); // jshint ignore:line\n var nothingInsdByResolve = oldLen === mapped.length;\n\n if( nothingInsdByResolve ){\n mapped.push( ret );\n }\n }\n\n resolve = origResolve; // jshint ignore:line\n\n return mapped;\n });\n\n },\n\n // parallel version of array.filter()\n filter: function( fn ){\n var _p = this._private;\n var pass = _p.pass[0];\n\n return this.map( fn ).then(function( include ){\n var ret = [];\n\n for( var i = 0; i < pass.length; i++ ){\n var datum = pass[i];\n var incDatum = include[i];\n\n if( incDatum ){\n ret.push( datum );\n }\n }\n\n return ret;\n });\n },\n\n // sorts the passed array using a divide and conquer strategy\n sort: function( cmp ){\n var self = this;\n var P = this._private.pass[0].length;\n var subsize = this.spreadSize();\n\n cmp = cmp || function( a, b ){ // default comparison function\n if( a < b ){\n return -1;\n } else if( a > b ){\n return 1;\n }\n\n return 0;\n };\n\n self.require( cmp, '_$_$_cmp' );\n\n return self.spread(function( split ){ // sort each split normally\n var sortedSplit = split.sort( _$_$_cmp ); // jshint ignore:line\n resolve( sortedSplit ); // jshint ignore:line\n\n }).then(function( joined ){\n // do all the merging in the main thread to minimise data transfer\n\n // TODO could do merging in separate threads but would incur add'l cost of data transfer\n // for each level of the merge\n\n var merge = function( i, j, max ){\n // don't overflow array\n j = Math.min( j, P );\n max = Math.min( max, P );\n\n // left and right sides of merge\n var l = i;\n var r = j;\n\n var sorted = [];\n\n for( var k = l; k < max; k++ ){\n\n var eleI = joined[i];\n var eleJ = joined[j];\n\n if( i < r && ( j >= max || cmp(eleI, eleJ) <= 0 ) ){\n sorted.push( eleI );\n i++;\n } else {\n sorted.push( eleJ );\n j++;\n }\n\n }\n\n // in the array proper, put the sorted values\n for( var k = 0; k < sorted.length; k++ ){ // kth sorted item\n var index = l + k;\n\n joined[ index ] = sorted[k];\n }\n };\n\n for( var splitL = subsize; splitL < P; splitL *= 2 ){ // merge until array is \"split\" as 1\n\n for( var i = 0; i < P; i += 2*splitL ){\n merge( i, i + splitL, i + 2*splitL );\n }\n\n }\n\n return joined;\n });\n }\n\n\n});\n\nvar defineRandomPasser = function( opts ){\n opts = opts || {};\n\n return function( fn, arg1 ){\n var pass = this._private.pass.shift();\n\n return this.random().pass( pass )[ opts.threadFn ]( fn, arg1 );\n };\n};\n\nutil.extend(fabfn, {\n randomMap: defineRandomPasser({ threadFn: 'map' }),\n\n reduce: defineRandomPasser({ threadFn: 'reduce' }),\n\n reduceRight: defineRandomPasser({ threadFn: 'reduceRight' })\n});\n\n// aliases\nvar fn = fabfn;\nfn.promise = fn.run;\nfn.terminate = fn.halt = fn.stop;\nfn.include = fn.require;\n\n// pull in event apis\nutil.extend(fabfn, {\n on: define.on(),\n one: define.on({ unbindSelfOnTrigger: true }),\n off: define.off(),\n trigger: define.trigger()\n});\n\ndefine.eventAliasesOn( fabfn );\n\nmodule.exports = Fabric;\n","'use strict';\n/* jshint ignore:start */\n\n// Generated by CoffeeScript 1.8.0\n(function() {\n var Heap, defaultCmp, floor, heapify, heappop, heappush, heappushpop, heapreplace, insort, min, nlargest, nsmallest, updateItem, _siftdown, _siftup;\n\n floor = Math.floor, min = Math.min;\n\n\n /*\n Default comparison function to be used\n */\n\n defaultCmp = function(x, y) {\n if (x < y) {\n return -1;\n }\n if (x > y) {\n return 1;\n }\n return 0;\n };\n\n\n /*\n Insert item x in list a, and keep it sorted assuming a is sorted.\n\n If x is already in a, insert it to the right of the rightmost x.\n\n Optional args lo (default 0) and hi (default a.length) bound the slice\n of a to be searched.\n */\n\n insort = function(a, x, lo, hi, cmp) {\n var mid;\n if (lo == null) {\n lo = 0;\n }\n if (cmp == null) {\n cmp = defaultCmp;\n }\n if (lo < 0) {\n throw new Error('lo must be non-negative');\n }\n if (hi == null) {\n hi = a.length;\n }\n while (lo < hi) {\n mid = floor((lo + hi) / 2);\n if (cmp(x, a[mid]) < 0) {\n hi = mid;\n } else {\n lo = mid + 1;\n }\n }\n return ([].splice.apply(a, [lo, lo - lo].concat(x)), x);\n };\n\n\n /*\n Push item onto heap, maintaining the heap invariant.\n */\n\n heappush = function(array, item, cmp) {\n if (cmp == null) {\n cmp = defaultCmp;\n }\n array.push(item);\n return _siftdown(array, 0, array.length - 1, cmp);\n };\n\n\n /*\n Pop the smallest item off the heap, maintaining the heap invariant.\n */\n\n heappop = function(array, cmp) {\n var lastelt, returnitem;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n lastelt = array.pop();\n if (array.length) {\n returnitem = array[0];\n array[0] = lastelt;\n _siftup(array, 0, cmp);\n } else {\n returnitem = lastelt;\n }\n return returnitem;\n };\n\n\n /*\n Pop and return the current smallest value, and add the new item.\n\n This is more efficient than heappop() followed by heappush(), and can be\n more appropriate when using a fixed size heap. Note that the value\n returned may be larger than item! That constrains reasonable use of\n this routine unless written as part of a conditional replacement:\n if item > array[0]\n item = heapreplace(array, item)\n */\n\n heapreplace = function(array, item, cmp) {\n var returnitem;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n returnitem = array[0];\n array[0] = item;\n _siftup(array, 0, cmp);\n return returnitem;\n };\n\n\n /*\n Fast version of a heappush followed by a heappop.\n */\n\n heappushpop = function(array, item, cmp) {\n var _ref;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n if (array.length && cmp(array[0], item) < 0) {\n _ref = [array[0], item], item = _ref[0], array[0] = _ref[1];\n _siftup(array, 0, cmp);\n }\n return item;\n };\n\n\n /*\n Transform list into a heap, in-place, in O(array.length) time.\n */\n\n heapify = function(array, cmp) {\n var i, _i, _j, _len, _ref, _ref1, _results, _results1;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n _ref1 = (function() {\n _results1 = [];\n for (var _j = 0, _ref = floor(array.length / 2); 0 <= _ref ? _j < _ref : _j > _ref; 0 <= _ref ? _j++ : _j--){ _results1.push(_j); }\n return _results1;\n }).apply(this).reverse();\n _results = [];\n for (_i = 0, _len = _ref1.length; _i < _len; _i++) {\n i = _ref1[_i];\n _results.push(_siftup(array, i, cmp));\n }\n return _results;\n };\n\n\n /*\n Update the position of the given item in the heap.\n This function should be called every time the item is being modified.\n */\n\n updateItem = function(array, item, cmp) {\n var pos;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n pos = array.indexOf(item);\n if (pos === -1) {\n return;\n }\n _siftdown(array, 0, pos, cmp);\n return _siftup(array, pos, cmp);\n };\n\n\n /*\n Find the n largest elements in a dataset.\n */\n\n nlargest = function(array, n, cmp) {\n var elem, result, _i, _len, _ref;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n result = array.slice(0, n);\n if (!result.length) {\n return result;\n }\n heapify(result, cmp);\n _ref = array.slice(n);\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n elem = _ref[_i];\n heappushpop(result, elem, cmp);\n }\n return result.sort(cmp).reverse();\n };\n\n\n /*\n Find the n smallest elements in a dataset.\n */\n\n nsmallest = function(array, n, cmp) {\n var elem, i, los, result, _i, _j, _len, _ref, _ref1, _results;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n if (n * 10 <= array.length) {\n result = array.slice(0, n).sort(cmp);\n if (!result.length) {\n return result;\n }\n los = result[result.length - 1];\n _ref = array.slice(n);\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n elem = _ref[_i];\n if (cmp(elem, los) < 0) {\n insort(result, elem, 0, null, cmp);\n result.pop();\n los = result[result.length - 1];\n }\n }\n return result;\n }\n heapify(array, cmp);\n _results = [];\n for (i = _j = 0, _ref1 = min(n, array.length); 0 <= _ref1 ? _j < _ref1 : _j > _ref1; i = 0 <= _ref1 ? ++_j : --_j) {\n _results.push(heappop(array, cmp));\n }\n return _results;\n };\n\n _siftdown = function(array, startpos, pos, cmp) {\n var newitem, parent, parentpos;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n newitem = array[pos];\n while (pos > startpos) {\n parentpos = (pos - 1) >> 1;\n parent = array[parentpos];\n if (cmp(newitem, parent) < 0) {\n array[pos] = parent;\n pos = parentpos;\n continue;\n }\n break;\n }\n return array[pos] = newitem;\n };\n\n _siftup = function(array, pos, cmp) {\n var childpos, endpos, newitem, rightpos, startpos;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n endpos = array.length;\n startpos = pos;\n newitem = array[pos];\n childpos = 2 * pos + 1;\n while (childpos < endpos) {\n rightpos = childpos + 1;\n if (rightpos < endpos && !(cmp(array[childpos], array[rightpos]) < 0)) {\n childpos = rightpos;\n }\n array[pos] = array[childpos];\n pos = childpos;\n childpos = 2 * pos + 1;\n }\n array[pos] = newitem;\n return _siftdown(array, startpos, pos, cmp);\n };\n\n Heap = (function() {\n Heap.push = heappush;\n\n Heap.pop = heappop;\n\n Heap.replace = heapreplace;\n\n Heap.pushpop = heappushpop;\n\n Heap.heapify = heapify;\n\n Heap.updateItem = updateItem;\n\n Heap.nlargest = nlargest;\n\n Heap.nsmallest = nsmallest;\n\n function Heap(cmp) {\n this.cmp = cmp != null ? cmp : defaultCmp;\n this.nodes = [];\n }\n\n Heap.prototype.push = function(x) {\n return heappush(this.nodes, x, this.cmp);\n };\n\n Heap.prototype.pop = function() {\n return heappop(this.nodes, this.cmp);\n };\n\n Heap.prototype.peek = function() {\n return this.nodes[0];\n };\n\n Heap.prototype.contains = function(x) {\n return this.nodes.indexOf(x) !== -1;\n };\n\n Heap.prototype.replace = function(x) {\n return heapreplace(this.nodes, x, this.cmp);\n };\n\n Heap.prototype.pushpop = function(x) {\n return heappushpop(this.nodes, x, this.cmp);\n };\n\n Heap.prototype.heapify = function() {\n return heapify(this.nodes, this.cmp);\n };\n\n Heap.prototype.updateItem = function(x) {\n return updateItem(this.nodes, x, this.cmp);\n };\n\n Heap.prototype.clear = function() {\n return this.nodes = [];\n };\n\n Heap.prototype.empty = function() {\n return this.nodes.length === 0;\n };\n\n Heap.prototype.size = function() {\n return this.nodes.length;\n };\n\n Heap.prototype.clone = function() {\n var heap;\n heap = new Heap();\n heap.nodes = this.nodes.slice(0);\n return heap;\n };\n\n Heap.prototype.toArray = function() {\n return this.nodes.slice(0);\n };\n\n Heap.prototype.insert = Heap.prototype.push;\n\n Heap.prototype.top = Heap.prototype.peek;\n\n Heap.prototype.front = Heap.prototype.peek;\n\n Heap.prototype.has = Heap.prototype.contains;\n\n Heap.prototype.copy = Heap.prototype.clone;\n\n return Heap;\n\n })();\n\n (function(root, factory) {\n if (typeof define === 'function' && define.amd) {\n return define([], factory);\n } else if (typeof exports === 'object') {\n return module.exports = factory();\n } else {\n return root.Heap = factory();\n }\n })(this, function() {\n return Heap;\n });\n\n}).call(this);\n\n/* jshint ignore:end */\n","'use strict';\n\nvar window = require('./window');\nvar is = require('./is');\nvar Core = require('./core');\nvar extension = require('./extension');\nvar registerJquery = require('./jquery-plugin');\nvar Stylesheet = require('./stylesheet');\nvar Thread = require('./thread');\nvar Fabric = require('./fabric');\n\nvar cytoscape = function( options ){ // jshint ignore:line\n // if no options specified, use default\n if( options === undefined ){\n options = {};\n }\n\n // create instance\n if( is.plainObject( options ) ){\n return new Core( options );\n }\n\n // allow for registration of extensions\n else if( is.string( options ) ) {\n return extension.apply(extension, arguments);\n }\n};\n\n// replaced by build system\ncytoscape.version = '{{VERSION}}';\n\n// try to register w/ jquery\nif( window && window.jQuery ){\n registerJquery( window.jQuery, cytoscape );\n}\n\n// expose register api\ncytoscape.registerJquery = function( jQuery ){\n registerJquery( jQuery, cytoscape );\n};\n\n// expose public apis (mostly for extensions)\ncytoscape.stylesheet = cytoscape.Stylesheet = Stylesheet;\ncytoscape.thread = cytoscape.Thread = Thread;\ncytoscape.fabric = cytoscape.Fabric = Fabric;\n\nmodule.exports = cytoscape;\n","'use strict';\n\nvar window = require('./window');\nvar navigator = window ? window.navigator : null;\n\nvar typeofstr = typeof '';\nvar typeofobj = typeof {};\nvar typeoffn = typeof function(){};\nvar typeofhtmlele = typeof HTMLElement;\n\nvar instanceStr = function( obj ){\n return obj && obj.instanceString && is.fn( obj.instanceString ) ? obj.instanceString() : null;\n};\n\nvar is = {\n defined: function(obj){\n return obj != null; // not undefined or null\n },\n\n string: function(obj){\n return obj != null && typeof obj == typeofstr;\n },\n\n fn: function(obj){\n return obj != null && typeof obj === typeoffn;\n },\n\n array: function(obj){\n return Array.isArray ? Array.isArray(obj) : obj != null && obj instanceof Array;\n },\n\n plainObject: function(obj){\n return obj != null && typeof obj === typeofobj && !is.array(obj) && obj.constructor === Object;\n },\n\n object: function(obj){\n return obj != null && typeof obj === typeofobj;\n },\n\n number: function(obj){\n return obj != null && typeof obj === typeof 1 && !isNaN(obj);\n },\n\n integer: function( obj ){\n return is.number(obj) && Math.floor(obj) === obj;\n },\n\n bool: function(obj){\n return obj != null && typeof obj === typeof true;\n },\n\n htmlElement: function(obj){\n if( 'undefined' === typeofhtmlele ){\n return undefined;\n } else {\n return null != obj && obj instanceof HTMLElement;\n }\n },\n\n elementOrCollection: function(obj){\n return is.element(obj) || is.collection(obj);\n },\n\n element: function(obj){\n return instanceStr(obj) === 'collection' && obj._private.single;\n },\n\n collection: function(obj){\n return instanceStr(obj) === 'collection' && !obj._private.single;\n },\n\n core: function(obj){\n return instanceStr(obj) === 'core';\n },\n\n style: function(obj){\n return instanceStr(obj) === 'style';\n },\n\n stylesheet: function(obj){\n return instanceStr(obj) === 'stylesheet';\n },\n\n event: function(obj){\n return instanceStr(obj) === 'event';\n },\n\n thread: function(obj){\n return instanceStr(obj) === 'thread';\n },\n\n fabric: function(obj){\n return instanceStr(obj) === 'fabric';\n },\n\n emptyString: function(obj){\n if( !obj ){ // null is empty\n return true;\n } else if( is.string(obj) ){\n if( obj === '' || obj.match(/^\\s+$/) ){\n return true; // empty string is empty\n }\n }\n\n return false; // otherwise, we don't know what we've got\n },\n\n nonemptyString: function(obj){\n if( obj && is.string(obj) && obj !== '' && !obj.match(/^\\s+$/) ){\n return true;\n }\n\n return false;\n },\n\n domElement: function(obj){\n if( typeof HTMLElement === 'undefined' ){\n return false; // we're not in a browser so it doesn't matter\n } else {\n return obj instanceof HTMLElement;\n }\n },\n\n boundingBox: function(obj){\n return is.plainObject(obj) &&\n is.number(obj.x1) && is.number(obj.x2) &&\n is.number(obj.y1) && is.number(obj.y2)\n ;\n },\n\n promise: function(obj){\n return is.object(obj) && is.fn(obj.then);\n },\n\n touch: function(){\n return window && ( ('ontouchstart' in window) || window.DocumentTouch && document instanceof DocumentTouch );\n },\n\n gecko: function(){\n return typeof InstallTrigger !== 'undefined' || ('MozAppearance' in document.documentElement.style);\n },\n\n webkit: function(){\n return typeof webkitURL !== 'undefined' || ('WebkitAppearance' in document.documentElement.style);\n },\n\n chromium: function(){\n return typeof chrome !== 'undefined';\n },\n\n khtml: function(){\n return navigator && navigator.vendor.match(/kde/i); // probably a better way to detect this...\n },\n\n khtmlEtc: function(){\n return is.khtml() || is.webkit() || is.chromium();\n },\n\n ms: function(){\n return navigator && navigator.userAgent.match(/msie|trident|edge/i); // probably a better way to detect this...\n },\n\n windows: function(){\n return navigator && navigator.appVersion.match(/Win/i);\n },\n\n mac: function(){\n return navigator && navigator.appVersion.match(/Mac/i);\n },\n\n linux: function(){\n return navigator && navigator.appVersion.match(/Linux/i);\n },\n\n unix: function(){\n return navigator && navigator.appVersion.match(/X11/i);\n }\n};\n\nmodule.exports = is;\n","'use strict';\n\nvar is = require('./is');\n\nvar cyReg = function( $ele ){\n var d = $ele[0]._cyreg = $ele[0]._cyreg || {};\n\n return d;\n};\n\nvar registerJquery = function( $, cytoscape ){\n if( !$ ){ return; } // no jquery => don't need this\n\n if( $.fn.cytoscape ){ return; } // already registered\n\n // allow calls on a jQuery selector by proxying calls to $.cytoscape\n // e.g. $(\"#foo\").cytoscape(options) => $.cytoscape(options) on #foo\n $.fn.cytoscape = function(opts){\n var $this = $(this);\n\n // get object\n if( opts === 'get' ){\n return cyReg( $this ).cy;\n }\n\n // bind to ready\n else if( is.fn(opts) ){\n\n var ready = opts;\n var cy = cyReg( $this ).cy;\n\n if( cy && cy.isReady() ){ // already ready so just trigger now\n cy.trigger('ready', [], ready);\n\n } else { // not yet ready, so add to readies list\n var data = cyReg( $this );\n var readies = data.readies = data.readies || [];\n\n readies.push( ready );\n }\n\n }\n\n // proxy to create instance\n else if( is.plainObject(opts) ){\n return $this.each(function(){\n var options = $.extend({}, opts, {\n container: $(this)[0]\n });\n\n cytoscape(options);\n });\n }\n };\n\n // allow access to the global cytoscape object under jquery for legacy reasons\n $.cytoscape = cytoscape;\n\n // use short alias (cy) if not already defined\n if( $.fn.cy == null && $.cy == null ){\n $.fn.cy = $.fn.cytoscape;\n $.cy = $.cytoscape;\n }\n};\n\nmodule.exports = registerJquery;\n","'use strict';\n\nvar math = {};\n\nmath.signum = function(x){\n if( x > 0 ){\n return 1;\n } else if( x < 0 ){\n return -1;\n } else {\n return 0;\n }\n};\n\nmath.distance = function( p1, p2 ){\n return Math.sqrt( math.sqDistance(p1, p2) );\n};\n\nmath.sqDistance = function( p1, p2 ){\n var dx = p2.x - p1.x;\n var dy = p2.y - p1.y;\n\n return dx*dx + dy*dy;\n};\n\n// from http://en.wikipedia.org/wiki/Bézier_curve#Quadratic_curves\nmath.qbezierAt = function(p0, p1, p2, t){\n return (1 - t)*(1 - t)*p0 + 2*(1 - t)*t*p1 + t*t*p2;\n};\n\nmath.qbezierPtAt = function(p0, p1, p2, t){\n return {\n x: math.qbezierAt( p0.x, p1.x, p2.x, t ),\n y: math.qbezierAt( p0.y, p1.y, p2.y, t )\n };\n};\n\n// makes a full bb (x1, y1, x2, y2, w, h) from implicit params\nmath.makeBoundingBox = function( bb ){\n if( bb.x1 != null && bb.y1 != null ){\n if( bb.x2 != null && bb.y2 != null && bb.x2 >= bb.x1 && bb.y2 >= bb.y1 ){\n return {\n x1: bb.x1,\n y1: bb.y1,\n x2: bb.x2,\n y2: bb.y2,\n w: bb.x2 - bb.x1,\n h: bb.y2 - bb.y1\n };\n } else if( bb.w != null && bb.h != null && bb.w >= 0 && bb.h >= 0 ){\n return {\n x1: bb.x1,\n y1: bb.y1,\n x2: bb.x1 + bb.w,\n y2: bb.y1 + bb.h,\n w: bb.w,\n h: bb.h\n };\n }\n }\n};\n\nmath.boundingBoxesIntersect = function( bb1, bb2 ){\n // case: one bb to right of other\n if( bb1.x1 > bb2.x2 ){ return false; }\n if( bb2.x1 > bb1.x2 ){ return false; }\n\n // case: one bb to left of other\n if( bb1.x2 < bb2.x1 ){ return false; }\n if( bb2.x2 < bb1.x1 ){ return false; }\n\n // case: one bb above other\n if( bb1.y2 < bb2.y1 ){ return false; }\n if( bb2.y2 < bb1.y1 ){ return false; }\n\n // case: one bb below other\n if( bb1.y1 > bb2.y2 ){ return false; }\n if( bb2.y1 > bb1.y2 ){ return false; }\n\n // otherwise, must have some overlap\n return true;\n};\n\nmath.inBoundingBox = function( bb, x, y ){\n return bb.x1 <= x && x <= bb.x2 && bb.y1 <= y && y <= bb.y2;\n};\n\nmath.pointInBoundingBox = function( bb, pt ){\n return this.inBoundingBox( bb, pt.x, pt.y );\n};\n\nmath.roundRectangleIntersectLine = function(\n x, y, nodeX, nodeY, width, height, padding) {\n\n var cornerRadius = this.getRoundRectangleRadius(width, height);\n\n var halfWidth = width / 2;\n var halfHeight = height / 2;\n\n // Check intersections with straight line segments\n var straightLineIntersections;\n\n // Top segment, left to right\n {\n var topStartX = nodeX - halfWidth + cornerRadius - padding;\n var topStartY = nodeY - halfHeight - padding;\n var topEndX = nodeX + halfWidth - cornerRadius + padding;\n var topEndY = topStartY;\n\n straightLineIntersections = this.finiteLinesIntersect(\n x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false);\n\n if (straightLineIntersections.length > 0) {\n return straightLineIntersections;\n }\n }\n\n // Right segment, top to bottom\n {\n var rightStartX = nodeX + halfWidth + padding;\n var rightStartY = nodeY - halfHeight + cornerRadius - padding;\n var rightEndX = rightStartX;\n var rightEndY = nodeY + halfHeight - cornerRadius + padding;\n\n straightLineIntersections = this.finiteLinesIntersect(\n x, y, nodeX, nodeY, rightStartX, rightStartY, rightEndX, rightEndY, false);\n\n if (straightLineIntersections.length > 0) {\n return straightLineIntersections;\n }\n }\n\n // Bottom segment, left to right\n {\n var bottomStartX = nodeX - halfWidth + cornerRadius - padding;\n var bottomStartY = nodeY + halfHeight + padding;\n var bottomEndX = nodeX + halfWidth - cornerRadius + padding;\n var bottomEndY = bottomStartY;\n\n straightLineIntersections = this.finiteLinesIntersect(\n x, y, nodeX, nodeY, bottomStartX, bottomStartY, bottomEndX, bottomEndY, false);\n\n if (straightLineIntersections.length > 0) {\n return straightLineIntersections;\n }\n }\n\n // Left segment, top to bottom\n {\n var leftStartX = nodeX - halfWidth - padding;\n var leftStartY = nodeY - halfHeight + cornerRadius - padding;\n var leftEndX = leftStartX;\n var leftEndY = nodeY + halfHeight - cornerRadius + padding;\n\n straightLineIntersections = this.finiteLinesIntersect(\n x, y, nodeX, nodeY, leftStartX, leftStartY, leftEndX, leftEndY, false);\n\n if (straightLineIntersections.length > 0) {\n return straightLineIntersections;\n }\n }\n\n // Check intersections with arc segments\n var arcIntersections;\n\n // Top Left\n {\n var topLeftCenterX = nodeX - halfWidth + cornerRadius;\n var topLeftCenterY = nodeY - halfHeight + cornerRadius;\n arcIntersections = this.intersectLineCircle(\n x, y, nodeX, nodeY,\n topLeftCenterX, topLeftCenterY, cornerRadius + padding);\n\n // Ensure the intersection is on the desired quarter of the circle\n if (arcIntersections.length > 0\n && arcIntersections[0] <= topLeftCenterX\n && arcIntersections[1] <= topLeftCenterY) {\n return [arcIntersections[0], arcIntersections[1]];\n }\n }\n\n // Top Right\n {\n var topRightCenterX = nodeX + halfWidth - cornerRadius;\n var topRightCenterY = nodeY - halfHeight + cornerRadius;\n arcIntersections = this.intersectLineCircle(\n x, y, nodeX, nodeY,\n topRightCenterX, topRightCenterY, cornerRadius + padding);\n\n // Ensure the intersection is on the desired quarter of the circle\n if (arcIntersections.length > 0\n && arcIntersections[0] >= topRightCenterX\n && arcIntersections[1] <= topRightCenterY) {\n return [arcIntersections[0], arcIntersections[1]];\n }\n }\n\n // Bottom Right\n {\n var bottomRightCenterX = nodeX + halfWidth - cornerRadius;\n var bottomRightCenterY = nodeY + halfHeight - cornerRadius;\n arcIntersections = this.intersectLineCircle(\n x, y, nodeX, nodeY,\n bottomRightCenterX, bottomRightCenterY, cornerRadius + padding);\n\n // Ensure the intersection is on the desired quarter of the circle\n if (arcIntersections.length > 0\n && arcIntersections[0] >= bottomRightCenterX\n && arcIntersections[1] >= bottomRightCenterY) {\n return [arcIntersections[0], arcIntersections[1]];\n }\n }\n\n // Bottom Left\n {\n var bottomLeftCenterX = nodeX - halfWidth + cornerRadius;\n var bottomLeftCenterY = nodeY + halfHeight - cornerRadius;\n arcIntersections = this.intersectLineCircle(\n x, y, nodeX, nodeY,\n bottomLeftCenterX, bottomLeftCenterY, cornerRadius + padding);\n\n // Ensure the intersection is on the desired quarter of the circle\n if (arcIntersections.length > 0\n && arcIntersections[0] <= bottomLeftCenterX\n && arcIntersections[1] >= bottomLeftCenterY) {\n return [arcIntersections[0], arcIntersections[1]];\n }\n }\n\n return []; // if nothing\n};\n\nmath.inLineVicinity = function(x, y, lx1, ly1, lx2, ly2, tolerance){\n var t = tolerance;\n\n var x1 = Math.min(lx1, lx2);\n var x2 = Math.max(lx1, lx2);\n var y1 = Math.min(ly1, ly2);\n var y2 = Math.max(ly1, ly2);\n\n return x1 - t <= x && x <= x2 + t\n && y1 - t <= y && y <= y2 + t;\n};\n\nmath.inBezierVicinity = function(\n x, y, x1, y1, x2, y2, x3, y3, tolerance) {\n\n var bb = {\n x1: Math.min( x1, x3, x2 ) - tolerance,\n x2: Math.max( x1, x3, x2 ) + tolerance,\n y1: Math.min( y1, y3, y2 ) - tolerance,\n y2: Math.max( y1, y3, y2 ) + tolerance\n };\n\n // if outside the rough bounding box for the bezier, then it can't be a hit\n if( x < bb.x1 || x > bb.x2 || y < bb.y1 || y > bb.y2 ){\n // console.log('bezier out of rough bb')\n return false;\n } else {\n // console.log('do more expensive check');\n return true;\n }\n\n};\n\nmath.solveCubic = function(a, b, c, d, result) {\n\n // Solves a cubic function, returns root in form [r1, i1, r2, i2, r3, i3], where\n // r is the real component, i is the imaginary component\n\n // An implementation of the Cardano method from the year 1545\n // http://en.wikipedia.org/wiki/Cubic_function#The_nature_of_the_roots\n\n b /= a;\n c /= a;\n d /= a;\n\n var discriminant, q, r, dum1, s, t, term1, r13;\n\n q = (3.0 * c - (b * b)) / 9.0;\n r = -(27.0 * d) + b * (9.0 * c - 2.0 * (b * b));\n r /= 54.0;\n\n discriminant = q * q * q + r * r;\n result[1] = 0;\n term1 = (b / 3.0);\n\n if (discriminant > 0) {\n s = r + Math.sqrt(discriminant);\n s = ((s < 0) ? -Math.pow(-s, (1.0 / 3.0)) : Math.pow(s, (1.0 / 3.0)));\n t = r - Math.sqrt(discriminant);\n t = ((t < 0) ? -Math.pow(-t, (1.0 / 3.0)) : Math.pow(t, (1.0 / 3.0)));\n result[0] = -term1 + s + t;\n term1 += (s + t) / 2.0;\n result[4] = result[2] = -term1;\n term1 = Math.sqrt(3.0) * (-t + s) / 2;\n result[3] = term1;\n result[5] = -term1;\n return;\n }\n\n result[5] = result[3] = 0;\n\n if (discriminant === 0) {\n r13 = ((r < 0) ? -Math.pow(-r, (1.0 / 3.0)) : Math.pow(r, (1.0 / 3.0)));\n result[0] = -term1 + 2.0 * r13;\n result[4] = result[2] = -(r13 + term1);\n return;\n }\n\n q = -q;\n dum1 = q * q * q;\n dum1 = Math.acos(r / Math.sqrt(dum1));\n r13 = 2.0 * Math.sqrt(q);\n result[0] = -term1 + r13 * Math.cos(dum1 / 3.0);\n result[2] = -term1 + r13 * Math.cos((dum1 + 2.0 * Math.PI) / 3.0);\n result[4] = -term1 + r13 * Math.cos((dum1 + 4.0 * Math.PI) / 3.0);\n\n return;\n};\n\nmath.sqDistanceToQuadraticBezier = function(\n x, y, x1, y1, x2, y2, x3, y3) {\n\n // Find minimum distance by using the minimum of the distance\n // function between the given point and the curve\n\n // This gives the coefficients of the resulting cubic equation\n // whose roots tell us where a possible minimum is\n // (Coefficients are divided by 4)\n\n var a = 1.0 * x1*x1 - 4*x1*x2 + 2*x1*x3 + 4*x2*x2 - 4*x2*x3 + x3*x3\n + y1*y1 - 4*y1*y2 + 2*y1*y3 + 4*y2*y2 - 4*y2*y3 + y3*y3;\n\n var b = 1.0 * 9*x1*x2 - 3*x1*x1 - 3*x1*x3 - 6*x2*x2 + 3*x2*x3\n + 9*y1*y2 - 3*y1*y1 - 3*y1*y3 - 6*y2*y2 + 3*y2*y3;\n\n var c = 1.0 * 3*x1*x1 - 6*x1*x2 + x1*x3 - x1*x + 2*x2*x2 + 2*x2*x - x3*x\n + 3*y1*y1 - 6*y1*y2 + y1*y3 - y1*y + 2*y2*y2 + 2*y2*y - y3*y;\n\n var d = 1.0 * x1*x2 - x1*x1 + x1*x - x2*x\n + y1*y2 - y1*y1 + y1*y - y2*y;\n\n // debug(\"coefficients: \" + a / a + \", \" + b / a + \", \" + c / a + \", \" + d / a);\n\n var roots = [];\n\n // Use the cubic solving algorithm\n this.solveCubic(a, b, c, d, roots);\n\n var zeroThreshold = 0.0000001;\n\n var params = [];\n\n for (var index = 0; index < 6; index += 2) {\n if (Math.abs(roots[index + 1]) < zeroThreshold\n && roots[index] >= 0\n && roots[index] <= 1.0) {\n params.push(roots[index]);\n }\n }\n\n params.push(1.0);\n params.push(0.0);\n\n var minDistanceSquared = -1;\n var closestParam;\n\n var curX, curY, distSquared;\n for (var i = 0; i < params.length; i++) {\n curX = Math.pow(1.0 - params[i], 2.0) * x1\n + 2.0 * (1 - params[i]) * params[i] * x2\n + params[i] * params[i] * x3;\n\n curY = Math.pow(1 - params[i], 2.0) * y1\n + 2 * (1.0 - params[i]) * params[i] * y2\n + params[i] * params[i] * y3;\n\n distSquared = Math.pow(curX - x, 2) + Math.pow(curY - y, 2);\n // debug('distance for param ' + params[i] + \": \" + Math.sqrt(distSquared));\n if (minDistanceSquared >= 0) {\n if (distSquared < minDistanceSquared) {\n minDistanceSquared = distSquared;\n closestParam = params[i];\n }\n } else {\n minDistanceSquared = distSquared;\n closestParam = params[i];\n }\n }\n\n return minDistanceSquared;\n};\n\nmath.sqDistanceToFiniteLine = function(x, y, x1, y1, x2, y2) {\n var offset = [x - x1, y - y1];\n var line = [x2 - x1, y2 - y1];\n\n var lineSq = line[0] * line[0] + line[1] * line[1];\n var hypSq = offset[0] * offset[0] + offset[1] * offset[1];\n\n var dotProduct = offset[0] * line[0] + offset[1] * line[1];\n var adjSq = dotProduct * dotProduct / lineSq;\n\n if (dotProduct < 0) {\n return hypSq;\n }\n\n if (adjSq > lineSq) {\n return (x - x2) * (x - x2) + (y - y2) * (y - y2);\n }\n\n return hypSq - adjSq;\n};\n\nmath.pointInsidePolygonPoints = function(x, y, points){\n var x1, y1, x2, y2;\n var y3;\n\n // Intersect with vertical line through (x, y)\n var up = 0;\n var down = 0;\n for (var i = 0; i < points.length / 2; i++) {\n\n x1 = points[i * 2];\n y1 = points[i * 2 + 1];\n\n if (i + 1 < points.length / 2) {\n x2 = points[(i + 1) * 2];\n y2 = points[(i + 1) * 2 + 1];\n } else {\n x2 = points[(i + 1 - points.length / 2) * 2];\n y2 = points[(i + 1 - points.length / 2) * 2 + 1];\n }\n\n if (x1 == x && x2 == x) {\n\n } else if ((x1 >= x && x >= x2)\n || (x1 <= x && x <= x2)) {\n\n y3 = (x - x1) / (x2 - x1) * (y2 - y1) + y1;\n\n if (y3 > y) {\n up++;\n }\n\n if (y3 < y) {\n down++;\n }\n\n } else {\n continue;\n }\n\n }\n\n if (up % 2 === 0) {\n return false;\n } else {\n return true;\n }\n};\n\nmath.pointInsidePolygon = function(\n x, y, basePoints, centerX, centerY, width, height, direction, padding) {\n\n //var direction = arguments[6];\n var transformedPoints = new Array(basePoints.length);\n\n // Gives negative angle\n var angle;\n\n if( direction[0] != null ){\n angle = Math.atan(direction[1] / direction[0]);\n\n if (direction[0] < 0) {\n angle = angle + Math.PI / 2;\n } else {\n angle = -angle - Math.PI / 2;\n }\n } else {\n angle = direction;\n }\n\n var cos = Math.cos(-angle);\n var sin = Math.sin(-angle);\n\n // console.log(\"base: \" + basePoints);\n for (var i = 0; i < transformedPoints.length / 2; i++) {\n transformedPoints[i * 2] =\n width / 2 * (basePoints[i * 2] * cos\n - basePoints[i * 2 + 1] * sin);\n\n transformedPoints[i * 2 + 1] =\n height / 2 * (basePoints[i * 2 + 1] * cos\n + basePoints[i * 2] * sin);\n\n transformedPoints[i * 2] += centerX;\n transformedPoints[i * 2 + 1] += centerY;\n }\n\n var points;\n\n if (padding > 0) {\n var expandedLineSet = this.expandPolygon(\n transformedPoints,\n -padding);\n\n points = this.joinLines(expandedLineSet);\n } else {\n points = transformedPoints;\n }\n\n return math.pointInsidePolygonPoints( x, y, points );\n};\n\nmath.joinLines = function(lineSet) {\n\n var vertices = new Array(lineSet.length / 2);\n\n var currentLineStartX, currentLineStartY, currentLineEndX, currentLineEndY;\n var nextLineStartX, nextLineStartY, nextLineEndX, nextLineEndY;\n\n for (var i = 0; i < lineSet.length / 4; i++) {\n currentLineStartX = lineSet[i * 4];\n currentLineStartY = lineSet[i * 4 + 1];\n currentLineEndX = lineSet[i * 4 + 2];\n currentLineEndY = lineSet[i * 4 + 3];\n\n if (i < lineSet.length / 4 - 1) {\n nextLineStartX = lineSet[(i + 1) * 4];\n nextLineStartY = lineSet[(i + 1) * 4 + 1];\n nextLineEndX = lineSet[(i + 1) * 4 + 2];\n nextLineEndY = lineSet[(i + 1) * 4 + 3];\n } else {\n nextLineStartX = lineSet[0];\n nextLineStartY = lineSet[1];\n nextLineEndX = lineSet[2];\n nextLineEndY = lineSet[3];\n }\n\n var intersection = this.finiteLinesIntersect(\n currentLineStartX, currentLineStartY,\n currentLineEndX, currentLineEndY,\n nextLineStartX, nextLineStartY,\n nextLineEndX, nextLineEndY,\n true);\n\n vertices[i * 2] = intersection[0];\n vertices[i * 2 + 1] = intersection[1];\n }\n\n return vertices;\n};\n\nmath.expandPolygon = function(points, pad) {\n\n var expandedLineSet = new Array(points.length * 2);\n\n var currentPointX, currentPointY, nextPointX, nextPointY;\n\n for (var i = 0; i < points.length / 2; i++) {\n currentPointX = points[i * 2];\n currentPointY = points[i * 2 + 1];\n\n if (i < points.length / 2 - 1) {\n nextPointX = points[(i + 1) * 2];\n nextPointY = points[(i + 1) * 2 + 1];\n } else {\n nextPointX = points[0];\n nextPointY = points[1];\n }\n\n // Current line: [currentPointX, currentPointY] to [nextPointX, nextPointY]\n\n // Assume CCW polygon winding\n\n var offsetX = (nextPointY - currentPointY);\n var offsetY = -(nextPointX - currentPointX);\n\n // Normalize\n var offsetLength = Math.sqrt(offsetX * offsetX + offsetY * offsetY);\n var normalizedOffsetX = offsetX / offsetLength;\n var normalizedOffsetY = offsetY / offsetLength;\n\n expandedLineSet[i * 4] = currentPointX + normalizedOffsetX * pad;\n expandedLineSet[i * 4 + 1] = currentPointY + normalizedOffsetY * pad;\n expandedLineSet[i * 4 + 2] = nextPointX + normalizedOffsetX * pad;\n expandedLineSet[i * 4 + 3] = nextPointY + normalizedOffsetY * pad;\n }\n\n return expandedLineSet;\n};\n\nmath.intersectLineEllipse = function(\n x, y, centerX, centerY, ellipseWradius, ellipseHradius) {\n\n var dispX = centerX - x;\n var dispY = centerY - y;\n\n dispX /= ellipseWradius;\n dispY /= ellipseHradius;\n\n var len = Math.sqrt(dispX * dispX + dispY * dispY);\n\n var newLength = len - 1;\n\n if (newLength < 0) {\n return [];\n }\n\n var lenProportion = newLength / len;\n\n return [(centerX - x) * lenProportion + x, (centerY - y) * lenProportion + y];\n};\n\n// Returns intersections of increasing distance from line's start point\nmath.intersectLineCircle = function(\n x1, y1, x2, y2, centerX, centerY, radius) {\n\n // Calculate d, direction vector of line\n var d = [x2 - x1, y2 - y1]; // Direction vector of line\n var c = [centerX, centerY]; // Center of circle\n var f = [x1 - centerX, y1 - centerY];\n\n var a = d[0] * d[0] + d[1] * d[1];\n var b = 2 * (f[0] * d[0] + f[1] * d[1]);\n var c = (f[0] * f[0] + f[1] * f[1]) - radius * radius ;\n\n var discriminant = b*b-4*a*c;\n\n if (discriminant < 0) {\n return [];\n }\n\n var t1 = (-b + Math.sqrt(discriminant)) / (2 * a);\n var t2 = (-b - Math.sqrt(discriminant)) / (2 * a);\n\n var tMin = Math.min(t1, t2);\n var tMax = Math.max(t1, t2);\n var inRangeParams = [];\n\n if (tMin >= 0 && tMin <= 1) {\n inRangeParams.push(tMin);\n }\n\n if (tMax >= 0 && tMax <= 1) {\n inRangeParams.push(tMax);\n }\n\n if (inRangeParams.length === 0) {\n return [];\n }\n\n var nearIntersectionX = inRangeParams[0] * d[0] + x1;\n var nearIntersectionY = inRangeParams[0] * d[1] + y1;\n\n if (inRangeParams.length > 1) {\n\n if (inRangeParams[0] == inRangeParams[1]) {\n return [nearIntersectionX, nearIntersectionY];\n } else {\n\n var farIntersectionX = inRangeParams[1] * d[0] + x1;\n var farIntersectionY = inRangeParams[1] * d[1] + y1;\n\n return [nearIntersectionX, nearIntersectionY, farIntersectionX, farIntersectionY];\n }\n\n } else {\n return [nearIntersectionX, nearIntersectionY];\n }\n\n};\n\nmath.findCircleNearPoint = function(centerX, centerY,\n radius, farX, farY) {\n\n var displacementX = farX - centerX;\n var displacementY = farY - centerY;\n var distance = Math.sqrt(displacementX * displacementX\n + displacementY * displacementY);\n\n var unitDisplacementX = displacementX / distance;\n var unitDisplacementY = displacementY / distance;\n\n return [centerX + unitDisplacementX * radius,\n centerY + unitDisplacementY * radius];\n};\n\nmath.findMaxSqDistanceToOrigin = function(points) {\n var maxSqDistance = 0.000001;\n var sqDistance;\n\n for (var i = 0; i < points.length / 2; i++) {\n\n sqDistance = points[i * 2] * points[i * 2]\n + points[i * 2 + 1] * points[i * 2 + 1];\n\n if (sqDistance > maxSqDistance) {\n maxSqDistance = sqDistance;\n }\n }\n\n return maxSqDistance;\n};\n\nmath.finiteLinesIntersect = function(\n x1, y1, x2, y2, x3, y3, x4, y4, infiniteLines) {\n\n var ua_t = (x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3);\n var ub_t = (x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3);\n var u_b = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);\n\n if (u_b !== 0) {\n var ua = ua_t / u_b;\n var ub = ub_t / u_b;\n\n if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) {\n return [x1 + ua * (x2 - x1), y1 + ua * (y2 - y1)];\n\n } else {\n if (!infiniteLines) {\n return [];\n } else {\n return [x1 + ua * (x2 - x1), y1 + ua * (y2 - y1)];\n }\n }\n } else {\n if (ua_t === 0 || ub_t === 0) {\n\n // Parallel, coincident lines. Check if overlap\n\n // Check endpoint of second line\n if ([x1, x2, x4].sort()[1] === x4) {\n return [x4, y4];\n }\n\n // Check start point of second line\n if ([x1, x2, x3].sort()[1] === x3) {\n return [x3, y3];\n }\n\n // Endpoint of first line\n if ([x3, x4, x2].sort()[1] === x2) {\n return [x2, y2];\n }\n\n return [];\n } else {\n\n // Parallel, non-coincident\n return [];\n }\n }\n};\n\nmath.polygonIntersectLine = function(\n x, y, basePoints, centerX, centerY, width, height, padding) {\n\n var intersections = [];\n var intersection;\n\n var transformedPoints = new Array(basePoints.length);\n\n for (var i = 0; i < transformedPoints.length / 2; i++) {\n transformedPoints[i * 2] = basePoints[i * 2] * width + centerX;\n transformedPoints[i * 2 + 1] = basePoints[i * 2 + 1] * height + centerY;\n }\n\n var points;\n\n if (padding > 0) {\n var expandedLineSet = math.expandPolygon(\n transformedPoints,\n -padding);\n\n points = math.joinLines(expandedLineSet);\n } else {\n points = transformedPoints;\n }\n // var points = transformedPoints;\n\n var currentX, currentY, nextX, nextY;\n\n for (var i = 0; i < points.length / 2; i++) {\n\n currentX = points[i * 2];\n currentY = points[i * 2 + 1];\n\n if (i < points.length / 2 - 1) {\n nextX = points[(i + 1) * 2];\n nextY = points[(i + 1) * 2 + 1];\n } else {\n nextX = points[0];\n nextY = points[1];\n }\n\n intersection = this.finiteLinesIntersect(\n x, y, centerX, centerY,\n currentX, currentY,\n nextX, nextY);\n\n if (intersection.length !== 0) {\n intersections.push(intersection[0], intersection[1]);\n }\n }\n\n return intersections;\n};\n\nmath.shortenIntersection = function(\n intersection, offset, amount) {\n\n var disp = [intersection[0] - offset[0], intersection[1] - offset[1]];\n\n var length = Math.sqrt(disp[0] * disp[0] + disp[1] * disp[1]);\n\n var lenRatio = (length - amount) / length;\n\n if (lenRatio < 0) {\n lenRatio = 0.00001;\n }\n\n return [offset[0] + lenRatio * disp[0], offset[1] + lenRatio * disp[1]];\n};\n\nmath.generateUnitNgonPointsFitToSquare = function(sides, rotationRadians) {\n var points = math.generateUnitNgonPoints(sides, rotationRadians);\n points = math.fitPolygonToSquare(points);\n\n return points;\n};\n\nmath.fitPolygonToSquare = function(points){\n var x, y;\n var sides = points.length/2;\n var minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n\n for (var i = 0; i < sides; i++) {\n x = points[2 * i];\n y = points[2 * i + 1];\n\n minX = Math.min( minX, x );\n maxX = Math.max( maxX, x );\n minY = Math.min( minY, y );\n maxY = Math.max( maxY, y );\n }\n\n // stretch factors\n var sx = 2 / (maxX - minX);\n var sy = 2 / (maxY - minY);\n\n for (var i = 0; i < sides; i++){\n x = points[2 * i] = points[2 * i] * sx;\n y = points[2 * i + 1] = points[2 * i + 1] * sy;\n\n minX = Math.min( minX, x );\n maxX = Math.max( maxX, x );\n minY = Math.min( minY, y );\n maxY = Math.max( maxY, y );\n }\n\n if( minY < -1 ){\n for (var i = 0; i < sides; i++){\n y = points[2 * i + 1] = points[2 * i + 1] + (-1 -minY);\n }\n }\n\n return points;\n};\n\nmath.generateUnitNgonPoints = function(sides, rotationRadians) {\n\n var increment = 1.0 / sides * 2 * Math.PI;\n var startAngle = sides % 2 === 0 ?\n Math.PI / 2.0 + increment / 2.0 : Math.PI / 2.0;\n // console.log(nodeShapes['square']);\n startAngle += rotationRadians;\n\n var points = new Array(sides * 2);\n\n var currentAngle, x, y;\n for (var i = 0; i < sides; i++) {\n currentAngle = i * increment + startAngle;\n\n x = points[2 * i] = Math.cos(currentAngle);// * (1 + i/2);\n y = points[2 * i + 1] = Math.sin(-currentAngle);// * (1 + i/2);\n }\n\n return points;\n};\n\nmath.getRoundRectangleRadius = function(width, height) {\n\n // Set the default radius, unless half of width or height is smaller than default\n return Math.min(width / 4, height / 4, 8);\n};\n\nmodule.exports = math;\n","// internal, minimal Promise impl s.t. apis can return promises in old envs\n// based on thenable (http://github.com/rse/thenable)\n\n'use strict';\n\n/* promise states [Promises/A+ 2.1] */\nvar STATE_PENDING = 0; /* [Promises/A+ 2.1.1] */\nvar STATE_FULFILLED = 1; /* [Promises/A+ 2.1.2] */\nvar STATE_REJECTED = 2; /* [Promises/A+ 2.1.3] */\n\n/* promise object constructor */\nvar api = function (executor) {\n /* optionally support non-constructor/plain-function call */\n if (!(this instanceof api))\n return new api(executor);\n\n /* initialize object */\n this.id = \"Thenable/1.0.7\";\n this.state = STATE_PENDING; /* initial state */\n this.fulfillValue = undefined; /* initial value */ /* [Promises/A+ 1.3, 2.1.2.2] */\n this.rejectReason = undefined; /* initial reason */ /* [Promises/A+ 1.5, 2.1.3.2] */\n this.onFulfilled = []; /* initial handlers */\n this.onRejected = []; /* initial handlers */\n\n /* provide optional information-hiding proxy */\n this.proxy = {\n then: this.then.bind(this)\n };\n\n /* support optional executor function */\n if (typeof executor === \"function\")\n executor.call(this, this.fulfill.bind(this), this.reject.bind(this));\n};\n\n/* promise API methods */\napi.prototype = {\n /* promise resolving methods */\n fulfill: function (value) { return deliver(this, STATE_FULFILLED, \"fulfillValue\", value); },\n reject: function (value) { return deliver(this, STATE_REJECTED, \"rejectReason\", value); },\n\n /* \"The then Method\" [Promises/A+ 1.1, 1.2, 2.2] */\n then: function (onFulfilled, onRejected) {\n var curr = this;\n var next = new api(); /* [Promises/A+ 2.2.7] */\n curr.onFulfilled.push(\n resolver(onFulfilled, next, \"fulfill\")); /* [Promises/A+ 2.2.2/2.2.6] */\n curr.onRejected.push(\n resolver(onRejected, next, \"reject\" )); /* [Promises/A+ 2.2.3/2.2.6] */\n execute(curr);\n return next.proxy; /* [Promises/A+ 2.2.7, 3.3] */\n }\n};\n\n/* deliver an action */\nvar deliver = function (curr, state, name, value) {\n if (curr.state === STATE_PENDING) {\n curr.state = state; /* [Promises/A+ 2.1.2.1, 2.1.3.1] */\n curr[name] = value; /* [Promises/A+ 2.1.2.2, 2.1.3.2] */\n execute(curr);\n }\n return curr;\n};\n\n/* execute all handlers */\nvar execute = function (curr) {\n if (curr.state === STATE_FULFILLED)\n execute_handlers(curr, \"onFulfilled\", curr.fulfillValue);\n else if (curr.state === STATE_REJECTED)\n execute_handlers(curr, \"onRejected\", curr.rejectReason);\n};\n\n/* execute particular set of handlers */\nvar execute_handlers = function (curr, name, value) {\n /* global setImmediate: true */\n /* global setTimeout: true */\n\n /* short-circuit processing */\n if (curr[name].length === 0)\n return;\n\n /* iterate over all handlers, exactly once */\n var handlers = curr[name];\n curr[name] = []; /* [Promises/A+ 2.2.2.3, 2.2.3.3] */\n var func = function () {\n for (var i = 0; i < handlers.length; i++)\n handlers[i](value); /* [Promises/A+ 2.2.5] */\n };\n\n /* execute procedure asynchronously */ /* [Promises/A+ 2.2.4, 3.1] */\n if (typeof setImmediate === \"function\")\n setImmediate(func);\n else\n setTimeout(func, 0);\n};\n\n/* generate a resolver function */\nvar resolver = function (cb, next, method) {\n return function (value) {\n if (typeof cb !== \"function\") /* [Promises/A+ 2.2.1, 2.2.7.3, 2.2.7.4] */\n next[method].call(next, value); /* [Promises/A+ 2.2.7.3, 2.2.7.4] */\n else {\n var result;\n try { result = cb(value); } /* [Promises/A+ 2.2.2.1, 2.2.3.1, 2.2.5, 3.2] */\n catch (e) {\n next.reject(e); /* [Promises/A+ 2.2.7.2] */\n return;\n }\n resolve(next, result); /* [Promises/A+ 2.2.7.1] */\n }\n };\n};\n\n/* \"Promise Resolution Procedure\" */ /* [Promises/A+ 2.3] */\nvar resolve = function (promise, x) {\n /* sanity check arguments */ /* [Promises/A+ 2.3.1] */\n if (promise === x || promise.proxy === x) {\n promise.reject(new TypeError(\"cannot resolve promise with itself\"));\n return;\n }\n\n /* surgically check for a \"then\" method\n (mainly to just call the \"getter\" of \"then\" only once) */\n var then;\n if ((typeof x === \"object\" && x !== null) || typeof x === \"function\") {\n try { then = x.then; } /* [Promises/A+ 2.3.3.1, 3.5] */\n catch (e) {\n promise.reject(e); /* [Promises/A+ 2.3.3.2] */\n return;\n }\n }\n\n /* handle own Thenables [Promises/A+ 2.3.2]\n and similar \"thenables\" [Promises/A+ 2.3.3] */\n if (typeof then === \"function\") {\n var resolved = false;\n try {\n /* call retrieved \"then\" method */ /* [Promises/A+ 2.3.3.3] */\n then.call(x,\n /* resolvePromise */ /* [Promises/A+ 2.3.3.3.1] */\n function (y) {\n if (resolved) return; resolved = true; /* [Promises/A+ 2.3.3.3.3] */\n if (y === x) /* [Promises/A+ 3.6] */\n promise.reject(new TypeError(\"circular thenable chain\"));\n else\n resolve(promise, y);\n },\n\n /* rejectPromise */ /* [Promises/A+ 2.3.3.3.2] */\n function (r) {\n if (resolved) return; resolved = true; /* [Promises/A+ 2.3.3.3.3] */\n promise.reject(r);\n }\n );\n }\n catch (e) {\n if (!resolved) /* [Promises/A+ 2.3.3.3.3] */\n promise.reject(e); /* [Promises/A+ 2.3.3.3.4] */\n }\n return;\n }\n\n /* handle other values */\n promise.fulfill(x); /* [Promises/A+ 2.3.4, 2.3.3.4] */\n};\n\n// use native promises where possible\nvar Promise = typeof Promise === 'undefined' ? api : Promise;\n\n// so we always have Promise.all()\nPromise.all = Promise.all || function( ps ){\n return new Promise(function( resolveAll, rejectAll ){\n var vals = new Array( ps.length );\n var doneCount = 0;\n\n var fulfill = function( i, val ){\n vals[i] = val;\n doneCount++;\n\n if( doneCount === ps.length ){\n resolveAll( vals );\n }\n };\n\n for( var i = 0; i < ps.length; i++ ){\n (function( i ){\n var p = ps[i];\n var isPromise = p.then != null;\n\n if( isPromise ){\n p.then(function( val ){\n fulfill( i, val );\n }, function( err ){\n rejectAll( err );\n });\n } else {\n var val = p;\n fulfill( i, val );\n }\n })( i );\n }\n\n });\n};\n\nmodule.exports = Promise;\n","'use strict';\n\nvar is = require('./is');\nvar util = require('./util');\n\nvar Selector = function( onlyThisGroup, selector ){\n\n if( !(this instanceof Selector) ){\n return new Selector(onlyThisGroup, selector);\n }\n\n if( selector === undefined && onlyThisGroup !== undefined ){\n selector = onlyThisGroup;\n onlyThisGroup = undefined;\n }\n\n var self = this;\n\n self._private = {\n selectorText: null,\n invalid: true\n };\n\n if( !selector || ( is.string(selector) && selector.match(/^\\s*$/) ) ){\n\n if( onlyThisGroup == null ){\n // ignore\n self.length = 0;\n } else {\n self[0] = newQuery();\n self[0].group = onlyThisGroup;\n self.length = 1;\n }\n\n } else if( is.elementOrCollection( selector ) ){\n var collection = selector.collection();\n\n self[0] = newQuery();\n self[0].collection = collection;\n self.length = 1;\n\n } else if( is.fn( selector ) ) {\n self[0] = newQuery();\n self[0].filter = selector;\n self.length = 1;\n\n } else if( is.string( selector ) ){\n\n // the current subject in the query\n var currentSubject = null;\n\n // storage for parsed queries\n var newQuery = function(){\n return {\n classes: [],\n colonSelectors: [],\n data: [],\n group: null,\n ids: [],\n meta: [],\n\n // fake selectors\n collection: null, // a collection to match against\n filter: null, // filter function\n\n // these are defined in the upward direction rather than down (e.g. child)\n // because we need to go up in Selector.filter()\n parent: null, // parent query obj\n ancestor: null, // ancestor query obj\n subject: null, // defines subject in compound query (subject query obj; points to self if subject)\n\n // use these only when subject has been defined\n child: null,\n descendant: null\n };\n };\n\n // tokens in the query language\n var tokens = {\n metaChar: '[\\\\!\\\\\"\\\\#\\\\$\\\\%\\\\&\\\\\\'\\\\(\\\\)\\\\*\\\\+\\\\,\\\\.\\\\/\\\\:\\\\;\\\\<\\\\=\\\\>\\\\?\\\\@\\\\[\\\\]\\\\^\\\\`\\\\{\\\\|\\\\}\\\\~]', // chars we need to escape in var names, etc\n comparatorOp: '=|\\\\!=|>|>=|<|<=|\\\\$=|\\\\^=|\\\\*=', // binary comparison op (used in data selectors)\n boolOp: '\\\\?|\\\\!|\\\\^', // boolean (unary) operators (used in data selectors)\n string: '\"(?:\\\\\\\\\"|[^\"])+\"' + '|' + \"'(?:\\\\\\\\'|[^'])+'\", // string literals (used in data selectors) -- doublequotes | singlequotes\n number: util.regex.number, // number literal (used in data selectors) --- e.g. 0.1234, 1234, 12e123\n meta: 'degree|indegree|outdegree', // allowed metadata fields (i.e. allowed functions to use from Collection)\n separator: '\\\\s*,\\\\s*', // queries are separated by commas, e.g. edge[foo = 'bar'], node.someClass\n descendant: '\\\\s+',\n child: '\\\\s+>\\\\s+',\n subject: '\\\\$'\n };\n tokens.variable = '(?:[\\\\w-]|(?:\\\\\\\\'+ tokens.metaChar +'))+'; // a variable name\n tokens.value = tokens.string + '|' + tokens.number; // a value literal, either a string or number\n tokens.className = tokens.variable; // a class name (follows variable conventions)\n tokens.id = tokens.variable; // an element id (follows variable conventions)\n\n // when a token like a variable has escaped meta characters, we need to clean the backslashes out\n // so that values get compared properly in Selector.filter()\n var cleanMetaChars = function(str){\n return str.replace(new RegExp('\\\\\\\\(' + tokens.metaChar + ')', 'g'), function(match, $1, offset, original){\n return $1;\n });\n };\n\n // add @ variants to comparatorOp\n var ops = tokens.comparatorOp.split('|');\n for( var i = 0; i < ops.length; i++ ){\n var op = ops[i];\n tokens.comparatorOp += '|@' + op;\n }\n\n // add ! variants to comparatorOp\n var ops = tokens.comparatorOp.split('|');\n for( var i = 0; i < ops.length; i++ ){\n var op = ops[i];\n\n if( op.indexOf('!') >= 0 ){ continue; } // skip ops that explicitly contain !\n if( op === '=' ){ continue; } // skip = b/c != is explicitly defined\n\n tokens.comparatorOp += '|\\\\!' + op;\n }\n\n // NOTE: add new expression syntax here to have it recognised by the parser;\n // - a query contains all adjacent (i.e. no separator in between) expressions;\n // - the current query is stored in self[i] --- you can use the reference to `this` in the populate function;\n // - you need to check the query objects in Selector.filter() for it actually filter properly, but that's pretty straight forward\n // - when you add something here, also add to Selector.toString()\n var exprs = [\n {\n name: 'group',\n query: true,\n regex: '(node|edge|\\\\*)',\n populate: function( group ){\n this.group = group == \"*\" ? group : group + 's';\n }\n },\n\n {\n name: 'state',\n query: true,\n // NB: if one colon selector is a substring of another from its start, place the longer one first\n // e.g. :foobar|:foo\n regex: '(:selected|:unselected|:locked|:unlocked|:visible|:hidden|:transparent|:grabbed|:free|:removed|:inside|:grabbable|:ungrabbable|:animated|:unanimated|:selectable|:unselectable|:orphan|:nonorphan|:parent|:child|:loop|:simple|:active|:inactive|:touch|:backgrounding|:nonbackgrounding)',\n populate: function( state ){\n this.colonSelectors.push( state );\n }\n },\n\n {\n name: 'id',\n query: true,\n regex: '\\\\#('+ tokens.id +')',\n populate: function( id ){\n this.ids.push( cleanMetaChars(id) );\n }\n },\n\n {\n name: 'className',\n query: true,\n regex: '\\\\.('+ tokens.className +')',\n populate: function( className ){\n this.classes.push( cleanMetaChars(className) );\n }\n },\n\n {\n name: 'dataExists',\n query: true,\n regex: '\\\\[\\\\s*('+ tokens.variable +')\\\\s*\\\\]',\n populate: function( variable ){\n this.data.push({\n field: cleanMetaChars(variable)\n });\n }\n },\n\n {\n name: 'dataCompare',\n query: true,\n regex: '\\\\[\\\\s*('+ tokens.variable +')\\\\s*('+ tokens.comparatorOp +')\\\\s*('+ tokens.value +')\\\\s*\\\\]',\n populate: function( variable, comparatorOp, value ){\n var valueIsString = new RegExp('^' + tokens.string + '$').exec(value) != null;\n\n if( valueIsString ){\n value = value.substring(1, value.length - 1);\n } else {\n value = parseFloat(value);\n }\n\n this.data.push({\n field: cleanMetaChars(variable),\n operator: comparatorOp,\n value: value\n });\n }\n },\n\n {\n name: 'dataBool',\n query: true,\n regex: '\\\\[\\\\s*('+ tokens.boolOp +')\\\\s*('+ tokens.variable +')\\\\s*\\\\]',\n populate: function( boolOp, variable ){\n this.data.push({\n field: cleanMetaChars(variable),\n operator: boolOp\n });\n }\n },\n\n {\n name: 'metaCompare',\n query: true,\n regex: '\\\\[\\\\[\\\\s*('+ tokens.meta +')\\\\s*('+ tokens.comparatorOp +')\\\\s*('+ tokens.number +')\\\\s*\\\\]\\\\]',\n populate: function( meta, comparatorOp, number ){\n this.meta.push({\n field: cleanMetaChars(meta),\n operator: comparatorOp,\n value: parseFloat(number)\n });\n }\n },\n\n {\n name: 'nextQuery',\n separator: true,\n regex: tokens.separator,\n populate: function(){\n // go on to next query\n self[++i] = newQuery();\n currentSubject = null;\n }\n },\n\n {\n name: 'child',\n separator: true,\n regex: tokens.child,\n populate: function(){\n // this query is the parent of the following query\n var childQuery = newQuery();\n childQuery.parent = this;\n childQuery.subject = currentSubject;\n\n // we're now populating the child query with expressions that follow\n self[i] = childQuery;\n }\n },\n\n {\n name: 'descendant',\n separator: true,\n regex: tokens.descendant,\n populate: function(){\n // this query is the ancestor of the following query\n var descendantQuery = newQuery();\n descendantQuery.ancestor = this;\n descendantQuery.subject = currentSubject;\n\n // we're now populating the descendant query with expressions that follow\n self[i] = descendantQuery;\n }\n },\n\n {\n name: 'subject',\n modifier: true,\n regex: tokens.subject,\n populate: function(){\n if( currentSubject != null && this.subject != this ){\n util.error('Redefinition of subject in selector `' + selector + '`');\n return false;\n }\n\n currentSubject = this;\n this.subject = this;\n }\n\n }\n ];\n\n self._private.selectorText = selector;\n var remaining = selector;\n var i = 0;\n\n // of all the expressions, find the first match in the remaining text\n var consumeExpr = function( expectation ){\n var expr;\n var match;\n var name;\n\n for( var j = 0; j < exprs.length; j++ ){\n var e = exprs[j];\n var n = e.name;\n\n // ignore this expression if it doesn't meet the expectation function\n if( is.fn( expectation ) && !expectation(n, e) ){ continue; }\n\n var m = remaining.match(new RegExp( '^' + e.regex ));\n\n if( m != null ){\n match = m;\n expr = e;\n name = n;\n\n var consumed = m[0];\n remaining = remaining.substring( consumed.length );\n\n break; // we've consumed one expr, so we can return now\n }\n }\n\n return {\n expr: expr,\n match: match,\n name: name\n };\n };\n\n // consume all leading whitespace\n var consumeWhitespace = function(){\n var match = remaining.match(/^\\s+/);\n\n if( match ){\n var consumed = match[0];\n remaining = remaining.substring( consumed.length );\n }\n };\n\n self[0] = newQuery(); // get started\n\n consumeWhitespace(); // get rid of leading whitespace\n for(;;){\n var check = consumeExpr();\n\n if( check.expr == null ){\n util.error('The selector `'+ selector +'`is invalid');\n return;\n } else {\n var args = [];\n for(var j = 1; j < check.match.length; j++){\n args.push( check.match[j] );\n }\n\n // let the token populate the selector object (i.e. in self[i])\n var ret = check.expr.populate.apply( self[i], args );\n\n if( ret === false ){ return; } // exit if population failed\n }\n\n // we're done when there's nothing left to parse\n if( remaining.match(/^\\s*$/) ){\n break;\n }\n }\n\n self.length = i + 1;\n\n // adjust references for subject\n for(var j = 0; j < self.length; j++){\n var query = self[j];\n\n if( query.subject != null ){\n // go up the tree until we reach the subject\n for(;;){\n if( query.subject == query ){ break; } // done if subject is self\n\n if( query.parent != null ){ // swap parent/child reference\n var parent = query.parent;\n var child = query;\n\n child.parent = null;\n parent.child = child;\n\n query = parent; // go up the tree\n } else if( query.ancestor != null ){ // swap ancestor/descendant\n var ancestor = query.ancestor;\n var descendant = query;\n\n descendant.ancestor = null;\n ancestor.descendant = descendant;\n\n query = ancestor; // go up the tree\n } else {\n util.error('When adjusting references for the selector `'+ query +'`, neither parent nor ancestor was found');\n break;\n }\n } // for\n\n self[j] = query.subject; // subject should be the root query\n } // if\n } // for\n\n // make sure for each query that the subject group matches the implicit group if any\n if( onlyThisGroup != null ){\n for(var j = 0; j < self.length; j++){\n if( self[j].group != null && self[j].group != onlyThisGroup ){\n util.error('Group `'+ self[j].group +'` conflicts with implicit group `'+ onlyThisGroup +'` in selector `'+ selector +'`');\n return;\n }\n\n self[j].group = onlyThisGroup; // set to implicit group\n }\n }\n\n } else {\n util.error('A selector must be created from a string; found ' + selector);\n return;\n }\n\n self._private.invalid = false;\n\n};\n\nvar selfn = Selector.prototype;\n\nselfn.size = function(){\n return this.length;\n};\n\nselfn.eq = function(i){\n return this[i];\n};\n\nvar queryMatches = function(query, element){\n // check group\n if( query.group != null && query.group != '*' && query.group != element._private.group ){\n return false;\n }\n\n var cy = element.cy();\n\n // check colon selectors\n var allColonSelectorsMatch = true;\n for(var k = 0; k < query.colonSelectors.length; k++){\n var sel = query.colonSelectors[k];\n\n switch(sel){\n case ':selected':\n allColonSelectorsMatch = element.selected();\n break;\n case ':unselected':\n allColonSelectorsMatch = !element.selected();\n break;\n case ':selectable':\n allColonSelectorsMatch = element.selectable();\n break;\n case ':unselectable':\n allColonSelectorsMatch = !element.selectable();\n break;\n case ':locked':\n allColonSelectorsMatch = element.locked();\n break;\n case ':unlocked':\n allColonSelectorsMatch = !element.locked();\n break;\n case ':visible':\n allColonSelectorsMatch = element.visible();\n break;\n case ':hidden':\n allColonSelectorsMatch = !element.visible();\n break;\n case ':transparent':\n allColonSelectorsMatch = element.transparent();\n break;\n case ':grabbed':\n allColonSelectorsMatch = element.grabbed();\n break;\n case ':free':\n allColonSelectorsMatch = !element.grabbed();\n break;\n case ':removed':\n allColonSelectorsMatch = element.removed();\n break;\n case ':inside':\n allColonSelectorsMatch = !element.removed();\n break;\n case ':grabbable':\n allColonSelectorsMatch = element.grabbable();\n break;\n case ':ungrabbable':\n allColonSelectorsMatch = !element.grabbable();\n break;\n case ':animated':\n allColonSelectorsMatch = element.animated();\n break;\n case ':unanimated':\n allColonSelectorsMatch = !element.animated();\n break;\n case ':parent':\n allColonSelectorsMatch = element.isNode() && element.children().nonempty();\n break;\n case ':child':\n case ':nonorphan':\n allColonSelectorsMatch = element.isNode() && element.parent().nonempty();\n break;\n case ':orphan':\n allColonSelectorsMatch = element.isNode() && element.parent().empty();\n break;\n case ':loop':\n allColonSelectorsMatch = element.isEdge() && element.data('source') === element.data('target');\n break;\n case ':simple':\n allColonSelectorsMatch = element.isEdge() && element.data('source') !== element.data('target');\n break;\n case ':active':\n allColonSelectorsMatch = element.active();\n break;\n case ':inactive':\n allColonSelectorsMatch = !element.active();\n break;\n case ':touch':\n allColonSelectorsMatch = is.touch();\n break;\n case ':backgrounding':\n allColonSelectorsMatch = element.backgrounding();\n break;\n case ':nonbackgrounding':\n allColonSelectorsMatch = !element.backgrounding();\n break;\n }\n\n if( !allColonSelectorsMatch ) break;\n }\n if( !allColonSelectorsMatch ) return false;\n\n // check id\n var allIdsMatch = true;\n for(var k = 0; k < query.ids.length; k++){\n var id = query.ids[k];\n var actualId = element._private.data.id;\n\n allIdsMatch = allIdsMatch && (id == actualId);\n\n if( !allIdsMatch ) break;\n }\n if( !allIdsMatch ) return false;\n\n // check classes\n var allClassesMatch = true;\n for(var k = 0; k < query.classes.length; k++){\n var cls = query.classes[k];\n\n allClassesMatch = allClassesMatch && element.hasClass(cls);\n\n if( !allClassesMatch ) break;\n }\n if( !allClassesMatch ) return false;\n\n // generic checking for data/metadata\n var operandsMatch = function(params){\n var allDataMatches = true;\n for(var k = 0; k < query[params.name].length; k++){\n var data = query[params.name][k];\n var operator = data.operator;\n var value = data.value;\n var field = data.field;\n var matches;\n\n if( operator != null && value != null ){\n\n var fieldVal = params.fieldValue(field);\n var fieldStr = !is.string(fieldVal) && !is.number(fieldVal) ? '' : '' + fieldVal;\n var valStr = '' + value;\n\n var caseInsensitive = false;\n if( operator.indexOf('@') >= 0 ){\n fieldStr = fieldStr.toLowerCase();\n valStr = valStr.toLowerCase();\n\n operator = operator.replace('@', '');\n caseInsensitive = true;\n }\n\n var notExpr = false;\n var handledNotExpr = false;\n if( operator.indexOf('!') >= 0 ){\n operator = operator.replace('!', '');\n notExpr = true;\n }\n\n // if we're doing a case insensitive comparison, then we're using a STRING comparison\n // even if we're comparing numbers\n if( caseInsensitive ){\n value = valStr.toLowerCase();\n fieldVal = fieldStr.toLowerCase();\n }\n\n switch(operator){\n case '*=':\n matches = fieldStr.search(valStr) >= 0;\n break;\n case '$=':\n matches = new RegExp(valStr + '$').exec(fieldStr) != null;\n break;\n case '^=':\n matches = new RegExp('^' + valStr).exec(fieldStr) != null;\n break;\n case '=':\n matches = fieldVal === value;\n break;\n case '!=':\n matches = fieldVal !== value;\n break;\n case '>':\n matches = !notExpr ? fieldVal > value : fieldVal <= value;\n handledNotExpr = true;\n break;\n case '>=':\n matches = !notExpr ? fieldVal >= value : fieldVal < value;\n handledNotExpr = true;\n break;\n case '<':\n matches = !notExpr ? fieldVal < value : fieldVal >= value;\n handledNotExpr = true;\n break;\n case '<=':\n matches = !notExpr ? fieldVal <= value : fieldVal > value;\n handledNotExpr = true;\n break;\n default:\n matches = false;\n break;\n\n }\n } else if( operator != null ){\n switch(operator){\n case '?':\n matches = params.fieldTruthy(field);\n break;\n case '!':\n matches = !params.fieldTruthy(field);\n break;\n case '^':\n matches = params.fieldUndefined(field);\n break;\n }\n } else {\n matches = !params.fieldUndefined(field);\n }\n\n if( notExpr && !handledNotExpr ){\n matches = !matches;\n handledNotExpr = true;\n }\n\n if( !matches ){\n allDataMatches = false;\n break;\n }\n } // for\n\n return allDataMatches;\n }; // operandsMatch\n\n // check data matches\n var allDataMatches = operandsMatch({\n name: 'data',\n fieldValue: function(field){\n return element._private.data[field];\n },\n fieldRef: function(field){\n return 'element._private.data.' + field;\n },\n fieldUndefined: function(field){\n return element._private.data[field] === undefined;\n },\n fieldTruthy: function(field){\n if( element._private.data[field] ){\n return true;\n }\n return false;\n }\n });\n\n if( !allDataMatches ){\n return false;\n }\n\n // check metadata matches\n var allMetaMatches = operandsMatch({\n name: 'meta',\n fieldValue: function(field){\n return element[field]();\n },\n fieldRef: function(field){\n return 'element.' + field + '()';\n },\n fieldUndefined: function(field){\n return element[field]() == null;\n },\n fieldTruthy: function(field){\n if( element[field]() ){\n return true;\n }\n return false;\n }\n });\n\n if( !allMetaMatches ){\n return false;\n }\n\n // check collection\n if( query.collection != null ){\n var matchesAny = query.collection._private.ids[ element.id() ] != null;\n\n if( !matchesAny ){\n return false;\n }\n }\n\n // check filter function\n if( query.filter != null && element.collection().filter( query.filter ).size() === 0 ){\n return false;\n }\n\n\n // check parent/child relations\n var confirmRelations = function( query, elements ){\n if( query != null ){\n var matches = false;\n\n if( !cy.hasCompoundNodes() ){\n return false;\n }\n\n elements = elements(); // make elements functional so we save cycles if query == null\n\n // query must match for at least one element (may be recursive)\n for(var i = 0; i < elements.length; i++){\n if( queryMatches( query, elements[i] ) ){\n matches = true;\n break;\n }\n }\n\n return matches;\n } else {\n return true;\n }\n };\n\n if (! confirmRelations(query.parent, function(){\n return element.parent();\n }) ){ return false; }\n\n if (! confirmRelations(query.ancestor, function(){\n return element.parents();\n }) ){ return false; }\n\n if (! confirmRelations(query.child, function(){\n return element.children();\n }) ){ return false; }\n\n if (! confirmRelations(query.descendant, function(){\n return element.descendants();\n }) ){ return false; }\n\n // we've reached the end, so we've matched everything for this query\n return true;\n}; // queryMatches\n\n// filter an existing collection\nselfn.filter = function(collection){\n var self = this;\n var cy = collection.cy();\n\n // don't bother trying if it's invalid\n if( self._private.invalid ){\n return cy.collection();\n }\n\n var selectorFunction = function(i, element){\n for(var j = 0; j < self.length; j++){\n var query = self[j];\n\n if( queryMatches(query, element) ){\n return true;\n }\n }\n\n return false;\n };\n\n if( self._private.selectorText == null ){\n selectorFunction = function(){ return true; };\n }\n\n var filteredCollection = collection.filter( selectorFunction );\n\n return filteredCollection;\n}; // filter\n\n// does selector match a single element?\nselfn.matches = function(ele){\n var self = this;\n\n // don't bother trying if it's invalid\n if( self._private.invalid ){\n return false;\n }\n\n for(var j = 0; j < self.length; j++){\n var query = self[j];\n\n if( queryMatches(query, ele) ){\n return true;\n }\n }\n\n return false;\n}; // filter\n\n// ith query to string\nselfn.toString = selfn.selector = function(){\n\n var str = '';\n\n var clean = function(obj, isValue){\n if( is.string(obj) ){\n return isValue ? '\"' + obj + '\"' : obj;\n }\n return '';\n };\n\n var queryToString = function(query){\n var str = '';\n\n if( query.subject === query ){\n str += '$';\n }\n\n var group = clean(query.group);\n str += group.substring(0, group.length - 1);\n\n for(var j = 0; j < query.data.length; j++){\n var data = query.data[j];\n\n if( data.value ){\n str += '[' + data.field + clean(data.operator) + clean(data.value, true) + ']';\n } else {\n str += '[' + clean(data.operator) + data.field + ']';\n }\n }\n\n for(var j = 0; j < query.meta.length; j++){\n var meta = query.meta[j];\n str += '[[' + meta.field + clean(meta.operator) + clean(meta.value, true) + ']]';\n }\n\n for(var j = 0; j < query.colonSelectors.length; j++){\n var sel = query.colonSelectors[i];\n str += sel;\n }\n\n for(var j = 0; j < query.ids.length; j++){\n var sel = '#' + query.ids[i];\n str += sel;\n }\n\n for(var j = 0; j < query.classes.length; j++){\n var sel = '.' + query.classes[j];\n str += sel;\n }\n\n if( query.parent != null ){\n str = queryToString( query.parent ) + ' > ' + str;\n }\n\n if( query.ancestor != null ){\n str = queryToString( query.ancestor ) + ' ' + str;\n }\n\n if( query.child != null ){\n str += ' > ' + queryToString( query.child );\n }\n\n if( query.descendant != null ){\n str += ' ' + queryToString( query.descendant );\n }\n\n return str;\n };\n\n for(var i = 0; i < this.length; i++){\n var query = this[i];\n\n str += queryToString( query );\n\n if( this.length > 1 && i < this.length - 1 ){\n str += ', ';\n }\n }\n\n return str;\n};\n\nmodule.exports = Selector;\n","'use strict';\n\nvar util = require('../util');\nvar is = require('../is');\n\nvar styfn = {};\n\n// (potentially expensive calculation)\n// apply the style to the element based on\n// - its bypass\n// - what selectors match it\nstyfn.apply = function( eles ){\n var self = this;\n\n if( self._private.newStyle ){ // clear style caches\n this._private.contextStyles = {};\n this._private.propDiffs = {};\n }\n\n for( var ie = 0; ie < eles.length; ie++ ){\n var ele = eles[ie];\n var cxtMeta = self.getContextMeta( ele );\n var cxtStyle = self.getContextStyle( cxtMeta );\n var app = self.applyContextStyle( cxtMeta, cxtStyle, ele );\n\n self.updateTransitions( ele, app.diffProps );\n self.updateStyleHints( ele );\n\n } // for elements\n\n self._private.newStyle = false;\n};\n\nstyfn.getPropertiesDiff = function( oldCxtKey, newCxtKey ){\n var self = this;\n var cache = self._private.propDiffs = self._private.propDiffs || {};\n var dualCxtKey = oldCxtKey + '-' + newCxtKey;\n var cachedVal = cache[dualCxtKey];\n\n if( cachedVal ){\n return cachedVal;\n }\n\n var diffProps = [];\n var addedProp = {};\n\n for( var i = 0; i < self.length; i++ ){\n var cxt = self[i];\n var oldHasCxt = oldCxtKey[i] === 't';\n var newHasCxt = newCxtKey[i] === 't';\n var cxtHasDiffed = oldHasCxt !== newHasCxt;\n var cxtHasMappedProps = cxt.mappedProperties.length > 0;\n\n if( cxtHasDiffed || cxtHasMappedProps ){\n var props;\n\n if( cxtHasDiffed && cxtHasMappedProps ){\n props = cxt.properties; // suffices b/c mappedProperties is a subset of properties\n } else if( cxtHasDiffed ){\n props = cxt.properties; // need to check them all\n } else if( cxtHasMappedProps ){\n props = cxt.mappedProperties; // only need to check mapped\n }\n\n for( var j = 0; j < props.length; j++ ){\n var prop = props[j];\n var name = prop.name;\n\n // if a later context overrides this property, then the fact that this context has switched/diffed doesn't matter\n // (semi expensive check since it makes this function O(n^2) on context length, but worth it since overall result\n // is cached)\n var laterCxtOverrides = false;\n for( var k = i + 1; k < self.length; k++ ){\n var laterCxt = self[k];\n var hasLaterCxt = newCxtKey[k] === 't';\n\n if( !hasLaterCxt ){ continue; } // can't override unless the context is active\n\n laterCxtOverrides = laterCxt.properties[ prop.name ] != null;\n\n if( laterCxtOverrides ){ break; } // exit early as long as one later context overrides\n }\n\n if( !addedProp[name] && !laterCxtOverrides ){\n addedProp[name] = true;\n diffProps.push( name );\n }\n } // for props\n } // if\n\n } // for contexts\n\n cache[ dualCxtKey ] = diffProps;\n return diffProps;\n};\n\nstyfn.getContextMeta = function( ele ){\n var self = this;\n var cxtKey = '';\n var diffProps;\n var prevKey = ele._private.styleCxtKey || '';\n\n if( self._private.newStyle ){\n prevKey = ''; // since we need to apply all style if a fresh stylesheet\n }\n\n // get the cxt key\n for( var i = 0; i < self.length; i++ ){\n var context = self[i];\n var contextSelectorMatches = context.selector && context.selector.matches( ele ); // NB: context.selector may be null for 'core'\n\n if( contextSelectorMatches ){\n cxtKey += 't';\n } else {\n cxtKey += 'f';\n }\n } // for context\n\n diffProps = self.getPropertiesDiff( prevKey, cxtKey );\n\n ele._private.styleCxtKey = cxtKey;\n\n return {\n key: cxtKey,\n diffPropNames: diffProps\n };\n};\n\n// gets a computed ele style object based on matched contexts\nstyfn.getContextStyle = function( cxtMeta ){\n var cxtKey = cxtMeta.key;\n var self = this;\n var cxtStyles = this._private.contextStyles = this._private.contextStyles || {};\n\n // if already computed style, returned cached copy\n if( cxtStyles[cxtKey] ){ return cxtStyles[cxtKey]; }\n\n var style = {\n _private: {\n key: cxtKey\n }\n };\n\n for( var i = 0; i < self.length; i++ ){\n var cxt = self[i];\n var hasCxt = cxtKey[i] === 't';\n\n if( !hasCxt ){ continue; }\n\n for( var j = 0; j < cxt.properties.length; j++ ){\n var prop = cxt.properties[j];\n var styProp = style[ prop.name ] = prop;\n\n styProp.context = cxt;\n }\n }\n\n cxtStyles[cxtKey] = style;\n return style;\n};\n\nstyfn.applyContextStyle = function( cxtMeta, cxtStyle, ele ){\n var self = this;\n var diffProps = cxtMeta.diffPropNames;\n var retDiffProps = {};\n\n for( var i = 0; i < diffProps.length; i++ ){\n var diffPropName = diffProps[i];\n var cxtProp = cxtStyle[ diffPropName ];\n var eleProp = ele._private.style[ diffPropName ];\n\n // save cycles when the context prop doesn't need to be applied\n if( !cxtProp || eleProp === cxtProp ){ continue; }\n\n var retDiffProp = retDiffProps[ diffPropName ] = {\n prev: eleProp\n };\n\n self.applyParsedProperty( ele, cxtProp );\n\n retDiffProp.next = ele._private.style[ diffPropName ];\n\n if( retDiffProp.next && retDiffProp.next.bypass ){\n retDiffProp.next = retDiffProp.next.bypassed;\n }\n }\n\n return {\n diffProps: retDiffProps\n };\n};\n\nstyfn.updateStyleHints = function(ele){\n var _p = ele._private;\n var self = this;\n var style = _p.style;\n\n if( ele.removed() ){ return; }\n\n // set whether has pie or not; for greater efficiency\n var hasPie = false;\n if( _p.group === 'nodes' && self._private.hasPie ){\n for( var i = 1; i <= self.pieBackgroundN; i++ ){ // 1..N\n var size = _p.style['pie-' + i + '-background-size'].value;\n\n if( size > 0 ){\n hasPie = true;\n break;\n }\n }\n }\n\n _p.hasPie = hasPie;\n\n var transform = style['text-transform'].strValue;\n var content = style['label'].strValue;\n var fStyle = style['font-style'].strValue;\n var size = style['font-size'].pfValue + 'px';\n var family = style['font-family'].strValue;\n // var variant = style['font-variant'].strValue;\n var weight = style['font-weight'].strValue;\n var valign = style['text-valign'].strValue;\n var halign = style['text-valign'].strValue;\n var oWidth = style['text-outline-width'].pfValue;\n var wrap = style['text-wrap'].strValue;\n var wrapW = style['text-max-width'].pfValue;\n _p.labelKey = fStyle +'$'+ size +'$'+ family +'$'+ weight +'$'+ content +'$'+ transform +'$'+ valign +'$'+ halign +'$'+ oWidth + '$' + wrap + '$' + wrapW;\n _p.fontKey = fStyle +'$'+ weight +'$'+ size +'$'+ family;\n\n var width = style['width'].pfValue;\n var height = style['height'].pfValue;\n var borderW = style['border-width'].pfValue;\n _p.boundingBoxKey = width +'$'+ height +'$'+ borderW;\n\n if( ele._private.group === 'edges' ){\n var cpss = style['control-point-step-size'].pfValue;\n var cpd = style['control-point-distances'] ? style['control-point-distances'].pfValue.join('_') : undefined;\n var cpw = style['control-point-weights'].value.join('_');\n var curve = style['curve-style'].strValue;\n var sd = style['segment-distances'] ? style['segment-distances'].pfValue.join('_') : undefined;\n var sw = style['segment-weights'].value.join('_');\n\n _p.boundingBoxKey += '$'+ cpss +'$'+ cpd +'$'+ cpw +'$'+ sd +'$'+ sw +'$'+ curve;\n }\n\n _p.styleKey = Date.now();\n};\n\n// apply a property to the style (for internal use)\n// returns whether application was successful\n//\n// now, this function flattens the property, and here's how:\n//\n// for parsedProp:{ bypass: true, deleteBypass: true }\n// no property is generated, instead the bypass property in the\n// element's style is replaced by what's pointed to by the `bypassed`\n// field in the bypass property (i.e. restoring the property the\n// bypass was overriding)\n//\n// for parsedProp:{ mapped: truthy }\n// the generated flattenedProp:{ mapping: prop }\n//\n// for parsedProp:{ bypass: true }\n// the generated flattenedProp:{ bypassed: parsedProp }\nstyfn.applyParsedProperty = function( ele, parsedProp ){\n var self = this;\n var prop = parsedProp;\n var style = ele._private.style;\n var fieldVal, flatProp;\n var types = self.types;\n var type = self.properties[ prop.name ].type;\n var propIsBypass = prop.bypass;\n var origProp = style[ prop.name ];\n var origPropIsBypass = origProp && origProp.bypass;\n var _p = ele._private;\n\n // can't apply auto to width or height unless it's a parent node\n if( (parsedProp.name === 'height' || parsedProp.name === 'width') && ele.isNode() ){\n if( parsedProp.value === 'auto' && !ele.isParent() ){\n return false;\n } else if( parsedProp.value !== 'auto' && ele.isParent() ){\n prop = parsedProp = this.parse( parsedProp.name, 'auto', propIsBypass );\n }\n }\n\n // check if we need to delete the current bypass\n if( propIsBypass && prop.deleteBypass ){ // then this property is just here to indicate we need to delete\n var currentProp = style[ prop.name ];\n\n // can only delete if the current prop is a bypass and it points to the property it was overriding\n if( !currentProp ){\n return true; // property is already not defined\n } else if( currentProp.bypass && currentProp.bypassed ){ // then replace the bypass property with the original\n\n // because the bypassed property was already applied (and therefore parsed), we can just replace it (no reapplying necessary)\n style[ prop.name ] = currentProp.bypassed;\n return true;\n\n } else {\n return false; // we're unsuccessful deleting the bypass\n }\n }\n\n var printMappingErr = function(){\n util.error('Do not assign mappings to elements without corresponding data (e.g. ele `'+ ele.id() +'` for property `'+ prop.name +'` with data field `'+ prop.field +'`); try a `['+ prop.field +']` selector to limit scope to elements with `'+ prop.field +'` defined');\n };\n\n // put the property in the style objects\n switch( prop.mapped ){ // flatten the property if mapped\n case types.mapData:\n case types.mapLayoutData:\n case types.mapScratch:\n\n var isLayout = prop.mapped === types.mapLayoutData;\n var isScratch = prop.mapped === types.mapScratch;\n\n // flatten the field (e.g. data.foo.bar)\n var fields = prop.field.split(\".\");\n var fieldVal;\n\n if( isScratch || isLayout ){\n fieldVal = _p.scratch;\n } else {\n fieldVal = _p.data;\n }\n\n for( var i = 0; i < fields.length && fieldVal; i++ ){\n var field = fields[i];\n fieldVal = fieldVal[ field ];\n }\n\n var percent;\n if( !is.number(fieldVal) ){ // then keep the mapping but assume 0% for now\n percent = 0;\n } else {\n percent = (fieldVal - prop.fieldMin) / (prop.fieldMax - prop.fieldMin);\n }\n\n // make sure to bound percent value\n if( percent < 0 ){\n percent = 0;\n } else if( percent > 1 ){\n percent = 1;\n }\n\n if( type.color ){\n var r1 = prop.valueMin[0];\n var r2 = prop.valueMax[0];\n var g1 = prop.valueMin[1];\n var g2 = prop.valueMax[1];\n var b1 = prop.valueMin[2];\n var b2 = prop.valueMax[2];\n var a1 = prop.valueMin[3] == null ? 1 : prop.valueMin[3];\n var a2 = prop.valueMax[3] == null ? 1 : prop.valueMax[3];\n\n var clr = [\n Math.round( r1 + (r2 - r1)*percent ),\n Math.round( g1 + (g2 - g1)*percent ),\n Math.round( b1 + (b2 - b1)*percent ),\n Math.round( a1 + (a2 - a1)*percent )\n ];\n\n flatProp = { // colours are simple, so just create the flat property instead of expensive string parsing\n bypass: prop.bypass, // we're a bypass if the mapping property is a bypass\n name: prop.name,\n value: clr,\n strValue: 'rgb(' + clr[0] + ', ' + clr[1] + ', ' + clr[2] + ')'\n };\n\n } else if( type.number ){\n var calcValue = prop.valueMin + (prop.valueMax - prop.valueMin) * percent;\n flatProp = this.parse( prop.name, calcValue, prop.bypass, true );\n\n } else {\n return false; // can only map to colours and numbers\n }\n\n if( !flatProp ){ // if we can't flatten the property, then use the origProp so we still keep the mapping itself\n flatProp = this.parse( prop.name, origProp.strValue, prop.bypass, true );\n }\n\n if( !flatProp ){ printMappingErr(); }\n flatProp.mapping = prop; // keep a reference to the mapping\n prop = flatProp; // the flattened (mapped) property is the one we want\n\n break;\n\n // direct mapping\n case types.data:\n case types.layoutData:\n case types.scratch:\n var isLayout = prop.mapped === types.layoutData;\n var isScratch = prop.mapped === types.scratch;\n\n // flatten the field (e.g. data.foo.bar)\n var fields = prop.field.split(\".\");\n var fieldVal;\n\n if( isScratch || isLayout ){\n fieldVal = _p.scratch;\n } else {\n fieldVal = _p.data;\n }\n\n if( fieldVal ){ for( var i = 0; i < fields.length; i++ ){\n var field = fields[i];\n fieldVal = fieldVal[ field ];\n } }\n\n flatProp = this.parse( prop.name, fieldVal, prop.bypass, true );\n\n if( !flatProp ){ // if we can't flatten the property, then use the origProp so we still keep the mapping itself\n var flatPropVal = origProp ? origProp.strValue : '';\n\n flatProp = this.parse( prop.name, flatPropVal, prop.bypass, true );\n }\n\n if( !flatProp ){ printMappingErr(); }\n flatProp.mapping = prop; // keep a reference to the mapping\n prop = flatProp; // the flattened (mapped) property is the one we want\n\n break;\n\n case types.fn:\n var fn = prop.value;\n var fnRetVal = fn( ele );\n\n flatProp = this.parse( prop.name, fnRetVal, prop.bypass, true );\n flatProp.mapping = prop; // keep a reference to the mapping\n prop = flatProp; // the flattened (mapped) property is the one we want\n\n break;\n\n case undefined:\n break; // just set the property\n\n default:\n return false; // not a valid mapping\n }\n\n // if the property is a bypass property, then link the resultant property to the original one\n if( propIsBypass ){\n if( origPropIsBypass ){ // then this bypass overrides the existing one\n prop.bypassed = origProp.bypassed; // steal bypassed prop from old bypass\n } else { // then link the orig prop to the new bypass\n prop.bypassed = origProp;\n }\n\n style[ prop.name ] = prop; // and set\n\n } else { // prop is not bypass\n if( origPropIsBypass ){ // then keep the orig prop (since it's a bypass) and link to the new prop\n origProp.bypassed = prop;\n } else { // then just replace the old prop with the new one\n style[ prop.name ] = prop;\n }\n }\n\n return true;\n};\n\n// updates the visual style for all elements (useful for manual style modification after init)\nstyfn.update = function(){\n var cy = this._private.cy;\n var eles = cy.elements();\n\n eles.updateStyle();\n};\n\n// just update the functional properties (i.e. mappings) in the elements'\n// styles (less expensive than recalculation)\nstyfn.updateMappers = function( eles ){\n var self = this;\n\n for( var i = 0; i < eles.length; i++ ){ // for each ele\n var ele = eles[i];\n var style = ele._private.style;\n\n for( var j = 0; j < self.properties.length; j++ ){ // for each prop\n var prop = self.properties[j];\n var propInStyle = style[ prop.name ];\n\n if( propInStyle && propInStyle.mapping ){\n var mapping = propInStyle.mapping;\n this.applyParsedProperty( ele, mapping ); // reapply the mapping property\n }\n }\n\n this.updateStyleHints( ele );\n }\n};\n\n// diffProps : { name => { prev, next } }\nstyfn.updateTransitions = function( ele, diffProps, isBypass ){\n var self = this;\n var _p = ele._private;\n var style = _p.style;\n var props = style['transition-property'].value;\n var duration = style['transition-duration'].pfValue;\n var delay = style['transition-delay'].pfValue;\n var css = {};\n\n if( props.length > 0 && duration > 0 ){\n\n // build up the style to animate towards\n var anyPrev = false;\n for( var i = 0; i < props.length; i++ ){\n var prop = props[i];\n var styProp = style[ prop ];\n var diffProp = diffProps[ prop ];\n\n if( !diffProp ){ continue; }\n\n var prevProp = diffProp.prev;\n var fromProp = prevProp;\n var toProp = diffProp.next != null ? diffProp.next : styProp;\n var diff = false;\n var initVal;\n var initDt = 0.000001; // delta time % value for initVal (allows animating out of init zero opacity)\n\n if( !fromProp ){ continue; }\n\n // consider px values\n if( is.number( fromProp.pfValue ) && is.number( toProp.pfValue ) ){\n diff = toProp.pfValue - fromProp.pfValue; // nonzero is truthy\n initVal = fromProp.pfValue + initDt * diff;\n\n // consider numerical values\n } else if( is.number( fromProp.value ) && is.number( toProp.value ) ){\n diff = toProp.value - fromProp.value; // nonzero is truthy\n initVal = fromProp.value + initDt * diff;\n\n // consider colour values\n } else if( is.array( fromProp.value ) && is.array( toProp.value ) ){\n diff = fromProp.value[0] !== toProp.value[0]\n || fromProp.value[1] !== toProp.value[1]\n || fromProp.value[2] !== toProp.value[2]\n ;\n\n initVal = fromProp.strValue;\n }\n\n // the previous value is good for an animation only if it's different\n if( diff ){\n css[ prop ] = toProp.strValue; // to val\n this.applyBypass( ele, prop, initVal ); // from val\n anyPrev = true;\n }\n\n } // end if props allow ani\n\n // can't transition if there's nothing previous to transition from\n if( !anyPrev ){ return; }\n\n _p.transitioning = true;\n\n ele.stop();\n\n if( delay > 0 ){\n ele.delay( delay );\n }\n\n ele.animate({\n css: css\n }, {\n duration: duration,\n easing: style['transition-timing-function'].value,\n queue: false,\n complete: function(){\n if( !isBypass ){\n self.removeBypasses( ele, props );\n }\n\n _p.transitioning = false;\n }\n });\n\n } else if( _p.transitioning ){\n ele.stop();\n\n this.removeBypasses( ele, props );\n\n _p.transitioning = false;\n }\n};\n\nmodule.exports = styfn;\n","'use strict';\n\nvar is = require('../is');\nvar util = require('../util');\n\nvar styfn = {};\n\n// bypasses are applied to an existing style on an element, and just tacked on temporarily\n// returns true iff application was successful for at least 1 specified property\nstyfn.applyBypass = function( eles, name, value, updateTransitions ){\n var self = this;\n var props = [];\n var isBypass = true;\n\n // put all the properties (can specify one or many) in an array after parsing them\n if( name === \"*\" || name === \"**\" ){ // apply to all property names\n\n if( value !== undefined ){\n for( var i = 0; i < self.properties.length; i++ ){\n var prop = self.properties[i];\n var name = prop.name;\n\n var parsedProp = this.parse(name, value, true);\n\n if( parsedProp ){\n props.push( parsedProp );\n }\n }\n }\n\n } else if( is.string(name) ){ // then parse the single property\n var parsedProp = this.parse(name, value, true);\n\n if( parsedProp ){\n props.push( parsedProp );\n }\n } else if( is.plainObject(name) ){ // then parse each property\n var specifiedProps = name;\n updateTransitions = value;\n\n for( var i = 0; i < self.properties.length; i++ ){\n var prop = self.properties[i];\n var name = prop.name;\n var value = specifiedProps[ name ];\n\n if( value === undefined ){ // try camel case name too\n value = specifiedProps[ util.dash2camel(name) ];\n }\n\n if( value !== undefined ){\n var parsedProp = this.parse(name, value, true);\n\n if( parsedProp ){\n props.push( parsedProp );\n }\n }\n }\n } else { // can't do anything without well defined properties\n return false;\n }\n\n // we've failed if there are no valid properties\n if( props.length === 0 ){ return false; }\n\n // now, apply the bypass properties on the elements\n var ret = false; // return true if at least one succesful bypass applied\n for( var i = 0; i < eles.length; i++ ){ // for each ele\n var ele = eles[i];\n var style = ele._private.style;\n var diffProps = {};\n var diffProp;\n\n for( var j = 0; j < props.length; j++ ){ // for each prop\n var prop = props[j];\n\n if( updateTransitions ){\n var prevProp = style[ prop.name ];\n diffProp = diffProps[ prop.name ] = { prev: prevProp };\n }\n\n ret = this.applyParsedProperty( ele, prop ) || ret;\n\n if( updateTransitions ){\n diffProp.next = style[ prop.name ];\n }\n\n } // for props\n\n if( ret ){\n this.updateStyleHints( ele );\n }\n\n if( updateTransitions ){\n this.updateTransitions( ele, diffProps, isBypass );\n }\n } // for eles\n\n return ret;\n};\n\n// only useful in specific cases like animation\nstyfn.overrideBypass = function( eles, name, value ){\n name = util.camel2dash(name);\n\n for( var i = 0; i < eles.length; i++ ){\n var ele = eles[i];\n var prop = ele._private.style[ name ];\n var type = this.properties[ name ].type;\n var isColor = type.color;\n var isMulti = type.mutiple;\n\n if( !prop.bypass ){ // need a bypass if one doesn't exist\n this.applyBypass( ele, name, value );\n continue;\n }\n\n prop.value = value;\n\n if( prop.pfValue != null ){\n prop.pfValue = value;\n }\n\n if( isColor ){\n prop.strValue = 'rgb(' + value.join(',') + ')';\n } else if( isMulti ){\n prop.strValue = value.join(' ');\n } else {\n prop.strValue = '' + value;\n }\n }\n};\n\nstyfn.removeAllBypasses = function( eles, updateTransitions ){\n return this.removeBypasses( eles, this.propertyNames, updateTransitions );\n};\n\nstyfn.removeBypasses = function( eles, props, updateTransitions ){\n var isBypass = true;\n\n for( var j = 0; j < eles.length; j++ ){\n var ele = eles[j];\n var diffProps = {};\n var style = ele._private.style;\n\n for( var i = 0; i < props.length; i++ ){\n var name = props[i];\n var prop = this.properties[ name ];\n var value = ''; // empty => remove bypass\n var parsedProp = this.parse(name, value, true);\n var prevProp = style[ prop.name ];\n var diffProp = diffProps[ prop.name ] = { prev: prevProp };\n\n this.applyParsedProperty(ele, parsedProp);\n\n diffProp.next = style[ prop.name ];\n } // for props\n\n this.updateStyleHints( ele );\n\n if( updateTransitions ){\n this.updateTransitions( ele, diffProps, isBypass );\n }\n } // for eles\n};\n\nmodule.exports = styfn;\n","'use strict';\n\nvar window = require('../window');\n\nvar styfn = {};\n\n// gets what an em size corresponds to in pixels relative to a dom element\nstyfn.getEmSizeInPixels = function(){\n var px = this.containerCss('font-size');\n\n if( px != null ){\n return parseFloat( px );\n } else {\n return 1; // for headless\n }\n};\n\n// gets css property from the core container\nstyfn.containerCss = function( propName ){\n var cy = this._private.cy;\n var domElement = cy.container();\n\n if( window && domElement && window.getComputedStyle ){\n return window.getComputedStyle(domElement).getPropertyValue( propName );\n }\n};\n\nmodule.exports = styfn;\n","'use strict';\n\nvar util = require('../util');\nvar is = require('../is');\n\nvar styfn = {};\n\n// gets the rendered style for an element\nstyfn.getRenderedStyle = function( ele ){\n return this.getRawStyle( ele, true );\n};\n\n// gets the raw style for an element\nstyfn.getRawStyle = function( ele, isRenderedVal ){\n var self = this;\n var ele = ele[0]; // insure it's an element\n\n if( ele ){\n var rstyle = {};\n\n for( var i = 0; i < self.properties.length; i++ ){\n var prop = self.properties[i];\n var val = self.getStylePropertyValue( ele, prop.name, isRenderedVal );\n\n if( val ){\n rstyle[ prop.name ] = val;\n rstyle[ util.dash2camel(prop.name) ] = val;\n }\n }\n\n return rstyle;\n }\n};\n\nstyfn.getStylePropertyValue = function( ele, propName, isRenderedVal ){\n var self = this;\n var ele = ele[0]; // insure it's an element\n\n if( ele ){\n var style = ele._private.style;\n var prop = self.properties[ propName ];\n var type = prop.type;\n var styleProp = style[ prop.name ];\n var zoom = ele.cy().zoom();\n\n if( styleProp ){\n var units = styleProp.units ? type.implicitUnits || 'px' : null;\n var val = units ? [].concat( styleProp.pfValue ).map(function( pfValue ){\n return ( pfValue * (isRenderedVal ? zoom : 1) ) + units;\n }).join(' ') : styleProp.strValue;\n\n return val;\n }\n }\n};\n\n// gets the value style for an element (useful for things like animations)\nstyfn.getValueStyle = function( ele ){\n var self = this;\n var rstyle = {};\n var style;\n var isEle = is.element(ele);\n\n if( isEle ){\n style = ele._private.style;\n } else {\n style = ele; // just passed the style itself\n }\n\n if( style ){\n for( var i = 0; i < self.properties.length; i++ ){\n var prop = self.properties[i];\n var styleProp = style[ prop.name ] || style[ util.dash2camel(prop.name) ];\n\n if( styleProp !== undefined ){ // then make a prop of it\n if( is.plainObject( styleProp ) ){\n styleProp = this.parse( prop.name, styleProp.strValue );\n } else {\n styleProp = this.parse( prop.name, styleProp );\n }\n }\n\n if( styleProp ){\n rstyle[ prop.name ] = styleProp;\n rstyle[ util.dash2camel(prop.name) ] = styleProp;\n }\n }\n }\n\n return rstyle;\n};\n\nstyfn.getPropsList = function( propsObj ){\n var self = this;\n var rstyle = [];\n var style = propsObj;\n var props = self.properties;\n\n if( style ){\n for( var name in style ){\n var val = style[name];\n var prop = props[name] || props[ util.camel2dash(name) ];\n var styleProp = this.parse( prop.name, val );\n\n rstyle.push( styleProp );\n }\n }\n\n return rstyle;\n};\n\nmodule.exports = styfn;\n","'use strict';\n\nvar is = require('../is');\nvar util = require('../util');\nvar Selector = require('../selector');\n\nvar Style = function( cy ){\n\n if( !(this instanceof Style) ){\n return new Style(cy);\n }\n\n if( !is.core(cy) ){\n util.error('A style must have a core reference');\n return;\n }\n\n this._private = {\n cy: cy,\n coreStyle: {},\n newStyle: true\n };\n\n this.length = 0;\n\n this.addDefaultStylesheet();\n};\n\nvar styfn = Style.prototype;\n\nstyfn.instanceString = function(){\n return 'style';\n};\n\n// remove all contexts\nstyfn.clear = function(){\n for( var i = 0; i < this.length; i++ ){\n this[i] = undefined;\n }\n this.length = 0;\n this._private.newStyle = true;\n\n return this; // chaining\n};\n\nstyfn.resetToDefault = function(){\n this.clear();\n this.addDefaultStylesheet();\n\n return this;\n};\n\n// builds a style object for the 'core' selector\nstyfn.core = function(){\n return this._private.coreStyle;\n};\n\n// create a new context from the specified selector string and switch to that context\nstyfn.selector = function( selectorStr ){\n // 'core' is a special case and does not need a selector\n var selector = selectorStr === 'core' ? null : new Selector( selectorStr );\n\n var i = this.length++; // new context means new index\n this[i] = {\n selector: selector,\n properties: [],\n mappedProperties: [],\n index: i\n };\n\n return this; // chaining\n};\n\n// add one or many css rules to the current context\nstyfn.css = function(){\n var self = this;\n var args = arguments;\n\n switch( args.length ){\n case 1:\n var map = args[0];\n\n for( var i = 0; i < self.properties.length; i++ ){\n var prop = self.properties[i];\n var mapVal = map[ prop.name ];\n\n if( mapVal === undefined ){\n mapVal = map[ util.dash2camel(prop.name) ];\n }\n\n if( mapVal !== undefined ){\n this.cssRule( prop.name, mapVal );\n }\n }\n\n break;\n\n case 2:\n this.cssRule( args[0], args[1] );\n break;\n\n default:\n break; // do nothing if args are invalid\n }\n\n return this; // chaining\n};\nstyfn.style = styfn.css;\n\n// add a single css rule to the current context\nstyfn.cssRule = function( name, value ){\n // name-value pair\n var property = this.parse( name, value );\n\n // add property to current context if valid\n if( property ){\n var i = this.length - 1;\n this[i].properties.push( property );\n this[i].properties[ property.name ] = property; // allow access by name as well\n\n if( property.name.match(/pie-(\\d+)-background-size/) && property.value ){\n this._private.hasPie = true;\n }\n\n if( property.mapped ){\n this[i].mappedProperties.push( property );\n }\n\n // add to core style if necessary\n var currentSelectorIsCore = !this[i].selector;\n if( currentSelectorIsCore ){\n this._private.coreStyle[ property.name ] = property;\n }\n }\n\n return this; // chaining\n};\n\n// static function\nStyle.fromJson = function( cy, json ){\n var style = new Style( cy );\n\n style.fromJson( json );\n\n return style;\n};\n\nStyle.fromString = function( cy, string ){\n return new Style( cy ).fromString( string );\n};\n\n[\n require('./apply'),\n require('./bypass'),\n require('./container'),\n require('./get-for-ele'),\n require('./json'),\n require('./string-sheet'),\n require('./properties'),\n require('./parse')\n].forEach(function( props ){\n util.extend( styfn, props );\n});\n\n\nStyle.types = styfn.types;\nStyle.properties = styfn.properties;\n\nmodule.exports = Style;\n","'use strict';\n\nvar styfn = {};\n\nstyfn.applyFromJson = function( json ){\n var style = this;\n\n for( var i = 0; i < json.length; i++ ){\n var context = json[i];\n var selector = context.selector;\n var props = context.style || context.css;\n\n style.selector( selector ); // apply selector\n\n for( var name in props ){\n var value = props[name];\n\n style.css( name, value ); // apply property\n }\n }\n\n return style;\n};\n\n// accessible cy.style() function\nstyfn.fromJson = function( json ){\n var style = this;\n\n style.resetToDefault();\n style.applyFromJson( json );\n\n return style;\n};\n\n// get json from cy.style() api\nstyfn.json = function(){\n var json = [];\n\n for( var i = this.defaultLength; i < this.length; i++ ){\n var cxt = this[i];\n var selector = cxt.selector;\n var props = cxt.properties;\n var css = {};\n\n for( var j = 0; j < props.length; j++ ){\n var prop = props[j];\n css[ prop.name ] = prop.strValue;\n }\n\n json.push({\n selector: !selector ? 'core' : selector.toString(),\n style: css\n });\n }\n\n return json;\n};\n\nmodule.exports = styfn;\n","'use strict';\n\nvar util = require('../util');\nvar is = require('../is');\n\nvar styfn = {};\n\n// a caching layer for property parsing\nstyfn.parse = function( name, value, propIsBypass, propIsFlat ){\n var argHash = [ name, value, propIsBypass, propIsFlat ].join('$');\n var propCache = this.propCache = this.propCache || {};\n var ret;\n var impl = parseImpl.bind( this );\n\n if( !(ret = propCache[argHash]) ){\n ret = propCache[argHash] = impl( name, value, propIsBypass, propIsFlat );\n }\n\n // always need a copy since props are mutated later in their lifecycles\n ret = util.copy( ret );\n\n if( ret ){\n ret.value = util.copy( ret.value ); // because it could be an array, e.g. colour\n }\n\n return ret;\n};\n\n// parse a property; return null on invalid; return parsed property otherwise\n// fields :\n// - name : the name of the property\n// - value : the parsed, native-typed value of the property\n// - strValue : a string value that represents the property value in valid css\n// - bypass : true iff the property is a bypass property\nvar parseImpl = function( name, value, propIsBypass, propIsFlat ){\n var self = this;\n\n name = util.camel2dash( name ); // make sure the property name is in dash form (e.g. 'property-name' not 'propertyName')\n\n var property = self.properties[ name ];\n var passedValue = value;\n var types = self.types;\n\n if( !property ){ return null; } // return null on property of unknown name\n if( value === undefined || value === null ){ return null; } // can't assign null\n\n // the property may be an alias\n if( property.alias ){\n property = property.pointsTo;\n name = property.name;\n }\n\n var valueIsString = is.string(value);\n if( valueIsString ){ // trim the value to make parsing easier\n value = value.trim();\n }\n\n var type = property.type;\n if( !type ){ return null; } // no type, no luck\n\n // check if bypass is null or empty string (i.e. indication to delete bypass property)\n if( propIsBypass && (value === '' || value === null) ){\n return {\n name: name,\n value: value,\n bypass: true,\n deleteBypass: true\n };\n }\n\n // check if value is a function used as a mapper\n if( is.fn(value) ){\n return {\n name: name,\n value: value,\n strValue: 'fn',\n mapped: types.fn,\n bypass: propIsBypass\n };\n }\n\n // check if value is mapped\n var data, mapData, layoutData, mapLayoutData, scratch, mapScratch;\n if( !valueIsString || propIsFlat ){\n // then don't bother to do the expensive regex checks\n\n } else if(\n ( data = new RegExp( types.data.regex ).exec( value ) ) ||\n ( layoutData = new RegExp( types.layoutData.regex ).exec( value ) ) ||\n ( scratch = new RegExp( types.scratch.regex ).exec( value ) )\n ){\n if( propIsBypass ){ return false; } // mappers not allowed in bypass\n\n var mapped;\n if( data ){\n mapped = types.data;\n } else if( layoutData ){\n mapped = types.layoutData;\n } else {\n mapped = types.scratch;\n }\n\n data = data || layoutData || scratch;\n\n return {\n name: name,\n value: data,\n strValue: '' + value,\n mapped: mapped,\n field: data[1],\n bypass: propIsBypass\n };\n\n } else if(\n ( mapData = new RegExp( types.mapData.regex ).exec( value ) ) ||\n ( mapLayoutData = new RegExp( types.mapLayoutData.regex ).exec( value ) ) ||\n ( mapScratch = new RegExp( types.mapScratch.regex ).exec( value ) )\n ){\n if( propIsBypass ){ return false; } // mappers not allowed in bypass\n if( type.multiple ){ return false; } // impossible to map to num\n\n var mapped;\n if( mapData ){\n mapped = types.mapData;\n } else if( mapLayoutData ){\n mapped = types.mapLayoutData;\n } else {\n mapped = types.mapScratch;\n }\n\n mapData = mapData || mapLayoutData || mapScratch;\n\n // we can map only if the type is a colour or a number\n if( !(type.color || type.number) ){ return false; }\n\n var valueMin = this.parse( name, mapData[4] ); // parse to validate\n if( !valueMin || valueMin.mapped ){ return false; } // can't be invalid or mapped\n\n var valueMax = this.parse( name, mapData[5] ); // parse to validate\n if( !valueMax || valueMax.mapped ){ return false; } // can't be invalid or mapped\n\n // check if valueMin and valueMax are the same\n if( valueMin.value === valueMax.value ){\n return false; // can't make much of a mapper without a range\n\n } else if( type.color ){\n var c1 = valueMin.value;\n var c2 = valueMax.value;\n\n var same = c1[0] === c2[0] // red\n && c1[1] === c2[1] // green\n && c1[2] === c2[2] // blue\n && ( // optional alpha\n c1[3] === c2[3] // same alpha outright\n || (\n (c1[3] == null || c1[3] === 1) // full opacity for colour 1?\n &&\n (c2[3] == null || c2[3] === 1) // full opacity for colour 2?\n )\n )\n ;\n\n if( same ){ return false; } // can't make a mapper without a range\n }\n\n return {\n name: name,\n value: mapData,\n strValue: '' + value,\n mapped: mapped,\n field: mapData[1],\n fieldMin: parseFloat( mapData[2] ), // min & max are numeric\n fieldMax: parseFloat( mapData[3] ),\n valueMin: valueMin.value,\n valueMax: valueMax.value,\n bypass: propIsBypass\n };\n }\n\n if( type.multiple && propIsFlat !== 'multiple' ){\n var vals;\n\n if( valueIsString ){\n vals = value.split(/\\s+/);\n } else if( is.array(value) ){\n vals = value;\n } else {\n vals = [ value ];\n }\n\n if( type.evenMultiple && vals.length % 2 !== 0 ){ return null; }\n\n var valArr = vals.map(function( v ){\n var p = self.parse( name, v, propIsBypass, 'multiple' );\n\n if( p.pfValue != null ){\n return p.pfValue;\n } else {\n return p.value;\n }\n });\n\n return {\n name: name,\n value: valArr,\n pfValue: valArr,\n strValue: valArr.join(' '),\n bypass: propIsBypass,\n units: type.number && !type.unitless ? type.implicitUnits || 'px' : undefined\n };\n }\n\n // several types also allow enums\n var checkEnums = function(){\n for( var i = 0; i < type.enums.length; i++ ){\n var en = type.enums[i];\n\n if( en === value ){\n return {\n name: name,\n value: value,\n strValue: '' + value,\n bypass: propIsBypass\n };\n }\n }\n\n return null;\n };\n\n // check the type and return the appropriate object\n if( type.number ){\n var units;\n var implicitUnits = 'px'; // not set => px\n\n if( type.units ){ // use specified units if set\n units = type.units;\n }\n\n if( type.implicitUnits ){\n implicitUnits = type.implicitUnits;\n }\n\n if( !type.unitless ){\n if( valueIsString ){\n var unitsRegex = 'px|em' + (type.allowPercent ? '|\\\\%' : '');\n if( units ){ unitsRegex = units; } // only allow explicit units if so set\n var match = value.match( '^(' + util.regex.number + ')(' + unitsRegex + ')?' + '$' );\n\n if( match ){\n value = match[1];\n units = match[2] || implicitUnits;\n }\n\n } else if( !units || type.implicitUnits ) {\n units = implicitUnits; // implicitly px if unspecified\n }\n }\n\n value = parseFloat( value );\n\n // if not a number and enums not allowed, then the value is invalid\n if( isNaN(value) && type.enums === undefined ){\n return null;\n }\n\n // check if this number type also accepts special keywords in place of numbers\n // (i.e. `left`, `auto`, etc)\n if( isNaN(value) && type.enums !== undefined ){\n value = passedValue;\n\n return checkEnums();\n }\n\n // check if value must be an integer\n if( type.integer && !is.integer(value) ){\n return null;\n }\n\n // check value is within range\n if( (type.min !== undefined && value < type.min)\n || (type.max !== undefined && value > type.max)\n ){\n return null;\n }\n\n var ret = {\n name: name,\n value: value,\n strValue: '' + value + (units ? units : ''),\n units: units,\n bypass: propIsBypass\n };\n\n // normalise value in pixels\n if( type.unitless || (units !== 'px' && units !== 'em') ){\n ret.pfValue = value;\n } else {\n ret.pfValue = ( units === 'px' || !units ? (value) : (this.getEmSizeInPixels() * value) );\n }\n\n // normalise value in ms\n if( units === 'ms' || units === 's' ){\n ret.pfValue = units === 'ms' ? value : 1000 * value;\n }\n\n // normalise value in rad\n if( units === 'deg' || units === 'rad' ){\n ret.pfValue = units === 'rad' ? value : value * Math.PI/180;\n }\n\n return ret;\n\n } else if( type.propList ) {\n\n var props = [];\n var propsStr = '' + value;\n\n if( propsStr === 'none' ){\n // leave empty\n\n } else { // go over each prop\n\n var propsSplit = propsStr.split(',');\n for( var i = 0; i < propsSplit.length; i++ ){\n var propName = propsSplit[i].trim();\n\n if( self.properties[propName] ){\n props.push( propName );\n }\n }\n\n if( props.length === 0 ){ return null; }\n }\n\n return {\n name: name,\n value: props,\n strValue: props.length === 0 ? 'none' : props.join(', '),\n bypass: propIsBypass\n };\n\n } else if( type.color ){\n var tuple = util.color2tuple( value );\n\n if( !tuple ){ return null; }\n\n return {\n name: name,\n value: tuple,\n strValue: '' + value,\n bypass: propIsBypass,\n roundValue: true\n };\n\n } else if( type.regex || type.regexes ){\n\n // first check enums\n if( type.enums ){\n var enumProp = checkEnums();\n\n if( enumProp ){ return enumProp; }\n }\n\n var regexes = type.regexes ? type.regexes : [ type.regex ];\n\n for( var i = 0; i < regexes.length; i++ ){\n var regex = new RegExp( regexes[i] ); // make a regex from the type string\n var m = regex.exec( value );\n\n if( m ){ // regex matches\n return {\n name: name,\n value: m,\n strValue: '' + value,\n bypass: propIsBypass\n };\n\n }\n }\n\n return null; // didn't match any\n\n } else if( type.string ){\n // just return\n return {\n name: name,\n value: value,\n strValue: '' + value,\n bypass: propIsBypass\n };\n\n } else if( type.enums ){ // check enums last because it's a combo type in others\n return checkEnums();\n\n } else {\n return null; // not a type we can handle\n }\n\n};\n\nmodule.exports = styfn;\n","'use strict';\n\nvar util = require('../util');\n\nvar styfn = {};\n\n(function(){\n var number = util.regex.number;\n var rgba = util.regex.rgbaNoBackRefs;\n var hsla = util.regex.hslaNoBackRefs;\n var hex3 = util.regex.hex3;\n var hex6 = util.regex.hex6;\n var data = function( prefix ){ return '^' + prefix + '\\\\s*\\\\(\\\\s*([\\\\w\\\\.]+)\\\\s*\\\\)$'; };\n var mapData = function( prefix ){\n var mapArg = number + '|\\\\w+|' + rgba + '|' + hsla + '|' + hex3 + '|' + hex6;\n return '^' + prefix + '\\\\s*\\\\(([\\\\w\\\\.]+)\\\\s*\\\\,\\\\s*(' + number + ')\\\\s*\\\\,\\\\s*(' + number + ')\\\\s*,\\\\s*(' + mapArg + ')\\\\s*\\\\,\\\\s*(' + mapArg + ')\\\\)$';\n };\n\n // each visual style property has a type and needs to be validated according to it\n styfn.types = {\n time: { number: true, min: 0, units: 's|ms', implicitUnits: 'ms' },\n percent: { number: true, min: 0, max: 100, units: '%', implicitUnits: '%' },\n zeroOneNumber: { number: true, min: 0, max: 1, unitless: true },\n nOneOneNumber: { number: true, min: -1, max: 1, unitless: true },\n nonNegativeInt: { number: true, min: 0, integer: true, unitless: true },\n position: { enums: ['parent', 'origin'] },\n nodeSize: { number: true, min: 0, enums: ['auto', 'label'] },\n number: { number: true, unitless: true },\n numbers: { number: true, unitless: true, multiple: true },\n size: { number: true, min: 0 },\n bidirectionalSize: { number: true }, // allows negative\n bidirectionalSizes: { number: true, multiple: true }, // allows negative\n bgSize: { number: true, min: 0, allowPercent: true },\n bgWH: { number: true, min: 0, allowPercent: true, enums: ['auto'] },\n bgPos: { number: true, allowPercent: true },\n bgRepeat: { enums: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat'] },\n bgFit: { enums: ['none', 'contain', 'cover'] },\n bgClip: { enums: ['none', 'node'] },\n color: { color: true },\n bool: { enums: ['yes', 'no'] },\n lineStyle: { enums: ['solid', 'dotted', 'dashed'] },\n borderStyle: { enums: ['solid', 'dotted', 'dashed', 'double'] },\n curveStyle: { enums: ['bezier', 'unbundled-bezier', 'haystack', 'segments'] },\n fontFamily: { regex: '^([\\\\w- \\\\\"]+(?:\\\\s*,\\\\s*[\\\\w- \\\\\"]+)*)$' },\n fontVariant: { enums: ['small-caps', 'normal'] },\n fontStyle: { enums: ['italic', 'normal', 'oblique'] },\n fontWeight: { enums: ['normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '800', '900', 100, 200, 300, 400, 500, 600, 700, 800, 900] },\n textDecoration: { enums: ['none', 'underline', 'overline', 'line-through'] },\n textTransform: { enums: ['none', 'uppercase', 'lowercase'] },\n textWrap: { enums: ['none', 'wrap'] },\n textBackgroundShape: { enums: ['rectangle', 'roundrectangle']},\n nodeShape: { enums: ['rectangle', 'roundrectangle', 'ellipse', 'triangle', 'square', 'pentagon', 'hexagon', 'heptagon', 'octagon', 'star', 'diamond', 'vee', 'rhomboid', 'polygon'] },\n compoundIncludeLabels: { enums: ['include', 'exclude'] },\n arrowShape: { enums: ['tee', 'triangle', 'triangle-tee', 'triangle-backcurve', 'half-triangle-overshot', 'vee', 'square', 'circle', 'diamond', 'none'] },\n arrowFill: { enums: ['filled', 'hollow'] },\n display: { enums: ['element', 'none'] },\n visibility: { enums: ['hidden', 'visible'] },\n valign: { enums: ['top', 'center', 'bottom'] },\n halign: { enums: ['left', 'center', 'right'] },\n text: { string: true },\n data: { mapping: true, regex: data('data') },\n layoutData: { mapping: true, regex: data('layoutData') },\n scratch: { mapping: true, regex: data('scratch') },\n mapData: { mapping: true, regex: mapData('mapData') },\n mapLayoutData: { mapping: true, regex: mapData('mapLayoutData') },\n mapScratch: { mapping: true, regex: mapData('mapScratch') },\n fn: { mapping: true, fn: true },\n url: { regex: '^url\\\\s*\\\\(\\\\s*([^\\\\s]+)\\\\s*\\\\s*\\\\)|none|(.+)$' },\n propList: { propList: true },\n angle: { number: true, units: 'deg|rad', implicitUnits: 'rad' },\n textRotation: { enums: ['none', 'autorotate'] },\n polygonPointList: { number: true, multiple: true, evenMultiple: true, min: -1, max: 1, unitless: true },\n easing: {\n regexes: [\n '^(spring)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*,\\\\s*(' + number + ')\\\\s*\\\\)$',\n '^(cubic-bezier)\\\\s*\\\\(\\\\s*(' + number + ')\\\\s*,\\\\s*(' + number + ')\\\\s*,\\\\s*(' + number + ')\\\\s*,\\\\s*(' + number + ')\\\\s*\\\\)$'\n ],\n enums: [\n 'linear',\n 'ease', 'ease-in', 'ease-out', 'ease-in-out',\n 'ease-in-sine', 'ease-out-sine', 'ease-in-out-sine',\n 'ease-in-quad', 'ease-out-quad', 'ease-in-out-quad',\n 'ease-in-cubic', 'ease-out-cubic', 'ease-in-out-cubic',\n 'ease-in-quart', 'ease-out-quart', 'ease-in-out-quart',\n 'ease-in-quint', 'ease-out-quint', 'ease-in-out-quint',\n 'ease-in-expo', 'ease-out-expo', 'ease-in-out-expo',\n 'ease-in-circ', 'ease-out-circ', 'ease-in-out-circ'\n ]\n }\n };\n\n // define visual style properties\n var t = styfn.types;\n var props = styfn.properties = [\n // labels\n { name: 'text-valign', type: t.valign },\n { name: 'text-halign', type: t.halign },\n { name: 'color', type: t.color },\n { name: 'label', type: t.text },\n { name: 'text-outline-color', type: t.color },\n { name: 'text-outline-width', type: t.size },\n { name: 'text-outline-opacity', type: t.zeroOneNumber },\n { name: 'text-opacity', type: t.zeroOneNumber },\n { name: 'text-background-color', type: t.color },\n { name: 'text-background-opacity', type: t.zeroOneNumber },\n { name: 'text-border-opacity', type: t.zeroOneNumber },\n { name: 'text-border-color', type: t.color },\n { name: 'text-border-width', type: t.size },\n { name: 'text-border-style', type: t.borderStyle },\n { name: 'text-background-shape', type: t.textBackgroundShape},\n // { name: 'text-decoration', type: t.textDecoration }, // not supported in canvas\n { name: 'text-transform', type: t.textTransform },\n { name: 'text-wrap', type: t.textWrap },\n { name: 'text-max-width', type: t.size },\n { name: 'text-events', type: t.bool },\n\n // { name: 'text-rotation', type: t.angle }, // TODO disabled b/c rotation breaks bounding boxes\n { name: 'font-family', type: t.fontFamily },\n { name: 'font-style', type: t.fontStyle },\n // { name: 'font-variant', type: t.fontVariant }, // not useful\n { name: 'font-weight', type: t.fontWeight },\n { name: 'font-size', type: t.size },\n { name: 'min-zoomed-font-size', type: t.size },\n { name: 'edge-text-rotation', type: t.textRotation },\n\n // behaviour\n { name: 'events', type: t.bool },\n\n // visibility\n { name: 'display', type: t.display },\n { name: 'visibility', type: t.visibility },\n { name: 'opacity', type: t.zeroOneNumber },\n { name: 'z-index', type: t.nonNegativeInt },\n\n // overlays\n { name: 'overlay-padding', type: t.size },\n { name: 'overlay-color', type: t.color },\n { name: 'overlay-opacity', type: t.zeroOneNumber },\n\n // shadows\n { name: 'shadow-blur', type: t.size },\n { name: 'shadow-color', type: t.color },\n { name: 'shadow-opacity', type: t.zeroOneNumber },\n { name: 'shadow-offset-x', type: t.bidirectionalSize },\n { name: 'shadow-offset-y', type: t.bidirectionalSize },\n\n // label shadows\n { name: 'text-shadow-blur', type: t.size },\n { name: 'text-shadow-color', type: t.color },\n { name: 'text-shadow-opacity', type: t.zeroOneNumber },\n { name: 'text-shadow-offset-x', type: t.bidirectionalSize },\n { name: 'text-shadow-offset-y', type: t.bidirectionalSize },\n\n // transition anis\n { name: 'transition-property', type: t.propList },\n { name: 'transition-duration', type: t.time },\n { name: 'transition-delay', type: t.time },\n { name: 'transition-timing-function', type: t.easing },\n\n // node body\n { name: 'height', type: t.nodeSize },\n { name: 'width', type: t.nodeSize },\n { name: 'shape', type: t.nodeShape },\n { name: 'shape-polygon-points', type: t.polygonPointList },\n { name: 'background-color', type: t.color },\n { name: 'background-opacity', type: t.zeroOneNumber },\n { name: 'background-blacken', type: t.nOneOneNumber },\n { name: 'padding-left', type: t.size },\n { name: 'padding-right', type: t.size },\n { name: 'padding-top', type: t.size },\n { name: 'padding-bottom', type: t.size },\n\n // node border\n { name: 'border-color', type: t.color },\n { name: 'border-opacity', type: t.zeroOneNumber },\n { name: 'border-width', type: t.size },\n { name: 'border-style', type: t.borderStyle },\n\n // node background images\n { name: 'background-image', type: t.url },\n { name: 'background-image-opacity', type: t.zeroOneNumber },\n { name: 'background-position-x', type: t.bgPos },\n { name: 'background-position-y', type: t.bgPos },\n { name: 'background-repeat', type: t.bgRepeat },\n { name: 'background-fit', type: t.bgFit },\n { name: 'background-clip', type: t.bgClip },\n { name: 'background-width', type: t.bgWH },\n { name: 'background-height', type: t.bgWH },\n\n // compound props\n { name: 'position', type: t.position },\n { name: 'compound-sizing-wrt-labels', type: t.compoundIncludeLabels },\n\n // edge line\n { name: 'line-style', type: t.lineStyle },\n { name: 'line-color', type: t.color },\n { name: 'curve-style', type: t.curveStyle },\n { name: 'haystack-radius', type: t.zeroOneNumber },\n { name: 'control-point-step-size', type: t.size },\n { name: 'control-point-distances', type: t.bidirectionalSizes },\n { name: 'control-point-weights', type: t.numbers },\n { name: 'segment-distances', type: t.bidirectionalSizes },\n { name: 'segment-weights', type: t.numbers },\n\n // these are just for the core\n { name: 'selection-box-color', type: t.color },\n { name: 'selection-box-opacity', type: t.zeroOneNumber },\n { name: 'selection-box-border-color', type: t.color },\n { name: 'selection-box-border-width', type: t.size },\n { name: 'active-bg-color', type: t.color },\n { name: 'active-bg-opacity', type: t.zeroOneNumber },\n { name: 'active-bg-size', type: t.size },\n { name: 'outside-texture-bg-color', type: t.color },\n { name: 'outside-texture-bg-opacity', type: t.zeroOneNumber }\n ];\n\n // define aliases\n var aliases = styfn.aliases = [\n { name: 'content', pointsTo: 'label' },\n { name: 'control-point-distance', pointsTo: 'control-point-distances' },\n { name: 'control-point-weight', pointsTo: 'control-point-weights' }\n ];\n\n // pie backgrounds for nodes\n styfn.pieBackgroundN = 16; // because the pie properties are numbered, give access to a constant N (for renderer use)\n props.push({ name: 'pie-size', type: t.bgSize });\n for( var i = 1; i <= styfn.pieBackgroundN; i++ ){\n props.push({ name: 'pie-'+i+'-background-color', type: t.color });\n props.push({ name: 'pie-'+i+'-background-size', type: t.percent });\n props.push({ name: 'pie-'+i+'-background-opacity', type: t.zeroOneNumber });\n }\n\n // edge arrows\n var arrowPrefixes = styfn.arrowPrefixes = ['source', 'mid-source', 'target', 'mid-target'];\n [\n { name: 'arrow-shape', type: t.arrowShape },\n { name: 'arrow-color', type: t.color },\n { name: 'arrow-fill', type: t.arrowFill }\n ].forEach(function( prop ){\n arrowPrefixes.forEach(function( prefix ){\n var name = prefix + '-' + prop.name;\n var type = prop.type;\n\n props.push({ name: name, type: type });\n });\n }, {});\n\n // list of property names\n styfn.propertyNames = props.map(function(p){ return p.name; });\n\n // allow access of properties by name ( e.g. style.properties.height )\n for( var i = 0; i < props.length; i++ ){\n var prop = props[i];\n\n props[ prop.name ] = prop; // allow lookup by name\n }\n\n // map aliases\n for( var i = 0; i < aliases.length; i++ ){\n var alias = aliases[i];\n var pointsToProp = props[ alias.pointsTo ];\n var aliasProp = {\n name: alias.name,\n alias: true,\n pointsTo: pointsToProp\n };\n\n // add alias prop for parsing\n props.push( aliasProp );\n\n props[ alias.name ] = aliasProp; // allow lookup by name\n }\n})();\n\n// adds the default stylesheet to the current style\nstyfn.addDefaultStylesheet = function(){\n // fill the style with the default stylesheet\n this\n .selector('node, edge') // common properties\n .css( util.extend( {\n 'events': 'yes',\n 'text-events': 'no',\n 'text-valign': 'top',\n 'text-halign': 'center',\n 'color': '#000',\n 'text-outline-color': '#000',\n 'text-outline-width': 0,\n 'text-outline-opacity': 1,\n 'text-opacity': 1,\n 'text-decoration': 'none',\n 'text-transform': 'none',\n 'text-wrap': 'none',\n 'text-max-width': 9999,\n 'text-background-color': '#000',\n 'text-background-opacity': 0,\n 'text-border-opacity': 0,\n 'text-border-width': 0,\n 'text-border-style': 'solid',\n 'text-border-color':'#000',\n 'text-background-shape':'rectangle',\n 'font-family': 'Helvetica Neue, Helvetica, sans-serif',\n 'font-style': 'normal',\n // 'font-variant': fontVariant,\n 'font-weight': 'normal',\n 'font-size': 16,\n 'min-zoomed-font-size': 0,\n 'edge-text-rotation': 'none',\n 'visibility': 'visible',\n 'display': 'element',\n 'opacity': 1,\n 'z-index': 0,\n 'label': '',\n 'overlay-opacity': 0,\n 'overlay-color': '#000',\n 'overlay-padding': 10,\n 'shadow-opacity': 0,\n 'shadow-color': '#000',\n 'shadow-blur': 10,\n 'shadow-offset-x': 0,\n 'shadow-offset-y': 0,\n 'text-shadow-opacity': 0,\n 'text-shadow-color': '#000',\n 'text-shadow-blur': 5,\n 'text-shadow-offset-x': 0,\n 'text-shadow-offset-y': 0,\n 'transition-property': 'none',\n 'transition-duration': 0,\n 'transition-delay': 0,\n 'transition-timing-function': 'linear',\n\n // node props\n 'background-blacken': 0,\n 'background-color': '#888',\n 'background-opacity': 1,\n 'background-image': 'none',\n 'background-image-opacity': 1,\n 'background-position-x': '50%',\n 'background-position-y': '50%',\n 'background-repeat': 'no-repeat',\n 'background-fit': 'none',\n 'background-clip': 'node',\n 'background-width': 'auto',\n 'background-height': 'auto',\n 'border-color': '#000',\n 'border-opacity': 1,\n 'border-width': 0,\n 'border-style': 'solid',\n 'height': 30,\n 'width': 30,\n 'shape': 'ellipse',\n 'shape-polygon-points': '-1, -1, 1, -1, 1, 1, -1, 1',\n\n // compound props\n 'padding-top': 0,\n 'padding-bottom': 0,\n 'padding-left': 0,\n 'padding-right': 0,\n 'position': 'origin',\n 'compound-sizing-wrt-labels': 'include'\n }, {\n // node pie bg\n 'pie-size': '100%'\n }, [\n { name: 'pie-{{i}}-background-color', value: 'black' },\n { name: 'pie-{{i}}-background-size', value: '0%' },\n { name: 'pie-{{i}}-background-opacity', value: 1 }\n ].reduce(function( css, prop ){\n for( var i = 1; i <= styfn.pieBackgroundN; i++ ){\n var name = prop.name.replace('{{i}}', i);\n var val = prop.value;\n\n css[ name ] = val;\n }\n\n return css;\n }, {}), {\n // edge props\n 'line-style': 'solid',\n 'line-color': '#ddd',\n 'control-point-step-size': 40,\n 'control-point-weights': 0.5,\n 'segment-weights': 0.5,\n 'segment-distances': 20,\n 'curve-style': 'bezier',\n 'haystack-radius': 0.8\n }, [\n { name: 'arrow-shape', value: 'none' },\n { name: 'arrow-color', value: '#ddd' },\n { name: 'arrow-fill', value: 'filled' }\n ].reduce(function( css, prop ){\n styfn.arrowPrefixes.forEach(function( prefix ){\n var name = prefix + '-' + prop.name;\n var val = prop.value;\n\n css[ name ] = val;\n });\n\n return css;\n }, {}) ) )\n .selector('$node > node') // compound (parent) node properties\n .css({\n 'width': 'auto',\n 'height': 'auto',\n 'shape': 'rectangle',\n 'padding-top': 10,\n 'padding-right': 10,\n 'padding-left': 10,\n 'padding-bottom': 10\n })\n .selector('edge') // just edge properties\n .css({\n 'width': 1\n })\n .selector(':active')\n .css({\n 'overlay-color': 'black',\n 'overlay-padding': 10,\n 'overlay-opacity': 0.25\n })\n .selector('core') // just core properties\n .css({\n 'selection-box-color': '#ddd',\n 'selection-box-opacity': 0.65,\n 'selection-box-border-color': '#aaa',\n 'selection-box-border-width': 1,\n 'active-bg-color': 'black',\n 'active-bg-opacity': 0.15,\n 'active-bg-size': 30,\n 'outside-texture-bg-color': '#000',\n 'outside-texture-bg-opacity': 0.125\n })\n ;\n\n this.defaultLength = this.length;\n};\n\nmodule.exports = styfn;\n","'use strict';\n\nvar util = require('../util');\nvar Selector = require('../selector');\n\nvar styfn = {};\n\nstyfn.applyFromString = function( string ){\n var self = this;\n var style = this;\n var remaining = '' + string;\n var selAndBlockStr;\n var blockRem;\n var propAndValStr;\n\n // remove comments from the style string\n remaining = remaining.replace(/[/][*](\\s|.)+?[*][/]/g, '');\n\n function removeSelAndBlockFromRemaining(){\n // remove the parsed selector and block from the remaining text to parse\n if( remaining.length > selAndBlockStr.length ){\n remaining = remaining.substr( selAndBlockStr.length );\n } else {\n remaining = '';\n }\n }\n\n function removePropAndValFromRem(){\n // remove the parsed property and value from the remaining block text to parse\n if( blockRem.length > propAndValStr.length ){\n blockRem = blockRem.substr( propAndValStr.length );\n } else {\n blockRem = '';\n }\n }\n\n while(true){\n var nothingLeftToParse = remaining.match(/^\\s*$/);\n if( nothingLeftToParse ){ break; }\n\n var selAndBlock = remaining.match(/^\\s*((?:.|\\s)+?)\\s*\\{((?:.|\\s)+?)\\}/);\n\n if( !selAndBlock ){\n util.error('Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: ' + remaining);\n break;\n }\n\n selAndBlockStr = selAndBlock[0];\n\n // parse the selector\n var selectorStr = selAndBlock[1];\n if( selectorStr !== 'core' ){\n var selector = new Selector( selectorStr );\n if( selector._private.invalid ){\n util.error('Skipping parsing of block: Invalid selector found in string stylesheet: ' + selectorStr);\n\n // skip this selector and block\n removeSelAndBlockFromRemaining();\n continue;\n }\n }\n\n // parse the block of properties and values\n var blockStr = selAndBlock[2];\n var invalidBlock = false;\n blockRem = blockStr;\n var props = [];\n\n while(true){\n var nothingLeftToParse = blockRem.match(/^\\s*$/);\n if( nothingLeftToParse ){ break; }\n\n var propAndVal = blockRem.match(/^\\s*(.+?)\\s*:\\s*(.+?)\\s*;/);\n\n if( !propAndVal ){\n util.error('Skipping parsing of block: Invalid formatting of style property and value definitions found in:' + blockStr);\n invalidBlock = true;\n break;\n }\n\n propAndValStr = propAndVal[0];\n var propStr = propAndVal[1];\n var valStr = propAndVal[2];\n\n var prop = self.properties[ propStr ];\n if( !prop ){\n util.error('Skipping property: Invalid property name in: ' + propAndValStr);\n\n // skip this property in the block\n removePropAndValFromRem();\n continue;\n }\n\n var parsedProp = style.parse( propStr, valStr );\n\n if( !parsedProp ){\n util.error('Skipping property: Invalid property definition in: ' + propAndValStr);\n\n // skip this property in the block\n removePropAndValFromRem();\n continue;\n }\n\n props.push({\n name: propStr,\n val: valStr\n });\n removePropAndValFromRem();\n }\n\n if( invalidBlock ){\n removeSelAndBlockFromRemaining();\n break;\n }\n\n // put the parsed block in the style\n style.selector( selectorStr );\n for( var i = 0; i < props.length; i++ ){\n var prop = props[i];\n style.css( prop.name, prop.val );\n }\n\n removeSelAndBlockFromRemaining();\n }\n\n return style;\n};\n\nstyfn.fromString = function( string ){\n var style = this;\n\n style.resetToDefault();\n style.applyFromString( string );\n\n return style;\n};\n\nmodule.exports = styfn;\n","'use strict';\n\nvar is = require('./is');\nvar util = require('./util');\nvar Style = require('./style');\n\n// a dummy stylesheet object that doesn't need a reference to the core\n// (useful for init)\nvar Stylesheet = function(){\n if( !(this instanceof Stylesheet) ){\n return new Stylesheet();\n }\n\n this.length = 0;\n};\n\nvar sheetfn = Stylesheet.prototype;\n\nsheetfn.instanceString = function(){\n return 'stylesheet';\n};\n\n// just store the selector to be parsed later\nsheetfn.selector = function( selector ){\n var i = this.length++;\n\n this[i] = {\n selector: selector,\n properties: []\n };\n\n return this; // chaining\n};\n\n// just store the property to be parsed later\nsheetfn.css = function( name, value ){\n var i = this.length - 1;\n\n if( is.string(name) ){\n this[i].properties.push({\n name: name,\n value: value\n });\n } else if( is.plainObject(name) ){\n var map = name;\n\n for( var j = 0; j < Style.properties.length; j++ ){\n var prop = Style.properties[j];\n var mapVal = map[ prop.name ];\n\n if( mapVal === undefined ){ // also try camel case name\n mapVal = map[ util.dash2camel(prop.name) ];\n }\n\n if( mapVal !== undefined ){\n var name = prop.name;\n var value = mapVal;\n\n this[i].properties.push({\n name: name,\n value: value\n });\n }\n }\n }\n\n return this; // chaining\n};\n\nsheetfn.style = sheetfn.css;\n\n// generate a real style object from the dummy stylesheet\nsheetfn.generateStyle = function( cy ){\n var style = new Style(cy);\n\n for( var i = 0; i < this.length; i++ ){\n var context = this[i];\n var selector = context.selector;\n var props = context.properties;\n\n style.selector(selector); // apply selector\n\n for( var j = 0; j < props.length; j++ ){\n var prop = props[j];\n\n style.css( prop.name, prop.value ); // apply property\n }\n }\n\n return style;\n};\n\nmodule.exports = Stylesheet;\n","// cross-env thread/worker\n// NB : uses (heavyweight) processes on nodejs so best not to create too many threads\n\n'use strict';\n\nvar window = require('./window');\nvar util = require('./util');\nvar Promise = require('./promise');\nvar Event = require('./event');\nvar define = require('./define');\nvar is = require('./is');\n\nvar Thread = function( opts ){\n if( !(this instanceof Thread) ){\n return new Thread( opts );\n }\n\n var _p = this._private = {\n requires: [],\n files: [],\n queue: null,\n pass: [],\n disabled: false\n };\n\n if( is.plainObject(opts) ){\n if( opts.disabled != null ){\n _p.disabled = !!opts.disabled;\n }\n }\n\n};\n\nvar thdfn = Thread.prototype; // short alias\n\nvar stringifyFieldVal = function( val ){\n var valStr = is.fn( val ) ? val.toString() : \"JSON.parse('\" + JSON.stringify(val) + \"')\";\n\n return valStr;\n};\n\n// allows for requires with prototypes and subobjs etc\nvar fnAsRequire = function( fn ){\n var req;\n var fnName;\n\n if( is.object(fn) && fn.fn ){ // manual fn\n req = fnAs( fn.fn, fn.name );\n fnName = fn.name;\n fn = fn.fn;\n } else if( is.fn(fn) ){ // auto fn\n req = fn.toString();\n fnName = fn.name;\n } else if( is.string(fn) ){ // stringified fn\n req = fn;\n } else if( is.object(fn) ){ // plain object\n if( fn.proto ){\n req = '';\n } else {\n req = fn.name + ' = {};';\n }\n\n fnName = fn.name;\n fn = fn.obj;\n }\n\n req += '\\n';\n\n var protoreq = function( val, subname ){\n if( val.prototype ){\n var protoNonempty = false;\n for( var prop in val.prototype ){ protoNonempty = true; break; } // jshint ignore:line\n\n if( protoNonempty ){\n req += fnAsRequire( {\n name: subname,\n obj: val,\n proto: true\n }, val );\n }\n }\n };\n\n // pull in prototype\n if( fn.prototype && fnName != null ){\n\n for( var name in fn.prototype ){\n var protoStr = '';\n\n var val = fn.prototype[ name ];\n var valStr = stringifyFieldVal( val );\n var subname = fnName + '.prototype.' + name;\n\n protoStr += subname + ' = ' + valStr + ';\\n';\n\n if( protoStr ){\n req += protoStr;\n }\n\n protoreq( val, subname ); // subobject with prototype\n }\n\n }\n\n // pull in properties for obj/fns\n if( !is.string(fn) ){ for( var name in fn ){\n var propsStr = '';\n\n if( fn.hasOwnProperty(name) ){\n var val = fn[ name ];\n var valStr = stringifyFieldVal( val );\n var subname = fnName + '[\"' + name + '\"]';\n\n propsStr += subname + ' = ' + valStr + ';\\n';\n }\n\n if( propsStr ){\n req += propsStr;\n }\n\n protoreq( val, subname ); // subobject with prototype\n } }\n\n return req;\n};\n\nvar isPathStr = function( str ){\n return is.string(str) && str.match(/\\.js$/);\n};\n\nutil.extend(thdfn, {\n\n instanceString: function(){ return 'thread'; },\n\n require: function( fn, as ){\n var requires = this._private.requires;\n\n if( isPathStr(fn) ){\n this._private.files.push( fn );\n\n return this;\n }\n\n if( as ){\n if( is.fn(fn) ){\n fn = { name: as, fn: fn };\n } else {\n fn = { name: as, obj: fn };\n }\n } else {\n if( is.fn(fn) ){\n if( !fn.name ){\n throw 'The function name could not be automatically determined. Use thread.require( someFunction, \"someFunction\" )';\n }\n\n fn = { name: fn.name, fn: fn };\n }\n }\n\n requires.push( fn );\n\n return this; // chaining\n },\n\n pass: function( data ){\n this._private.pass.push( data );\n\n return this; // chaining\n },\n\n run: function( fn, pass ){ // fn used like main()\n var self = this;\n var _p = this._private;\n pass = pass || _p.pass.shift();\n\n if( _p.stopped ){\n throw 'Attempted to run a stopped thread! Start a new thread or do not stop the existing thread and reuse it.';\n }\n\n if( _p.running ){\n return ( _p.queue = _p.queue.then(function(){ // inductive step\n return self.run( fn, pass );\n }) );\n }\n\n var useWW = window != null && !_p.disabled;\n var useNode = !window && typeof module !== 'undefined' && !_p.disabled;\n\n self.trigger('run');\n\n var runP = new Promise(function( resolve, reject ){\n\n _p.running = true;\n\n var threadTechAlreadyExists = _p.ran;\n\n var fnImplStr = is.string( fn ) ? fn : fn.toString();\n\n // worker code to exec\n var fnStr = '\\n' + ( _p.requires.map(function( r ){\n return fnAsRequire( r );\n }) ).concat( _p.files.map(function( f ){\n if( useWW ){\n var wwifyFile = function( file ){\n if( file.match(/^\\.\\//) || file.match(/^\\.\\./) ){\n return window.location.origin + window.location.pathname + file;\n } else if( file.match(/^\\//) ){\n return window.location.origin + '/' + file;\n }\n return file;\n };\n\n return 'importScripts(\"' + wwifyFile(f) + '\");';\n } else if( useNode ) {\n return 'eval( require(\"fs\").readFileSync(\"' + f + '\", { encoding: \"utf8\" }) );';\n } else {\n throw 'External file `' + f + '` can not be required without any threading technology.';\n }\n }) ).concat([\n '( function(){',\n 'var ret = (' + fnImplStr + ')(' + JSON.stringify(pass) + ');',\n 'if( ret !== undefined ){ resolve(ret); }', // assume if ran fn returns defined value (incl. null), that we want to resolve to it\n '} )()\\n'\n ]).join('\\n');\n\n // because we've now consumed the requires, empty the list so we don't dupe on next run()\n _p.requires = [];\n _p.files = [];\n\n if( useWW ){\n var fnBlob, fnUrl;\n\n // add normalised thread api functions\n if( !threadTechAlreadyExists ){\n var fnPre = fnStr + '';\n\n fnStr = [\n 'function _ref_(o){ return eval(o); };',\n 'function broadcast(m){ return message(m); };', // alias\n 'function message(m){ postMessage(m); };',\n 'function listen(fn){',\n ' self.addEventListener(\"message\", function(m){ ',\n ' if( typeof m === \"object\" && (m.data.$$eval || m.data === \"$$start\") ){',\n ' } else { ',\n ' fn( m.data );',\n ' }',\n ' });',\n '};',\n 'self.addEventListener(\"message\", function(m){ if( m.data.$$eval ){ eval( m.data.$$eval ); } });',\n 'function resolve(v){ postMessage({ $$resolve: v }); };',\n 'function reject(v){ postMessage({ $$reject: v }); };'\n ].join('\\n');\n\n fnStr += fnPre;\n\n fnBlob = new Blob([ fnStr ], {\n type: 'application/javascript'\n });\n fnUrl = window.URL.createObjectURL( fnBlob );\n }\n // create webworker and let it exec the serialised code\n var ww = _p.webworker = _p.webworker || new Worker( fnUrl );\n\n if( threadTechAlreadyExists ){ // then just exec new run() code\n ww.postMessage({\n $$eval: fnStr\n });\n }\n\n // worker messages => events\n var cb;\n ww.addEventListener('message', cb = function( m ){\n var isObject = is.object(m) && is.object( m.data );\n\n if( isObject && ('$$resolve' in m.data) ){\n ww.removeEventListener('message', cb); // done listening b/c resolve()\n\n resolve( m.data.$$resolve );\n } else if( isObject && ('$$reject' in m.data) ){\n ww.removeEventListener('message', cb); // done listening b/c reject()\n\n reject( m.data.$$reject );\n } else {\n self.trigger( new Event(m, { type: 'message', message: m.data }) );\n }\n }, false);\n\n if( !threadTechAlreadyExists ){\n ww.postMessage('$$start'); // start up the worker\n }\n\n } else if( useNode ){\n // create a new process\n\n if( !_p.child ){\n _p.child = ( require('child_process').fork( require('path').join(__dirname, 'thread-node-fork') ) );\n }\n\n var child = _p.child;\n\n // child process messages => events\n var cb;\n child.on('message', cb = function( m ){\n if( is.object(m) && ('$$resolve' in m) ){\n child.removeListener('message', cb); // done listening b/c resolve()\n\n resolve( m.$$resolve );\n } else if( is.object(m) && ('$$reject' in m) ){\n child.removeListener('message', cb); // done listening b/c reject()\n\n reject( m.$$reject );\n } else {\n self.trigger( new Event({}, { type: 'message', message: m }) );\n }\n });\n\n // ask the child process to eval the worker code\n child.send({\n $$eval: fnStr\n });\n\n } else { // use a fallback mechanism using a timeout\n\n var promiseResolve = resolve;\n var promiseReject = reject;\n\n var timer = _p.timer = _p.timer || {\n\n listeners: [],\n\n exec: function(){\n // as a string so it can't be mangled by minifiers and processors\n fnStr = [\n 'function _ref_(o){ return eval(o); };',\n 'function broadcast(m){ return message(m); };',\n 'function message(m){ self.trigger( new Event({}, { type: \"message\", message: m }) ); };',\n 'function listen(fn){ timer.listeners.push( fn ); };',\n 'function resolve(v){ promiseResolve(v); };',\n 'function reject(v){ promiseReject(v); };'\n ].join('\\n') + fnStr;\n\n // the .run() code\n eval( fnStr ); // jshint ignore:line\n },\n\n message: function( m ){\n var ls = timer.listeners;\n\n for( var i = 0; i < ls.length; i++ ){\n var fn = ls[i];\n\n fn( m );\n }\n }\n\n };\n\n timer.exec();\n }\n\n }).then(function( v ){\n _p.running = false;\n _p.ran = true;\n\n self.trigger('ran');\n\n return v;\n });\n\n if( _p.queue == null ){\n _p.queue = runP; // i.e. first step of inductive promise chain (for queue)\n }\n\n return runP;\n },\n\n // send the thread a message\n message: function( m ){\n var _p = this._private;\n\n if( _p.webworker ){\n _p.webworker.postMessage( m );\n }\n\n if( _p.child ){\n _p.child.send( m );\n }\n\n if( _p.timer ){\n _p.timer.message( m );\n }\n\n return this; // chaining\n },\n\n stop: function(){\n var _p = this._private;\n\n if( _p.webworker ){\n _p.webworker.terminate();\n }\n\n if( _p.child ){\n _p.child.kill();\n }\n\n if( _p.timer ){\n // nothing we can do if we've run a timeout\n }\n\n _p.stopped = true;\n\n return this.trigger('stop'); // chaining\n },\n\n stopped: function(){\n return this._private.stopped;\n }\n\n});\n\n// turns a stringified function into a (re)named function\nvar fnAs = function( fn, name ){\n var fnStr = fn.toString();\n fnStr = fnStr.replace(/function\\s*?\\S*?\\s*?\\(/, 'function ' + name + '(');\n\n return fnStr;\n};\n\nvar defineFnal = function( opts ){\n opts = opts || {};\n\n return function fnalImpl( fn, arg1 ){\n var fnStr = fnAs( fn, '_$_$_' + opts.name );\n\n this.require( fnStr );\n\n return this.run( [\n 'function( data ){',\n ' var origResolve = resolve;',\n ' var res = [];',\n ' ',\n ' resolve = function( val ){',\n ' res.push( val );',\n ' };',\n ' ',\n ' var ret = data.' + opts.name + '( _$_$_' + opts.name + ( arguments.length > 1 ? ', ' + JSON.stringify(arg1) : '' ) + ' );',\n ' ',\n ' resolve = origResolve;',\n ' resolve( res.length > 0 ? res : ret );',\n '}'\n ].join('\\n') );\n };\n};\n\nutil.extend(thdfn, {\n reduce: defineFnal({ name: 'reduce' }),\n\n reduceRight: defineFnal({ name: 'reduceRight' }),\n\n map: defineFnal({ name: 'map' })\n});\n\n// aliases\nvar fn = thdfn;\nfn.promise = fn.run;\nfn.terminate = fn.halt = fn.stop;\nfn.include = fn.require;\n\n// pull in event apis\nutil.extend(thdfn, {\n on: define.on(),\n one: define.on({ unbindSelfOnTrigger: true }),\n off: define.off(),\n trigger: define.trigger()\n});\n\ndefine.eventAliasesOn( thdfn );\n\nmodule.exports = Thread;\n","'use strict';\n\nvar is = require('../is');\n\nmodule.exports = {\n // get [r, g, b] from #abc or #aabbcc\n hex2tuple: function( hex ){\n if( !(hex.length === 4 || hex.length === 7) || hex[0] !== \"#\" ){ return; }\n\n var shortHex = hex.length === 4;\n var r, g, b;\n var base = 16;\n\n if( shortHex ){\n r = parseInt( hex[1] + hex[1], base );\n g = parseInt( hex[2] + hex[2], base );\n b = parseInt( hex[3] + hex[3], base );\n } else {\n r = parseInt( hex[1] + hex[2], base );\n g = parseInt( hex[3] + hex[4], base );\n b = parseInt( hex[5] + hex[6], base );\n }\n\n return [r, g, b];\n },\n\n // get [r, g, b, a] from hsl(0, 0, 0) or hsla(0, 0, 0, 0)\n hsl2tuple: function( hsl ){\n var ret;\n var h, s, l, a, r, g, b;\n function hue2rgb(p, q, t){\n if(t < 0) t += 1;\n if(t > 1) t -= 1;\n if(t < 1/6) return p + (q - p) * 6 * t;\n if(t < 1/2) return q;\n if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;\n return p;\n }\n\n var m = new RegExp(\"^\" + this.regex.hsla + \"$\").exec(hsl);\n if( m ){\n\n // get hue\n h = parseInt( m[1] );\n if( h < 0 ){\n h = ( 360 - (-1*h % 360) ) % 360;\n } else if( h > 360 ){\n h = h % 360;\n }\n h /= 360; // normalise on [0, 1]\n\n s = parseFloat( m[2] );\n if( s < 0 || s > 100 ){ return; } // saturation is [0, 100]\n s = s/100; // normalise on [0, 1]\n\n l = parseFloat( m[3] );\n if( l < 0 || l > 100 ){ return; } // lightness is [0, 100]\n l = l/100; // normalise on [0, 1]\n\n a = m[4];\n if( a !== undefined ){\n a = parseFloat( a );\n\n if( a < 0 || a > 1 ){ return; } // alpha is [0, 1]\n }\n\n // now, convert to rgb\n // code from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript\n if( s === 0 ){\n r = g = b = Math.round(l * 255); // achromatic\n } else {\n var q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n var p = 2 * l - q;\n r = Math.round( 255 * hue2rgb(p, q, h + 1/3) );\n g = Math.round( 255 * hue2rgb(p, q, h) );\n b = Math.round( 255 * hue2rgb(p, q, h - 1/3) );\n }\n\n ret = [r, g, b, a];\n }\n\n return ret;\n },\n\n // get [r, g, b, a] from rgb(0, 0, 0) or rgba(0, 0, 0, 0)\n rgb2tuple: function( rgb ){\n var ret;\n\n var m = new RegExp(\"^\" + this.regex.rgba + \"$\").exec(rgb);\n if( m ){\n ret = [];\n\n var isPct = [];\n for( var i = 1; i <= 3; i++ ){\n var channel = m[i];\n\n if( channel[ channel.length - 1 ] === \"%\" ){\n isPct[i] = true;\n }\n channel = parseFloat( channel );\n\n if( isPct[i] ){\n channel = channel/100 * 255; // normalise to [0, 255]\n }\n\n if( channel < 0 || channel > 255 ){ return; } // invalid channel value\n\n ret.push( Math.floor(channel) );\n }\n\n var atLeastOneIsPct = isPct[1] || isPct[2] || isPct[3];\n var allArePct = isPct[1] && isPct[2] && isPct[3];\n if( atLeastOneIsPct && !allArePct ){ return; } // must all be percent values if one is\n\n var alpha = m[4];\n if( alpha !== undefined ){\n alpha = parseFloat( alpha );\n\n if( alpha < 0 || alpha > 1 ){ return; } // invalid alpha value\n\n ret.push( alpha );\n }\n }\n\n return ret;\n },\n\n colorname2tuple: function( color ){\n return this.colors[ color.toLowerCase() ];\n },\n\n color2tuple: function( color ){\n return ( is.array(color) ? color : null )\n || this.colorname2tuple(color)\n || this.hex2tuple(color)\n || this.rgb2tuple(color)\n || this.hsl2tuple(color);\n },\n\n colors: {\n // special colour names\n transparent: [0, 0, 0, 0], // NB alpha === 0\n\n // regular colours\n aliceblue: [240, 248, 255],\n antiquewhite: [250, 235, 215],\n aqua: [0, 255, 255],\n aquamarine: [127, 255, 212],\n azure: [240, 255, 255],\n beige: [245, 245, 220],\n bisque: [255, 228, 196],\n black: [0, 0, 0],\n blanchedalmond: [255, 235, 205],\n blue: [0, 0, 255],\n blueviolet: [138, 43, 226],\n brown: [165, 42, 42],\n burlywood: [222, 184, 135],\n cadetblue: [95, 158, 160],\n chartreuse: [127, 255, 0],\n chocolate: [210, 105, 30],\n coral: [255, 127, 80],\n cornflowerblue: [100, 149, 237],\n cornsilk: [255, 248, 220],\n crimson: [220, 20, 60],\n cyan: [0, 255, 255],\n darkblue: [0, 0, 139],\n darkcyan: [0, 139, 139],\n darkgoldenrod: [184, 134, 11],\n darkgray: [169, 169, 169],\n darkgreen: [0, 100, 0],\n darkgrey: [169, 169, 169],\n darkkhaki: [189, 183, 107],\n darkmagenta: [139, 0, 139],\n darkolivegreen: [85, 107, 47],\n darkorange: [255, 140, 0],\n darkorchid: [153, 50, 204],\n darkred: [139, 0, 0],\n darksalmon: [233, 150, 122],\n darkseagreen: [143, 188, 143],\n darkslateblue: [72, 61, 139],\n darkslategray: [47, 79, 79],\n darkslategrey: [47, 79, 79],\n darkturquoise: [0, 206, 209],\n darkviolet: [148, 0, 211],\n deeppink: [255, 20, 147],\n deepskyblue: [0, 191, 255],\n dimgray: [105, 105, 105],\n dimgrey: [105, 105, 105],\n dodgerblue: [30, 144, 255],\n firebrick: [178, 34, 34],\n floralwhite: [255, 250, 240],\n forestgreen: [34, 139, 34],\n fuchsia: [255, 0, 255],\n gainsboro: [220, 220, 220],\n ghostwhite: [248, 248, 255],\n gold: [255, 215, 0],\n goldenrod: [218, 165, 32],\n gray: [128, 128, 128],\n grey: [128, 128, 128],\n green: [0, 128, 0],\n greenyellow: [173, 255, 47],\n honeydew: [240, 255, 240],\n hotpink: [255, 105, 180],\n indianred: [205, 92, 92],\n indigo: [75, 0, 130],\n ivory: [255, 255, 240],\n khaki: [240, 230, 140],\n lavender: [230, 230, 250],\n lavenderblush: [255, 240, 245],\n lawngreen: [124, 252, 0],\n lemonchiffon: [255, 250, 205],\n lightblue: [173, 216, 230],\n lightcoral: [240, 128, 128],\n lightcyan: [224, 255, 255],\n lightgoldenrodyellow: [250, 250, 210],\n lightgray: [211, 211, 211],\n lightgreen: [144, 238, 144],\n lightgrey: [211, 211, 211],\n lightpink: [255, 182, 193],\n lightsalmon: [255, 160, 122],\n lightseagreen: [32, 178, 170],\n lightskyblue: [135, 206, 250],\n lightslategray: [119, 136, 153],\n lightslategrey: [119, 136, 153],\n lightsteelblue: [176, 196, 222],\n lightyellow: [255, 255, 224],\n lime: [0, 255, 0],\n limegreen: [50, 205, 50],\n linen: [250, 240, 230],\n magenta: [255, 0, 255],\n maroon: [128, 0, 0],\n mediumaquamarine: [102, 205, 170],\n mediumblue: [0, 0, 205],\n mediumorchid: [186, 85, 211],\n mediumpurple: [147, 112, 219],\n mediumseagreen: [60, 179, 113],\n mediumslateblue: [123, 104, 238],\n mediumspringgreen: [0, 250, 154],\n mediumturquoise: [72, 209, 204],\n mediumvioletred: [199, 21, 133],\n midnightblue: [25, 25, 112],\n mintcream: [245, 255, 250],\n mistyrose: [255, 228, 225],\n moccasin: [255, 228, 181],\n navajowhite: [255, 222, 173],\n navy: [0, 0, 128],\n oldlace: [253, 245, 230],\n olive: [128, 128, 0],\n olivedrab: [107, 142, 35],\n orange: [255, 165, 0],\n orangered: [255, 69, 0],\n orchid: [218, 112, 214],\n palegoldenrod: [238, 232, 170],\n palegreen: [152, 251, 152],\n paleturquoise: [175, 238, 238],\n palevioletred: [219, 112, 147],\n papayawhip: [255, 239, 213],\n peachpuff: [255, 218, 185],\n peru: [205, 133, 63],\n pink: [255, 192, 203],\n plum: [221, 160, 221],\n powderblue: [176, 224, 230],\n purple: [128, 0, 128],\n red: [255, 0, 0],\n rosybrown: [188, 143, 143],\n royalblue: [65, 105, 225],\n saddlebrown: [139, 69, 19],\n salmon: [250, 128, 114],\n sandybrown: [244, 164, 96],\n seagreen: [46, 139, 87],\n seashell: [255, 245, 238],\n sienna: [160, 82, 45],\n silver: [192, 192, 192],\n skyblue: [135, 206, 235],\n slateblue: [106, 90, 205],\n slategray: [112, 128, 144],\n slategrey: [112, 128, 144],\n snow: [255, 250, 250],\n springgreen: [0, 255, 127],\n steelblue: [70, 130, 180],\n tan: [210, 180, 140],\n teal: [0, 128, 128],\n thistle: [216, 191, 216],\n tomato: [255, 99, 71],\n turquoise: [64, 224, 208],\n violet: [238, 130, 238],\n wheat: [245, 222, 179],\n white: [255, 255, 255],\n whitesmoke: [245, 245, 245],\n yellow: [255, 255, 0],\n yellowgreen: [154, 205, 50]\n }\n};\n","'use strict';\n\nvar is = require('../is');\nvar math = require('../math');\n\nvar util = {\n\n falsify: function(){ return false; },\n\n zeroify: function(){ return 0; },\n\n noop: function(){},\n\n /* jshint ignore:start */\n error: function( msg ){\n if( console.error ){\n console.error.apply( console, arguments );\n\n if( console.trace ){ console.trace(); }\n } else {\n console.log.apply( console, arguments );\n\n if( console.trace ){ console.trace(); }\n }\n },\n /* jshint ignore:end */\n\n clone: function( obj ){\n return this.extend( {}, obj );\n },\n\n // gets a shallow copy of the argument\n copy: function( obj ){\n if( obj == null ){\n return obj;\n } if( is.array(obj) ){\n return obj.slice();\n } else if( is.plainObject(obj) ){\n return this.clone( obj );\n } else {\n return obj;\n }\n }\n\n};\n\nutil.makeBoundingBox = math.makeBoundingBox.bind( math );\n\nutil._staticEmptyObject = {};\n\nutil.staticEmptyObject = function(){\n return util._staticEmptyObject;\n};\n\nutil.extend = Object.assign != null ? Object.assign : function( tgt ){\n var args = arguments;\n\n for( var i = 1; i < args.length; i++ ){\n var obj = args[i];\n\n for( var k in obj ){\n tgt[k] = obj[k];\n }\n }\n\n return tgt;\n};\n\n[\n require('./colors'),\n require('./maps'),\n { memoize: require('./memoize') },\n require('./regex'),\n require('./strings'),\n require('./timing')\n].forEach(function( req ){\n util.extend( util, req );\n});\n\nmodule.exports = util;\n","'use strict';\n\nvar is = require('../is');\n\nmodule.exports = {\n // has anything been set in the map\n mapEmpty: function( map ){\n var empty = true;\n\n if( map != null ){\n for(var i in map){ // jshint ignore:line\n empty = false;\n break;\n }\n }\n\n return empty;\n },\n\n // pushes to the array at the end of a map (map may not be built)\n pushMap: function( options ){\n var array = this.getMap(options);\n\n if( array == null ){ // if empty, put initial array\n this.setMap( this.extend({}, options, {\n value: [ options.value ]\n }) );\n } else {\n array.push( options.value );\n }\n },\n\n // sets the value in a map (map may not be built)\n setMap: function( options ){\n var obj = options.map;\n var key;\n var keys = options.keys;\n var l = keys.length;\n\n for(var i = 0; i < l; i++){\n var key = keys[i];\n\n if( is.plainObject( key ) ){\n this.error('Tried to set map with object key');\n }\n\n if( i < keys.length - 1 ){\n\n // extend the map if necessary\n if( obj[key] == null ){\n obj[key] = {};\n }\n\n obj = obj[key];\n } else {\n // set the value\n obj[key] = options.value;\n }\n }\n },\n\n // gets the value in a map even if it's not built in places\n getMap: function( options ){\n var obj = options.map;\n var keys = options.keys;\n var l = keys.length;\n\n for(var i = 0; i < l; i++){\n var key = keys[i];\n\n if( is.plainObject( key ) ){\n this.error('Tried to get map with object key');\n }\n\n obj = obj[key];\n\n if( obj == null ){\n return obj;\n }\n }\n\n return obj;\n },\n\n // deletes the entry in the map\n deleteMap: function( options ){\n var obj = options.map;\n var keys = options.keys;\n var l = keys.length;\n var keepChildren = options.keepChildren;\n\n for(var i = 0; i < l; i++){\n var key = keys[i];\n\n if( is.plainObject( key ) ){\n this.error('Tried to delete map with object key');\n }\n\n var lastKey = i === options.keys.length - 1;\n if( lastKey ){\n\n if( keepChildren ){ // then only delete child fields not in keepChildren\n for( var child in obj ){\n if( !keepChildren[child] ){\n obj[child] = undefined;\n }\n }\n } else {\n obj[key] = undefined;\n }\n\n } else {\n obj = obj[key];\n }\n }\n }\n};\n","'use strict';\n\nmodule.exports = function memoize( fn, keyFn ){\n var self = this;\n var cache = {};\n\n if( !keyFn ){\n keyFn = function(){\n if( arguments.length === 1 ){\n return arguments[0];\n }\n\n var args = [];\n\n for( var i = 0; i < arguments.length; i++ ){\n args.push( arguments[i] );\n }\n\n return args.join('$');\n };\n }\n\n return function memoizedFn(){\n var args = arguments;\n var ret;\n var k = keyFn.apply( self, args );\n\n if( !(ret = cache[k]) ){\n ret = cache[k] = fn.apply( self, args );\n }\n\n return ret;\n };\n};\n","'use strict';\n\nvar number = \"(?:[-+]?(?:(?:\\\\d+|\\\\d*\\\\.\\\\d+)(?:[Ee][+-]?\\\\d+)?))\";\n\nvar rgba = \"rgb[a]?\\\\((\"+ number +\"[%]?)\\\\s*,\\\\s*(\"+ number +\"[%]?)\\\\s*,\\\\s*(\"+ number +\"[%]?)(?:\\\\s*,\\\\s*(\"+ number +\"))?\\\\)\";\nvar rgbaNoBackRefs = \"rgb[a]?\\\\((?:\"+ number +\"[%]?)\\\\s*,\\\\s*(?:\"+ number +\"[%]?)\\\\s*,\\\\s*(?:\"+ number +\"[%]?)(?:\\\\s*,\\\\s*(?:\"+ number +\"))?\\\\)\";\n\nvar hsla = \"hsl[a]?\\\\((\"+ number +\")\\\\s*,\\\\s*(\"+ number +\"[%])\\\\s*,\\\\s*(\"+ number +\"[%])(?:\\\\s*,\\\\s*(\"+ number +\"))?\\\\)\";\nvar hslaNoBackRefs = \"hsl[a]?\\\\((?:\"+ number +\")\\\\s*,\\\\s*(?:\"+ number +\"[%])\\\\s*,\\\\s*(?:\"+ number +\"[%])(?:\\\\s*,\\\\s*(?:\"+ number +\"))?\\\\)\";\n\nvar hex3 = \"\\\\#[0-9a-fA-F]{3}\";\nvar hex6 = \"\\\\#[0-9a-fA-F]{6}\";\n\nmodule.exports = {\n regex: {\n number: number,\n rgba: rgba,\n rgbaNoBackRefs: rgbaNoBackRefs,\n hsla: hsla,\n hslaNoBackRefs: hslaNoBackRefs,\n hex3: hex3,\n hex6: hex6\n }\n};\n","'use strict';\n\nvar memoize = require('./memoize');\nvar is = require('../is');\n\nmodule.exports = {\n\n camel2dash: memoize( function( str ){\n return str.replace(/([A-Z])/g, function( v ){\n return '-' + v.toLowerCase();\n });\n } ),\n\n dash2camel: memoize( function( str ){\n return str.replace(/(-\\w)/g, function( v ){\n return v[1].toUpperCase();\n });\n } ),\n\n capitalize: function(str){\n if( is.emptyString(str) ){\n return str;\n }\n\n return str.charAt(0).toUpperCase() + str.substring(1);\n }\n\n};\n","'use strict';\n\nvar window = require('../window');\nvar is = require('../is');\nvar performance = window ? window.performance : null;\n\nvar util = {};\n\nvar raf = !window ? null : ( window.requestAnimationFrame || window.mozRequestAnimationFrame ||\n window.webkitRequestAnimationFrame || window.msRequestAnimationFrame );\n\nraf = raf || function( fn ){\n if( fn ){\n setTimeout(function(){\n fn( pnow() );\n }, 1000/60);\n }\n};\n\nutil.requestAnimationFrame = function(fn){\n raf( fn );\n};\n\nvar pnow = performance && performance.now ? function(){ return performance.now(); } : function(){ return Date.now(); };\n\nutil.performanceNow = pnow;\n\n// ported lodash throttle function\nutil.throttle = function(func, wait, options) {\n var leading = true,\n trailing = true;\n\n if (options === false) {\n leading = false;\n } else if (is.plainObject(options)) {\n leading = 'leading' in options ? options.leading : leading;\n trailing = 'trailing' in options ? options.trailing : trailing;\n }\n options = options || {};\n options.leading = leading;\n options.maxWait = wait;\n options.trailing = trailing;\n\n return util.debounce(func, wait, options);\n};\n\nutil.now = function(){\n return Date.now();\n};\n\nutil.debounce = function(func, wait, options) { // ported lodash debounce function\n var util = this;\n var args,\n maxTimeoutId,\n result,\n stamp,\n thisArg,\n timeoutId,\n trailingCall,\n lastCalled = 0,\n maxWait = false,\n trailing = true;\n\n if (!is.fn(func)) {\n return;\n }\n wait = Math.max(0, wait) || 0;\n if (options === true) {\n var leading = true;\n trailing = false;\n } else if (is.plainObject(options)) {\n leading = options.leading;\n maxWait = 'maxWait' in options && (Math.max(wait, options.maxWait) || 0);\n trailing = 'trailing' in options ? options.trailing : trailing;\n }\n var delayed = function() {\n var remaining = wait - (util.now() - stamp);\n if (remaining <= 0) {\n if (maxTimeoutId) {\n clearTimeout(maxTimeoutId);\n }\n var isCalled = trailingCall;\n maxTimeoutId = timeoutId = trailingCall = undefined;\n if (isCalled) {\n lastCalled = util.now();\n result = func.apply(thisArg, args);\n if (!timeoutId && !maxTimeoutId) {\n args = thisArg = null;\n }\n }\n } else {\n timeoutId = setTimeout(delayed, remaining);\n }\n };\n\n var maxDelayed = function() {\n if (timeoutId) {\n clearTimeout(timeoutId);\n }\n maxTimeoutId = timeoutId = trailingCall = undefined;\n if (trailing || (maxWait !== wait)) {\n lastCalled = util.now();\n result = func.apply(thisArg, args);\n if (!timeoutId && !maxTimeoutId) {\n args = thisArg = null;\n }\n }\n };\n\n return function() {\n args = arguments;\n stamp = util.now();\n thisArg = this;\n trailingCall = trailing && (timeoutId || !leading);\n\n if (maxWait === false) {\n var leadingCall = leading && !timeoutId;\n } else {\n if (!maxTimeoutId && !leading) {\n lastCalled = stamp;\n }\n var remaining = maxWait - (stamp - lastCalled),\n isCalled = remaining <= 0;\n\n if (isCalled) {\n if (maxTimeoutId) {\n maxTimeoutId = clearTimeout(maxTimeoutId);\n }\n lastCalled = stamp;\n result = func.apply(thisArg, args);\n }\n else if (!maxTimeoutId) {\n maxTimeoutId = setTimeout(maxDelayed, remaining);\n }\n }\n if (isCalled && timeoutId) {\n timeoutId = clearTimeout(timeoutId);\n }\n else if (!timeoutId && wait !== maxWait) {\n timeoutId = setTimeout(delayed, wait);\n }\n if (leadingCall) {\n isCalled = true;\n result = func.apply(thisArg, args);\n }\n if (isCalled && !timeoutId && !maxTimeoutId) {\n args = thisArg = null;\n }\n return result;\n };\n};\n\nmodule.exports = util;\n","module.exports = ( typeof window === 'undefined' ? null : window );\n"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/index.php b/index.php index a238823..ccae55d 100644 --- a/index.php +++ b/index.php @@ -9,7 +9,7 @@ - +