{"version":3,"sources":["webpack:///./node_modules/@progress/kendo-ui/js/dataviz/diagram/layout.js"],"names":["module","exports","modules","installedModules","__webpack_require__","moduleId","id","loaded","call","m","c","p","0","3","Error","909","__WEBPACK_AMD_DEFINE_FACTORY__","__WEBPACK_AMD_DEFINE_ARRAY__","__WEBPACK_AMD_DEFINE_RESULT__","f","define","apply","undefined","$","kendo","window","diagram","dataviz","Graph","Node","Link","deepExtend","Size","Rect","Dictionary","Set","HyperTree","Utils","Point","EPSILON","DEG_TO_RAD","Math","PI","contains","grep","LayoutBase","Class","extend","defaultOptions","type","subtype","roots","animate","limitToView","friction","nodeDistance","iterations","horizontalSeparation","verticalSeparation","underneathVerticalTopOffset","underneathHorizontalOffset","underneathVerticalSeparation","grid","width","offsetX","offsetY","componentSpacingX","componentSpacingY","layerSeparation","layeredIterations","startRadialAngle","endRadialAngle","radialSeparation","radialFirstLevelSeparation","keepComponentsInOneRadialLayout","ignoreContainers","layoutContainerChildren","ignoreInvisible","animateTransitions","init","gridLayoutComponents","components","forEach","calcBounds","sort","a","b","bounds","i","maxWidth","this","options","height","startX","startY","x","y","resultLinkSet","resultNodeSet","length","component","pop","moveToOffset","nodes","push","links","boundingRect","currentHeight","isNaN","currentWidth","j","deltax","deltay","node","nodeBounds","link","points","newpoints","pt","currentHorizontalOffset","transferOptions","isUndefined","DiagramToHyperTreeAdapter","nodeMap","shapeMap","edges","edgeMap","finalNodes","finalLinks","ignoredConnections","ignoredShapes","hyperMap","hyperTree","finalGraph","convert","clear","_renormalizeShapes","_renormalizeConnections","n","addNode","l","addExistingLink","mapConnection","connection","get","mapShape","shape","getEdge","first","getComplement","listToRoot","containerGraph","list","s","container","parentContainer","reverse","firstNonIgnorableContainer","isContainer","_isIgnorableItem","isContainerConnection","isDescendantOf","scope","children","containers","len","isIgnorableItem","isCollapsed","_isVisible","_isTop","isShapeMapped","leastCommonAncestor","al","bl","found","isEmpty","root","data","xa","xb","item","visible","_isCollapsed","shapes","isVirtual","add","connections","conn","source","sourceConnector","sink","targetConnector","containsKey","sourceNode","sinkNode","areConnectedAlready","newEdge","any","target","SpringLayout","that","fn","layout","adapter","graph","getConnectedComponents","layoutGraph","finalNodeSet","LayoutState","isDefined","initialTemperature","temperature","guessBounds","_expectedBounds","step","refineStage","tick","_repulsion","_attraction","offset","sqrt","dx","dy","min","max","_shake","rho","random","alpha","cos","sin","_InverseSquareForce","d","force","wn","hn","wm","hm","pow","_SquareForce","vx","vy","distance","r","t","size","N","ratio","multiplier","fold","area","av","squareSize","ceil","TreeLayoutProcessor","center","treeGraph","cacheRelationships","layoutSwitch","layoutLeft","left","setChildrenDirection","setChildrenLayout","h","w","TreeDirection","measure","Empty","Width","arrange","layoutRight","right","layoutUp","up","layoutDown","down","treeDirection","layoutRadialTree","previousRoot","startAngle","endAngle","maxDepth","origin","calculateAngularWidth","radialLayout","Angle","tipOverTree","startFromLevel","associatedShape","aw","diameter","child","sectorAngle","sortChildren","basevalue","parents","pl","nl","normalizeAngle","atan2","count","angle","idx","bisort","col","radius","deltaTheta","deltaThetaHalf","parentSector","fraction","sorted","childNode","cp","childAngleFraction","setPolarLocation","BoundingRectangle","direction","includeStart","rootDirection","depthFirstTraversal","rootLayout","childrenLayout","assignLevels","level","givenSize","result","shapeWidth","shapeHeight","parent","abs","AngleToParent","SectorAngle","pp","childrenwidth","selfLocation","single","male","female","leftcount","toLowerCase","indexOf","tipOverTreeStartLevel","TreeLayout","layoutComponents","trees","getTree","tree","givenRootShape","getTreeForRoot","getSpanningTree","LayeredLayout","_initRuntimeProperties","k","layer","downstreamLinkCount","upstreamLinkCount","uBaryCenter","dBaryCenter","upstreamPriority","downstreamPriority","gridPosition","_prepare","targetLayer","next","current","layerMap","layerCount","incoming","set","shift","outgoing","sortedNodes","keys","o1","o2","o1layer","o2layer","sign","minLayer","Number","MAX_VALUE","layers","linksTo","setItemIndices","reversedEdges","makeAcyclic","_dummify","_optimizeCrossings","_swapPairs","arrangeNodes","_moveThingsAround","_dedummify","e","setMinDist","minDist","layerIndex","minDistances","getMinDist","dist","i1","i2","placeLeftToRight","leftClasses","leftPos","classNodes","placeLeft","POSITIVE_INFINITY","rightSibling","nodeLeftClass","D","neighbors","addRange","upNodes","downNodes","neighbor","intDiv","placeRightToLeft","rightClasses","rightPos","placeRight","NEGATIVE_INFINITY","leftSibling","nodeRightClass","_getLeftWing","leftWing","value","computeClasses","_getRightWing","rightWing","wingPair","currentWing","wing","ndsinl","_nodesInLink","kk","vnode","wings","classIndex","_isVerticalLayout","_isHorizontalLayout","_isIncreasingLayout","_gridPositionComparer","dest","forEachValue","currentNode","currDown","downNode","pos","order","placed","sequenceStart","directions","start","virtualStartIndex","_firstVirtualNode","virtualStart","sequence","_sequencer","virtualEnd","nextVirtualNode","virtualEndIndex","adjustDirections","fromLayerIndex","reachedFinalLayerIndex","ctx","layerIncrement","maximumHeight","MIN_VALUE","prevBridge","prevBridgeTarget","nextBridge","nextBridgeTarget","getNeighborOnLayer","clayer","j1","j2","dir","_sequenceSingle","slice","combineSequences","pair","leftHeap","v","_positionDescendingComparer","rightHeap","_positionAscendingComparer","leftRes","rightRes","leftClass","_getComposite","rightClass","ni","maxLayoutIterations","it","layoutLayer","gridPos","iconsidered","considered","n1","n2","n1Priority","n2Priority","nodeGridPos","nodeBaryCenter","calcBaryCenter","nodePriority","moveRight","moveLeft","calcDownData","calcUpData","priority","index","rightNode","rightNodePriority","leftNode","leftNodePriority","mapVirtualNode","nodeToLinkMap","linkToNodeMap","newNode","newLink","addLinkBetweenLayers","upLayer","downLayer","o","oLayer","dLayer","oPos","dPos","insert","depthOfDumminess","_addNode","addLink","changeSource","dedum","unshift","temp","prevLink","splice","moves","maxIterations","iter","optimizeLayerCrossings","sum","total","presorted","n1BaryCenter","n2BaryCenter","degree","compareByIndex","compareValue","inode","downwards","secondPass","hasSwapped","calcCrossings","memCrossings","crossBefore","countLinksCrossingBetweenTwoLayers","node1","node2","node1GridPos","node2GridPos","crossAfter","revert","ulayer","dlayer","link1","link2","n11","n12","n21","n22","l1","l2","crossings","n11gp","n12gp","n21gp","n22gp","numerator","denominator","nodeIndex","graphOrNodes","linkMap","capture","diagramOrGraphOrNodes","visual","associatedConnection","Array","hasOwnProperty","element","ui","GraphAdapter","jQuery","910"],"mappings":"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","file":"js/chunk-vendors~e5f83e2f.56c01b02.js","sourcesContent":["module.exports =\n/******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n\n\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ({\n\n/***/ 0:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tmodule.exports = __webpack_require__(909);\n\n\n/***/ }),\n\n/***/ 3:\n/***/ (function(module, exports) {\n\n\tmodule.exports = function() { throw new Error(\"define cannot be used indirect\"); };\r\n\n\n/***/ }),\n\n/***/ 909:\n/***/ (function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function(f, define){\n\t !(__WEBPACK_AMD_DEFINE_ARRAY__ = [ __webpack_require__(910) ], __WEBPACK_AMD_DEFINE_FACTORY__ = (f), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t})(function(){\n\n\t(function ($, undefined) {\n\t var kendo = window.kendo,\n\t diagram = kendo.dataviz.diagram,\n\t Graph = diagram.Graph,\n\t Node = diagram.Node,\n\t Link = diagram.Link,\n\t deepExtend = kendo.deepExtend,\n\t Size = diagram.Size,\n\t Rect = diagram.Rect,\n\t Dictionary = diagram.Dictionary,\n\t Set = diagram.Set,\n\t HyperTree = diagram.Graph,\n\t Utils = diagram.Utils,\n\t Point = diagram.Point,\n\t EPSILON = 1e-06,\n\t DEG_TO_RAD = Math.PI / 180,\n\t contains = Utils.contains,\n\t grep = $.grep;\n\n\t /**\n\t * Base class for layout algorithms.\n\t * @type {*}\n\t */\n\t var LayoutBase = kendo.Class.extend({\n\t defaultOptions: {\n\t type: \"Tree\",\n\t subtype: \"Down\",\n\t roots: null,\n\t animate: false,\n\t //-------------------------------------------------------------------\n\t /**\n\t * Force-directed option: whether the motion of the nodes should be limited by the boundaries of the diagram surface.\n\t */\n\t limitToView: false,\n\t /**\n\t * Force-directed option: the amount of friction applied to the motion of the nodes.\n\t */\n\t friction: 0.9,\n\t /**\n\t * Force-directed option: the optimal distance between nodes (minimum energy).\n\t */\n\t nodeDistance: 50,\n\t /**\n\t * Force-directed option: the number of time things are being calculated.\n\t */\n\t iterations: 300,\n\t //-------------------------------------------------------------------\n\t /**\n\t * Tree option: the separation in one direction (depends on the subtype what direction this is).\n\t */\n\t horizontalSeparation: 90,\n\t /**\n\t * Tree option: the separation in the complementary direction (depends on the subtype what direction this is).\n\t */\n\t verticalSeparation: 50,\n\n\t //-------------------------------------------------------------------\n\t /**\n\t * Tip-over tree option: children-to-parent vertical distance.\n\t */\n\t underneathVerticalTopOffset: 15,\n\t /**\n\t * Tip-over tree option: children-to-parent horizontal distance.\n\t */\n\t underneathHorizontalOffset: 15,\n\t /**\n\t * Tip-over tree option: leaf-to-next-branch vertical distance.\n\t */\n\t underneathVerticalSeparation: 15,\n\t //-------------------------------------------------------------------\n\t /**\n\t * Settings object to organize the different components of the diagram in a grid layout structure\n\t */\n\t grid: {\n\t /**\n\t * The width of the grid in which components are arranged. Beyond this width a component will be on the next row.\n\t */\n\t width: 1500,\n\t /**\n\t * The left offset of the grid.\n\t */\n\t offsetX: 50,\n\t /**\n\t * The top offset of the grid.\n\t */\n\t offsetY: 50,\n\t /**\n\t * The horizontal padding within a cell of the grid where a single component resides.\n\t */\n\t componentSpacingX: 20,\n\t /**\n\t * The vertical padding within a cell of the grid where a single component resides.\n\t */\n\t componentSpacingY: 20\n\t },\n\n\t //-------------------------------------------------------------------\n\t /**\n\t * Layered option: the separation height/width between the layers.\n\t */\n\t layerSeparation: 50,\n\t /**\n\t * Layered option: how many rounds of shifting and fine-tuning.\n\t */\n\t layeredIterations: 2,\n\t /**\n\t * Tree-radial option: the angle at which the layout starts.\n\t */\n\t startRadialAngle: 0,\n\t /**\n\t * Tree-radial option: the angle at which the layout starts.\n\t */\n\t endRadialAngle: 360,\n\t /**\n\t * Tree-radial option: the separation between levels.\n\t */\n\t radialSeparation: 150,\n\t /**\n\t * Tree-radial option: the separation between the root and the first level.\n\t */\n\t radialFirstLevelSeparation: 200,\n\t /**\n\t * Tree-radial option: whether a virtual roots bing the components in one radial layout.\n\t */\n\t keepComponentsInOneRadialLayout: false,\n\t //-------------------------------------------------------------------\n\n\t // TODO: ensure to change this to false when containers are around\n\t ignoreContainers: true,\n\t layoutContainerChildren: false,\n\t ignoreInvisible: true,\n\t animateTransitions: false\n\t },\n\t init: function () {\n\t },\n\n\t /**\n\t * Organizes the components in a grid.\n\t * Returns the final set of nodes (not the Graph).\n\t * @param components\n\t */\n\t gridLayoutComponents: function (components) {\n\t if (!components) {\n\t throw \"No components supplied.\";\n\t }\n\n\t // calculate and cache the bounds of the components\n\t Utils.forEach(components, function (c) {\n\t c.calcBounds();\n\t });\n\n\t // order by decreasing width\n\t components.sort(function (a, b) {\n\t return b.bounds.width - a.bounds.width;\n\t });\n\n\t var maxWidth = this.options.grid.width,\n\t offsetX = this.options.grid.componentSpacingX,\n\t offsetY = this.options.grid.componentSpacingY,\n\t height = 0,\n\t startX = this.options.grid.offsetX,\n\t startY = this.options.grid.offsetY,\n\t x = startX,\n\t y = startY,\n\t i,\n\t resultLinkSet = [],\n\t resultNodeSet = [];\n\n\t while (components.length > 0) {\n\t if (x >= maxWidth) {\n\t // start a new row\n\t x = startX;\n\t y += height + offsetY;\n\t // reset the row height\n\t height = 0;\n\t }\n\t var component = components.pop();\n\t this.moveToOffset(component, new Point(x, y));\n\t for (i = 0; i < component.nodes.length; i++) {\n\t resultNodeSet.push(component.nodes[i]); // to be returned in the end\n\t }\n\t for (i = 0; i < component.links.length; i++) {\n\t resultLinkSet.push(component.links[i]);\n\t }\n\t var boundingRect = component.bounds;\n\t var currentHeight = boundingRect.height;\n\t if (currentHeight <= 0 || isNaN(currentHeight)) {\n\t currentHeight = 0;\n\t }\n\t var currentWidth = boundingRect.width;\n\t if (currentWidth <= 0 || isNaN(currentWidth)) {\n\t currentWidth = 0;\n\t }\n\n\t if (currentHeight >= height) {\n\t height = currentHeight;\n\t }\n\t x += currentWidth + offsetX;\n\t }\n\n\t return {\n\t nodes: resultNodeSet,\n\t links: resultLinkSet\n\t };\n\t },\n\n\t moveToOffset: function (component, p) {\n\t var i, j,\n\t bounds = component.bounds,\n\t deltax = p.x - bounds.x,\n\t deltay = p.y - bounds.y;\n\n\t for (i = 0; i < component.nodes.length; i++) {\n\t var node = component.nodes[i];\n\t var nodeBounds = node.bounds();\n\t if (nodeBounds.width === 0 && nodeBounds.height === 0 && nodeBounds.x === 0 && nodeBounds.y === 0) {\n\t nodeBounds = new Rect(0, 0, 0, 0);\n\t }\n\t nodeBounds.x += deltax;\n\t nodeBounds.y += deltay;\n\t node.bounds(nodeBounds);\n\t }\n\t for (i = 0; i < component.links.length; i++) {\n\t var link = component.links[i];\n\t if (link.points) {\n\t var newpoints = [];\n\t var points = link.points;\n\t for (j = 0; j < points.length; j++) {\n\t var pt = points[j];\n\t pt.x += deltax;\n\t pt.y += deltay;\n\t newpoints.push(pt);\n\t }\n\t link.points = newpoints;\n\t }\n\t }\n\t this.currentHorizontalOffset += bounds.width + this.options.grid.offsetX;\n\t return new Point(deltax, deltay);\n\t },\n\n\t transferOptions: function (options) {\n\n\t // Size options lead to stackoverflow and need special handling\n\n\t this.options = kendo.deepExtend({}, this.defaultOptions);\n\t if (Utils.isUndefined(options)) {\n\t return;\n\t }\n\n\t this.options = kendo.deepExtend(this.options, options || {});\n\t }\n\t });\n\n\t /**\n\t * The data bucket a hypertree holds in its nodes. *\n\t * @type {*}\n\t */\n\t /* var ContainerGraph = kendo.Class.extend({\n\t init: function (diagram) {\n\t this.diagram = diagram;\n\t this.graph = new Graph(diagram);\n\t this.container = null;\n\t this.containerNode = null;\n\t }\n\n\t });*/\n\n\t /**\n\t * Adapter between the diagram control and the graph representation. It converts shape and connections to nodes and edges taking into the containers and their collapsef state,\n\t * the visibility of items and more. If the layoutContainerChildren is true a hypertree is constructed which holds the hierarchy of containers and many conditions are analyzed\n\t * to investigate how the effective graph structure looks like and how the layout has to be performed.\n\t * @type {*}\n\t */\n\t var DiagramToHyperTreeAdapter = kendo.Class.extend({\n\t init: function (diagram) {\n\n\t /**\n\t * The mapping to/from the original nodes.\n\t * @type {Dictionary}\n\t */\n\t this.nodeMap = new Dictionary();\n\n\t /**\n\t * Gets the mapping of a shape to a container in case the shape sits in a collapsed container.\n\t * @type {Dictionary}\n\t */\n\t this.shapeMap = new Dictionary();\n\n\t /**\n\t * The nodes being mapped.\n\t * @type {Dictionary}\n\t */\n\t this.nodes = [];\n\n\t /**\n\t * The connections being mapped.\n\t * @type {Dictionary}\n\t */\n\t this.edges = [];\n\n\t // the mapping from an edge to all the connections it represents, this can be both because of multiple connections between\n\t // two shapes or because a container holds multiple connections to another shape or container.\n\t this.edgeMap = new Dictionary();\n\n\t /**\n\t * The resulting set of Nodes when the analysis has finished.\n\t * @type {Array}\n\t */\n\t this.finalNodes = [];\n\n\t /**\n\t * The resulting set of Links when the analysis has finished.\n\t * @type {Array}\n\t */\n\t this.finalLinks = [];\n\n\t /**\n\t * The items being omitted because of multigraph edges.\n\t * @type {Array}\n\t */\n\t this.ignoredConnections = [];\n\n\t /**\n\t * The items being omitted because of containers, visibility and other factors.\n\t * @type {Array}\n\t */\n\t this.ignoredShapes = [];\n\n\t /**\n\t * The map from a node to the partition/hypernode in which it sits. This hyperMap is null if 'options.layoutContainerChildren' is false.\n\t * @type {Dictionary}\n\t */\n\t this.hyperMap = new Dictionary();\n\n\t /**\n\t * The hypertree contains the hierarchy defined by the containers.\n\t * It's in essence a Graph of Graphs with a tree structure defined by the hierarchy of containers.\n\t * @type {HyperTree}\n\t */\n\t this.hyperTree = new Graph();\n\n\t /**\n\t * The resulting graph after conversion. Note that this does not supply the information contained in the\n\t * ignored connection and shape collections.\n\t * @type {null}\n\t */\n\t this.finalGraph = null;\n\n\t this.diagram = diagram;\n\t },\n\n\t /**\n\t * The hyperTree is used when the 'options.layoutContainerChildren' is true. It contains the hierarchy of containers whereby each node is a ContainerGraph.\n\t * This type of node has a Container reference to the container which holds the Graph items. There are three possible situations during the conversion process:\n\t * - Ignore the containers: the container are non-existent and only normal shapes are mapped. If a shape has a connection to a container it will be ignored as well\n\t * since there is no node mapped for the container.\n\t * - Do not ignore the containers and leave the content of the containers untouched: the top-level elements are being mapped and the children within a container are not altered.\n\t * - Do not ignore the containers and organize the content of the containers as well: the hypertree is constructed and there is a partitioning of all nodes and connections into the hypertree.\n\t * The only reason a connection or node is not being mapped might be due to the visibility, which includes the visibility change through a collapsed parent container.\n\t * @param options\n\t */\n\t convert: function (options) {\n\n\t if (Utils.isUndefined(this.diagram)) {\n\t throw \"No diagram to convert.\";\n\t }\n\n\t this.options = kendo.deepExtend({\n\t ignoreInvisible: true,\n\t ignoreContainers: true,\n\t layoutContainerChildren: false\n\t },\n\t options || {}\n\t );\n\n\t this.clear();\n\t // create the nodes which participate effectively in the graph analysis\n\t this._renormalizeShapes();\n\n\t // recreate the incoming and outgoing collections of each and every node\n\t this._renormalizeConnections();\n\n\t // export the resulting graph\n\t this.finalNodes = new Dictionary(this.nodes);\n\t this.finalLinks = new Dictionary(this.edges);\n\n\t this.finalGraph = new Graph();\n\t this.finalNodes.forEach(function (n) {\n\t this.finalGraph.addNode(n);\n\t }, this);\n\t this.finalLinks.forEach(function (l) {\n\t this.finalGraph.addExistingLink(l);\n\t }, this);\n\t return this.finalGraph;\n\t },\n\n\t /**\n\t * Maps the specified connection to an edge of the graph deduced from the given diagram.\n\t * @param connection\n\t * @returns {*}\n\t */\n\t mapConnection: function (connection) {\n\t return this.edgeMap.get(connection.id);\n\t },\n\n\t /**\n\t * Maps the specified shape to a node of the graph deduced from the given diagram.\n\t * @param shape\n\t * @returns {*}\n\t */\n\t mapShape: function (shape) {\n\t return this.nodeMap.get(shape.id);\n\t },\n\n\t /**\n\t * Gets the edge, if any, between the given nodes.\n\t * @param a\n\t * @param b\n\t */\n\t getEdge: function (a, b) {\n\t return Utils.first(a.links, function (link) {\n\t return link.getComplement(a) === b;\n\t });\n\t },\n\n\t /**\n\t * Clears all the collections used by the conversion process.\n\t */\n\t clear: function () {\n\t this.finalGraph = null;\n\t this.hyperTree = (!this.options.ignoreContainers && this.options.layoutContainerChildren) ? new HyperTree() : null;\n\t this.hyperMap = (!this.options.ignoreContainers && this.options.layoutContainerChildren) ? new Dictionary() : null;\n\t this.nodeMap = new Dictionary();\n\t this.shapeMap = new Dictionary();\n\t this.nodes = [];\n\t this.edges = [];\n\t this.edgeMap = new Dictionary();\n\t this.ignoredConnections = [];\n\t this.ignoredShapes = [];\n\t this.finalNodes = [];\n\t this.finalLinks = [];\n\t },\n\n\t /**\n\t * The path from a given ContainerGraph to the root (container).\n\t * @param containerGraph\n\t * @returns {Array}\n\t */\n\t listToRoot: function (containerGraph) {\n\t var list = [];\n\t var s = containerGraph.container;\n\t if (!s) {\n\t return list;\n\t }\n\t list.push(s);\n\t while (s.parentContainer) {\n\t s = s.parentContainer;\n\t list.push(s);\n\t }\n\t list.reverse();\n\t return list;\n\t },\n\n\t firstNonIgnorableContainer: function (shape) {\n\n\t if (shape.isContainer && !this._isIgnorableItem(shape)) {\n\t return shape;\n\t }\n\t return !shape.parentContainer ? null : this.firstNonIgnorableContainer(shape.parentContainer);\n\t },\n\t isContainerConnection: function (a, b) {\n\t if (a.isContainer && this.isDescendantOf(a, b)) {\n\t return true;\n\t }\n\t return b.isContainer && this.isDescendantOf(b, a);\n\t },\n\n\t /**\n\t * Returns true if the given shape is a direct child or a nested container child of the given container.\n\t * If the given container and shape are the same this will return false since a shape cannot be its own child.\n\t * @param scope\n\t * @param a\n\t * @returns {boolean}\n\t */\n\t isDescendantOf: function (scope, a) {\n\t if (!scope.isContainer) {\n\t throw \"Expecting a container.\";\n\t }\n\t if (scope === a) {\n\t return false;\n\t }\n\t if (contains(scope.children, a)) {\n\t return true;\n\t }\n\t var containers = [];\n\t for (var i = 0, len = scope.children.length; i < len; i++) {\n\t var c = scope.children[i];\n\t if (c.isContainer && this.isDescendantOf(c, a)) {\n\t containers.push(c);\n\t }\n\t }\n\n\t return containers.length > 0;\n\t },\n\t isIgnorableItem: function (shape) {\n\t if (this.options.ignoreInvisible) {\n\t if (shape.isCollapsed && this._isVisible(shape)) {\n\t return false;\n\t }\n\t if (!shape.isCollapsed && this._isVisible(shape)) {\n\t return false;\n\t }\n\t return true;\n\t }\n\t else {\n\t return shape.isCollapsed && !this._isTop(shape);\n\t }\n\t },\n\n\t /**\n\t * Determines whether the shape is or needs to be mapped to another shape. This occurs essentially when the shape sits in\n\t * a collapsed container hierarchy and an external connection needs a node endpoint. This node then corresponds to the mapped shape and is\n\t * necessarily a container in the parent hierarchy of the shape.\n\t * @param shape\n\t */\n\t isShapeMapped: function (shape) {\n\t return shape.isCollapsed && !this._isVisible(shape) && !this._isTop(shape);\n\t },\n\n\t leastCommonAncestor: function (a, b) {\n\t if (!a) {\n\t throw \"Parameter should not be null.\";\n\t }\n\t if (!b) {\n\t throw \"Parameter should not be null.\";\n\t }\n\n\t if (!this.hyperTree) {\n\t throw \"No hypertree available.\";\n\t }\n\t var al = this.listToRoot(a);\n\t var bl = this.listToRoot(b);\n\t var found = null;\n\t if (Utils.isEmpty(al) || Utils.isEmpty(bl)) {\n\t return this.hyperTree.root.data;\n\t }\n\t var xa = al[0];\n\t var xb = bl[0];\n\t var i = 0;\n\t while (xa === xb) {\n\t found = al[i];\n\t i++;\n\t if (i >= al.length || i >= bl.length) {\n\t break;\n\t }\n\t xa = al[i];\n\t xb = bl[i];\n\t }\n\t if (!found) {\n\t return this.hyperTree.root.data;\n\t }\n\t else {\n\t return grep(this.hyperTree.nodes, function (n) {\n\t return n.data.container === found;\n\t });\n\t }\n\t },\n\t /**\n\t * Determines whether the specified item is a top-level shape or container.\n\t * @param item\n\t * @returns {boolean}\n\t * @private\n\t */\n\t _isTop: function (item) {\n\t return !item.parentContainer;\n\t },\n\n\t /**\n\t * Determines iteratively (by walking up the container stack) whether the specified shape is visible.\n\t * This does NOT tell whether the item is not visible due to an explicit Visibility change or due to a collapse state.\n\t * @param shape\n\t * @returns {*}\n\t * @private\n\t */\n\t _isVisible: function (shape) {\n\n\t if (!shape.visible()) {\n\t return false;\n\t }\n\t return !shape.parentContainer ? shape.visible() : this._isVisible(shape.parentContainer);\n\t },\n\n\t _isCollapsed: function (shape) {\n\n\t if (shape.isContainer && shape.isCollapsed) {\n\t return true;\n\t }\n\t return shape.parentContainer && this._isCollapsed(shape.parentContainer);\n\t },\n\n\t /**\n\t * First part of the graph creation; analyzing the shapes and containers and deciding whether they should be mapped to a Node.\n\t * @private\n\t */\n\t _renormalizeShapes: function () {\n\t // add the nodes, the adjacency structure will be reconstructed later on\n\t if (this.options.ignoreContainers) {\n\t for (var i = 0, len = this.diagram.shapes.length; i < len; i++) {\n\t var shape = this.diagram.shapes[i];\n\n\t // if not visible (and ignoring the invisible ones) or a container we skip\n\t if ((this.options.ignoreInvisible && !this._isVisible(shape)) || shape.isContainer) {\n\t this.ignoredShapes.push(shape);\n\t continue;\n\t }\n\t var node = new Node(shape.id, shape);\n\t node.isVirtual = false;\n\n\t // the mapping will always contain singletons and the hyperTree will be null\n\t this.nodeMap.add(shape.id, node);\n\t this.nodes.push(node);\n\t }\n\t }\n\t else {\n\t throw \"Containers are not supported yet, but stay tuned.\";\n\t }\n\t },\n\n\t /**\n\t * Second part of the graph creation; analyzing the connections and deciding whether they should be mapped to an edge.\n\t * @private\n\t */\n\t _renormalizeConnections: function () {\n\t if (this.diagram.connections.length === 0) {\n\t return;\n\t }\n\t for (var i = 0, len = this.diagram.connections.length; i < len; i++) {\n\t var conn = this.diagram.connections[i];\n\n\t if (this.isIgnorableItem(conn)) {\n\t this.ignoredConnections.push(conn);\n\t continue;\n\t }\n\n\t var source = !conn.sourceConnector ? null : conn.sourceConnector.shape;\n\t var sink = !conn.targetConnector ? null : conn.targetConnector.shape;\n\n\t // no layout for floating connections\n\t if (!source || !sink) {\n\t this.ignoredConnections.push(conn);\n\t continue;\n\t }\n\n\t if (contains(this.ignoredShapes, source) && !this.shapeMap.containsKey(source)) {\n\t this.ignoredConnections.push(conn);\n\t continue;\n\t }\n\t if (contains(this.ignoredShapes, sink) && !this.shapeMap.containsKey(sink)) {\n\t this.ignoredConnections.push(conn);\n\t continue;\n\t }\n\n\t // if the endpoint sits in a collapsed container we need the container rather than the shape itself\n\t if (this.shapeMap.containsKey(source)) {\n\t source = this.shapeMap[source];\n\t }\n\t if (this.shapeMap.containsKey(sink)) {\n\t sink = this.shapeMap[sink];\n\t }\n\n\t var sourceNode = this.mapShape(source);\n\t var sinkNode = this.mapShape(sink);\n\t if ((sourceNode === sinkNode) || this.areConnectedAlready(sourceNode, sinkNode)) {\n\t this.ignoredConnections.push(conn);\n\t continue;\n\t }\n\n\t if (sourceNode === null || sinkNode === null) {\n\t throw \"A shape was not mapped to a node.\";\n\t }\n\t if (this.options.ignoreContainers) {\n\t // much like a floating connection here since at least one end is attached to a container\n\t if (sourceNode.isVirtual || sinkNode.isVirtual) {\n\t this.ignoredConnections.push(conn);\n\t continue;\n\t }\n\t var newEdge = new Link(sourceNode, sinkNode, conn.id, conn);\n\n\t this.edgeMap.add(conn.id, newEdge);\n\t this.edges.push(newEdge);\n\t }\n\t else {\n\t throw \"Containers are not supported yet, but stay tuned.\";\n\t }\n\t }\n\t },\n\n\t areConnectedAlready: function (n, m) {\n\t return Utils.any(this.edges, function (l) {\n\t return l.source === n && l.target === m || l.source === m && l.target === n;\n\t });\n\t }\n\n\t /**\n\t * Depth-first traversal of the given container.\n\t * @param container\n\t * @param action\n\t * @param includeStart\n\t * @private\n\t */\n\t /* _visitContainer: function (container, action, includeStart) {\n\n\t *//*if (container == null) throw new ArgumentNullException(\"container\");\n\t if (action == null) throw new ArgumentNullException(\"action\");\n\t if (includeStart) action(container);\n\t if (container.children.isEmpty()) return;\n\t foreach(\n\t var item\n\t in\n\t container.children.OfType < IShape > ()\n\t )\n\t {\n\t var childContainer = item\n\t as\n\t IContainerShape;\n\t if (childContainer != null) this.VisitContainer(childContainer, action);\n\t else action(item);\n\t }*//*\n\t }*/\n\n\n\t });\n\n\t /**\n\t * The classic spring-embedder (aka force-directed, Fruchterman-Rheingold, barycentric) algorithm.\n\t * http://en.wikipedia.org/wiki/Force-directed_graph_drawing\n\t * - Chapter 12 of Tamassia et al. \"Handbook of graph drawing and visualization\".\n\t * - Kobourov on preprint arXiv; http://arxiv.org/pdf/1201.3011.pdf\n\t * - Fruchterman and Rheingold in SOFTWARE-PRACTICE AND EXPERIENCE, VOL. 21(1 1), 1129-1164 (NOVEMBER 1991)\n\t * @type {*}\n\t */\n\t var SpringLayout = LayoutBase.extend({\n\t init: function (diagram) {\n\t var that = this;\n\t LayoutBase.fn.init.call(that);\n\t if (Utils.isUndefined(diagram)) {\n\t throw \"Diagram is not specified.\";\n\t }\n\t this.diagram = diagram;\n\t },\n\n\t layout: function (options) {\n\n\t this.transferOptions(options);\n\n\t var adapter = new DiagramToHyperTreeAdapter(this.diagram);\n\t var graph = adapter.convert(options);\n\t if (graph.isEmpty()) {\n\t return;\n\t }\n\t // split into connected components\n\t var components = graph.getConnectedComponents();\n\t if (Utils.isEmpty(components)) {\n\t return;\n\t }\n\t for (var i = 0; i < components.length; i++) {\n\t var component = components[i];\n\t this.layoutGraph(component, options);\n\t }\n\t var finalNodeSet = this.gridLayoutComponents(components);\n\t return new diagram.LayoutState(this.diagram, finalNodeSet);\n\t },\n\n\t layoutGraph: function (graph, options) {\n\n\t if (Utils.isDefined(options)) {\n\t this.transferOptions(options);\n\t }\n\t this.graph = graph;\n\n\t var initialTemperature = this.options.nodeDistance * 9;\n\t this.temperature = initialTemperature;\n\n\t var guessBounds = this._expectedBounds();\n\t this.width = guessBounds.width;\n\t this.height = guessBounds.height;\n\n\t for (var step = 0; step < this.options.iterations; step++) {\n\t this.refineStage = step >= this.options.iterations * 5 / 6;\n\t this.tick();\n\t // exponential cooldown\n\t this.temperature = this.refineStage ?\n\t initialTemperature / 30 :\n\t initialTemperature * (1 - step / (2 * this.options.iterations ));\n\t }\n\t },\n\n\t /**\n\t * Single iteration of the simulation.\n\t */\n\t tick: function () {\n\t var i;\n\t // collect the repulsive forces on each node\n\t for (i = 0; i < this.graph.nodes.length; i++) {\n\t this._repulsion(this.graph.nodes[i]);\n\t }\n\n\t // collect the attractive forces on each node\n\t for (i = 0; i < this.graph.links.length; i++) {\n\t this._attraction(this.graph.links[i]);\n\t }\n\t // update the positions\n\t for (i = 0; i < this.graph.nodes.length; i++) {\n\t var node = this.graph.nodes[i];\n\t var offset = Math.sqrt(node.dx * node.dx + node.dy * node.dy);\n\t if (offset === 0) {\n\t return;\n\t }\n\t node.x += Math.min(offset, this.temperature) * node.dx / offset;\n\t node.y += Math.min(offset, this.temperature) * node.dy / offset;\n\t if (this.options.limitToView) {\n\t node.x = Math.min(this.width, Math.max(node.width / 2, node.x));\n\t node.y = Math.min(this.height, Math.max(node.height / 2, node.y));\n\t }\n\t }\n\t },\n\n\t /**\n\t * Shakes the node away from its current position to escape the deadlock.\n\t * @param node A Node.\n\t * @private\n\t */\n\t _shake: function (node) {\n\t // just a simple polar neighborhood\n\t var rho = Math.random() * this.options.nodeDistance / 4;\n\t var alpha = Math.random() * 2 * Math.PI;\n\t node.x += rho * Math.cos(alpha);\n\t node.y -= rho * Math.sin(alpha);\n\t },\n\n\t /**\n\t * The typical Coulomb-Newton force law F=k/r^2\n\t * @remark This only works in dimensions less than three.\n\t * @param d\n\t * @param n A Node.\n\t * @param m Another Node.\n\t * @returns {number}\n\t * @private\n\t */\n\t _InverseSquareForce: function (d, n, m) {\n\t var force;\n\t if (!this.refineStage) {\n\t force = Math.pow(d, 2) / Math.pow(this.options.nodeDistance, 2);\n\t }\n\t else {\n\t var deltax = n.x - m.x;\n\t var deltay = n.y - m.y;\n\n\t var wn = n.width / 2;\n\t var hn = n.height / 2;\n\t var wm = m.width / 2;\n\t var hm = m.height / 2;\n\n\t force = (Math.pow(deltax, 2) / Math.pow(wn + wm + this.options.nodeDistance, 2)) + (Math.pow(deltay, 2) / Math.pow(hn + hm + this.options.nodeDistance, 2));\n\t }\n\t return force * 4 / 3;\n\t },\n\n\t /**\n\t * The typical Hooke force law F=kr^2\n\t * @param d\n\t * @param n\n\t * @param m\n\t * @returns {number}\n\t * @private\n\t */\n\t _SquareForce: function (d, n, m) {\n\t return 1 / this._InverseSquareForce(d, n, m);\n\t },\n\n\t _repulsion: function (n) {\n\t n.dx = 0;\n\t n.dy = 0;\n\t Utils.forEach(this.graph.nodes, function (m) {\n\t if (m === n) {\n\t return;\n\t }\n\t while (n.x === m.x && n.y === m.y) {\n\t this._shake(m);\n\t }\n\t var vx = n.x - m.x;\n\t var vy = n.y - m.y;\n\t var distance = Math.sqrt(vx * vx + vy * vy);\n\t var r = this._SquareForce(distance, n, m) * 2;\n\t n.dx += (vx / distance) * r;\n\t n.dy += (vy / distance) * r;\n\t }, this);\n\t },\n\t _attraction: function (link) {\n\t var t = link.target;\n\t var s = link.source;\n\t if (s === t) {\n\t // loops induce endless shakes\n\t return;\n\t }\n\t while (s.x === t.x && s.y === t.y) {\n\t this._shake(t);\n\t }\n\n\t var vx = s.x - t.x;\n\t var vy = s.y - t.y;\n\t var distance = Math.sqrt(vx * vx + vy * vy);\n\n\t var a = this._InverseSquareForce(distance, s, t) * 5;\n\t var dx = (vx / distance) * a;\n\t var dy = (vy / distance) * a;\n\t t.dx += dx;\n\t t.dy += dy;\n\t s.dx -= dx;\n\t s.dy -= dy;\n\t },\n\n\t /**\n\t * Calculates the expected bounds after layout.\n\t * @returns {*}\n\t * @private\n\t */\n\t _expectedBounds: function () {\n\n\t var size, N = this.graph.nodes.length, /*golden ration optimal?*/ ratio = 1.5, multiplier = 4;\n\t if (N === 0) {\n\t return size;\n\t }\n\t size = Utils.fold(this.graph.nodes, function (s, node) {\n\t var area = node.width * node.height;\n\t if (area > 0) {\n\t s += Math.sqrt(area);\n\t return s;\n\t }\n\t return 0;\n\t }, 0, this);\n\t var av = size / N;\n\t var squareSize = av * Math.ceil(Math.sqrt(N));\n\t var width = squareSize * Math.sqrt(ratio);\n\t var height = squareSize / Math.sqrt(ratio);\n\t return { width: width * multiplier, height: height * multiplier };\n\t }\n\n\t });\n\n\t var TreeLayoutProcessor = kendo.Class.extend({\n\n\t init: function (options) {\n\t this.center = null;\n\t this.options = options;\n\t },\n\t layout: function (treeGraph, root) {\n\t this.graph = treeGraph;\n\t if (!this.graph.nodes || this.graph.nodes.length === 0) {\n\t return;\n\t }\n\n\t if (!contains(this.graph.nodes, root)) {\n\t throw \"The given root is not in the graph.\";\n\t }\n\n\t this.center = root;\n\t this.graph.cacheRelationships();\n\t /* var nonull = this.graph.nodes.where(function (n) {\n\t return n.associatedShape != null;\n\t });*/\n\n\t // transfer the rects\n\t /*nonull.forEach(function (n) {\n\t n.Location = n.associatedShape.Position;\n\t n.NodeSize = n.associatedShape.ActualBounds.ToSize();\n\t }\n\n\t );*/\n\n\t // caching the children\n\t /* nonull.forEach(function (n) {\n\t n.children = n.getChildren();\n\t });*/\n\n\t this.layoutSwitch();\n\n\t // apply the layout to the actual visuals\n\t // nonull.ForEach(n => n.associatedShape.Position = n.Location);\n\t },\n\n\t layoutLeft: function (left) {\n\t this.setChildrenDirection(this.center, \"Left\", false);\n\t this.setChildrenLayout(this.center, \"Default\", false);\n\t var h = 0, w = 0, y, i, node;\n\t for (i = 0; i < left.length; i++) {\n\t node = left[i];\n\t node.TreeDirection = \"Left\";\n\t var s = this.measure(node, Size.Empty);\n\t w = Math.max(w, s.Width);\n\t h += s.height + this.options.verticalSeparation;\n\t }\n\n\t h -= this.options.verticalSeparation;\n\t var x = this.center.x - this.options.horizontalSeparation;\n\t y = this.center.y + ((this.center.height - h) / 2);\n\t for (i = 0; i < left.length; i++) {\n\t node = left[i];\n\t var p = new Point(x - node.Size.width, y);\n\n\t this.arrange(node, p);\n\t y += node.Size.height + this.options.verticalSeparation;\n\t }\n\t },\n\n\t layoutRight: function (right) {\n\t this.setChildrenDirection(this.center, \"Right\", false);\n\t this.setChildrenLayout(this.center, \"Default\", false);\n\t var h = 0, w = 0, y, i, node;\n\t for (i = 0; i < right.length; i++) {\n\t node = right[i];\n\t node.TreeDirection = \"Right\";\n\t var s = this.measure(node, Size.Empty);\n\t w = Math.max(w, s.Width);\n\t h += s.height + this.options.verticalSeparation;\n\t }\n\n\t h -= this.options.verticalSeparation;\n\t var x = this.center.x + this.options.horizontalSeparation + this.center.width;\n\t y = this.center.y + ((this.center.height - h) / 2);\n\t for (i = 0; i < right.length; i++) {\n\t node = right[i];\n\t var p = new Point(x, y);\n\t this.arrange(node, p);\n\t y += node.Size.height + this.options.verticalSeparation;\n\t }\n\t },\n\n\t layoutUp: function (up) {\n\t this.setChildrenDirection(this.center, \"Up\", false);\n\t this.setChildrenLayout(this.center, \"Default\", false);\n\t var w = 0, y, node, i;\n\t for (i = 0; i < up.length; i++) {\n\t node = up[i];\n\t node.TreeDirection = \"Up\";\n\t var s = this.measure(node, Size.Empty);\n\t w += s.width + this.options.horizontalSeparation;\n\t }\n\n\t w -= this.options.horizontalSeparation;\n\t var x = this.center.x + (this.center.width / 2) - (w / 2);\n\n\t // y = this.center.y -verticalSeparation -this.center.height/2 - h;\n\t for (i = 0; i < up.length; i++) {\n\t node = up[i];\n\t y = this.center.y - this.options.verticalSeparation - node.Size.height;\n\t var p = new Point(x, y);\n\t this.arrange(node, p);\n\t x += node.Size.width + this.options.horizontalSeparation;\n\t }\n\t },\n\n\t layoutDown: function (down) {\n\t var node, i;\n\t this.setChildrenDirection(this.center, \"Down\", false);\n\t this.setChildrenLayout(this.center, \"Default\", false);\n\t var w = 0, y;\n\t for (i = 0; i < down.length; i++) {\n\t node = down[i];\n\t node.treeDirection = \"Down\";\n\t var s = this.measure(node, Size.Empty);\n\t w += s.width + this.options.horizontalSeparation;\n\t }\n\n\t w -= this.options.horizontalSeparation;\n\t var x = this.center.x + (this.center.width / 2) - (w / 2);\n\t y = this.center.y + this.options.verticalSeparation + this.center.height;\n\t for (i = 0; i < down.length; i++) {\n\t node = down[i];\n\t var p = new Point(x, y);\n\t this.arrange(node, p);\n\t x += node.Size.width + this.options.horizontalSeparation;\n\t }\n\t },\n\n\t layoutRadialTree: function () {\n\t // var rmax = children.Aggregate(0D, (current, node) => Math.max(node.SectorAngle, current));\n\t this.setChildrenDirection(this.center, \"Radial\", false);\n\t this.setChildrenLayout(this.center, \"Default\", false);\n\t this.previousRoot = null;\n\t var startAngle = this.options.startRadialAngle * DEG_TO_RAD;\n\t var endAngle = this.options.endRadialAngle * DEG_TO_RAD;\n\t if (endAngle <= startAngle) {\n\t throw \"Final angle should not be less than the start angle.\";\n\t }\n\n\t this.maxDepth = 0;\n\t this.origin = new Point(this.center.x, this.center.y);\n\t this.calculateAngularWidth(this.center, 0);\n\n\t // perform the layout\n\t if (this.maxDepth > 0) {\n\t this.radialLayout(this.center, this.options.radialFirstLevelSeparation, startAngle, endAngle);\n\t }\n\n\t // update properties of the root node\n\t this.center.Angle = endAngle - startAngle;\n\t },\n\n\t tipOverTree: function (down, startFromLevel) {\n\t if (Utils.isUndefined(startFromLevel)) {\n\t startFromLevel = 0;\n\t }\n\n\t this.setChildrenDirection(this.center, \"Down\", false);\n\t this.setChildrenLayout(this.center, \"Default\", false);\n\t this.setChildrenLayout(this.center, \"Underneath\", false, startFromLevel);\n\t var w = 0, y, node, i;\n\t for (i = 0; i < down.length; i++) {\n\t node = down[i];\n\n\t // if (node.IsSpecial) continue;\n\t node.TreeDirection = \"Down\";\n\t var s = this.measure(node, Size.Empty);\n\t w += s.width + this.options.horizontalSeparation;\n\t }\n\n\t w -= this.options.horizontalSeparation;\n\n\t // putting the root in the center with respect to the whole diagram is not a nice result, let's put it with respect to the first level only\n\t w -= down[down.length - 1].width;\n\t w += down[down.length - 1].associatedShape.bounds().width;\n\n\t var x = this.center.x + (this.center.width / 2) - (w / 2);\n\t y = this.center.y + this.options.verticalSeparation + this.center.height;\n\t for (i = 0; i < down.length; i++) {\n\t node = down[i];\n\t // if (node.IsSpecial) continue;\n\t var p = new Point(x, y);\n\t this.arrange(node, p);\n\t x += node.Size.width + this.options.horizontalSeparation;\n\t }\n\n\t /*//let's place the special node, assuming there is only one\n\t if (down.Count(n => n.IsSpecial) > 0)\n\t {\n\t var special = (from n in down where n.IsSpecial select n).First();\n\t if (special.Children.Count > 0)\n\t throw new DiagramException(\"The 'special' element should not have children.\");\n\t special.Data.Location = new Point(Center.Data.Location.X + Center.AssociatedShape.BoundingRectangle.Width + this.options.HorizontalSeparation, Center.Data.Location.Y);\n\t }*/\n\t },\n\t calculateAngularWidth: function (n, d) {\n\t if (d > this.maxDepth) {\n\t this.maxDepth = d;\n\t }\n\n\t var aw = 0, w = 1000, h = 1000, diameter = d === 0 ? 0 : Math.sqrt((w * w) + (h * h)) / d;\n\n\t if (n.children.length > 0) {\n\t // eventually with n.IsExpanded\n\t for (var i = 0, len = n.children.length; i < len; i++) {\n\t var child = n.children[i];\n\t aw += this.calculateAngularWidth(child, d + 1);\n\t }\n\t aw = Math.max(diameter, aw);\n\t }\n\t else {\n\t aw = diameter;\n\t }\n\n\t n.sectorAngle = aw;\n\t return aw;\n\t },\n\t sortChildren: function (n) {\n\t var basevalue = 0, i;\n\n\t // update basevalue angle for node ordering\n\t if (n.parents.length > 1) {\n\t throw \"Node is not part of a tree.\";\n\t }\n\t var p = n.parents[0];\n\t if (p) {\n\t var pl = new Point(p.x, p.y);\n\t var nl = new Point(n.x, n.y);\n\t basevalue = this.normalizeAngle(Math.atan2(pl.y - nl.y, pl.x - nl.x));\n\t }\n\n\t var count = n.children.length;\n\t if (count === 0) {\n\t return null;\n\t }\n\n\t var angle = [];\n\t var idx = [];\n\n\t for (i = 0; i < count; ++i) {\n\t var c = n.children[i];\n\t var l = new Point(c.x, c.y);\n\t idx[i] = i;\n\t angle[i] = this.normalizeAngle(-basevalue + Math.atan2(l.y - l.y, l.x - l.x));\n\t }\n\n\t Utils.bisort(angle, idx);\n\t var col = []; // list of nodes\n\t var children = n.children;\n\t for (i = 0; i < count; ++i) {\n\t col.push(children[idx[i]]);\n\t }\n\n\t return col;\n\t },\n\n\t normalizeAngle: function (angle) {\n\t while (angle > Math.PI * 2) {\n\t angle -= 2 * Math.PI;\n\t }\n\t while (angle < 0) {\n\t angle += Math.PI * 2;\n\t }\n\t return angle;\n\t },\n\t radialLayout: function (node, radius, startAngle, endAngle) {\n\t var deltaTheta = endAngle - startAngle;\n\t var deltaThetaHalf = deltaTheta / 2.0;\n\t var parentSector = node.sectorAngle;\n\t var fraction = 0;\n\t var sorted = this.sortChildren(node);\n\t for (var i = 0, len = sorted.length; i < len; i++) {\n\t var childNode = sorted[i];\n\t var cp = childNode;\n\t var childAngleFraction = cp.sectorAngle / parentSector;\n\t if (childNode.children.length > 0) {\n\t this.radialLayout(childNode,\n\t radius + this.options.radialSeparation,\n\t startAngle + (fraction * deltaTheta),\n\t startAngle + ((fraction + childAngleFraction) * deltaTheta));\n\t }\n\n\t this.setPolarLocation(childNode, radius, startAngle + (fraction * deltaTheta) + (childAngleFraction * deltaThetaHalf));\n\t cp.angle = childAngleFraction * deltaTheta;\n\t fraction += childAngleFraction;\n\t }\n\t },\n\t setPolarLocation: function (node, radius, angle) {\n\t node.x = this.origin.x + (radius * Math.cos(angle));\n\t node.y = this.origin.y + (radius * Math.sin(angle));\n\t node.BoundingRectangle = new Rect(node.x, node.y, node.width, node.height);\n\t },\n\n\t /**\n\t * Sets the children direction recursively.\n\t * @param node\n\t * @param direction\n\t * @param includeStart\n\t */\n\t setChildrenDirection: function (node, direction, includeStart) {\n\t var rootDirection = node.treeDirection;\n\t this.graph.depthFirstTraversal(node, function (n) {\n\t n.treeDirection = direction;\n\t });\n\t if (!includeStart) {\n\t node.treeDirection = rootDirection;\n\t }\n\t },\n\n\t /**\n\t * Sets the children layout recursively.\n\t * @param node\n\t * @param layout\n\t * @param includeStart\n\t * @param startFromLevel\n\t */\n\t setChildrenLayout: function (node, layout, includeStart, startFromLevel) {\n\t if (Utils.isUndefined(startFromLevel)) {\n\t startFromLevel = 0;\n\t }\n\t var rootLayout = node.childrenLayout;\n\t if (startFromLevel > 0) {\n\t // assign levels to the Node.Level property\n\t this.graph.assignLevels(node);\n\n\t // assign the layout on the condition that the level is at least the 'startFromLevel'\n\t this.graph.depthFirstTraversal(\n\t node, function (s) {\n\t if (s.level >= startFromLevel + 1) {\n\t s.childrenLayout = layout;\n\t }\n\t }\n\t );\n\t }\n\t else {\n\t this.graph.depthFirstTraversal(node, function (s) {\n\t s.childrenLayout = layout;\n\t });\n\n\t // if the start should not be affected we put the state back\n\t if (!includeStart) {\n\t node.childrenLayout = rootLayout;\n\t }\n\t }\n\t },\n\n\t /**\n\t * Returns the actual size of the node. The given size is the allowed space wherein the node can lay out itself.\n\t * @param node\n\t * @param givenSize\n\t * @returns {Size}\n\t */\n\t measure: function (node, givenSize) {\n\t var w = 0, h = 0, s;\n\t var result = new Size(0, 0);\n\t if (!node) {\n\t throw \"\";\n\t }\n\t var b = node.associatedShape.bounds();\n\t var shapeWidth = b.width;\n\t var shapeHeight = b.height;\n\t if (node.parents.length !== 1) {\n\t throw \"Node not in a spanning tree.\";\n\t }\n\n\t var parent = node.parents[0];\n\t if (node.treeDirection === \"Undefined\") {\n\t node.treeDirection = parent.treeDirection;\n\t }\n\n\t if (Utils.isEmpty(node.children)) {\n\t result = new Size(\n\t Math.abs(shapeWidth) < EPSILON ? 50 : shapeWidth,\n\t Math.abs(shapeHeight) < EPSILON ? 25 : shapeHeight);\n\t }\n\t else if (node.children.length === 1) {\n\t switch (node.treeDirection) {\n\t case \"Radial\":\n\t s = this.measure(node.children[0], givenSize); // child size\n\t w = shapeWidth + (this.options.radialSeparation * Math.cos(node.AngleToParent)) + s.width;\n\t h = shapeHeight + Math.abs(this.options.radialSeparation * Math.sin(node.AngleToParent)) + s.height;\n\t break;\n\t case \"Left\":\n\t case \"Right\":\n\t switch (node.childrenLayout) {\n\n\t case \"TopAlignedWithParent\":\n\t break;\n\n\t case \"BottomAlignedWithParent\":\n\t break;\n\n\t case \"Underneath\":\n\t s = this.measure(node.children[0], givenSize);\n\t w = shapeWidth + s.width + this.options.underneathHorizontalOffset;\n\t h = shapeHeight + this.options.underneathVerticalTopOffset + s.height;\n\t break;\n\n\t case \"Default\":\n\t s = this.measure(node.children[0], givenSize);\n\t w = shapeWidth + this.options.horizontalSeparation + s.width;\n\t h = Math.max(shapeHeight, s.height);\n\t break;\n\n\t default:\n\t throw \"Unhandled TreeDirection in the Radial layout measuring.\";\n\t }\n\t break;\n\t case \"Up\":\n\t case \"Down\":\n\t switch (node.childrenLayout) {\n\n\t case \"TopAlignedWithParent\":\n\t case \"BottomAlignedWithParent\":\n\t break;\n\n\t case \"Underneath\":\n\t s = this.measure(node.children[0], givenSize);\n\t w = Math.max(shapeWidth, s.width + this.options.underneathHorizontalOffset);\n\t h = shapeHeight + this.options.underneathVerticalTopOffset + s.height;\n\t break;\n\n\t case \"Default\":\n\t s = this.measure(node.children[0], givenSize);\n\t h = shapeHeight + this.options.verticalSeparation + s.height;\n\t w = Math.max(shapeWidth, s.width);\n\t break;\n\n\t default:\n\t throw \"Unhandled TreeDirection in the Down layout measuring.\";\n\t }\n\t break;\n\t default:\n\t throw \"Unhandled TreeDirection in the layout measuring.\";\n\t }\n\n\t result = new Size(w, h);\n\t }\n\t else {\n\t var i, childNode;\n\t switch (node.treeDirection) {\n\t case \"Left\":\n\t case \"Right\":\n\t switch (node.childrenLayout) {\n\n\t case \"TopAlignedWithParent\":\n\t case \"BottomAlignedWithParent\":\n\t break;\n\n\t case \"Underneath\":\n\t w = shapeWidth;\n\t h = shapeHeight + this.options.underneathVerticalTopOffset;\n\t for (i = 0; i < node.children.length; i++) {\n\t childNode = node.children[i];\n\t s = this.measure(childNode, givenSize);\n\t w = Math.max(w, s.width + this.options.underneathHorizontalOffset);\n\t h += s.height + this.options.underneathVerticalSeparation;\n\t }\n\n\t h -= this.options.underneathVerticalSeparation;\n\t break;\n\n\t case \"Default\":\n\t w = shapeWidth;\n\t h = 0;\n\t for (i = 0; i < node.children.length; i++) {\n\t childNode = node.children[i];\n\t s = this.measure(childNode, givenSize);\n\t w = Math.max(w, shapeWidth + this.options.horizontalSeparation + s.width);\n\t h += s.height + this.options.verticalSeparation;\n\t }\n\t h -= this.options.verticalSeparation;\n\t break;\n\n\t default:\n\t throw \"Unhandled TreeDirection in the Right layout measuring.\";\n\t }\n\n\t break;\n\t case \"Up\":\n\t case \"Down\":\n\n\t switch (node.childrenLayout) {\n\n\t case \"TopAlignedWithParent\":\n\t case \"BottomAlignedWithParent\":\n\t break;\n\n\t case \"Underneath\":\n\t w = shapeWidth;\n\t h = shapeHeight + this.options.underneathVerticalTopOffset;\n\t for (i = 0; i < node.children.length; i++) {\n\t childNode = node.children[i];\n\t s = this.measure(childNode, givenSize);\n\t w = Math.max(w, s.width + this.options.underneathHorizontalOffset);\n\t h += s.height + this.options.underneathVerticalSeparation;\n\t }\n\n\t h -= this.options.underneathVerticalSeparation;\n\t break;\n\n\t case \"Default\":\n\t w = 0;\n\t h = 0;\n\t for (i = 0; i < node.children.length; i++) {\n\t childNode = node.children[i];\n\t s = this.measure(childNode, givenSize);\n\t w += s.width + this.options.horizontalSeparation;\n\t h = Math.max(h, s.height + this.options.verticalSeparation + shapeHeight);\n\t }\n\n\t w -= this.options.horizontalSeparation;\n\t break;\n\n\t default:\n\t throw \"Unhandled TreeDirection in the Down layout measuring.\";\n\t }\n\n\t break;\n\t default:\n\t throw \"Unhandled TreeDirection in the layout measuring.\";\n\t }\n\n\t result = new Size(w, h);\n\t }\n\n\t node.SectorAngle = Math.sqrt((w * w / 4) + (h * h / 4));\n\t node.Size = result;\n\t return result;\n\t },\n\t arrange: function (n, p) {\n\t var i, pp, child, node, childrenwidth, b = n.associatedShape.bounds();\n\t var shapeWidth = b.width;\n\t var shapeHeight = b.height;\n\t if (Utils.isEmpty(n.children)) {\n\t n.x = p.x;\n\t n.y = p.y;\n\t n.BoundingRectangle = new Rect(p.x, p.y, shapeWidth, shapeHeight);\n\t }\n\t else {\n\t var x, y;\n\t var selfLocation;\n\t switch (n.treeDirection) {\n\t case \"Left\":\n\t switch (n.childrenLayout) {\n\t case \"TopAlignedWithParent\":\n\t case \"BottomAlignedWithParent\":\n\t break;\n\n\t case \"Underneath\":\n\t selfLocation = p;\n\t n.x = selfLocation.x;\n\t n.y = selfLocation.y;\n\t n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n\t y = p.y + shapeHeight + this.options.underneathVerticalTopOffset;\n\t for (i = 0; i < node.children.length; i++) {\n\t node = node.children[i];\n\t x = selfLocation.x - node.associatedShape.width - this.options.underneathHorizontalOffset;\n\t pp = new Point(x, y);\n\t this.arrange(node, pp);\n\t y += node.Size.height + this.options.underneathVerticalSeparation;\n\t }\n\t break;\n\n\t case \"Default\":\n\t selfLocation = new Point(p.x + n.Size.width - shapeWidth, p.y + ((n.Size.height - shapeHeight) / 2));\n\t n.x = selfLocation.x;\n\t n.y = selfLocation.y;\n\t n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n\t x = selfLocation.x - this.options.horizontalSeparation; // alignment of children\n\t y = p.y;\n\t for (i = 0; i < n.children.length; i++) {\n\t node = n.children[i];\n\t pp = new Point(x - node.Size.width, y);\n\t this.arrange(node, pp);\n\t y += node.Size.height + this.options.verticalSeparation;\n\t }\n\t break;\n\n\t default:\n\t throw \"Unsupported TreeDirection\";\n\t }\n\n\t break;\n\t case \"Right\":\n\t switch (n.childrenLayout) {\n\t case \"TopAlignedWithParent\":\n\t case \"BottomAlignedWithParent\":\n\t break;\n\n\t case \"Underneath\":\n\t selfLocation = p;\n\t n.x = selfLocation.x;\n\t n.y = selfLocation.y;\n\t n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n\t x = p.x + shapeWidth + this.options.underneathHorizontalOffset;\n\n\t // alignment of children left-underneath the parent\n\t y = p.y + shapeHeight + this.options.underneathVerticalTopOffset;\n\t for (i = 0; i < n.children.length; i++) {\n\t node = n.children[i];\n\t pp = new Point(x, y);\n\t this.arrange(node, pp);\n\t y += node.Size.height + this.options.underneathVerticalSeparation;\n\t }\n\n\t break;\n\n\t case \"Default\":\n\t selfLocation = new Point(p.x, p.y + ((n.Size.height - shapeHeight) / 2));\n\t n.x = selfLocation.x;\n\t n.y = selfLocation.y;\n\t n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n\t x = p.x + shapeWidth + this.options.horizontalSeparation; // alignment of children\n\t y = p.y;\n\t for (i = 0; i < n.children.length; i++) {\n\t node = n.children[i];\n\t pp = new Point(x, y);\n\t this.arrange(node, pp);\n\t y += node.Size.height + this.options.verticalSeparation;\n\t }\n\t break;\n\n\t default:\n\t throw \"Unsupported TreeDirection\";\n\t }\n\n\t break;\n\t case \"Up\":\n\t selfLocation = new Point(p.x + ((n.Size.width - shapeWidth) / 2), p.y + n.Size.height - shapeHeight);\n\t n.x = selfLocation.x;\n\t n.y = selfLocation.y;\n\t n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n\t if (Math.abs(selfLocation.x - p.x) < EPSILON) {\n\t childrenwidth = 0;\n\t // means there is an aberration due to the oversized Element with respect to the children\n\t for (i = 0; i < n.children.length; i++) {\n\t child = n.children[i];\n\t childrenwidth += child.Size.width + this.options.horizontalSeparation;\n\t }\n\t childrenwidth -= this.options.horizontalSeparation;\n\t x = p.x + ((shapeWidth - childrenwidth) / 2);\n\t }\n\t else {\n\t x = p.x;\n\t }\n\n\t for (i = 0; i < n.children.length; i++) {\n\t node = n.children[i];\n\t y = selfLocation.y - this.options.verticalSeparation - node.Size.height;\n\t pp = new Point(x, y);\n\t this.arrange(node, pp);\n\t x += node.Size.width + this.options.horizontalSeparation;\n\t }\n\t break;\n\n\t case \"Down\":\n\n\t switch (n.childrenLayout) {\n\t case \"TopAlignedWithParent\":\n\t case \"BottomAlignedWithParent\":\n\t break;\n\t case \"Underneath\":\n\t selfLocation = p;\n\t n.x = selfLocation.x;\n\t n.y = selfLocation.y;\n\t n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n\t x = p.x + this.options.underneathHorizontalOffset; // alignment of children left-underneath the parent\n\t y = p.y + shapeHeight + this.options.underneathVerticalTopOffset;\n\t for (i = 0; i < n.children.length; i++) {\n\t node = n.children[i];\n\t pp = new Point(x, y);\n\t this.arrange(node, pp);\n\t y += node.Size.height + this.options.underneathVerticalSeparation;\n\t }\n\t break;\n\n\t case \"Default\":\n\t selfLocation = new Point(p.x + ((n.Size.width - shapeWidth) / 2), p.y);\n\t n.x = selfLocation.x;\n\t n.y = selfLocation.y;\n\t n.BoundingRectangle = new Rect(n.x, n.y, n.width, n.height);\n\t if (Math.abs(selfLocation.x - p.x) < EPSILON) {\n\t childrenwidth = 0;\n\t // means there is an aberration due to the oversized Element with respect to the children\n\t for (i = 0; i < n.children.length; i++) {\n\t child = n.children[i];\n\t childrenwidth += child.Size.width + this.options.horizontalSeparation;\n\t }\n\n\t childrenwidth -= this.options.horizontalSeparation;\n\t x = p.x + ((shapeWidth - childrenwidth) / 2);\n\t }\n\t else {\n\t x = p.x;\n\t }\n\n\t for (i = 0; i < n.children.length; i++) {\n\t node = n.children[i];\n\t y = selfLocation.y + this.options.verticalSeparation + shapeHeight;\n\t pp = new Point(x, y);\n\t this.arrange(node, pp);\n\t x += node.Size.width + this.options.horizontalSeparation;\n\t }\n\t break;\n\n\t default:\n\t throw \"Unsupported TreeDirection\";\n\t }\n\t break;\n\n\t case \"None\":\n\t break;\n\n\t default:\n\t throw \"Unsupported TreeDirection\";\n\t }\n\t }\n\t },\n\t layoutSwitch: function () {\n\t if (!this.center) {\n\t return;\n\t }\n\n\t if (Utils.isEmpty(this.center.children)) {\n\t return;\n\t }\n\n\t var type = this.options.subtype;\n\t if (Utils.isUndefined(type)) {\n\t type = \"Down\";\n\t }\n\t var single, male, female, leftcount;\n\t var children = this.center.children;\n\t switch (type.toLowerCase()) {\n\t case \"radial\":\n\t case \"radialtree\":\n\t this.layoutRadialTree();\n\t break;\n\n\t case \"mindmaphorizontal\":\n\t case \"mindmap\":\n\t single = this.center.children;\n\n\t if (this.center.children.length === 1) {\n\t this.layoutRight(single);\n\t }\n\t else {\n\t // odd number will give one more at the right\n\t leftcount = children.length / 2;\n\t male = grep(this.center.children, function (n) {\n\t return Utils.indexOf(children, n) < leftcount;\n\t });\n\t female = grep(this.center.children, function (n) {\n\t return Utils.indexOf(children, n) >= leftcount;\n\t });\n\n\t this.layoutLeft(male);\n\t this.layoutRight(female);\n\t }\n\t break;\n\n\t case \"mindmapvertical\":\n\t single = this.center.children;\n\n\t if (this.center.children.length === 1) {\n\t this.layoutDown(single);\n\t }\n\t else {\n\t // odd number will give one more at the right\n\t leftcount = children.length / 2;\n\t male = grep(this.center.children, function (n) {\n\t return Utils.indexOf(children, n) < leftcount;\n\t });\n\t female = grep(this.center.children, function (n) {\n\t return Utils.indexOf(children, n) >= leftcount;\n\t });\n\t this.layoutUp(male);\n\t this.layoutDown(female);\n\t }\n\t break;\n\n\t case \"right\":\n\t this.layoutRight(this.center.children);\n\t break;\n\n\t case \"left\":\n\t this.layoutLeft(this.center.children);\n\t break;\n\n\t case \"up\":\n\t case \"bottom\":\n\t this.layoutUp(this.center.children);\n\t break;\n\n\t case \"down\":\n\t case \"top\":\n\t this.layoutDown(this.center.children);\n\t break;\n\n\t case \"tipover\":\n\t case \"tipovertree\":\n\t if (this.options.tipOverTreeStartLevel < 0) {\n\t throw \"The tip-over level should be a positive integer.\";\n\t }\n\t this.tipOverTree(this.center.children, this.options.tipOverTreeStartLevel);\n\t break;\n\n\t case \"undefined\":\n\t case \"none\":\n\t break;\n\t }\n\t }\n\t });\n\n\t /**\n\t * The various tree layout algorithms.\n\t * @type {*}\n\t */\n\t var TreeLayout = LayoutBase.extend({\n\t init: function (diagram) {\n\t var that = this;\n\t LayoutBase.fn.init.call(that);\n\t if (Utils.isUndefined(diagram)) {\n\t throw \"No diagram specified.\";\n\t }\n\t this.diagram = diagram;\n\t },\n\n\t /**\n\t * Arranges the diagram in a tree-layout with the specified options and tree subtype.\n\t */\n\t layout: function (options) {\n\n\t this.transferOptions(options);\n\n\t // transform the diagram into a Graph\n\t var adapter = new DiagramToHyperTreeAdapter(this.diagram);\n\n\t /**\n\t * The Graph reduction from the given diagram.\n\t * @type {*}\n\t */\n\t this.graph = adapter.convert();\n\n\t var finalNodeSet = this.layoutComponents();\n\n\t // note that the graph contains the original data and\n\t // the components are another instance of nodes referring to the same set of shapes\n\t return new diagram.LayoutState(this.diagram, finalNodeSet);\n\t },\n\n\t layoutComponents: function () {\n\t if (this.graph.isEmpty()) {\n\t return;\n\t }\n\n\t // split into connected components\n\t var components = this.graph.getConnectedComponents();\n\t if (Utils.isEmpty(components)) {\n\t return;\n\t }\n\n\t var layout = new TreeLayoutProcessor(this.options);\n\t var trees = [];\n\t // find a spanning tree for each component\n\t for (var i = 0; i < components.length; i++) {\n\t var component = components[i];\n\n\t var treeGraph = this.getTree(component);\n\t if (!treeGraph) {\n\t throw \"Failed to find a spanning tree for the component.\";\n\t }\n\t var root = treeGraph.root;\n\t var tree = treeGraph.tree;\n\t layout.layout(tree, root);\n\n\t trees.push(tree);\n\t }\n\n\t return this.gridLayoutComponents(trees);\n\n\t },\n\n\t /**\n\t * Gets a spanning tree (and root) for the given graph.\n\t * Ensure that the given graph is connected!\n\t * @param graph\n\t * @returns {*} A literal object consisting of the found root and the spanning tree.\n\t */\n\t getTree: function (graph) {\n\t var root = null;\n\t if (this.options.roots && this.options.roots.length > 0) {\n\t for (var i = 0, len = graph.nodes.length; i < len; i++) {\n\t var node = graph.nodes[i];\n\t for (var j = 0; j < this.options.roots.length; j++) {\n\t var givenRootShape = this.options.roots[j];\n\t if (givenRootShape === node.associatedShape) {\n\t root = node;\n\t break;\n\t }\n\t }\n\t }\n\t }\n\t if (!root) {\n\t // finds the most probable root on the basis of the longest path in the component\n\t root = graph.root();\n\t // should not happen really\n\t if (!root) {\n\t throw \"Unable to find a root for the tree.\";\n\t }\n\t }\n\t return this.getTreeForRoot(graph, root);\n\t },\n\n\t getTreeForRoot: function (graph, root) {\n\n\t var tree = graph.getSpanningTree(root);\n\t if (Utils.isUndefined(tree) || tree.isEmpty()) {\n\t return null;\n\t }\n\t return {\n\t tree: tree,\n\t root: tree.root\n\t };\n\t }\n\n\t });\n\n\t /**\n\t * The Sugiyama aka layered layout algorithm.\n\t * @type {*}\n\t */\n\t var LayeredLayout = LayoutBase.extend({\n\t init: function (diagram) {\n\t var that = this;\n\t LayoutBase.fn.init.call(that);\n\t if (Utils.isUndefined(diagram)) {\n\t throw \"Diagram is not specified.\";\n\t }\n\t this.diagram = diagram;\n\t },\n\n\t layout: function (options) {\n\n\t this.transferOptions(options);\n\n\t var adapter = new DiagramToHyperTreeAdapter(this.diagram);\n\t var graph = adapter.convert(options);\n\t if (graph.isEmpty()) {\n\t return;\n\t }\n\t // split into connected components\n\t var components = graph.getConnectedComponents();\n\t if (Utils.isEmpty(components)) {\n\t return;\n\t }\n\t for (var i = 0; i < components.length; i++) {\n\t var component = components[i];\n\t this.layoutGraph(component, options);\n\t }\n\t var finalNodeSet = this.gridLayoutComponents(components);\n\t return new diagram.LayoutState(this.diagram, finalNodeSet);\n\n\t },\n\n\t /**\n\t * Initializes the runtime data properties of the layout.\n\t * @private\n\t */\n\t _initRuntimeProperties: function () {\n\t for (var k = 0; k < this.graph.nodes.length; k++) {\n\t var node = this.graph.nodes[k];\n\t node.layer = -1;\n\t node.downstreamLinkCount = 0;\n\t node.upstreamLinkCount = 0;\n\n\t node.isVirtual = false;\n\n\t node.uBaryCenter = 0.0;\n\t node.dBaryCenter = 0.0;\n\n\t node.upstreamPriority = 0;\n\t node.downstreamPriority = 0;\n\n\t node.gridPosition = 0;\n\t }\n\t },\n\t _prepare: function (graph) {\n\t var current = [], i, l, link;\n\n\t // defines a mapping of a node to the layer index\n\t var layerMap = new Dictionary();\n\t var layerCount = 0;\n\t var targetLayer, next, target;\n\n\t Utils.forEach(graph.nodes, function (node) {\n\t if (node.incoming.length === 0) {\n\t layerMap.set(node, 0);\n\t current.push(node);\n\t }\n\t });\n\n\t while (current.length > 0) {\n\t next = current.shift();\n\t for (i = 0; i < next.outgoing.length; i++) {\n\t link = next.outgoing[i];\n\t target = link.target;\n\n\t if (layerMap.containsKey(target)) {\n\t targetLayer = Math.max(layerMap.get(next) + 1, layerMap.get(target));\n\t } else {\n\t targetLayer = layerMap.get(next) + 1;\n\t }\n\t layerMap.set(target, targetLayer);\n\t if (targetLayer > layerCount) {\n\t layerCount = targetLayer;\n\t }\n\n\t if (!contains(current, target)) {\n\t current.push(target);\n\t }\n\t }\n\t }\n\n\t var sortedNodes = layerMap.keys();\n\n\t sortedNodes.sort(function (o1, o2) {\n\t var o1layer = layerMap.get(o1);\n\t var o2layer = layerMap.get(o2);\n\t return Utils.sign(o2layer - o1layer);\n\t });\n\n\t for (var n = 0; n < sortedNodes.length; ++n) {\n\t var node = sortedNodes[n];\n\t var minLayer = Number.MAX_VALUE;\n\n\t if (node.outgoing.length === 0) {\n\t continue;\n\t }\n\n\t for (l = 0; l < node.outgoing.length; ++l) {\n\t link = node.outgoing[l];\n\t minLayer = Math.min(minLayer, layerMap.get(link.target));\n\t }\n\n\t if (minLayer > 1) {\n\t layerMap.set(node, minLayer - 1);\n\t }\n\t }\n\n\t this.layers = [];\n\t var layer;\n\t for (i = 0; i < layerCount + 1; i++) {\n\t layer = [];\n\t layer.linksTo = {};\n\t this.layers.push(layer);\n\t }\n\n\t layerMap.forEach(function (node, layer) {\n\t node.layer = layer;\n\t this.layers[layer].push(node);\n\t }, this);\n\n\t // set initial grid positions\n\t for (l = 0; l < this.layers.length; l++) {\n\t layer = this.layers[l];\n\t for (i = 0; i < layer.length; i++) {\n\t layer[i].gridPosition = i;\n\t }\n\t }\n\t },\n\t /**\n\t * Performs the layout of a single component.\n\t */\n\t layoutGraph: function (graph, options) {\n\t if (Utils.isUndefined(graph)) {\n\t throw \"No graph given or graph analysis of the diagram failed.\";\n\t }\n\t if (Utils.isDefined(options)) {\n\t this.transferOptions(options);\n\t }\n\t this.graph = graph;\n\n\t // sets unique indices on the nodes\n\t graph.setItemIndices();\n\n\t // ensures no cycles present for this layout\n\t var reversedEdges = graph.makeAcyclic();\n\n\t // define the runtime props being used by the layout algorithm\n\t this._initRuntimeProperties();\n\n\t this._prepare(graph, options);\n\n\t this._dummify();\n\n\t this._optimizeCrossings();\n\n\t this._swapPairs();\n\n\t this.arrangeNodes();\n\n\t this._moveThingsAround();\n\n\t this._dedummify();\n\n\t // re-reverse the links which were switched earlier\n\t Utils.forEach(reversedEdges, function (e) {\n\t if (e.points) {\n\t e.points.reverse();\n\t }\n\t });\n\t },\n\n\t setMinDist: function (m, n, minDist) {\n\t var l = m.layer;\n\t var i = m.layerIndex;\n\t this.minDistances[l][i] = minDist;\n\t },\n\n\t getMinDist: function (m, n) {\n\t var dist = 0,\n\t i1 = m.layerIndex,\n\t i2 = n.layerIndex,\n\t l = m.layer,\n\t min = Math.min(i1, i2),\n\t max = Math.max(i1, i2);\n\t // use Sum()?\n\t for (var k = min; k < max; ++k) {\n\t dist += this.minDistances[l][k];\n\t }\n\t return dist;\n\t },\n\n\t placeLeftToRight: function (leftClasses) {\n\t var leftPos = new Dictionary(), n, node;\n\t for (var c = 0; c < this.layers.length; ++c) {\n\t var classNodes = leftClasses[c];\n\t if (!classNodes) {\n\t continue;\n\t }\n\n\t for (n = 0; n < classNodes.length; n++) {\n\t node = classNodes[n];\n\t if (!leftPos.containsKey(node)) {\n\t this.placeLeft(node, leftPos, c);\n\t }\n\t }\n\n\t // adjust class\n\t var d = Number.POSITIVE_INFINITY;\n\t for (n = 0; n < classNodes.length; n++) {\n\t node = classNodes[n];\n\t var rightSibling = this.rightSibling(node);\n\t if (rightSibling && this.nodeLeftClass.get(rightSibling) !== c) {\n\t d = Math.min(d, leftPos.get(rightSibling) - leftPos.get(node) - this.getMinDist(node, rightSibling));\n\t }\n\t }\n\t if (d === Number.POSITIVE_INFINITY) {\n\t var D = [];\n\t for (n = 0; n < classNodes.length; n++) {\n\t node = classNodes[n];\n\t var neighbors = [];\n\t Utils.addRange(neighbors, this.upNodes.get(node));\n\t Utils.addRange(neighbors, this.downNodes.get(node));\n\n\t for (var e = 0; e < neighbors.length; e++) {\n\t var neighbor = neighbors[e];\n\t if (this.nodeLeftClass.get(neighbor) < c) {\n\t D.push(leftPos.get(neighbor) - leftPos.get(node));\n\t }\n\t }\n\t }\n\t D.sort();\n\t if (D.length === 0) {\n\t d = 0;\n\t }\n\t else if (D.length % 2 === 1) {\n\t d = D[this.intDiv(D.length, 2)];\n\t }\n\t else {\n\t d = (D[this.intDiv(D.length, 2) - 1] + D[this.intDiv(D.length, 2)]) / 2;\n\t }\n\t }\n\t for (n = 0; n < classNodes.length; n++) {\n\t node = classNodes[n];\n\t leftPos.set(node, leftPos.get(node) + d);\n\t }\n\t }\n\t return leftPos;\n\t },\n\n\t placeRightToLeft: function (rightClasses) {\n\t var rightPos = new Dictionary(), n, node;\n\t for (var c = 0; c < this.layers.length; ++c) {\n\t var classNodes = rightClasses[c];\n\t if (!classNodes) {\n\t continue;\n\t }\n\n\t for (n = 0; n < classNodes.length; n++) {\n\t node = classNodes[n];\n\t if (!rightPos.containsKey(node)) {\n\t this.placeRight(node, rightPos, c);\n\t }\n\t }\n\n\t // adjust class\n\t var d = Number.NEGATIVE_INFINITY;\n\t for (n = 0; n < classNodes.length; n++) {\n\t node = classNodes[n];\n\t var leftSibling = this.leftSibling(node);\n\t if (leftSibling && this.nodeRightClass.get(leftSibling) !== c) {\n\t d = Math.max(d, rightPos.get(leftSibling) - rightPos.get(node) + this.getMinDist(leftSibling, node));\n\t }\n\t }\n\t if (d === Number.NEGATIVE_INFINITY) {\n\t var D = [];\n\t for (n = 0; n < classNodes.length; n++) {\n\t node = classNodes[n];\n\t var neighbors = [];\n\t Utils.addRange(neighbors, this.upNodes.get(node));\n\t Utils.addRange(neighbors, this.downNodes.get(node));\n\n\t for (var e = 0; e < neighbors.length; e++) {\n\t var neighbor = neighbors[e];\n\t if (this.nodeRightClass.get(neighbor) < c) {\n\t D.push(rightPos.get(node) - rightPos.get(neighbor));\n\t }\n\t }\n\t }\n\t D.sort();\n\t if (D.length === 0) {\n\t d = 0;\n\t }\n\t else if (D.length % 2 === 1) {\n\t d = D[this.intDiv(D.length, 2)];\n\t }\n\t else {\n\t d = (D[this.intDiv(D.length, 2) - 1] + D[this.intDiv(D.length, 2)]) / 2;\n\t }\n\t }\n\t for (n = 0; n < classNodes.length; n++) {\n\t node = classNodes[n];\n\t rightPos.set(node, rightPos.get(node) + d);\n\t }\n\t }\n\t return rightPos;\n\t },\n\n\t _getLeftWing: function () {\n\t var leftWing = { value: null };\n\t var result = this.computeClasses(leftWing, 1);\n\t this.nodeLeftClass = leftWing.value;\n\t return result;\n\t },\n\n\t _getRightWing: function () {\n\t var rightWing = { value: null };\n\t var result = this.computeClasses(rightWing, -1);\n\t this.nodeRightClass = rightWing.value;\n\t return result;\n\t },\n\n\t computeClasses: function (wingPair, d) {\n\t var currentWing = 0,\n\t wing = wingPair.value = new Dictionary();\n\n\t for (var l = 0; l < this.layers.length; ++l) {\n\t currentWing = l;\n\n\t var layer = this.layers[l];\n\t for (var n = d === 1 ? 0 : layer.length - 1; 0 <= n && n < layer.length; n += d) {\n\t var node = layer[n];\n\t if (!wing.containsKey(node)) {\n\t wing.set(node, currentWing);\n\t if (node.isVirtual) {\n\t var ndsinl = this._nodesInLink(node);\n\t for (var kk = 0; kk < ndsinl.length; kk++) {\n\t var vnode = ndsinl[kk];\n\t wing.set(vnode, currentWing);\n\t }\n\t }\n\t }\n\t else {\n\t currentWing = wing.get(node);\n\t }\n\t }\n\t }\n\n\t var wings = [];\n\t for (var i = 0; i < this.layers.length; i++) {\n\t wings.push(null);\n\t }\n\t wing.forEach(function (node, classIndex) {\n\t if (wings[classIndex] === null) {\n\t wings[classIndex] = [];\n\t }\n\t wings[classIndex].push(node);\n\t });\n\n\t return wings;\n\t },\n\t _isVerticalLayout: function () {\n\t return this.options.subtype.toLowerCase() === \"up\" || this.options.subtype.toLowerCase() === \"down\" || this.options.subtype.toLowerCase() === \"vertical\";\n\t },\n\n\t _isHorizontalLayout: function () {\n\t return this.options.subtype.toLowerCase() === \"right\" || this.options.subtype.toLowerCase() === \"left\" || this.options.subtype.toLowerCase() === \"horizontal\";\n\t },\n\t _isIncreasingLayout: function () {\n\t // meaning that the visiting of the layers goes in the natural order of increasing layer index\n\t return this.options.subtype.toLowerCase() === \"right\" || this.options.subtype.toLowerCase() === \"down\";\n\t },\n\t _moveThingsAround: function () {\n\t var i, l, node, layer, n, w;\n\t // sort the layers by their grid position\n\t for (l = 0; l < this.layers.length; ++l) {\n\t layer = this.layers[l];\n\t layer.sort(this._gridPositionComparer);\n\t }\n\n\t this.minDistances = [];\n\t for (l = 0; l < this.layers.length; ++l) {\n\t layer = this.layers[l];\n\t this.minDistances[l] = [];\n\t for (n = 0; n < layer.length; ++n) {\n\t node = layer[n];\n\t node.layerIndex = n;\n\t this.minDistances[l][n] = this.options.nodeDistance;\n\t if (n < layer.length - 1) {\n\t if (this._isVerticalLayout()) {\n\t this.minDistances[l][n] += (node.width + layer[n + 1].width) / 2;\n\t }\n\t else {\n\t this.minDistances[l][n] += (node.height + layer[n + 1].height) / 2;\n\t }\n\t }\n\t }\n\t }\n\n\t this.downNodes = new Dictionary();\n\t this.upNodes = new Dictionary();\n\t Utils.forEach(this.graph.nodes, function (node) {\n\t this.downNodes.set(node, []);\n\t this.upNodes.set(node, []);\n\t }, this);\n\t Utils.forEach(this.graph.links, function (link) {\n\t var origin = link.source;\n\t var dest = link.target;\n\t var down = null, up = null;\n\t if (origin.layer > dest.layer) {\n\t down = link.source;\n\t up = link.target;\n\t }\n\t else {\n\t up = link.source;\n\t down = link.target;\n\t }\n\t this.downNodes.get(up).push(down);\n\t this.upNodes.get(down).push(up);\n\t }, this);\n\t this.downNodes.forEachValue(function (list) {\n\t list.sort(this._gridPositionComparer);\n\t }, this);\n\t this.upNodes.forEachValue(function (list) {\n\t list.sort(this._gridPositionComparer);\n\t }, this);\n\n\t for (l = 0; l < this.layers.length - 1; ++l) {\n\t layer = this.layers[l];\n\t for (w = 0; w < layer.length - 1; w++) {\n\t var currentNode = layer[w];\n\t if (!currentNode.isVirtual) {\n\t continue;\n\t }\n\n\t var currDown = this.downNodes.get(currentNode)[0];\n\t if (!currDown.isVirtual) {\n\t continue;\n\t }\n\n\t for (n = w + 1; n < layer.length; ++n) {\n\t node = layer[n];\n\t if (!node.isVirtual) {\n\t continue;\n\t }\n\n\t var downNode = this.downNodes.get(node)[0];\n\t if (!downNode.isVirtual) {\n\t continue;\n\t }\n\n\t if (currDown.gridPosition > downNode.gridPosition) {\n\t var pos = currDown.gridPosition;\n\t currDown.gridPosition = downNode.gridPosition;\n\t downNode.gridPosition = pos;\n\t var i1 = currDown.layerIndex;\n\t var i2 = downNode.layerIndex;\n\t this.layers[l + 1][i1] = downNode;\n\t this.layers[l + 1][i2] = currDown;\n\t currDown.layerIndex = i2;\n\t downNode.layerIndex = i1;\n\t }\n\t }\n\t }\n\t }\n\n\n\t var leftClasses = this._getLeftWing();\n\t var rightClasses = this._getRightWing();\n\n\n\t var leftPos = this.placeLeftToRight(leftClasses);\n\t var rightPos = this.placeRightToLeft(rightClasses);\n\t var x = new Dictionary();\n\t Utils.forEach(this.graph.nodes, function (node) {\n\t x.set(node, (leftPos.get(node) + rightPos.get(node)) / 2);\n\t });\n\n\n\t var order = new Dictionary();\n\t var placed = new Dictionary();\n\t for (l = 0; l < this.layers.length; ++l) {\n\t layer = this.layers[l];\n\t var sequenceStart = -1, sequenceEnd = -1;\n\t for (n = 0; n < layer.length; ++n) {\n\t node = layer[n];\n\t order.set(node, 0);\n\t placed.set(node, false);\n\t if (node.isVirtual) {\n\t if (sequenceStart === -1) {\n\t sequenceStart = n;\n\t }\n\t else if (sequenceStart === n - 1) {\n\t sequenceStart = n;\n\t }\n\t else {\n\t sequenceEnd = n;\n\t order.set(layer[sequenceStart], 0);\n\t if (x.get(node) - x.get(layer[sequenceStart]) === this.getMinDist(layer[sequenceStart], node)) {\n\t placed.set(layer[sequenceStart], true);\n\t }\n\t else {\n\t placed.set(layer[sequenceStart], false);\n\t }\n\t sequenceStart = n;\n\t }\n\t }\n\t }\n\t }\n\t var directions = [1, -1];\n\t Utils.forEach(directions, function (d) {\n\t var start = d === 1 ? 0 : this.layers.length - 1;\n\t for (var l = start; 0 <= l && l < this.layers.length; l += d) {\n\t var layer = this.layers[l];\n\t var virtualStartIndex = this._firstVirtualNode(layer);\n\t var virtualStart = null;\n\t var sequence = null;\n\t if (virtualStartIndex !== -1) {\n\t virtualStart = layer[virtualStartIndex];\n\t sequence = [];\n\t for (i = 0; i < virtualStartIndex; i++) {\n\t sequence.push(layer[i]);\n\t }\n\t }\n\t else {\n\t virtualStart = null;\n\t sequence = layer;\n\t }\n\t if (sequence.length > 0) {\n\t this._sequencer(x, null, virtualStart, d, sequence);\n\t for (i = 0; i < sequence.length - 1; ++i) {\n\t this.setMinDist(sequence[i], sequence[i + 1], x.get(sequence[i + 1]) - x.get(sequence[i]));\n\t }\n\t if (virtualStart) {\n\t this.setMinDist(sequence[sequence.length - 1], virtualStart, x.get(virtualStart) - x.get(sequence[sequence.length - 1]));\n\t }\n\t }\n\n\t while (virtualStart) {\n\t var virtualEnd = this.nextVirtualNode(layer, virtualStart);\n\t if (!virtualEnd) {\n\t virtualStartIndex = virtualStart.layerIndex;\n\t sequence = [];\n\t for (i = virtualStartIndex + 1; i < layer.length; i++) {\n\t sequence.push(layer[i]);\n\t }\n\t if (sequence.length > 0) {\n\t this._sequencer(x, virtualStart, null, d, sequence);\n\t for (i = 0; i < sequence.length - 1; ++i) {\n\t this.setMinDist(sequence[i], sequence[i + 1], x.get(sequence[i + 1]) - x.get(sequence[i]));\n\t }\n\t this.setMinDist(virtualStart, sequence[0], x.get(sequence[0]) - x.get(virtualStart));\n\t }\n\t }\n\t else if (order.get(virtualStart) === d) {\n\t virtualStartIndex = virtualStart.layerIndex;\n\t var virtualEndIndex = virtualEnd.layerIndex;\n\t sequence = [];\n\t for (i = virtualStartIndex + 1; i < virtualEndIndex; i++) {\n\t sequence.push(layer[i]);\n\t }\n\t if (sequence.length > 0) {\n\t this._sequencer(x, virtualStart, virtualEnd, d, sequence);\n\t }\n\t placed.set(virtualStart, true);\n\t }\n\t virtualStart = virtualEnd;\n\t }\n\t this.adjustDirections(l, d, order, placed);\n\t }\n\t }, this);\n\n\n\t var fromLayerIndex = this._isIncreasingLayout() ? 0 : this.layers.length - 1;\n\t var reachedFinalLayerIndex = function (k, ctx) {\n\t if (ctx._isIncreasingLayout()) {\n\t return k < ctx.layers.length;\n\t }\n\t else {\n\t return k >= 0;\n\t }\n\t };\n\t var layerIncrement = this._isIncreasingLayout() ? +1 : -1, offset = 0;\n\n\t /**\n\t * Calcs the max height of the given layer.\n\t */\n\t function maximumHeight(layer, ctx) {\n\t var height = Number.MIN_VALUE;\n\t for (var n = 0; n < layer.length; ++n) {\n\t var node = layer[n];\n\t if (ctx._isVerticalLayout()) {\n\t height = Math.max(height, node.height);\n\t }\n\t else {\n\t height = Math.max(height, node.width);\n\t }\n\t }\n\t return height;\n\t }\n\n\t for (i = fromLayerIndex; reachedFinalLayerIndex(i, this); i += layerIncrement) {\n\t layer = this.layers[i];\n\t var height = maximumHeight(layer, this);\n\n\t for (n = 0; n < layer.length; ++n) {\n\t node = layer[n];\n\t if (this._isVerticalLayout()) {\n\t node.x = x.get(node);\n\t node.y = offset + height / 2;\n\t }\n\t else {\n\t node.x = offset + height / 2;\n\t node.y = x.get(node);\n\t }\n\t }\n\n\t offset += this.options.layerSeparation + height;\n\t }\n\t },\n\n\t adjustDirections: function (l, d, order, placed) {\n\t if (l + d < 0 || l + d >= this.layers.length) {\n\t return;\n\t }\n\n\t var prevBridge = null, prevBridgeTarget = null;\n\t var layer = this.layers[l + d];\n\t for (var n = 0; n < layer.length; ++n) {\n\t var nextBridge = layer[n];\n\t if (nextBridge.isVirtual) {\n\t var nextBridgeTarget = this.getNeighborOnLayer(nextBridge, l);\n\t if (nextBridgeTarget.isVirtual) {\n\t if (prevBridge) {\n\t var p = placed.get(prevBridgeTarget);\n\t var clayer = this.layers[l];\n\t var i1 = prevBridgeTarget.layerIndex;\n\t var i2 = nextBridgeTarget.layerIndex;\n\t for (var i = i1 + 1; i < i2; ++i) {\n\t if (clayer[i].isVirtual) {\n\t p = p && placed.get(clayer[i]);\n\t }\n\t }\n\t if (p) {\n\t order.set(prevBridge, d);\n\t var j1 = prevBridge.layerIndex;\n\t var j2 = nextBridge.layerIndex;\n\t for (var j = j1 + 1; j < j2; ++j) {\n\t if (layer[j].isVirtual) {\n\t order.set(layer[j], d);\n\t }\n\t }\n\t }\n\t }\n\t prevBridge = nextBridge;\n\t prevBridgeTarget = nextBridgeTarget;\n\t }\n\t }\n\t }\n\t },\n\n\t getNeighborOnLayer: function (node, l) {\n\t var neighbor = this.upNodes.get(node)[0];\n\t if (neighbor.layer === l) {\n\t return neighbor;\n\t }\n\t neighbor = this.downNodes.get(node)[0];\n\t if (neighbor.layer === l) {\n\t return neighbor;\n\t }\n\t return null;\n\t },\n\n\t _sequencer: function (x, virtualStart, virtualEnd, dir, sequence) {\n\t if (sequence.length === 1) {\n\t this._sequenceSingle(x, virtualStart, virtualEnd, dir, sequence[0]);\n\t }\n\n\t if (sequence.length > 1) {\n\t var r = sequence.length, t = this.intDiv(r, 2);\n\t this._sequencer(x, virtualStart, virtualEnd, dir, sequence.slice(0, t));\n\t this._sequencer(x, virtualStart, virtualEnd, dir, sequence.slice(t));\n\t this.combineSequences(x, virtualStart, virtualEnd, dir, sequence);\n\t }\n\t },\n\n\t _sequenceSingle: function (x, virtualStart, virtualEnd, dir, node) {\n\t var neighbors = dir === -1 ? this.downNodes.get(node) : this.upNodes.get(node);\n\n\t var n = neighbors.length;\n\t if (n !== 0) {\n\t if (n % 2 === 1) {\n\t x.set(node, x.get(neighbors[this.intDiv(n, 2)]));\n\t }\n\t else {\n\t x.set(node, (x.get(neighbors[this.intDiv(n, 2) - 1]) + x.get(neighbors[this.intDiv(n, 2)])) / 2);\n\t }\n\n\t if (virtualStart) {\n\t x.set(node, Math.max(x.get(node), x.get(virtualStart) + this.getMinDist(virtualStart, node)));\n\t }\n\t if (virtualEnd) {\n\t x.set(node, Math.min(x.get(node), x.get(virtualEnd) - this.getMinDist(node, virtualEnd)));\n\t }\n\t }\n\t },\n\n\t combineSequences: function (x, virtualStart, virtualEnd, dir, sequence) {\n\t var r = sequence.length, t = this.intDiv(r, 2);\n\n\t // collect left changes\n\t var leftHeap = [], i, c, n, neighbors, neighbor, pair;\n\t for (i = 0; i < t; ++i) {\n\t c = 0;\n\t neighbors = dir === -1 ? this.downNodes.get(sequence[i]) : this.upNodes.get(sequence[i]);\n\t for (n = 0; n < neighbors.length; ++n) {\n\t neighbor = neighbors[n];\n\t if (x.get(neighbor) >= x.get(sequence[i])) {\n\t c++;\n\t }\n\t else {\n\t c--;\n\t leftHeap.push({ k: x.get(neighbor) + this.getMinDist(sequence[i], sequence[t - 1]), v: 2 });\n\t }\n\t }\n\t leftHeap.push({ k: x.get(sequence[i]) + this.getMinDist(sequence[i], sequence[t - 1]), v: c });\n\t }\n\t if (virtualStart) {\n\t leftHeap.push({ k: x.get(virtualStart) + this.getMinDist(virtualStart, sequence[t - 1]), v: Number.MAX_VALUE });\n\t }\n\t leftHeap.sort(this._positionDescendingComparer);\n\n\t // collect right changes\n\t var rightHeap = [];\n\t for (i = t; i < r; ++i) {\n\t c = 0;\n\t neighbors = dir === -1 ? this.downNodes.get(sequence[i]) : this.upNodes.get(sequence[i]);\n\t for (n = 0; n < neighbors.length; ++n) {\n\t neighbor = neighbors[n];\n\t if (x.get(neighbor) <= x.get(sequence[i])) {\n\t c++;\n\t }\n\t else {\n\t c--;\n\t rightHeap.push({ k: x.get(neighbor) - this.getMinDist(sequence[i], sequence[t]), v: 2 });\n\t }\n\t }\n\t rightHeap.push({ k: x.get(sequence[i]) - this.getMinDist(sequence[i], sequence[t]), v: c });\n\t }\n\t if (virtualEnd) {\n\t rightHeap.push({ k: x.get(virtualEnd) - this.getMinDist(virtualEnd, sequence[t]), v: Number.MAX_VALUE });\n\t }\n\t rightHeap.sort(this._positionAscendingComparer);\n\n\t var leftRes = 0, rightRes = 0;\n\t var m = this.getMinDist(sequence[t - 1], sequence[t]);\n\t while (x.get(sequence[t]) - x.get(sequence[t - 1]) < m) {\n\t if (leftRes < rightRes) {\n\t if (leftHeap.length === 0) {\n\t x.set(sequence[t - 1], x.get(sequence[t]) - m);\n\t break;\n\t }\n\t else {\n\t pair = leftHeap.shift();\n\t leftRes = leftRes + pair.v;\n\t x.set(sequence[t - 1], pair.k);\n\t x.set(sequence[t - 1], Math.max(x.get(sequence[t - 1]), x.get(sequence[t]) - m));\n\t }\n\t }\n\t else {\n\t if (rightHeap.length === 0) {\n\t x.set(sequence[t], x.get(sequence[t - 1]) + m);\n\t break;\n\t }\n\t else {\n\t pair = rightHeap.shift();\n\t rightRes = rightRes + pair.v;\n\t x.set(sequence[t], pair.k);\n\t x.set(sequence[t], Math.min(x.get(sequence[t]), x.get(sequence[t - 1]) + m));\n\t }\n\t }\n\t }\n\t for (i = t - 2; i >= 0; i--) {\n\t x.set(sequence[i], Math.min(x.get(sequence[i]), x.get(sequence[t - 1]) - this.getMinDist(sequence[i], sequence[t - 1])));\n\t }\n\t for (i = t + 1; i < r; i++) {\n\t x.set(sequence[i], Math.max(x.get(sequence[i]), x.get(sequence[t]) + this.getMinDist(sequence[i], sequence[t])));\n\t }\n\t },\n\n\t placeLeft: function (node, leftPos, leftClass) {\n\t var pos = Number.NEGATIVE_INFINITY;\n\t Utils.forEach(this._getComposite(node), function (v) {\n\t var leftSibling = this.leftSibling(v);\n\t if (leftSibling && this.nodeLeftClass.get(leftSibling) === this.nodeLeftClass.get(v)) {\n\t if (!leftPos.containsKey(leftSibling)) {\n\t this.placeLeft(leftSibling, leftPos, leftClass);\n\t }\n\t pos = Math.max(pos, leftPos.get(leftSibling) + this.getMinDist(leftSibling, v));\n\t }\n\t }, this);\n\t if (pos === Number.NEGATIVE_INFINITY) {\n\t pos = 0;\n\t }\n\t Utils.forEach(this._getComposite(node), function (v) {\n\t leftPos.set(v, pos);\n\t });\n\t },\n\n\t placeRight: function (node, rightPos, rightClass) {\n\t var pos = Number.POSITIVE_INFINITY;\n\t Utils.forEach(this._getComposite(node), function (v) {\n\t var rightSibling = this.rightSibling(v);\n\t if (rightSibling && this.nodeRightClass.get(rightSibling) === this.nodeRightClass.get(v)) {\n\t if (!rightPos.containsKey(rightSibling)) {\n\t this.placeRight(rightSibling, rightPos, rightClass);\n\t }\n\t pos = Math.min(pos, rightPos.get(rightSibling) - this.getMinDist(v, rightSibling));\n\t }\n\t }, this);\n\t if (pos === Number.POSITIVE_INFINITY) {\n\t pos = 0;\n\t }\n\t Utils.forEach(this._getComposite(node), function (v) {\n\t rightPos.set(v, pos);\n\t });\n\t },\n\n\t leftSibling: function (node) {\n\t var layer = this.layers[node.layer],\n\t layerIndex = node.layerIndex;\n\t return layerIndex === 0 ? null : layer[layerIndex - 1];\n\t },\n\n\t rightSibling: function (node) {\n\t var layer = this.layers[node.layer];\n\t var layerIndex = node.layerIndex;\n\t return layerIndex === layer.length - 1 ? null : layer[layerIndex + 1];\n\n\t },\n\n\t _getComposite: function (node) {\n\t return node.isVirtual ? this._nodesInLink(node) : [node];\n\t },\n\n\t arrangeNodes: function () {\n\t var i, l, ni, layer, node;\n\t // Initialize node's base priority\n\t for (l = 0; l < this.layers.length; l++) {\n\t layer = this.layers[l];\n\n\t for (ni = 0; ni < layer.length; ni++) {\n\t node = layer[ni];\n\t node.upstreamPriority = node.upstreamLinkCount;\n\t node.downstreamPriority = node.downstreamLinkCount;\n\t }\n\t }\n\n\t // Layout is invoked after MinimizeCrossings\n\t // so we may assume node's barycenters are initially correct\n\n\t var maxLayoutIterations = 2;\n\t for (var it = 0; it < maxLayoutIterations; it++) {\n\t for (i = this.layers.length - 1; i >= 1; i--) {\n\t this.layoutLayer(false, i);\n\t }\n\n\t for (i = 0; i < this.layers.length - 1; i++) {\n\t this.layoutLayer(true, i);\n\t }\n\t }\n\n\t // Offset the whole structure so that there are no gridPositions < 0\n\t var gridPos = Number.MAX_VALUE;\n\t for (l = 0; l < this.layers.length; l++) {\n\t layer = this.layers[l];\n\n\t for (ni = 0; ni < layer.length; ni++) {\n\t node = layer[ni];\n\t gridPos = Math.min(gridPos, node.gridPosition);\n\t }\n\t }\n\n\t if (gridPos < 0) {\n\t for (l = 0; l < this.layers.length; l++) {\n\t layer = this.layers[l];\n\n\t for (ni = 0; ni < layer.length; ni++) {\n\t node = layer[ni];\n\t node.gridPosition = node.gridPosition - gridPos;\n\t }\n\t }\n\t }\n\t },\n\n\t /// \n\t /// Layout of a single layer.\n\t /// \n\t /// The layer to organize.\n\t /// If set to true we move down in the layer stack.\n\t /// \n\t layoutLayer: function (down, layer) {\n\t var iconsidered;\n\t var considered;\n\n\t if (down) {\n\t considered = this.layers[iconsidered = layer + 1];\n\t }\n\t else {\n\t considered = this.layers[iconsidered = layer - 1];\n\t }\n\n\t // list containing the nodes in the considered layer sorted by priority\n\t var sorted = [];\n\t for (var n = 0; n < considered.length; n++) {\n\t sorted.push(considered[n]);\n\t }\n\t sorted.sort(function (n1, n2) {\n\t var n1Priority = (n1.upstreamPriority + n1.downstreamPriority) / 2;\n\t var n2Priority = (n2.upstreamPriority + n2.downstreamPriority) / 2;\n\n\t if (Math.abs(n1Priority - n2Priority) < 0.0001) {\n\t return 0;\n\t }\n\t if (n1Priority < n2Priority) {\n\t return 1;\n\t }\n\t return -1;\n\t });\n\n\t // each node strives for its barycenter; high priority nodes start first\n\t Utils.forEach(sorted, function (node) {\n\t var nodeGridPos = node.gridPosition;\n\t var nodeBaryCenter = this.calcBaryCenter(node);\n\t var nodePriority = (node.upstreamPriority + node.downstreamPriority) / 2;\n\n\t if (Math.abs(nodeGridPos - nodeBaryCenter) < 0.0001) {\n\t // This node is exactly at its barycenter -> perfect\n\t return;\n\t }\n\n\t if (Math.abs(nodeGridPos - nodeBaryCenter) < 0.25 + 0.0001) {\n\t // This node is close enough to the barycenter -> should work\n\t return;\n\t }\n\n\t if (nodeGridPos < nodeBaryCenter) {\n\t // Try to move the node to the right in an\n\t // attempt to reach its barycenter\n\t while (nodeGridPos < nodeBaryCenter) {\n\t if (!this.moveRight(node, considered, nodePriority)) {\n\t break;\n\t }\n\n\t nodeGridPos = node.gridPosition;\n\t }\n\t }\n\t else {\n\t // Try to move the node to the left in an\n\t // attempt to reach its barycenter\n\t while (nodeGridPos > nodeBaryCenter) {\n\t if (!this.moveLeft(node, considered, nodePriority)) {\n\t break;\n\t }\n\n\t nodeGridPos = node.gridPosition;\n\t }\n\t }\n\t }, this);\n\n\t // after the layer has been rearranged we need to recalculate the barycenters\n\t // of the nodes in the surrounding layers\n\t if (iconsidered > 0) {\n\t this.calcDownData(iconsidered - 1);\n\t }\n\t if (iconsidered < this.layers.length - 1) {\n\t this.calcUpData(iconsidered + 1);\n\t }\n\t },\n\n\t /// \n\t /// Moves the node to the right and returns true if this was possible.\n\t /// \n\t /// The node.\n\t /// The layer.\n\t /// Returns true if the shift was possible, otherwise false.\n\t moveRight: function (node, layer, priority) {\n\t var index = Utils.indexOf(layer, node);\n\t if (index === layer.length - 1) {\n\t // this is the last node in the layer, so we can move to the right without troubles\n\t node.gridPosition = node.gridPosition + 0.5;\n\t return true;\n\t }\n\n\t var rightNode = layer[index + 1];\n\t var rightNodePriority = (rightNode.upstreamPriority + rightNode.downstreamPriority) / 2;\n\n\t // check if there is space between the right and the current node\n\t if (rightNode.gridPosition > node.gridPosition + 1) {\n\t node.gridPosition = node.gridPosition + 0.5;\n\t return true;\n\t }\n\n\t // we have reached a node with higher priority; no movement is allowed\n\t if (rightNodePriority > priority ||\n\t Math.abs(rightNodePriority - priority) < 0.0001) {\n\t return false;\n\t }\n\n\t // the right node has lower priority - try to move it\n\t if (this.moveRight(rightNode, layer, priority)) {\n\t node.gridPosition = node.gridPosition + 0.5;\n\t return true;\n\t }\n\n\t return false;\n\t },\n\n\t /// \n\t /// Moves the node to the left and returns true if this was possible.\n\t /// \n\t /// The node.\n\t /// The layer.\n\t /// Returns true if the shift was possible, otherwise false.\n\t moveLeft: function (node, layer, priority) {\n\t var index = Utils.indexOf(layer, node);\n\t if (index === 0) {\n\t // this is the last node in the layer, so we can move to the left without troubles\n\t node.gridPosition = node.gridPosition - 0.5;\n\t return true;\n\t }\n\n\t var leftNode = layer[index - 1];\n\t var leftNodePriority = (leftNode.upstreamPriority + leftNode.downstreamPriority) / 2;\n\n\t // check if there is space between the left and the current node\n\t if (leftNode.gridPosition < node.gridPosition - 1) {\n\t node.gridPosition = node.gridPosition - 0.5;\n\t return true;\n\t }\n\n\t // we have reached a node with higher priority; no movement is allowed\n\t if (leftNodePriority > priority ||\n\t Math.abs(leftNodePriority - priority) < 0.0001) {\n\t return false;\n\t }\n\n\t // The left node has lower priority - try to move it\n\t if (this.moveLeft(leftNode, layer, priority)) {\n\t node.gridPosition = node.gridPosition - 0.5;\n\t return true;\n\t }\n\n\t return false;\n\t },\n\n\t mapVirtualNode: function (node, link) {\n\t this.nodeToLinkMap.set(node, link);\n\t if (!this.linkToNodeMap.containsKey(link)) {\n\t this.linkToNodeMap.set(link, []);\n\t }\n\t this.linkToNodeMap.get(link).push(node);\n\t },\n\n\t _nodesInLink: function (node) {\n\t return this.linkToNodeMap.get(this.nodeToLinkMap.get(node));\n\t },\n\n\t /// \n\t /// Inserts dummy nodes to break long links.\n\t /// \n\t _dummify: function () {\n\t this.linkToNodeMap = new Dictionary();\n\t this.nodeToLinkMap = new Dictionary();\n\n\t var layer, pos, newNode, node, r, newLink, i, l, links = this.graph.links.slice(0);\n\t var layers = this.layers;\n\n\t var addLinkBetweenLayers = function(upLayer, downLayer, link) {\n\t layers[upLayer].linksTo[downLayer] = layers[upLayer].linksTo[downLayer] || [];\n\t layers[upLayer].linksTo[downLayer].push(link);\n\t };\n\n\t for (l = 0; l < links.length; l++) {\n\t var link = links[l];\n\t var o = link.source;\n\t var d = link.target;\n\n\t var oLayer = o.layer;\n\t var dLayer = d.layer;\n\t var oPos = o.gridPosition;\n\t var dPos = d.gridPosition;\n\n\t var step = (dPos - oPos) / Math.abs(dLayer - oLayer);\n\n\t var p = o;\n\t if (oLayer - dLayer > 1) {\n\t for (i = oLayer - 1; i > dLayer; i--) {\n\t newNode = new Node();\n\t newNode.x = o.x;\n\t newNode.y = o.y;\n\t newNode.width = o.width / 100;\n\t newNode.height = o.height / 100;\n\n\t layer = layers[i];\n\t pos = (i - dLayer) * step + oPos;\n\t if (pos > layer.length) {\n\t pos = layer.length;\n\t }\n\n\t // check if origin and dest are both last\n\t if (oPos >= layers[oLayer].length - 1 &&\n\t dPos >= layers[dLayer].length - 1) {\n\t pos = layer.length;\n\t }\n\n\t // check if origin and destination are both first\n\t else if (oPos === 0 && dPos === 0) {\n\t pos = 0;\n\t }\n\n\t newNode.layer = i;\n\t newNode.uBaryCenter = 0.0;\n\t newNode.dBaryCenter = 0.0;\n\t newNode.upstreamLinkCount = 0;\n\t newNode.downstreamLinkCount = 0;\n\t newNode.gridPosition = pos;\n\t newNode.isVirtual = true;\n\n\t Utils.insert(layer, newNode, pos);\n\n\t // translate rightwards nodes' positions\n\t for (r = pos + 1; r < layer.length; r++) {\n\t node = layer[r];\n\t node.gridPosition = node.gridPosition + 1;\n\t }\n\n\t newLink = new Link(p, newNode);\n\t newLink.depthOfDumminess = 0;\n\n\t addLinkBetweenLayers(i - 1, i, newLink);\n\n\t p = newNode;\n\n\t // add the new node and the new link to the graph\n\t this.graph._addNode(newNode);\n\t this.graph.addLink(newLink);\n\n\t newNode.index = this.graph.nodes.length - 1;\n\t this.mapVirtualNode(newNode, link);\n\t }\n\n\t // set the origin of the real arrow to the last dummy\n\t addLinkBetweenLayers(dLayer - 1, dLayer, newLink);\n\t link.changeSource(p);\n\t link.depthOfDumminess = oLayer - dLayer - 1;\n\t } else if (oLayer - dLayer < -1) {\n\t for (i = oLayer + 1; i < dLayer; i++) {\n\t newNode = new Node();\n\t newNode.x = o.x;\n\t newNode.y = o.y;\n\t newNode.width = o.width / 100;\n\t newNode.height = o.height / 100;\n\n\t layer = layers[i];\n\t pos = (i - oLayer) * step + oPos;\n\t if (pos > layer.length) {\n\t pos = layer.length;\n\t }\n\n\t // check if origin and dest are both last\n\t if (oPos >= layers[oLayer].length - 1 &&\n\t dPos >= layers[dLayer].length - 1) {\n\t pos = layer.length;\n\t }\n\n\t // check if origin and destination are both first\n\t else if (oPos === 0 && dPos === 0) {\n\t pos = 0;\n\t }\n\n\t newNode.layer = i;\n\t newNode.uBaryCenter = 0.0;\n\t newNode.dBaryCenter = 0.0;\n\t newNode.upstreamLinkCount = 0;\n\t newNode.downstreamLinkCount = 0;\n\t newNode.gridPosition = pos;\n\t newNode.isVirtual = true;\n\n\t pos &= pos; // truncates to int\n\t Utils.insert(layer, newNode, pos);\n\n\t // translate rightwards nodes' positions\n\t for (r = pos + 1; r < layer.length; r++) {\n\t node = layer[r];\n\t node.gridPosition = node.gridPosition + 1;\n\t }\n\n\t newLink = new Link(p, newNode);\n\t newLink.depthOfDumminess = 0;\n\t addLinkBetweenLayers(i - 1, i, newLink);\n\n\t p = newNode;\n\n\t // add the new node and the new link to the graph\n\t this.graph._addNode(newNode);\n\t this.graph.addLink(newLink);\n\n\t newNode.index = this.graph.nodes.length - 1;\n\t this.mapVirtualNode(newNode, link);\n\t }\n\t addLinkBetweenLayers(dLayer - 1, dLayer, link);\n\n\t // Set the origin of the real arrow to the last dummy\n\t link.changeSource(p);\n\t link.depthOfDumminess = dLayer - oLayer - 1;\n\t } else {\n\t addLinkBetweenLayers(oLayer, dLayer, link);\n\t }\n\t }\n\t },\n\n\t /// \n\t /// Removes the dummy nodes inserted earlier to break long links.\n\t /// \n\t /// The virtual nodes are effectively turned into intermediate connection points.\n\t _dedummify: function () {\n\t var dedum = true;\n\t while (dedum) {\n\t dedum = false;\n\n\t for (var l = 0; l < this.graph.links.length; l++) {\n\t var link = this.graph.links[l];\n\t if (!link.depthOfDumminess) {\n\t continue;\n\t }\n\n\t var points = [];\n\n\t // add points in reverse order\n\t points.unshift({ x: link.target.x, y: link.target.y });\n\t points.unshift({ x: link.source.x, y: link.source.y });\n\n\t // _dedummify the link\n\t var temp = link;\n\t var depthOfDumminess = link.depthOfDumminess;\n\t for (var d = 0; d < depthOfDumminess; d++) {\n\t var node = temp.source;\n\t var prevLink = node.incoming[0];\n\n\t points.unshift({ x: prevLink.source.x, y: prevLink.source.y });\n\n\t temp = prevLink;\n\t }\n\n\t // restore the original link origin\n\t link.changeSource(temp.source);\n\n\t // reset dummification flag\n\t link.depthOfDumminess = 0;\n\n\t // note that we only need the intermediate points, floating links have been dropped in the analysis\n\t if (points.length > 2) {\n\t // first and last are the endpoints\n\t points.splice(0, 1);\n\t points.splice(points.length - 1);\n\t link.points = points;\n\t }\n\t else {\n\t link.points = [];\n\t }\n\n\t // we are not going to delete the dummy elements;\n\t // they won't be needed anymore anyway.\n\n\t dedum = true;\n\t break;\n\t }\n\t }\n\t },\n\n\t /// \n\t /// Optimizes/reduces the crossings between the layers by turning the crossing problem into a (combinatorial) number ordering problem.\n\t /// \n\t _optimizeCrossings: function () {\n\t var moves = -1, i;\n\t var maxIterations = 3;\n\t var iter = 0;\n\n\t while (moves !== 0) {\n\t if (iter++ > maxIterations) {\n\t break;\n\t }\n\n\t moves = 0;\n\n\t for (i = this.layers.length - 1; i >= 1; i--) {\n\t moves += this.optimizeLayerCrossings(false, i);\n\t }\n\n\t for (i = 0; i < this.layers.length - 1; i++) {\n\t moves += this.optimizeLayerCrossings(true, i);\n\t }\n\t }\n\t },\n\n\t calcUpData: function (layer) {\n\t if (layer === 0) {\n\t return;\n\t }\n\n\t var considered = this.layers[layer], i, l, link;\n\t var upLayer = new Set();\n\t var temp = this.layers[layer - 1];\n\t for (i = 0; i < temp.length; i++) {\n\t upLayer.add(temp[i]);\n\t }\n\n\t for (i = 0; i < considered.length; i++) {\n\t var node = considered[i];\n\n\t // calculate barycenter\n\t var sum = 0;\n\t var total = 0;\n\n\t for (l = 0; l < node.incoming.length; l++) {\n\t link = node.incoming[l];\n\t if (upLayer.contains(link.source)) {\n\t total++;\n\t sum += link.source.gridPosition;\n\t }\n\t }\n\n\t for (l = 0; l < node.outgoing.length; l++) {\n\t link = node.outgoing[l];\n\t if (upLayer.contains(link.target)) {\n\t total++;\n\t sum += link.target.gridPosition;\n\t }\n\t }\n\n\t if (total > 0) {\n\t node.uBaryCenter = sum / total;\n\t node.upstreamLinkCount = total;\n\t }\n\t else {\n\t node.uBaryCenter = i;\n\t node.upstreamLinkCount = 0;\n\t }\n\t }\n\t },\n\n\t calcDownData: function (layer) {\n\t if (layer === this.layers.length - 1) {\n\t return;\n\t }\n\n\t var considered = this.layers[layer], i , l, link;\n\t var downLayer = new Set();\n\t var temp = this.layers[layer + 1];\n\t for (i = 0; i < temp.length; i++) {\n\t downLayer.add(temp[i]);\n\t }\n\n\t for (i = 0; i < considered.length; i++) {\n\t var node = considered[i];\n\n\t // calculate barycenter\n\t var sum = 0;\n\t var total = 0;\n\n\t for (l = 0; l < node.incoming.length; l++) {\n\t link = node.incoming[l];\n\t if (downLayer.contains(link.source)) {\n\t total++;\n\t sum += link.source.gridPosition;\n\t }\n\t }\n\n\t for (l = 0; l < node.outgoing.length; l++) {\n\t link = node.outgoing[l];\n\t if (downLayer.contains(link.target)) {\n\t total++;\n\t sum += link.target.gridPosition;\n\t }\n\t }\n\n\t if (total > 0) {\n\t node.dBaryCenter = sum / total;\n\t node.downstreamLinkCount = total;\n\t }\n\t else {\n\t node.dBaryCenter = i;\n\t node.downstreamLinkCount = 0;\n\t }\n\t }\n\t },\n\n\t /// \n\t /// Optimizes the crossings.\n\t /// \n\t /// The big trick here is the usage of weights or values attached to connected nodes which turn a problem of crossing links\n\t /// to an a problem of ordering numbers.\n\t /// The layer index.\n\t /// If set to true we move down in the layer stack.\n\t /// The number of nodes having moved, i.e. the number of crossings reduced.\n\t optimizeLayerCrossings: function (down, layer) {\n\t var iconsidered;\n\t var considered;\n\n\t if (down) {\n\t considered = this.layers[iconsidered = layer + 1];\n\t }\n\t else {\n\t considered = this.layers[iconsidered = layer - 1];\n\t }\n\n\t // remember what it was\n\t var presorted = considered.slice(0);\n\n\t // calculate barycenters for all nodes in the considered layer\n\t if (down) {\n\t this.calcUpData(iconsidered);\n\t }\n\t else {\n\t this.calcDownData(iconsidered);\n\t }\n\n\t var that = this;\n\t // sort nodes within this layer according to the barycenters\n\t considered.sort(function(n1, n2) {\n\t var n1BaryCenter = that.calcBaryCenter(n1),\n\t n2BaryCenter = that.calcBaryCenter(n2);\n\t if (Math.abs(n1BaryCenter - n2BaryCenter) < 0.0001) {\n\t // in case of coinciding barycenters compare by the count of in/out links\n\t if (n1.degree() === n2.degree()) {\n\t return that.compareByIndex(n1, n2);\n\t }\n\t else if (n1.degree() < n2.degree()) {\n\t return 1;\n\t }\n\t return -1;\n\t }\n\t var compareValue = (n2BaryCenter - n1BaryCenter) * 1000;\n\t if (compareValue > 0) {\n\t return -1;\n\t }\n\t else if (compareValue < 0) {\n\t return 1;\n\t }\n\t return that.compareByIndex(n1, n2);\n\t });\n\n\t // count relocations\n\t var i, moves = 0;\n\t for (i = 0; i < considered.length; i++) {\n\t if (considered[i] !== presorted[i]) {\n\t moves++;\n\t }\n\t }\n\n\t if (moves > 0) {\n\t // now that the boxes have been arranged, update their grid positions\n\t var inode = 0;\n\t for (i = 0; i < considered.length; i++) {\n\t var node = considered[i];\n\t node.gridPosition = inode++;\n\t }\n\t }\n\n\t return moves;\n\t },\n\n\t /// \n\t /// Swaps a pair of nodes in a layer.\n\t /// \n\t /// Index of the layer.\n\t /// The Nth node in the layer.\n\t _swapPairs: function () {\n\t var maxIterations = this.options.layeredIterations;\n\t var iter = 0;\n\n\t while (true) {\n\t if (iter++ > maxIterations) {\n\t break;\n\t }\n\n\t var downwards = (iter % 4 <= 1);\n\t var secondPass = (iter % 4 === 1);\n\n\t for (var l = (downwards ? 0 : this.layers.length - 1);\n\t downwards ? l <= this.layers.length - 1 : l >= 0; l += (downwards ? 1 : -1)) {\n\t var layer = this.layers[l];\n\t var hasSwapped = false;\n\n\t // there is no need to recalculate crossings if they were calculated\n\t // on the previous step and nothing has changed\n\t var calcCrossings = true;\n\t var memCrossings = 0;\n\n\t for (var n = 0; n < layer.length - 1; n++) {\n\t // count crossings\n\t var up = 0;\n\t var down = 0;\n\t var crossBefore = 0;\n\n\t if (calcCrossings) {\n\t if (l !== 0) {\n\t up = this.countLinksCrossingBetweenTwoLayers(l - 1, l);\n\t }\n\t if (l !== this.layers.length - 1) {\n\t down = this.countLinksCrossingBetweenTwoLayers(l, l + 1);\n\t }\n\t if (downwards) {\n\t up *= 2;\n\t }\n\t else {\n\t down *= 2;\n\t }\n\n\t crossBefore = up + down;\n\t }\n\t else {\n\t crossBefore = memCrossings;\n\t }\n\n\t if (crossBefore === 0) {\n\t continue;\n\t }\n\n\t // Swap nodes\n\t var node1 = layer[n];\n\t var node2 = layer[n + 1];\n\n\t var node1GridPos = node1.gridPosition;\n\t var node2GridPos = node2.gridPosition;\n\t layer[n] = node2;\n\t layer[n + 1] = node1;\n\t node1.gridPosition = node2GridPos;\n\t node2.gridPosition = node1GridPos;\n\n\t // count crossings again and if worse than before, restore swapping\n\t up = 0;\n\t if (l !== 0) {\n\t up = this.countLinksCrossingBetweenTwoLayers(l - 1, l);\n\t }\n\t down = 0;\n\t if (l !== this.layers.length - 1) {\n\t down = this.countLinksCrossingBetweenTwoLayers(l, l + 1);\n\t }\n\t if (downwards) {\n\t up *= 2;\n\t }\n\t else {\n\t down *= 2;\n\t }\n\t var crossAfter = up + down;\n\n\t var revert = false;\n\t if (secondPass) {\n\t revert = crossAfter >= crossBefore;\n\t }\n\t else {\n\t revert = crossAfter > crossBefore;\n\t }\n\n\t if (revert) {\n\t node1 = layer[n];\n\t node2 = layer[n + 1];\n\n\t node1GridPos = node1.gridPosition;\n\t node2GridPos = node2.gridPosition;\n\t layer[n] = node2;\n\t layer[n + 1] = node1;\n\t node1.gridPosition = node2GridPos;\n\t node2.gridPosition = node1GridPos;\n\n\t // nothing has changed, remember the crossings so that\n\t // they are not calculated again on the next step\n\t memCrossings = crossBefore;\n\t calcCrossings = false;\n\t }\n\t else {\n\t hasSwapped = true;\n\t calcCrossings = true;\n\t }\n\t }\n\n\t if (hasSwapped) {\n\t if (l !== this.layers.length - 1) {\n\t this.calcUpData(l + 1);\n\t }\n\t if (l !== 0) {\n\t this.calcDownData(l - 1);\n\t }\n\t }\n\t }\n\t }\n\t },\n\n\t /// \n\t /// Counts the number of links crossing between two layers.\n\t /// \n\t /// The layer index.\n\t /// Another layer index.\n\t /// \n\t countLinksCrossingBetweenTwoLayers: function (ulayer, dlayer) {\n\t var links = this.layers[ulayer].linksTo[dlayer];\n\t var link1, link2, n11, n12, n21, n22, l1, l2;\n\t var crossings = 0;\n\t var length = links.length;\n\n\t for (l1 = 0; l1 < length; l1++) {\n\t link1 = links[l1];\n\t for (l2 = l1 + 1; l2 < length; l2++) {\n\n\t link2 = links[l2];\n\n\t if (link1.target.layer === dlayer) {\n\t n11 = link1.source;\n\t n12 = link1.target;\n\t }\n\t else {\n\t n11 = link1.target;\n\t n12 = link1.source;\n\t }\n\n\t if (link2.target.layer === dlayer) {\n\t n21 = link2.source;\n\t n22 = link2.target;\n\t }\n\t else {\n\t n21 = link2.target;\n\t n22 = link2.source;\n\t }\n\n\t var n11gp = n11.gridPosition;\n\t var n12gp = n12.gridPosition;\n\t var n21gp = n21.gridPosition;\n\t var n22gp = n22.gridPosition;\n\n\t if ((n11gp - n21gp) * (n12gp - n22gp) < 0) {\n\t crossings++;\n\t }\n\t }\n\t }\n\n\t return crossings;\n\t },\n\n\t calcBaryCenter: function (node) {\n\t var upstreamLinkCount = node.upstreamLinkCount;\n\t var downstreamLinkCount = node.downstreamLinkCount;\n\t var uBaryCenter = node.uBaryCenter;\n\t var dBaryCenter = node.dBaryCenter;\n\n\t if (upstreamLinkCount > 0 && downstreamLinkCount > 0) {\n\t return (uBaryCenter + dBaryCenter) / 2;\n\t }\n\t if (upstreamLinkCount > 0) {\n\t return uBaryCenter;\n\t }\n\t if (downstreamLinkCount > 0) {\n\t return dBaryCenter;\n\t }\n\n\t return 0;\n\t },\n\n\t _gridPositionComparer: function (x, y) {\n\t if (x.gridPosition < y.gridPosition) {\n\t return -1;\n\t }\n\t if (x.gridPosition > y.gridPosition) {\n\t return 1;\n\t }\n\t return 0;\n\t },\n\n\t _positionAscendingComparer: function (x, y) {\n\t return x.k < y.k ? -1 : x.k > y.k ? 1 : 0;\n\t },\n\n\t _positionDescendingComparer: function (x, y) {\n\t return x.k < y.k ? 1 : x.k > y.k ? -1 : 0;\n\t },\n\n\t _firstVirtualNode: function (layer) {\n\t for (var c = 0; c < layer.length; c++) {\n\t if (layer[c].isVirtual) {\n\t return c;\n\t }\n\t }\n\t return -1;\n\t },\n\n\t compareByIndex: function (o1, o2) {\n\t var i1 = o1.index;\n\t var i2 = o2.index;\n\n\t if (i1 < i2) {\n\t return 1;\n\t }\n\n\t if (i1 > i2) {\n\t return -1;\n\t }\n\n\t return 0;\n\t },\n\n\t intDiv: function (numerator, denominator) {\n\t return (numerator - numerator % denominator) / denominator;\n\t },\n\n\t nextVirtualNode: function (layer, node) {\n\t var nodeIndex = node.layerIndex;\n\t for (var i = nodeIndex + 1; i < layer.length; ++i) {\n\t if (layer[i].isVirtual) {\n\t return layer[i];\n\t }\n\t }\n\t return null;\n\t }\n\n\t });\n\n\t /**\n\t * Captures the state of a diagram; node positions, link points and so on.\n\t * @type {*}\n\t */\n\t var LayoutState = kendo.Class.extend({\n\t init: function (diagram, graphOrNodes) {\n\t if (Utils.isUndefined(diagram)) {\n\t throw \"No diagram given\";\n\t }\n\t this.diagram = diagram;\n\t this.nodeMap = new Dictionary();\n\t this.linkMap = new Dictionary();\n\t this.capture(graphOrNodes ? graphOrNodes : diagram);\n\t },\n\n\t /**\n\t * Will capture either\n\t * - the state of the shapes and the intermediate points of the connections in the diagram\n\t * - the bounds of the nodes contained in the Graph together with the intermediate points of the links in the Graph\n\t * - the bounds of the nodes in the Array\n\t * - the links points and node bounds in the literal object\n\t * @param diagramOrGraphOrNodes\n\t */\n\t capture: function (diagramOrGraphOrNodes) {\n\t var node,\n\t nodes,\n\t shape,\n\t i,\n\t conn,\n\t link,\n\t links;\n\n\t if (diagramOrGraphOrNodes instanceof diagram.Graph) {\n\n\t for (i = 0; i < diagramOrGraphOrNodes.nodes.length; i++) {\n\t node = diagramOrGraphOrNodes.nodes[i];\n\t shape = node.associatedShape;\n\t //shape.bounds(new Rect(node.x, node.y, node.width, node.height));\n\t this.nodeMap.set(shape.visual.id, new Rect(node.x, node.y, node.width, node.height));\n\t }\n\t for (i = 0; i < diagramOrGraphOrNodes.links.length; i++) {\n\t link = diagramOrGraphOrNodes.links[i];\n\t conn = link.associatedConnection;\n\t this.linkMap.set(conn.visual.id, link.points());\n\t }\n\t }\n\t else if (diagramOrGraphOrNodes instanceof Array) {\n\t nodes = diagramOrGraphOrNodes;\n\t for (i = 0; i < nodes.length; i++) {\n\t node = nodes[i];\n\t shape = node.associatedShape;\n\t if (shape) {\n\t this.nodeMap.set(shape.visual.id, new Rect(node.x, node.y, node.width, node.height));\n\t }\n\t }\n\t }\n\t else if (diagramOrGraphOrNodes.hasOwnProperty(\"links\") && diagramOrGraphOrNodes.hasOwnProperty(\"nodes\")) {\n\t nodes = diagramOrGraphOrNodes.nodes;\n\t links = diagramOrGraphOrNodes.links;\n\t for (i = 0; i < nodes.length; i++) {\n\t node = nodes[i];\n\t shape = node.associatedShape;\n\t if (shape) {\n\t this.nodeMap.set(shape.visual.id, new Rect(node.x, node.y, node.width, node.height));\n\t }\n\t }\n\t for (i = 0; i < links.length; i++) {\n\t link = links[i];\n\t conn = link.associatedConnection;\n\t if (conn) {\n\t this.linkMap.set(conn.visual.id, link.points);\n\t }\n\t }\n\t }\n\t else { // capture the diagram\n\t var shapes = this.diagram.shapes;\n\t var connections = this.diagram.connections;\n\t for (i = 0; i < shapes.length; i++) {\n\t shape = shapes[i];\n\t this.nodeMap.set(shape.visual.id, shape.bounds());\n\t }\n\t for (i = 0; i < connections.length; i++) {\n\t conn = connections[i];\n\t this.linkMap.set(conn.visual.id, conn.points());\n\t }\n\t }\n\t }\n\t });\n\n\t deepExtend(diagram, {\n\t init: function (element) {\n\t kendo.init(element, diagram.ui);\n\t },\n\t SpringLayout: SpringLayout,\n\t TreeLayout: TreeLayout,\n\t GraphAdapter: DiagramToHyperTreeAdapter,\n\t LayeredLayout: LayeredLayout,\n\t LayoutBase: LayoutBase,\n\t LayoutState: LayoutState\n\t });\n\t})(window.kendo.jQuery);\n\n\t}, __webpack_require__(3));\n\n\n/***/ }),\n\n/***/ 910:\n/***/ (function(module, exports) {\n\n\tmodule.exports = require(\"./math\");\n\n/***/ })\n\n/******/ });"],"sourceRoot":""}